graphql 1.7.7 → 1.7.8
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/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
|