graphql 1.8.0.pre2 → 1.8.0.pre3
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.rb +1 -1
- data/lib/graphql/deprecated_dsl.rb +2 -0
- data/lib/graphql/enum_type.rb +1 -1
- data/lib/graphql/field.rb +10 -1
- data/lib/graphql/input_object_type.rb +3 -1
- data/lib/graphql/introspection.rb +3 -10
- data/lib/graphql/introspection/base_object.rb +15 -0
- data/lib/graphql/introspection/directive_location_enum.rb +11 -7
- data/lib/graphql/introspection/directive_type.rb +23 -16
- data/lib/graphql/introspection/dynamic_fields.rb +11 -0
- data/lib/graphql/introspection/entry_points.rb +29 -0
- data/lib/graphql/introspection/enum_value_type.rb +16 -11
- data/lib/graphql/introspection/field_type.rb +21 -12
- data/lib/graphql/introspection/input_value_type.rb +26 -23
- data/lib/graphql/introspection/schema_field.rb +7 -2
- data/lib/graphql/introspection/schema_type.rb +36 -22
- data/lib/graphql/introspection/type_by_name_field.rb +10 -2
- data/lib/graphql/introspection/type_kind_enum.rb +10 -6
- data/lib/graphql/introspection/type_type.rb +85 -23
- data/lib/graphql/introspection/typename_field.rb +1 -0
- data/lib/graphql/language.rb +1 -0
- data/lib/graphql/language/document_from_schema_definition.rb +129 -37
- data/lib/graphql/language/generation.rb +3 -182
- data/lib/graphql/language/nodes.rb +12 -2
- data/lib/graphql/language/parser.rb +63 -55
- data/lib/graphql/language/parser.y +2 -1
- data/lib/graphql/language/printer.rb +351 -0
- data/lib/graphql/object_type.rb +1 -1
- data/lib/graphql/query.rb +1 -1
- data/lib/graphql/query/arguments.rb +24 -8
- data/lib/graphql/query/context.rb +3 -0
- data/lib/graphql/query/literal_input.rb +4 -1
- data/lib/graphql/railtie.rb +28 -6
- data/lib/graphql/schema.rb +42 -7
- data/lib/graphql/schema/enum.rb +1 -0
- data/lib/graphql/schema/field.rb +26 -5
- data/lib/graphql/schema/field/dynamic_resolve.rb +18 -9
- data/lib/graphql/schema/input_object.rb +2 -2
- data/lib/graphql/schema/introspection_system.rb +93 -0
- data/lib/graphql/schema/late_bound_type.rb +32 -0
- data/lib/graphql/schema/member.rb +21 -1
- data/lib/graphql/schema/member/build_type.rb +8 -6
- data/lib/graphql/schema/member/has_fields.rb +1 -1
- data/lib/graphql/schema/member/instrumentation.rb +3 -1
- data/lib/graphql/schema/member/list_type_proxy.rb +4 -0
- data/lib/graphql/schema/member/non_null_type_proxy.rb +4 -0
- data/lib/graphql/schema/object.rb +2 -1
- data/lib/graphql/schema/printer.rb +33 -266
- data/lib/graphql/schema/traversal.rb +74 -6
- data/lib/graphql/schema/validation.rb +3 -2
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +6 -6
- data/lib/graphql/tracing/scout_tracing.rb +2 -2
- data/lib/graphql/upgrader/member.rb +463 -63
- data/lib/graphql/version.rb +1 -1
- data/spec/fixtures/upgrader/blame_range.original.rb +43 -0
- data/spec/fixtures/upgrader/blame_range.transformed.rb +31 -0
- data/spec/fixtures/upgrader/subscribable.original.rb +51 -0
- data/spec/fixtures/upgrader/subscribable.transformed.rb +46 -0
- data/spec/fixtures/upgrader/type_x.original.rb +35 -0
- data/spec/fixtures/upgrader/type_x.transformed.rb +35 -0
- data/spec/graphql/language/document_from_schema_definition_spec.rb +729 -296
- data/spec/graphql/language/generation_spec.rb +21 -186
- data/spec/graphql/language/nodes_spec.rb +21 -0
- data/spec/graphql/language/printer_spec.rb +203 -0
- data/spec/graphql/query/arguments_spec.rb +14 -4
- data/spec/graphql/query/context_spec.rb +17 -0
- data/spec/graphql/schema/build_from_definition_spec.rb +13 -4
- data/spec/graphql/schema/field_spec.rb +14 -0
- data/spec/graphql/schema/introspection_system_spec.rb +39 -0
- data/spec/graphql/schema/object_spec.rb +12 -1
- data/spec/graphql/schema/printer_spec.rb +14 -14
- data/spec/graphql/tracing/platform_tracing_spec.rb +2 -2
- data/spec/graphql/upgrader/member_spec.rb +274 -62
- data/spec/support/jazz.rb +75 -3
- metadata +38 -9
- data/lib/graphql/introspection/arguments_field.rb +0 -7
- data/lib/graphql/introspection/enum_values_field.rb +0 -18
- data/lib/graphql/introspection/fields_field.rb +0 -13
- data/lib/graphql/introspection/input_fields_field.rb +0 -12
- data/lib/graphql/introspection/interfaces_field.rb +0 -11
- data/lib/graphql/introspection/of_type_field.rb +0 -6
- data/lib/graphql/introspection/possible_types_field.rb +0 -11
@@ -4,8 +4,8 @@ module GraphQL
|
|
4
4
|
class InputObject < GraphQL::Schema::Member
|
5
5
|
extend GraphQL::Delegate
|
6
6
|
|
7
|
-
def initialize(values, context:)
|
8
|
-
@arguments = self.class.arguments_class.new(values, context: context)
|
7
|
+
def initialize(values, context:, defaults_used:)
|
8
|
+
@arguments = self.class.arguments_class.new(values, context: context, defaults_used: defaults_used)
|
9
9
|
@context = context
|
10
10
|
end
|
11
11
|
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
class IntrospectionSystem
|
5
|
+
attr_reader :schema_type, :type_type, :typename_field
|
6
|
+
|
7
|
+
def initialize(schema)
|
8
|
+
@schema = schema
|
9
|
+
@built_in_namespace = GraphQL::Introspection
|
10
|
+
@custom_namespace = schema.introspection_namespace || @built_in_namespace
|
11
|
+
|
12
|
+
# Use to-graphql to avoid sharing with any previous instantiations
|
13
|
+
@schema_type = load_constant(:SchemaType).to_graphql
|
14
|
+
@type_type = load_constant(:TypeType).to_graphql
|
15
|
+
@field_type = load_constant(:FieldType).to_graphql
|
16
|
+
@directive_type = load_constant(:DirectiveType).to_graphql
|
17
|
+
@enum_value_type = load_constant(:EnumValueType).to_graphql
|
18
|
+
@input_value_type = load_constant(:InputValueType).to_graphql
|
19
|
+
@type_kind_enum = load_constant(:TypeKindEnum).to_graphql
|
20
|
+
@directive_location_enum = load_constant(:DirectiveLocationEnum).to_graphql
|
21
|
+
@entry_point_fields = get_fields_from_class(class_sym: :EntryPoints)
|
22
|
+
@dynamic_fields = get_fields_from_class(class_sym: :DynamicFields)
|
23
|
+
end
|
24
|
+
|
25
|
+
def object_types
|
26
|
+
[
|
27
|
+
@schema_type,
|
28
|
+
@type_type,
|
29
|
+
@field_type,
|
30
|
+
@directive_type,
|
31
|
+
@enum_value_type,
|
32
|
+
@input_value_type,
|
33
|
+
@type_kind_enum,
|
34
|
+
@directive_location_enum,
|
35
|
+
]
|
36
|
+
end
|
37
|
+
|
38
|
+
def entry_points
|
39
|
+
@entry_point_fields.values
|
40
|
+
end
|
41
|
+
|
42
|
+
def entry_point(name:)
|
43
|
+
@entry_point_fields[name]
|
44
|
+
end
|
45
|
+
|
46
|
+
def dynamic_fields
|
47
|
+
@dynamic_fields.values
|
48
|
+
end
|
49
|
+
|
50
|
+
def dynamic_field(name:)
|
51
|
+
@dynamic_fields[name]
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def load_constant(class_name)
|
57
|
+
@custom_namespace.const_get(class_name)
|
58
|
+
rescue NameError
|
59
|
+
# Dup the built-in so that the cached fields aren't shared
|
60
|
+
@built_in_namespace.const_get(class_name)
|
61
|
+
end
|
62
|
+
|
63
|
+
def get_fields_from_class(class_sym:)
|
64
|
+
object_class = load_constant(class_sym)
|
65
|
+
object_type_defn = object_class.to_graphql
|
66
|
+
extracted_field_defns = {}
|
67
|
+
object_type_defn.all_fields.each do |field_defn|
|
68
|
+
inner_resolve = field_defn.resolve_proc
|
69
|
+
resolve_with_instantiate = PerFieldProxyResolve.new(object_class: object_class, inner_resolve: inner_resolve)
|
70
|
+
extracted_field_defns[field_defn.name] = field_defn.redefine(resolve: resolve_with_instantiate)
|
71
|
+
end
|
72
|
+
extracted_field_defns
|
73
|
+
end
|
74
|
+
|
75
|
+
class PerFieldProxyResolve
|
76
|
+
def initialize(object_class:, inner_resolve:)
|
77
|
+
@object_class = object_class
|
78
|
+
@inner_resolve = inner_resolve
|
79
|
+
end
|
80
|
+
|
81
|
+
def call(obj, args, ctx)
|
82
|
+
query_ctx = ctx.query.context
|
83
|
+
# Remove the QueryType wrapper
|
84
|
+
if obj.is_a?(GraphQL::Schema::Object)
|
85
|
+
obj = obj.object
|
86
|
+
end
|
87
|
+
wrapped_object = @object_class.new(obj, query_ctx)
|
88
|
+
@inner_resolve.call(wrapped_object, args, ctx)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
# A stand-in for a type which will be resolved in a given schema, by name.
|
5
|
+
# TODO: support argument types too, make this a public API somehow
|
6
|
+
# @api Private
|
7
|
+
class LateBoundType
|
8
|
+
attr_reader :name
|
9
|
+
def initialize(local_name)
|
10
|
+
@name = local_name
|
11
|
+
end
|
12
|
+
|
13
|
+
def unwrap
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_non_null_type
|
18
|
+
GraphQL::NonNullType.new(of_type: self)
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_list_type
|
22
|
+
GraphQL::ListType.new(of_type: self)
|
23
|
+
end
|
24
|
+
|
25
|
+
def inspect
|
26
|
+
"#<LateBoundType @name=#{name}>"
|
27
|
+
end
|
28
|
+
|
29
|
+
alias :to_s :inspect
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -15,6 +15,11 @@ module GraphQL
|
|
15
15
|
def graphql_definition
|
16
16
|
@graphql_definition ||= to_graphql
|
17
17
|
end
|
18
|
+
|
19
|
+
def initialize_copy(original)
|
20
|
+
super
|
21
|
+
@graphql_definition = nil
|
22
|
+
end
|
18
23
|
end
|
19
24
|
|
20
25
|
# These constants are interpreted as GraphQL types
|
@@ -58,7 +63,7 @@ module GraphQL
|
|
58
63
|
if new_name
|
59
64
|
@graphql_name = new_name
|
60
65
|
else
|
61
|
-
|
66
|
+
overridden_graphql_name || self.name.split("::").last.sub(/Type\Z/, "")
|
62
67
|
end
|
63
68
|
end
|
64
69
|
|
@@ -84,6 +89,15 @@ module GraphQL
|
|
84
89
|
end
|
85
90
|
end
|
86
91
|
|
92
|
+
# @return [Boolean] If true, this object is part of the introspection system
|
93
|
+
def introspection(new_introspection = nil)
|
94
|
+
if !new_introspection.nil?
|
95
|
+
@introspection = new_introspection
|
96
|
+
else
|
97
|
+
@introspection || (superclass <= Schema::Member ? superclass.introspection : false)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
87
101
|
def to_graphql
|
88
102
|
raise NotImplementedError
|
89
103
|
end
|
@@ -95,6 +109,12 @@ module GraphQL
|
|
95
109
|
def to_non_null_type
|
96
110
|
NonNullTypeProxy.new(self)
|
97
111
|
end
|
112
|
+
|
113
|
+
protected
|
114
|
+
|
115
|
+
def overridden_graphql_name
|
116
|
+
@graphql_name || (superclass <= GraphQL::Schema::Member ? superclass.overridden_graphql_name : nil)
|
117
|
+
end
|
98
118
|
end
|
99
119
|
end
|
100
120
|
end
|
@@ -43,7 +43,7 @@ module GraphQL
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|
46
|
-
when GraphQL::BaseType
|
46
|
+
when GraphQL::BaseType, GraphQL::Schema::LateBoundType
|
47
47
|
type_expr
|
48
48
|
when Array
|
49
49
|
if type_expr.length != 1
|
@@ -77,7 +77,7 @@ module GraphQL
|
|
77
77
|
|
78
78
|
def to_type_name(something)
|
79
79
|
case something
|
80
|
-
when GraphQL::BaseType
|
80
|
+
when GraphQL::BaseType, GraphQL::Schema::LateBoundType
|
81
81
|
something.unwrap.name
|
82
82
|
when Array
|
83
83
|
to_type_name(something.first)
|
@@ -95,11 +95,13 @@ module GraphQL
|
|
95
95
|
end
|
96
96
|
|
97
97
|
def camelize(string)
|
98
|
-
return string unless string.include?(
|
99
|
-
|
100
|
-
|
101
|
-
|
98
|
+
return string unless string.include?("_")
|
99
|
+
camelized = string.split('_').map(&:capitalize).join
|
100
|
+
camelized[0] = camelized[0].downcase
|
101
|
+
if string.start_with?("__")
|
102
|
+
camelized = "__#{camelized}"
|
102
103
|
end
|
104
|
+
camelized
|
103
105
|
end
|
104
106
|
|
105
107
|
def underscore(string)
|
@@ -100,7 +100,9 @@ module GraphQL
|
|
100
100
|
end
|
101
101
|
|
102
102
|
if concrete_type && (object_class = concrete_type.metadata[:object_class])
|
103
|
-
|
103
|
+
# use the query-level context here, since it won't be field-specific anyways
|
104
|
+
query_ctx = ctx.query.context
|
105
|
+
object_class.new(obj, query_ctx)
|
104
106
|
else
|
105
107
|
obj
|
106
108
|
end
|
@@ -45,9 +45,10 @@ module GraphQL
|
|
45
45
|
obj_type.name = graphql_name
|
46
46
|
obj_type.description = description
|
47
47
|
obj_type.interfaces = interfaces
|
48
|
+
obj_type.introspection = introspection
|
48
49
|
|
49
50
|
fields.each do |field_inst|
|
50
|
-
field_defn = field_inst.
|
51
|
+
field_defn = field_inst.to_graphql
|
51
52
|
obj_type.fields[field_defn.name] = field_defn
|
52
53
|
end
|
53
54
|
|
@@ -36,7 +36,7 @@ module GraphQL
|
|
36
36
|
# printer = GraphQL::Schema::Printer.new(MySchema)
|
37
37
|
# puts printer.print_type(post_type)
|
38
38
|
#
|
39
|
-
class Printer
|
39
|
+
class Printer < GraphQL::Language::Printer
|
40
40
|
attr_reader :schema, :warden
|
41
41
|
|
42
42
|
# @param schema [GraphQL::Schema]
|
@@ -45,21 +45,32 @@ module GraphQL
|
|
45
45
|
# @param except [<#call(member, ctx)>]
|
46
46
|
# @param introspection [Boolean] Should include the introspection types in the string?
|
47
47
|
def initialize(schema, context: nil, only: nil, except: nil, introspection: false)
|
48
|
-
@
|
49
|
-
|
48
|
+
@document_from_schema = GraphQL::Language::DocumentFromSchemaDefinition.new(
|
49
|
+
schema,
|
50
|
+
context: context,
|
51
|
+
only: only,
|
52
|
+
except: except,
|
53
|
+
include_introspection_types: introspection,
|
54
|
+
)
|
55
|
+
|
56
|
+
@document = @document_from_schema.document
|
50
57
|
|
51
|
-
|
52
|
-
filter = GraphQL::Filter.new(except: blacklist)
|
53
|
-
@warden = GraphQL::Schema::Warden.new(filter, schema: @schema, context: @context)
|
58
|
+
@schema = schema
|
54
59
|
end
|
55
60
|
|
56
61
|
# Return the GraphQL schema string for the introspection type system
|
57
62
|
def self.print_introspection_schema
|
58
63
|
query_root = ObjectType.define(name: "Root")
|
59
64
|
schema = GraphQL::Schema.define(query: query_root)
|
60
|
-
|
61
|
-
|
62
|
-
|
65
|
+
|
66
|
+
introspection_schema_ast = GraphQL::Language::DocumentFromSchemaDefinition.new(
|
67
|
+
schema,
|
68
|
+
except: ->(member, _) { member.name == "Root" },
|
69
|
+
include_introspection_types: true,
|
70
|
+
include_built_in_directives: true,
|
71
|
+
).document
|
72
|
+
|
73
|
+
introspection_schema_ast.to_query_string(printer: IntrospectionPrinter.new)
|
63
74
|
end
|
64
75
|
|
65
76
|
# Return a GraphQL schema string for the defined types in the schema
|
@@ -74,277 +85,33 @@ module GraphQL
|
|
74
85
|
|
75
86
|
# Return a GraphQL schema string for the defined types in the schema
|
76
87
|
def print_schema
|
77
|
-
|
78
|
-
|
79
|
-
printable_types = warden.types.reject(&:default_scalar?)
|
80
|
-
|
81
|
-
type_definitions = printable_types
|
82
|
-
.sort_by(&:name)
|
83
|
-
.map { |type| print_type(type) }
|
84
|
-
|
85
|
-
[print_schema_definition].compact
|
86
|
-
.concat(directive_definitions)
|
87
|
-
.concat(type_definitions).join("\n\n")
|
88
|
+
print(@document)
|
88
89
|
end
|
89
90
|
|
90
91
|
def print_type(type)
|
91
|
-
|
92
|
+
node = @document_from_schema.build_object_type_node(type)
|
93
|
+
print(node)
|
92
94
|
end
|
93
95
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
IS_USER_DEFINED_MEMBER = ->(member) {
|
98
|
-
case member
|
99
|
-
when GraphQL::BaseType
|
100
|
-
!member.introspection?
|
101
|
-
when GraphQL::Directive
|
102
|
-
!member.default_directive?
|
103
|
-
else
|
104
|
-
true
|
105
|
-
end
|
106
|
-
}
|
107
|
-
|
108
|
-
private_constant :IS_USER_DEFINED_MEMBER
|
96
|
+
def print_directive(directive)
|
97
|
+
if directive.name == "deprecated"
|
98
|
+
reason = directive.arguments.find { |arg| arg.name == "reason" }
|
109
99
|
|
110
|
-
|
111
|
-
|
112
|
-
if only
|
113
|
-
->(m, ctx) { !only.call(m, ctx) }
|
114
|
-
elsif except
|
115
|
-
except
|
100
|
+
if reason.value == GraphQL::Directive::DEFAULT_DEPRECATION_REASON
|
101
|
+
"@deprecated"
|
116
102
|
else
|
117
|
-
|
103
|
+
"@deprecated(reason: \"#{reason.value}\")"
|
118
104
|
end
|
119
105
|
else
|
120
|
-
|
121
|
-
->(m, ctx) { !(IS_USER_DEFINED_MEMBER.call(m) && only.call(m, ctx)) }
|
122
|
-
elsif except
|
123
|
-
->(m, ctx) { !IS_USER_DEFINED_MEMBER.call(m) || except.call(m, ctx) }
|
124
|
-
else
|
125
|
-
->(m, ctx) { !IS_USER_DEFINED_MEMBER.call(m) }
|
126
|
-
end
|
106
|
+
super
|
127
107
|
end
|
128
108
|
end
|
129
109
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
(schema.subscription.nil? || schema.subscription.name == 'Subscription')
|
134
|
-
return
|
110
|
+
class IntrospectionPrinter < GraphQL::Language::Printer
|
111
|
+
def print_schema_definition(schema)
|
112
|
+
"schema {\n query: Root\n}"
|
135
113
|
end
|
136
|
-
|
137
|
-
operations = [:query, :mutation, :subscription].map do |operation_type|
|
138
|
-
object_type = schema.public_send(operation_type)
|
139
|
-
# Special treatment for the introspection schema, which prints `{ query: "Root" }`
|
140
|
-
if object_type && (warden.get_type(object_type.name) || (object_type.name == "Root" && schema.query == object_type))
|
141
|
-
" #{operation_type}: #{object_type.name}\n"
|
142
|
-
else
|
143
|
-
nil
|
144
|
-
end
|
145
|
-
end.compact.join
|
146
|
-
"schema {\n#{operations}}"
|
147
|
-
end
|
148
|
-
|
149
|
-
def print_directive(directive)
|
150
|
-
TypeKindPrinters::DirectivePrinter.print(warden, directive)
|
151
|
-
end
|
152
|
-
|
153
|
-
module TypeKindPrinters
|
154
|
-
module DeprecatedPrinter
|
155
|
-
def print_deprecated(field_or_enum_value)
|
156
|
-
return unless field_or_enum_value.deprecation_reason
|
157
|
-
|
158
|
-
case field_or_enum_value.deprecation_reason
|
159
|
-
when nil
|
160
|
-
''
|
161
|
-
when '', GraphQL::Directive::DEFAULT_DEPRECATION_REASON
|
162
|
-
' @deprecated'
|
163
|
-
else
|
164
|
-
" @deprecated(reason: #{field_or_enum_value.deprecation_reason.to_s.inspect})"
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
module DescriptionPrinter
|
170
|
-
def print_description(definition, indentation='', first_in_block=true)
|
171
|
-
return '' unless definition.description
|
172
|
-
|
173
|
-
description = indentation != '' && !first_in_block ? "\n".dup : "".dup
|
174
|
-
description << GraphQL::Language::Comments.commentize(definition.description, indent: indentation)
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
module ArgsPrinter
|
179
|
-
include DescriptionPrinter
|
180
|
-
def print_args(warden, field, indentation = '')
|
181
|
-
arguments = warden.arguments(field)
|
182
|
-
return if arguments.empty?
|
183
|
-
|
184
|
-
if arguments.all?{ |arg| !arg.description }
|
185
|
-
return "(#{arguments.map{ |arg| print_input_value(arg) }.join(", ")})"
|
186
|
-
end
|
187
|
-
|
188
|
-
out = "(\n".dup
|
189
|
-
out << arguments.sort_by(&:name).map.with_index{ |arg, i|
|
190
|
-
"#{print_description(arg, " #{indentation}", i == 0)} #{indentation}"\
|
191
|
-
"#{print_input_value(arg)}"
|
192
|
-
}.join("\n")
|
193
|
-
out << "\n#{indentation})"
|
194
|
-
end
|
195
|
-
|
196
|
-
def print_input_value(arg)
|
197
|
-
if arg.default_value?
|
198
|
-
default_string = " = #{print_value(arg.default_value, arg.type)}"
|
199
|
-
else
|
200
|
-
default_string = nil
|
201
|
-
end
|
202
|
-
|
203
|
-
"#{arg.name}: #{arg.type.to_s}#{default_string}"
|
204
|
-
end
|
205
|
-
|
206
|
-
def print_value(value, type)
|
207
|
-
case type
|
208
|
-
when FLOAT_TYPE
|
209
|
-
return 'null' if value.nil?
|
210
|
-
value.to_f.inspect
|
211
|
-
when INT_TYPE
|
212
|
-
return 'null' if value.nil?
|
213
|
-
value.to_i.inspect
|
214
|
-
when BOOLEAN_TYPE
|
215
|
-
return 'null' if value.nil?
|
216
|
-
(!!value).inspect
|
217
|
-
when ScalarType, ID_TYPE, STRING_TYPE
|
218
|
-
return 'null' if value.nil?
|
219
|
-
value.to_s.inspect
|
220
|
-
when EnumType
|
221
|
-
return 'null' if value.nil?
|
222
|
-
type.coerce_isolated_result(value)
|
223
|
-
when InputObjectType
|
224
|
-
return 'null' if value.nil?
|
225
|
-
fields = value.to_h.map{ |field_name, field_value|
|
226
|
-
field_type = type.input_fields.fetch(field_name.to_s).type
|
227
|
-
"#{field_name}: #{print_value(field_value, field_type)}"
|
228
|
-
}.join(", ")
|
229
|
-
"{#{fields}}"
|
230
|
-
when NonNullType
|
231
|
-
print_value(value, type.of_type)
|
232
|
-
when ListType
|
233
|
-
return 'null' if value.nil?
|
234
|
-
"[#{value.to_a.map{ |v| print_value(v, type.of_type) }.join(", ")}]"
|
235
|
-
else
|
236
|
-
raise NotImplementedError, "Unexpected value type #{type.inspect}"
|
237
|
-
end
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
module FieldPrinter
|
242
|
-
include DeprecatedPrinter
|
243
|
-
include ArgsPrinter
|
244
|
-
include DescriptionPrinter
|
245
|
-
def print_fields(warden, type)
|
246
|
-
fields = warden.fields(type)
|
247
|
-
fields.sort_by(&:name).map.with_index { |field, i|
|
248
|
-
"#{print_description(field, ' ', i == 0)}"\
|
249
|
-
" #{field.name}#{print_args(warden, field, ' ')}: #{field.type}#{print_deprecated(field)}"
|
250
|
-
}.join("\n")
|
251
|
-
end
|
252
|
-
end
|
253
|
-
|
254
|
-
class DirectivePrinter
|
255
|
-
extend ArgsPrinter
|
256
|
-
extend DescriptionPrinter
|
257
|
-
def self.print(warden, directive)
|
258
|
-
"#{print_description(directive)}"\
|
259
|
-
"directive @#{directive.name}#{print_args(warden, directive)} "\
|
260
|
-
"on #{directive.locations.join(' | ')}"
|
261
|
-
end
|
262
|
-
end
|
263
|
-
|
264
|
-
class ScalarPrinter
|
265
|
-
extend DescriptionPrinter
|
266
|
-
def self.print(warden, type)
|
267
|
-
"#{print_description(type)}"\
|
268
|
-
"scalar #{type.name}"
|
269
|
-
end
|
270
|
-
end
|
271
|
-
|
272
|
-
class ObjectPrinter
|
273
|
-
extend FieldPrinter
|
274
|
-
extend DescriptionPrinter
|
275
|
-
def self.print(warden, type)
|
276
|
-
interfaces = warden.interfaces(type)
|
277
|
-
if interfaces.any?
|
278
|
-
implementations = " implements #{interfaces.sort_by(&:name).map(&:to_s).join(", ")}"
|
279
|
-
else
|
280
|
-
implementations = nil
|
281
|
-
end
|
282
|
-
|
283
|
-
"#{print_description(type)}"\
|
284
|
-
"type #{type.name}#{implementations} {\n"\
|
285
|
-
"#{print_fields(warden, type)}\n"\
|
286
|
-
"}"
|
287
|
-
end
|
288
|
-
end
|
289
|
-
|
290
|
-
class InterfacePrinter
|
291
|
-
extend FieldPrinter
|
292
|
-
extend DescriptionPrinter
|
293
|
-
def self.print(warden, type)
|
294
|
-
"#{print_description(type)}"\
|
295
|
-
"interface #{type.name} {\n#{print_fields(warden, type)}\n}"
|
296
|
-
end
|
297
|
-
end
|
298
|
-
|
299
|
-
class UnionPrinter
|
300
|
-
extend DescriptionPrinter
|
301
|
-
def self.print(warden, type)
|
302
|
-
possible_types = warden.possible_types(type)
|
303
|
-
"#{print_description(type)}"\
|
304
|
-
"union #{type.name} = #{possible_types.sort_by(&:name).map(&:to_s).join(" | ")}"
|
305
|
-
end
|
306
|
-
end
|
307
|
-
|
308
|
-
class EnumPrinter
|
309
|
-
extend DeprecatedPrinter
|
310
|
-
extend DescriptionPrinter
|
311
|
-
def self.print(warden, type)
|
312
|
-
enum_values = warden.enum_values(type)
|
313
|
-
|
314
|
-
values = enum_values.sort_by(&:name).map.with_index { |v, i|
|
315
|
-
"#{print_description(v, ' ', i == 0)}"\
|
316
|
-
" #{v.name}#{print_deprecated(v)}"
|
317
|
-
}.join("\n")
|
318
|
-
|
319
|
-
"#{print_description(type)}"\
|
320
|
-
"enum #{type.name} {\n#{values}\n}"
|
321
|
-
end
|
322
|
-
end
|
323
|
-
|
324
|
-
class InputObjectPrinter
|
325
|
-
extend FieldPrinter
|
326
|
-
extend DescriptionPrinter
|
327
|
-
def self.print(warden, type)
|
328
|
-
arguments = warden.arguments(type)
|
329
|
-
fields = arguments.sort_by(&:name).map.with_index{ |field, i|
|
330
|
-
"#{print_description(field, " ", i == 0)}"\
|
331
|
-
" #{print_input_value(field)}"
|
332
|
-
}.join("\n")
|
333
|
-
"#{print_description(type)}"\
|
334
|
-
"input #{type.name} {\n#{fields}\n}"
|
335
|
-
end
|
336
|
-
end
|
337
|
-
|
338
|
-
STRATEGIES = {
|
339
|
-
GraphQL::TypeKinds::SCALAR => ScalarPrinter,
|
340
|
-
GraphQL::TypeKinds::OBJECT => ObjectPrinter,
|
341
|
-
GraphQL::TypeKinds::INTERFACE => InterfacePrinter,
|
342
|
-
GraphQL::TypeKinds::UNION => UnionPrinter,
|
343
|
-
GraphQL::TypeKinds::ENUM => EnumPrinter,
|
344
|
-
GraphQL::TypeKinds::INPUT_OBJECT => InputObjectPrinter,
|
345
|
-
}
|
346
114
|
end
|
347
|
-
private_constant :TypeKindPrinters
|
348
115
|
end
|
349
116
|
end
|
350
117
|
end
|