graphql 1.7.7 → 1.7.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- 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/arguments_field.rb +1 -0
- data/lib/graphql/introspection/enum_values_field.rb +1 -0
- data/lib/graphql/introspection/fields_field.rb +1 -0
- data/lib/graphql/introspection/input_fields_field.rb +1 -0
- data/lib/graphql/introspection/interfaces_field.rb +1 -0
- data/lib/graphql/introspection/of_type_field.rb +1 -0
- data/lib/graphql/introspection/possible_types_field.rb +1 -0
- data/lib/graphql/introspection/schema_field.rb +1 -0
- data/lib/graphql/introspection/type_by_name_field.rb +1 -0
- 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/arguments.rb +27 -9
- data/lib/graphql/query/literal_input.rb +4 -1
- data/lib/graphql/schema/printer.rb +33 -266
- data/lib/graphql/tracing/scout_tracing.rb +2 -2
- data/lib/graphql/version.rb +1 -1
- 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 +33 -11
- data/spec/graphql/schema/build_from_definition_spec.rb +13 -4
- data/spec/graphql/schema/printer_spec.rb +14 -14
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d85dab3949103799bd681457cdb2fecd6ddcaddf
|
4
|
+
data.tar.gz: ed5808c8a3caba6bf7834c0c7e2299ad5597eab3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 19330668600890f1dd17e4231e5ded4a43b4cf35dc3c076b07a0b8d54449924c1967c8c9609c4ea9729beaf800c9d63280d48ce7ccefb18b0466db8b54494108
|
7
|
+
data.tar.gz: 80a05ac7f10d5c2a3727d12f4ca8f30cfa3634d8047e1d23cc15f66e1c63940c9d27e0d7d875e05d084897702d56794daf314c830785edae969d8fab0ab06399
|
data/lib/graphql/enum_type.rb
CHANGED
data/lib/graphql/field.rb
CHANGED
@@ -131,6 +131,7 @@ module GraphQL
|
|
131
131
|
:relay_nodes_field,
|
132
132
|
:subscription_scope,
|
133
133
|
:trace,
|
134
|
+
:introspection,
|
134
135
|
argument: GraphQL::Define::AssignArgument
|
135
136
|
|
136
137
|
ensure_defined(
|
@@ -138,7 +139,8 @@ module GraphQL
|
|
138
139
|
:mutation, :arguments, :complexity, :function,
|
139
140
|
:resolve, :resolve=, :lazy_resolve, :lazy_resolve=, :lazy_resolve_proc, :resolve_proc,
|
140
141
|
:type, :type=, :name=, :property=, :hash_key=,
|
141
|
-
:relay_node_field, :relay_nodes_field, :edges?, :edge_class, :subscription_scope
|
142
|
+
:relay_node_field, :relay_nodes_field, :edges?, :edge_class, :subscription_scope,
|
143
|
+
:introspection?
|
142
144
|
)
|
143
145
|
|
144
146
|
# @return [Boolean] True if this is the Relay find-by-id field
|
@@ -183,6 +185,7 @@ module GraphQL
|
|
183
185
|
attr_accessor :arguments_class
|
184
186
|
|
185
187
|
attr_writer :connection
|
188
|
+
attr_writer :introspection
|
186
189
|
|
187
190
|
# @return [nil, String] Prefix for subscription names from this field
|
188
191
|
attr_accessor :subscription_scope
|
@@ -217,6 +220,7 @@ module GraphQL
|
|
217
220
|
@connection_max_page_size = nil
|
218
221
|
@edge_class = nil
|
219
222
|
@trace = nil
|
223
|
+
@introspection = false
|
220
224
|
end
|
221
225
|
|
222
226
|
def initialize_copy(other)
|
@@ -224,6 +228,11 @@ module GraphQL
|
|
224
228
|
@arguments = other.arguments.dup
|
225
229
|
end
|
226
230
|
|
231
|
+
# @return [Boolean] Is this field a predefined introspection field?
|
232
|
+
def introspection?
|
233
|
+
@introspection
|
234
|
+
end
|
235
|
+
|
227
236
|
# Get a value for this field
|
228
237
|
# @example resolving a field value
|
229
238
|
# field.resolve(obj, args, ctx)
|
@@ -84,6 +84,7 @@ module GraphQL
|
|
84
84
|
|
85
85
|
def coerce_non_null_input(value, ctx)
|
86
86
|
input_values = {}
|
87
|
+
defaults_used = Set.new
|
87
88
|
|
88
89
|
arguments.each do |input_key, input_field_defn|
|
89
90
|
field_value = value[input_key]
|
@@ -93,10 +94,11 @@ module GraphQL
|
|
93
94
|
input_values[input_key] = input_field_defn.prepare(coerced_value, ctx)
|
94
95
|
elsif input_field_defn.default_value?
|
95
96
|
input_values[input_key] = input_field_defn.default_value
|
97
|
+
defaults_used << input_key
|
96
98
|
end
|
97
99
|
end
|
98
100
|
|
99
|
-
arguments_class.new(input_values)
|
101
|
+
arguments_class.new(input_values, defaults_used)
|
100
102
|
end
|
101
103
|
|
102
104
|
# @api private
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
GraphQL::Introspection::EnumValuesField = GraphQL::Field.define do
|
3
3
|
type types[!GraphQL::Introspection::EnumValueType]
|
4
|
+
introspection true
|
4
5
|
argument :includeDeprecated, types.Boolean, default_value: false
|
5
6
|
resolve ->(object, arguments, context) do
|
6
7
|
if !object.kind.enum?
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
GraphQL::Introspection::FieldsField = GraphQL::Field.define do
|
3
3
|
type -> { types[!GraphQL::Introspection::FieldType] }
|
4
|
+
introspection true
|
4
5
|
argument :includeDeprecated, GraphQL::BOOLEAN_TYPE, default_value: false
|
5
6
|
resolve ->(object, arguments, context) {
|
6
7
|
return nil if !object.kind.fields?
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
GraphQL::Introspection::InterfacesField = GraphQL::Field.define do
|
3
3
|
type -> { types[!GraphQL::Introspection::TypeType] }
|
4
|
+
introspection true
|
4
5
|
resolve ->(target, a, ctx) {
|
5
6
|
if target.kind == GraphQL::TypeKinds::OBJECT
|
6
7
|
ctx.warden.interfaces(target)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
GraphQL::Introspection::PossibleTypesField = GraphQL::Field.define do
|
3
3
|
type -> { types[!GraphQL::Introspection::TypeType] }
|
4
|
+
introspection true
|
4
5
|
resolve ->(target, args, ctx) {
|
5
6
|
if target.kind.resolves?
|
6
7
|
ctx.warden.possible_types(target)
|
data/lib/graphql/language.rb
CHANGED
@@ -6,10 +6,28 @@ module GraphQL
|
|
6
6
|
# {GraphQL::Language::DocumentFromSchemaDefinition} is used to convert a {GraphQL::Schema} object
|
7
7
|
# To a {GraphQL::Language::Document} AST node.
|
8
8
|
#
|
9
|
+
# @param context [Hash]
|
10
|
+
# @param only [<#call(member, ctx)>]
|
11
|
+
# @param except [<#call(member, ctx)>]
|
12
|
+
# @param include_introspection_types [Boolean] Whether or not to include introspection types in the AST
|
13
|
+
# @param include_built_in_scalars [Boolean] Whether or not to include built in scalars in the AST
|
14
|
+
# @param include_built_in_directives [Boolean] Whether or not to include built in diirectives in the AST
|
9
15
|
class DocumentFromSchemaDefinition
|
10
|
-
def initialize(
|
16
|
+
def initialize(
|
17
|
+
schema, context: nil, only: nil, except: nil, include_introspection_types: false,
|
18
|
+
include_built_in_directives: false, include_built_in_scalars: false, always_include_schema: false
|
19
|
+
)
|
11
20
|
@schema = schema
|
12
|
-
@
|
21
|
+
@always_include_schema = always_include_schema
|
22
|
+
@include_introspection_types = include_introspection_types
|
23
|
+
@include_built_in_scalars = include_built_in_scalars
|
24
|
+
@include_built_in_directives = include_built_in_directives
|
25
|
+
|
26
|
+
@warden = GraphQL::Schema::Warden.new(
|
27
|
+
GraphQL::Filter.new(only: only, except: except),
|
28
|
+
schema: @schema,
|
29
|
+
context: context,
|
30
|
+
)
|
13
31
|
end
|
14
32
|
|
15
33
|
def document
|
@@ -18,47 +36,46 @@ module GraphQL
|
|
18
36
|
)
|
19
37
|
end
|
20
38
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
39
|
+
def build_schema_node
|
40
|
+
GraphQL::Language::Nodes::SchemaDefinition.new(
|
41
|
+
query: warden.root_type_for_operation("query"),
|
42
|
+
mutation: warden.root_type_for_operation("mutation"),
|
43
|
+
subscription: warden.root_type_for_operation("subscription")
|
26
44
|
)
|
27
|
-
|
28
|
-
if schema.mutation
|
29
|
-
schema_node.mutation = schema.mutation.name
|
30
|
-
end
|
31
|
-
|
32
|
-
if schema.subscription
|
33
|
-
schema_node.subscription = schema.subscription.name
|
34
|
-
end
|
35
|
-
|
36
|
-
schema_node
|
37
45
|
end
|
38
46
|
|
39
47
|
def build_object_type_node(object_type)
|
40
48
|
GraphQL::Language::Nodes::ObjectTypeDefinition.new(
|
41
49
|
name: object_type.name,
|
42
|
-
interfaces:
|
43
|
-
fields: build_field_nodes(
|
50
|
+
interfaces: warden.interfaces(object_type).sort_by(&:name).map { |iface| build_type_name_node(iface) },
|
51
|
+
fields: build_field_nodes(warden.fields(object_type)),
|
44
52
|
description: object_type.description,
|
45
53
|
)
|
46
54
|
end
|
47
55
|
|
48
56
|
def build_field_node(field)
|
49
|
-
GraphQL::Language::Nodes::FieldDefinition.new(
|
57
|
+
field_node = GraphQL::Language::Nodes::FieldDefinition.new(
|
50
58
|
name: field.name,
|
51
|
-
arguments: build_argument_nodes(
|
59
|
+
arguments: build_argument_nodes(warden.arguments(field)),
|
52
60
|
type: build_type_name_node(field.type),
|
53
61
|
description: field.description,
|
54
62
|
)
|
63
|
+
|
64
|
+
if field.deprecation_reason
|
65
|
+
field_node.directives << GraphQL::Language::Nodes::Directive.new(
|
66
|
+
name: GraphQL::Directive::DeprecatedDirective.name,
|
67
|
+
arguments: [GraphQL::Language::Nodes::Argument.new(name: "reason", value: field.deprecation_reason)]
|
68
|
+
)
|
69
|
+
end
|
70
|
+
|
71
|
+
field_node
|
55
72
|
end
|
56
73
|
|
57
74
|
def build_union_type_node(union_type)
|
58
75
|
GraphQL::Language::Nodes::UnionTypeDefinition.new(
|
59
76
|
name: union_type.name,
|
60
77
|
description: union_type.description,
|
61
|
-
types:
|
78
|
+
types: warden.possible_types(union_type).sort_by(&:name).map { |type| build_type_name_node(type) }
|
62
79
|
)
|
63
80
|
end
|
64
81
|
|
@@ -66,14 +83,14 @@ module GraphQL
|
|
66
83
|
GraphQL::Language::Nodes::InterfaceTypeDefinition.new(
|
67
84
|
name: interface_type.name,
|
68
85
|
description: interface_type.description,
|
69
|
-
fields: build_field_nodes(
|
86
|
+
fields: build_field_nodes(warden.fields(interface_type))
|
70
87
|
)
|
71
88
|
end
|
72
89
|
|
73
90
|
def build_enum_type_node(enum_type)
|
74
91
|
GraphQL::Language::Nodes::EnumTypeDefinition.new(
|
75
92
|
name: enum_type.name,
|
76
|
-
values: enum_type.
|
93
|
+
values: warden.enum_values(enum_type).sort_by(&:name).map do |enum_value|
|
77
94
|
build_enum_value_node(enum_value)
|
78
95
|
end,
|
79
96
|
description: enum_type.description,
|
@@ -81,10 +98,19 @@ module GraphQL
|
|
81
98
|
end
|
82
99
|
|
83
100
|
def build_enum_value_node(enum_value)
|
84
|
-
GraphQL::Language::Nodes::EnumValueDefinition.new(
|
101
|
+
enum_value_node = GraphQL::Language::Nodes::EnumValueDefinition.new(
|
85
102
|
name: enum_value.name,
|
86
103
|
description: enum_value.description,
|
87
104
|
)
|
105
|
+
|
106
|
+
if enum_value.deprecation_reason
|
107
|
+
enum_value_node.directives << GraphQL::Language::Nodes::Directive.new(
|
108
|
+
name: GraphQL::Directive::DeprecatedDirective.name,
|
109
|
+
arguments: [GraphQL::Language::Nodes::Argument.new(name: "reason", value: enum_value.deprecation_reason)]
|
110
|
+
)
|
111
|
+
end
|
112
|
+
|
113
|
+
enum_value_node
|
88
114
|
end
|
89
115
|
|
90
116
|
def build_scalar_type_node(scalar_type)
|
@@ -95,18 +121,23 @@ module GraphQL
|
|
95
121
|
end
|
96
122
|
|
97
123
|
def build_argument_node(argument)
|
98
|
-
GraphQL::Language::Nodes::InputValueDefinition.new(
|
124
|
+
argument_node = GraphQL::Language::Nodes::InputValueDefinition.new(
|
99
125
|
name: argument.name,
|
100
126
|
description: argument.description,
|
101
127
|
type: build_type_name_node(argument.type),
|
102
|
-
default_value: argument.default_value,
|
103
128
|
)
|
129
|
+
|
130
|
+
if argument.default_value?
|
131
|
+
argument_node.default_value = build_default_value(argument.default_value, argument.type)
|
132
|
+
end
|
133
|
+
|
134
|
+
argument_node
|
104
135
|
end
|
105
136
|
|
106
137
|
def build_input_object_node(input_object)
|
107
138
|
GraphQL::Language::Nodes::InputObjectTypeDefinition.new(
|
108
139
|
name: input_object.name,
|
109
|
-
fields: build_argument_nodes(
|
140
|
+
fields: build_argument_nodes(warden.arguments(input_object)),
|
110
141
|
description: input_object.description,
|
111
142
|
)
|
112
143
|
end
|
@@ -114,7 +145,7 @@ module GraphQL
|
|
114
145
|
def build_directive_node(directive)
|
115
146
|
GraphQL::Language::Nodes::DirectiveDefinition.new(
|
116
147
|
name: directive.name,
|
117
|
-
arguments: build_argument_nodes(
|
148
|
+
arguments: build_argument_nodes(warden.arguments(directive)),
|
118
149
|
locations: directive.locations.map(&:to_s),
|
119
150
|
description: directive.description,
|
120
151
|
)
|
@@ -135,6 +166,35 @@ module GraphQL
|
|
135
166
|
end
|
136
167
|
end
|
137
168
|
|
169
|
+
def build_default_value(default_value, type)
|
170
|
+
if default_value.nil?
|
171
|
+
return GraphQL::Language::Nodes::NullValue.new(name: "null")
|
172
|
+
end
|
173
|
+
|
174
|
+
case type
|
175
|
+
when GraphQL::ScalarType
|
176
|
+
default_value
|
177
|
+
when EnumType
|
178
|
+
GraphQL::Language::Nodes::Enum.new(name: type.coerce_isolated_result(default_value))
|
179
|
+
when InputObjectType
|
180
|
+
GraphQL::Language::Nodes::InputObject.new(
|
181
|
+
arguments: default_value.to_h.map do |arg_name, arg_value|
|
182
|
+
arg_type = type.input_fields.fetch(arg_name.to_s).type
|
183
|
+
GraphQL::Language::Nodes::Argument.new(
|
184
|
+
name: arg_name,
|
185
|
+
value: build_default_value(arg_value, arg_type)
|
186
|
+
)
|
187
|
+
end
|
188
|
+
)
|
189
|
+
when NonNullType
|
190
|
+
build_default_value(default_value, type.of_type)
|
191
|
+
when ListType
|
192
|
+
default_value.to_a.map { |v| build_default_value(v, type.of_type) }
|
193
|
+
else
|
194
|
+
raise NotImplementedError, "Unexpected default value type #{type.inspect}"
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
138
198
|
def build_type_definition_node(type)
|
139
199
|
case type
|
140
200
|
when GraphQL::ObjectType
|
@@ -155,31 +215,63 @@ module GraphQL
|
|
155
215
|
end
|
156
216
|
|
157
217
|
def build_argument_nodes(arguments)
|
158
|
-
arguments
|
218
|
+
arguments
|
219
|
+
.map { |arg| build_argument_node(arg) }
|
220
|
+
.sort_by(&:name)
|
159
221
|
end
|
160
222
|
|
161
223
|
def build_directive_nodes(directives)
|
162
|
-
|
224
|
+
if !include_built_in_directives
|
225
|
+
directives = directives.reject { |directive| directive.default_directive? }
|
226
|
+
end
|
227
|
+
|
228
|
+
directives
|
229
|
+
.map { |directive| build_directive_node(directive) }
|
230
|
+
.sort_by(&:name)
|
163
231
|
end
|
164
232
|
|
165
233
|
def build_definition_nodes
|
166
|
-
definitions =
|
167
|
-
definitions
|
168
|
-
definitions
|
234
|
+
definitions = []
|
235
|
+
definitions << build_schema_node if include_schema_node?
|
236
|
+
definitions += build_directive_nodes(warden.directives)
|
237
|
+
definitions += build_type_definition_nodes(warden.types)
|
169
238
|
definitions
|
170
239
|
end
|
171
240
|
|
172
241
|
def build_type_definition_nodes(types)
|
173
|
-
|
242
|
+
if !include_introspection_types
|
243
|
+
types = types.reject { |type| type.introspection? }
|
244
|
+
end
|
245
|
+
|
246
|
+
if !include_built_in_scalars
|
247
|
+
types = types.reject { |type| type.default_scalar? }
|
248
|
+
end
|
249
|
+
|
250
|
+
types
|
251
|
+
.map { |type| build_type_definition_node(type) }
|
252
|
+
.sort_by(&:name)
|
174
253
|
end
|
175
254
|
|
176
255
|
def build_field_nodes(fields)
|
177
|
-
fields
|
256
|
+
fields
|
257
|
+
.map { |field| build_field_node(field) }
|
258
|
+
.sort_by(&:name)
|
178
259
|
end
|
179
260
|
|
180
261
|
private
|
181
262
|
|
182
|
-
|
263
|
+
def include_schema_node?
|
264
|
+
always_include_schema || !schema_respects_root_name_conventions?(schema)
|
265
|
+
end
|
266
|
+
|
267
|
+
def schema_respects_root_name_conventions?(schema)
|
268
|
+
(schema.query.nil? || schema.query.name == 'Query') &&
|
269
|
+
(schema.mutation.nil? || schema.mutation.name == 'Mutation') &&
|
270
|
+
(schema.subscription.nil? || schema.subscription.name == 'Subscription')
|
271
|
+
end
|
272
|
+
|
273
|
+
attr_reader :schema, :warden, :always_include_schema,
|
274
|
+
:include_introspection_types, :include_built_in_directives, :include_built_in_scalars
|
183
275
|
end
|
184
276
|
end
|
185
277
|
end
|