graphql 2.3.6 → 2.3.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/analysis/field_usage.rb +1 -1
- data/lib/graphql/analysis/query_complexity.rb +3 -3
- data/lib/graphql/analysis/visitor.rb +7 -6
- data/lib/graphql/execution/interpreter/runtime.rb +6 -6
- data/lib/graphql/execution/lookahead.rb +10 -10
- data/lib/graphql/introspection/directive_type.rb +1 -1
- data/lib/graphql/introspection/entry_points.rb +2 -2
- data/lib/graphql/introspection/field_type.rb +1 -1
- data/lib/graphql/introspection/schema_type.rb +13 -3
- data/lib/graphql/introspection/type_type.rb +5 -5
- data/lib/graphql/language/document_from_schema_definition.rb +19 -26
- data/lib/graphql/language/lexer.rb +0 -3
- data/lib/graphql/language/sanitized_printer.rb +1 -1
- data/lib/graphql/language.rb +0 -1
- data/lib/graphql/query/context.rb +4 -0
- data/lib/graphql/query/null_context.rb +4 -0
- data/lib/graphql/query.rb +26 -3
- data/lib/graphql/schema/always_visible.rb +1 -0
- data/lib/graphql/schema/enum.rb +4 -4
- data/lib/graphql/schema/field.rb +7 -3
- data/lib/graphql/schema/has_single_input_argument.rb +2 -1
- data/lib/graphql/schema/input_object.rb +8 -7
- data/lib/graphql/schema/introspection_system.rb +2 -14
- data/lib/graphql/schema/member/has_arguments.rb +7 -6
- data/lib/graphql/schema/member/has_fields.rb +6 -4
- data/lib/graphql/schema/resolver.rb +4 -5
- data/lib/graphql/schema/subset.rb +397 -0
- data/lib/graphql/schema/type_expression.rb +2 -2
- data/lib/graphql/schema/validator/all_validator.rb +60 -0
- data/lib/graphql/schema/validator.rb +2 -0
- data/lib/graphql/schema/warden.rb +88 -1
- data/lib/graphql/schema.rb +44 -15
- data/lib/graphql/static_validation/base_visitor.rb +6 -5
- data/lib/graphql/static_validation/literal_validator.rb +4 -4
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +1 -1
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -2
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +7 -7
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +1 -1
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
- data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/query_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +3 -3
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +3 -3
- data/lib/graphql/static_validation/rules/subscription_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +1 -1
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
- data/lib/graphql/static_validation/validation_context.rb +2 -2
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +10 -4
- data/lib/graphql/subscriptions/event.rb +1 -1
- data/lib/graphql/subscriptions.rb +2 -2
- data/lib/graphql/testing/helpers.rb +2 -2
- data/lib/graphql/types/relay/connection_behaviors.rb +10 -0
- data/lib/graphql/types/relay/edge_behaviors.rb +10 -0
- data/lib/graphql/types/relay/page_info_behaviors.rb +4 -0
- data/lib/graphql/version.rb +1 -1
- metadata +4 -4
- data/lib/graphql/language/token.rb +0 -34
- data/lib/graphql/schema/invalid_type_error.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47e1762bc5aa144c21841bf1671a63b2180b8dacd4145688bc6f131ceb2a8f4a
|
4
|
+
data.tar.gz: 9dd05b04b955e83c95cb4ad5d959fb68a49796417ca1759606be21cabc7bfd39
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3bfe0cf261815aed7f739eb797f0c400c5ec97d4caf4f2ab760a67392fb51be2fceefcde7f45ad62d49d5216d7ea19ccf43b8360162a4862d70268115b7395cd
|
7
|
+
data.tar.gz: 50a2a283a121761a4aae7174587e312b9ed39215101f18e9a14ce006844ca22b81572381a9636d63ecee9e7d7a15c62c996f6e736479b80aaec77684904cd392
|
@@ -72,7 +72,7 @@ module GraphQL
|
|
72
72
|
end
|
73
73
|
|
74
74
|
def extract_deprecated_enum_value(enum_type, value)
|
75
|
-
enum_value = @query.
|
75
|
+
enum_value = @query.types.enum_values(enum_type).find { |ev| ev.value == value }
|
76
76
|
if enum_value&.deprecation_reason
|
77
77
|
@used_deprecated_enum_values << enum_value.path
|
78
78
|
end
|
@@ -98,7 +98,7 @@ module GraphQL
|
|
98
98
|
possible_scope_types.keys.each do |possible_scope_type|
|
99
99
|
next unless possible_scope_type.kind.abstract?
|
100
100
|
|
101
|
-
query.possible_types(possible_scope_type).each do |impl_type|
|
101
|
+
query.types.possible_types(possible_scope_type).each do |impl_type|
|
102
102
|
possible_scope_types[impl_type] ||= true
|
103
103
|
end
|
104
104
|
possible_scope_types.delete(possible_scope_type)
|
@@ -123,8 +123,8 @@ module GraphQL
|
|
123
123
|
def types_intersect?(query, a, b)
|
124
124
|
return true if a == b
|
125
125
|
|
126
|
-
a_types = query.possible_types(a)
|
127
|
-
query.possible_types(b).any? { |t| a_types.include?(t) }
|
126
|
+
a_types = query.types.possible_types(a)
|
127
|
+
query.types.possible_types(b).any? { |t| a_types.include?(t) }
|
128
128
|
end
|
129
129
|
|
130
130
|
# A hook which is called whenever a field's max complexity is calculated.
|
@@ -21,6 +21,7 @@ module GraphQL
|
|
21
21
|
@rescued_errors = []
|
22
22
|
@query = query
|
23
23
|
@schema = query.schema
|
24
|
+
@types = query.types
|
24
25
|
@response_path = []
|
25
26
|
@skip_stack = [false]
|
26
27
|
super(query.selected_operation)
|
@@ -131,7 +132,7 @@ module GraphQL
|
|
131
132
|
@response_path.push(node.alias || node.name)
|
132
133
|
parent_type = @object_types.last
|
133
134
|
# This could be nil if the previous field wasn't found:
|
134
|
-
field_definition = parent_type && @
|
135
|
+
field_definition = parent_type && @types.field(parent_type, node.name)
|
135
136
|
@field_definitions.push(field_definition)
|
136
137
|
if !field_definition.nil?
|
137
138
|
next_object_type = field_definition.type.unwrap
|
@@ -167,14 +168,14 @@ module GraphQL
|
|
167
168
|
argument_defn = if (arg = @argument_definitions.last)
|
168
169
|
arg_type = arg.type.unwrap
|
169
170
|
if arg_type.kind.input_object?
|
170
|
-
|
171
|
+
@types.argument(arg_type, node.name)
|
171
172
|
else
|
172
173
|
nil
|
173
174
|
end
|
174
175
|
elsif (directive_defn = @directive_definitions.last)
|
175
|
-
|
176
|
+
@types.argument(directive_defn, node.name)
|
176
177
|
elsif (field_defn = @field_definitions.last)
|
177
|
-
|
178
|
+
@types.argument(field_defn, node.name)
|
178
179
|
else
|
179
180
|
nil
|
180
181
|
end
|
@@ -245,7 +246,7 @@ module GraphQL
|
|
245
246
|
fragment_def = query.fragments[fragment_spread.name]
|
246
247
|
|
247
248
|
object_type = if fragment_def.type
|
248
|
-
@
|
249
|
+
@types.type(fragment_def.type.name)
|
249
250
|
else
|
250
251
|
object_types.last
|
251
252
|
end
|
@@ -268,7 +269,7 @@ module GraphQL
|
|
268
269
|
|
269
270
|
def on_fragment_with_type(node)
|
270
271
|
object_type = if node.type
|
271
|
-
@
|
272
|
+
@types.type(node.type.name)
|
272
273
|
else
|
273
274
|
@object_types.last
|
274
275
|
end
|
@@ -160,9 +160,9 @@ module GraphQL
|
|
160
160
|
case node
|
161
161
|
when GraphQL::Language::Nodes::InlineFragment
|
162
162
|
if node.type
|
163
|
-
type_defn =
|
163
|
+
type_defn = query.types.type(node.type.name)
|
164
164
|
|
165
|
-
if query.
|
165
|
+
if query.types.possible_types(type_defn).include?(owner_type)
|
166
166
|
result = gather_selections(owner_object, owner_type, node.selections, selections_to_run, next_selections)
|
167
167
|
if !result.equal?(next_selections)
|
168
168
|
selections_to_run = result
|
@@ -177,8 +177,8 @@ module GraphQL
|
|
177
177
|
end
|
178
178
|
when GraphQL::Language::Nodes::FragmentSpread
|
179
179
|
fragment_def = query.fragments[node.name]
|
180
|
-
type_defn = query.
|
181
|
-
if query.
|
180
|
+
type_defn = query.types.type(fragment_def.type.name)
|
181
|
+
if query.types.possible_types(type_defn).include?(owner_type)
|
182
182
|
result = gather_selections(owner_object, owner_type, fragment_def.selections, selections_to_run, next_selections)
|
183
183
|
if !result.equal?(next_selections)
|
184
184
|
selections_to_run = result
|
@@ -245,7 +245,7 @@ module GraphQL
|
|
245
245
|
end
|
246
246
|
field_name = ast_node.name
|
247
247
|
owner_type = selections_result.graphql_result_type
|
248
|
-
field_defn = query.
|
248
|
+
field_defn = query.types.field(owner_type, field_name)
|
249
249
|
|
250
250
|
# Set this before calling `run_with_directives`, so that the directive can have the latest path
|
251
251
|
runtime_state = get_current_runtime_state
|
@@ -579,7 +579,7 @@ module GraphQL
|
|
579
579
|
resolved_value = value
|
580
580
|
end
|
581
581
|
|
582
|
-
possible_types = query.possible_types(current_type)
|
582
|
+
possible_types = query.types.possible_types(current_type)
|
583
583
|
if !possible_types.include?(resolved_type)
|
584
584
|
parent_type = field.owner_type
|
585
585
|
err_class = current_type::UnresolvedTypeError
|
@@ -108,16 +108,16 @@ module GraphQL
|
|
108
108
|
def selection(field_name, selected_type: @selected_type, arguments: nil)
|
109
109
|
next_field_defn = case field_name
|
110
110
|
when String
|
111
|
-
@query.
|
111
|
+
@query.types.field(selected_type, field_name)
|
112
112
|
when Symbol
|
113
113
|
# Try to avoid the `.to_s` below, if possible
|
114
114
|
all_fields = if selected_type.kind.fields?
|
115
|
-
@query.
|
115
|
+
@query.types.fields(selected_type)
|
116
116
|
else
|
117
117
|
# Handle unions by checking possible
|
118
|
-
@query.
|
118
|
+
@query.types
|
119
119
|
.possible_types(selected_type)
|
120
|
-
.map { |t| @query.
|
120
|
+
.map { |t| @query.types.fields(t) }
|
121
121
|
.tap(&:flatten!)
|
122
122
|
end
|
123
123
|
|
@@ -128,7 +128,7 @@ module GraphQL
|
|
128
128
|
# Symbol#name is only present on 3.0+
|
129
129
|
sym_s = field_name.respond_to?(:name) ? field_name.name : field_name.to_s
|
130
130
|
guessed_name = Schema::Member::BuildType.camelize(sym_s)
|
131
|
-
@query.
|
131
|
+
@query.types.field(selected_type, guessed_name)
|
132
132
|
end
|
133
133
|
end
|
134
134
|
lookahead_for_selection(next_field_defn, selected_type, arguments)
|
@@ -144,7 +144,7 @@ module GraphQL
|
|
144
144
|
alias_node = lookup_alias_node(ast_nodes, alias_name)
|
145
145
|
return NULL_LOOKAHEAD unless alias_node
|
146
146
|
|
147
|
-
next_field_defn = @query.
|
147
|
+
next_field_defn = @query.types.field(selected_type, alias_node.name)
|
148
148
|
|
149
149
|
alias_arguments = @query.arguments_for(alias_node, next_field_defn)
|
150
150
|
if alias_arguments.is_a?(::GraphQL::Execution::Interpreter::Arguments)
|
@@ -183,7 +183,7 @@ module GraphQL
|
|
183
183
|
|
184
184
|
subselections_by_type.each do |type, ast_nodes_by_response_key|
|
185
185
|
ast_nodes_by_response_key.each do |response_key, ast_nodes|
|
186
|
-
field_defn = @query.
|
186
|
+
field_defn = @query.types.field(type, ast_nodes.first.name)
|
187
187
|
lookahead = Lookahead.new(query: @query, ast_nodes: ast_nodes, field: field_defn, owner_type: type)
|
188
188
|
subselections.push(lookahead)
|
189
189
|
end
|
@@ -266,7 +266,7 @@ module GraphQL
|
|
266
266
|
elsif arguments.nil? || arguments.empty?
|
267
267
|
selections_on_type[response_key] = [ast_selection]
|
268
268
|
else
|
269
|
-
field_defn = @query.
|
269
|
+
field_defn = @query.types.field(selected_type, ast_selection.name)
|
270
270
|
if arguments_match?(arguments, field_defn, ast_selection)
|
271
271
|
selections_on_type[response_key] = [ast_selection]
|
272
272
|
end
|
@@ -276,14 +276,14 @@ module GraphQL
|
|
276
276
|
subselections_on_type = selections_on_type
|
277
277
|
if (t = ast_selection.type)
|
278
278
|
# Assuming this is valid, that `t` will be found.
|
279
|
-
on_type = @query.
|
279
|
+
on_type = @query.types.type(t.name)
|
280
280
|
subselections_on_type = subselections_by_type[on_type] ||= {}
|
281
281
|
end
|
282
282
|
find_selections(subselections_by_type, subselections_on_type, on_type, ast_selection.selections, arguments)
|
283
283
|
when GraphQL::Language::Nodes::FragmentSpread
|
284
284
|
frag_defn = lookup_fragment(ast_selection)
|
285
285
|
# Again, assuming a valid AST
|
286
|
-
on_type = @query.
|
286
|
+
on_type = @query.types.type(frag_defn.type.name)
|
287
287
|
subselections_on_type = subselections_by_type[on_type] ||= {}
|
288
288
|
find_selections(subselections_by_type, subselections_on_type, on_type, frag_defn.selections, arguments)
|
289
289
|
else
|
@@ -22,7 +22,7 @@ module GraphQL
|
|
22
22
|
field :is_repeatable, Boolean, method: :repeatable?
|
23
23
|
|
24
24
|
def args(include_deprecated:)
|
25
|
-
args = @context.
|
25
|
+
args = @context.types.arguments(@object)
|
26
26
|
args = args.reject(&:deprecation_reason) unless include_deprecated
|
27
27
|
args
|
28
28
|
end
|
@@ -15,8 +15,8 @@ module GraphQL
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def __type(name:)
|
18
|
-
if context.
|
19
|
-
context.
|
18
|
+
if context.types.reachable_type?(name)
|
19
|
+
context.types.type(name)
|
20
20
|
elsif (type = context.schema.extra_types.find { |t| t.graphql_name == name })
|
21
21
|
type
|
22
22
|
else
|
@@ -20,7 +20,8 @@ module GraphQL
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def types
|
23
|
-
|
23
|
+
query_types = context.types.all_types
|
24
|
+
types = query_types + context.schema.extra_types
|
24
25
|
types.sort_by!(&:graphql_name)
|
25
26
|
types
|
26
27
|
end
|
@@ -38,13 +39,22 @@ module GraphQL
|
|
38
39
|
end
|
39
40
|
|
40
41
|
def directives
|
41
|
-
@context.
|
42
|
+
@context.types.directives
|
42
43
|
end
|
43
44
|
|
44
45
|
private
|
45
46
|
|
46
47
|
def permitted_root_type(op_type)
|
47
|
-
|
48
|
+
case op_type
|
49
|
+
when "query"
|
50
|
+
@context.types.query_root
|
51
|
+
when "mutation"
|
52
|
+
@context.types.mutation_root
|
53
|
+
when "subcription"
|
54
|
+
@context.types.subscription_root
|
55
|
+
else
|
56
|
+
nil
|
57
|
+
end
|
48
58
|
end
|
49
59
|
end
|
50
60
|
end
|
@@ -52,7 +52,7 @@ module GraphQL
|
|
52
52
|
if !@object.kind.enum?
|
53
53
|
nil
|
54
54
|
else
|
55
|
-
enum_values = @context.
|
55
|
+
enum_values = @context.types.enum_values(@object)
|
56
56
|
|
57
57
|
if !include_deprecated
|
58
58
|
enum_values = enum_values.select {|f| !f.deprecation_reason }
|
@@ -64,7 +64,7 @@ module GraphQL
|
|
64
64
|
|
65
65
|
def interfaces
|
66
66
|
if @object.kind.object? || @object.kind.interface?
|
67
|
-
@context.
|
67
|
+
@context.types.interfaces(@object).sort_by(&:graphql_name)
|
68
68
|
else
|
69
69
|
nil
|
70
70
|
end
|
@@ -72,7 +72,7 @@ module GraphQL
|
|
72
72
|
|
73
73
|
def input_fields(include_deprecated:)
|
74
74
|
if @object.kind.input_object?
|
75
|
-
args = @context.
|
75
|
+
args = @context.types.arguments(@object)
|
76
76
|
args = args.reject(&:deprecation_reason) unless include_deprecated
|
77
77
|
args
|
78
78
|
else
|
@@ -82,7 +82,7 @@ module GraphQL
|
|
82
82
|
|
83
83
|
def possible_types
|
84
84
|
if @object.kind.abstract?
|
85
|
-
@context.
|
85
|
+
@context.types.possible_types(@object).sort_by(&:graphql_name)
|
86
86
|
else
|
87
87
|
nil
|
88
88
|
end
|
@@ -92,7 +92,7 @@ module GraphQL
|
|
92
92
|
if !@object.kind.fields?
|
93
93
|
nil
|
94
94
|
else
|
95
|
-
fields = @context.
|
95
|
+
fields = @context.types.fields(@object)
|
96
96
|
if !include_deprecated
|
97
97
|
fields = fields.select {|f| !f.deprecation_reason }
|
98
98
|
end
|
@@ -24,15 +24,8 @@ module GraphQL
|
|
24
24
|
@include_built_in_directives = include_built_in_directives
|
25
25
|
@include_one_of = false
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
@warden = @schema.warden_class.new(
|
31
|
-
schema: @schema,
|
32
|
-
context: schema_context,
|
33
|
-
)
|
34
|
-
|
35
|
-
schema_context.warden = @warden
|
27
|
+
dummy_query = @schema.query_class.new(@schema, "{ __typename }", validate: false, context: context)
|
28
|
+
@types = dummy_query.types # rubocop:disable Development/ContextIsPassedCop
|
36
29
|
end
|
37
30
|
|
38
31
|
def document
|
@@ -44,9 +37,9 @@ module GraphQL
|
|
44
37
|
def build_schema_node
|
45
38
|
if !schema_respects_root_name_conventions?(@schema)
|
46
39
|
GraphQL::Language::Nodes::SchemaDefinition.new(
|
47
|
-
query:
|
48
|
-
mutation:
|
49
|
-
subscription:
|
40
|
+
query: @types.query_root&.graphql_name,
|
41
|
+
mutation: @types.mutation_root&.graphql_name,
|
42
|
+
subscription: @types.subscription_root&.graphql_name,
|
50
43
|
directives: definition_directives(@schema, :schema_directives)
|
51
44
|
)
|
52
45
|
else
|
@@ -57,7 +50,7 @@ module GraphQL
|
|
57
50
|
end
|
58
51
|
|
59
52
|
def build_object_type_node(object_type)
|
60
|
-
ints =
|
53
|
+
ints = @types.interfaces(object_type)
|
61
54
|
if ints.any?
|
62
55
|
ints.sort_by!(&:graphql_name)
|
63
56
|
ints.map! { |iface| build_type_name_node(iface) }
|
@@ -66,7 +59,7 @@ module GraphQL
|
|
66
59
|
GraphQL::Language::Nodes::ObjectTypeDefinition.new(
|
67
60
|
name: object_type.graphql_name,
|
68
61
|
interfaces: ints,
|
69
|
-
fields: build_field_nodes(
|
62
|
+
fields: build_field_nodes(@types.fields(object_type)),
|
70
63
|
description: object_type.description,
|
71
64
|
directives: directives(object_type),
|
72
65
|
)
|
@@ -75,7 +68,7 @@ module GraphQL
|
|
75
68
|
def build_field_node(field)
|
76
69
|
GraphQL::Language::Nodes::FieldDefinition.new(
|
77
70
|
name: field.graphql_name,
|
78
|
-
arguments: build_argument_nodes(
|
71
|
+
arguments: build_argument_nodes(@types.arguments(field)),
|
79
72
|
type: build_type_name_node(field.type),
|
80
73
|
description: field.description,
|
81
74
|
directives: directives(field),
|
@@ -86,7 +79,7 @@ module GraphQL
|
|
86
79
|
GraphQL::Language::Nodes::UnionTypeDefinition.new(
|
87
80
|
name: union_type.graphql_name,
|
88
81
|
description: union_type.description,
|
89
|
-
types:
|
82
|
+
types: @types.possible_types(union_type).sort_by(&:graphql_name).map { |type| build_type_name_node(type) },
|
90
83
|
directives: directives(union_type),
|
91
84
|
)
|
92
85
|
end
|
@@ -94,9 +87,9 @@ module GraphQL
|
|
94
87
|
def build_interface_type_node(interface_type)
|
95
88
|
GraphQL::Language::Nodes::InterfaceTypeDefinition.new(
|
96
89
|
name: interface_type.graphql_name,
|
97
|
-
interfaces:
|
90
|
+
interfaces: @types.interfaces(interface_type).sort_by(&:graphql_name).map { |type| build_type_name_node(type) },
|
98
91
|
description: interface_type.description,
|
99
|
-
fields: build_field_nodes(
|
92
|
+
fields: build_field_nodes(@types.fields(interface_type)),
|
100
93
|
directives: directives(interface_type),
|
101
94
|
)
|
102
95
|
end
|
@@ -104,7 +97,7 @@ module GraphQL
|
|
104
97
|
def build_enum_type_node(enum_type)
|
105
98
|
GraphQL::Language::Nodes::EnumTypeDefinition.new(
|
106
99
|
name: enum_type.graphql_name,
|
107
|
-
values:
|
100
|
+
values: @types.enum_values(enum_type).sort_by(&:graphql_name).map do |enum_value|
|
108
101
|
build_enum_value_node(enum_value)
|
109
102
|
end,
|
110
103
|
description: enum_type.description,
|
@@ -149,7 +142,7 @@ module GraphQL
|
|
149
142
|
def build_input_object_node(input_object)
|
150
143
|
GraphQL::Language::Nodes::InputObjectTypeDefinition.new(
|
151
144
|
name: input_object.graphql_name,
|
152
|
-
fields: build_argument_nodes(
|
145
|
+
fields: build_argument_nodes(@types.arguments(input_object)),
|
153
146
|
description: input_object.description,
|
154
147
|
directives: directives(input_object),
|
155
148
|
)
|
@@ -159,7 +152,7 @@ module GraphQL
|
|
159
152
|
GraphQL::Language::Nodes::DirectiveDefinition.new(
|
160
153
|
name: directive.graphql_name,
|
161
154
|
repeatable: directive.repeatable?,
|
162
|
-
arguments: build_argument_nodes(
|
155
|
+
arguments: build_argument_nodes(@types.arguments(directive)),
|
163
156
|
locations: build_directive_location_nodes(directive.locations),
|
164
157
|
description: directive.description,
|
165
158
|
)
|
@@ -204,7 +197,7 @@ module GraphQL
|
|
204
197
|
when "INPUT_OBJECT"
|
205
198
|
GraphQL::Language::Nodes::InputObject.new(
|
206
199
|
arguments: default_value.to_h.map do |arg_name, arg_value|
|
207
|
-
args = @
|
200
|
+
args = @types.arguments(type)
|
208
201
|
arg = args.find { |a| a.keyword.to_s == arg_name.to_s }
|
209
202
|
if arg.nil?
|
210
203
|
raise ArgumentError, "No argument definition on #{type.graphql_name} for argument: #{arg_name.inspect} (expected one of: #{args.map(&:keyword)})"
|
@@ -260,13 +253,13 @@ module GraphQL
|
|
260
253
|
end
|
261
254
|
|
262
255
|
def build_definition_nodes
|
263
|
-
dirs_to_build =
|
256
|
+
dirs_to_build = @types.directives
|
264
257
|
if !include_built_in_directives
|
265
258
|
dirs_to_build = dirs_to_build.reject { |directive| directive.default_directive? }
|
266
259
|
end
|
267
260
|
definitions = build_directive_nodes(dirs_to_build)
|
268
|
-
|
269
|
-
type_nodes = build_type_definition_nodes(
|
261
|
+
all_types = @types.all_types
|
262
|
+
type_nodes = build_type_definition_nodes(all_types + schema.extra_types)
|
270
263
|
if @include_one_of
|
271
264
|
# This may have been set to true when iterating over all types
|
272
265
|
definitions.concat(build_directive_nodes([GraphQL::Schema::Directive::OneOf]))
|
@@ -351,7 +344,7 @@ module GraphQL
|
|
351
344
|
dirs
|
352
345
|
end
|
353
346
|
|
354
|
-
attr_reader :schema, :
|
347
|
+
attr_reader :schema, :always_include_schema,
|
355
348
|
:include_introspection_types, :include_built_in_directives, :include_built_in_scalars
|
356
349
|
end
|
357
350
|
end
|
@@ -345,17 +345,14 @@ module GraphQL
|
|
345
345
|
def self.tokenize(string)
|
346
346
|
lexer = GraphQL::Language::Lexer.new(string)
|
347
347
|
tokens = []
|
348
|
-
prev_token = nil
|
349
348
|
while (token_name = lexer.advance)
|
350
349
|
new_token = [
|
351
350
|
token_name,
|
352
351
|
lexer.line_number,
|
353
352
|
lexer.column_number,
|
354
353
|
lexer.debug_token_value(token_name),
|
355
|
-
prev_token,
|
356
354
|
]
|
357
355
|
tokens << new_token
|
358
|
-
prev_token = new_token
|
359
356
|
end
|
360
357
|
tokens
|
361
358
|
end
|
@@ -113,7 +113,7 @@ module GraphQL
|
|
113
113
|
end
|
114
114
|
|
115
115
|
def print_field(field, indent: "")
|
116
|
-
@current_field = query.
|
116
|
+
@current_field = query.types.field(@current_type, field.name)
|
117
117
|
old_type = @current_type
|
118
118
|
@current_type = @current_field.type.unwrap
|
119
119
|
super
|
data/lib/graphql/language.rb
CHANGED
@@ -9,7 +9,6 @@ require "graphql/language/nodes"
|
|
9
9
|
require "graphql/language/cache"
|
10
10
|
require "graphql/language/parser"
|
11
11
|
require "graphql/language/static_visitor"
|
12
|
-
require "graphql/language/token"
|
13
12
|
require "graphql/language/visitor"
|
14
13
|
require "graphql/language/definition_slice"
|
15
14
|
require "strscan"
|
@@ -84,6 +84,10 @@ module GraphQL
|
|
84
84
|
|
85
85
|
def_delegators :@query, :trace, :interpreter?
|
86
86
|
|
87
|
+
def types
|
88
|
+
@query.types
|
89
|
+
end
|
90
|
+
|
87
91
|
RUNTIME_METADATA_KEYS = Set.new([:current_object, :current_arguments, :current_field, :current_path])
|
88
92
|
# @!method []=(key, value)
|
89
93
|
# Reassign `key` to the hash passed to {Schema#execute} as `context:`
|
data/lib/graphql/query.rb
CHANGED
@@ -95,12 +95,24 @@ module GraphQL
|
|
95
95
|
# @param root_value [Object] the object used to resolve fields on the root type
|
96
96
|
# @param max_depth [Numeric] the maximum number of nested selections allowed for this query (falls back to schema-level value)
|
97
97
|
# @param max_complexity [Numeric] the maximum field complexity for this query (falls back to schema-level value)
|
98
|
-
def initialize(schema, query_string = nil, query: nil, document: nil, context: nil, variables: nil, validate: true, static_validator: nil, subscription_topic: nil, operation_name: nil, root_value: nil, max_depth: schema.max_depth, max_complexity: schema.max_complexity, warden: nil)
|
98
|
+
def initialize(schema, query_string = nil, query: nil, document: nil, context: nil, variables: nil, validate: true, static_validator: nil, subscription_topic: nil, operation_name: nil, root_value: nil, max_depth: schema.max_depth, max_complexity: schema.max_complexity, warden: nil, use_schema_subset: nil)
|
99
99
|
# Even if `variables: nil` is passed, use an empty hash for simpler logic
|
100
100
|
variables ||= {}
|
101
101
|
@schema = schema
|
102
102
|
@context = schema.context_class.new(query: self, values: context)
|
103
|
-
|
103
|
+
|
104
|
+
if use_schema_subset.nil?
|
105
|
+
use_schema_subset = warden ? false : schema.use_schema_subset?
|
106
|
+
end
|
107
|
+
|
108
|
+
if use_schema_subset
|
109
|
+
@schema_subset = @schema.subset_class.new(self)
|
110
|
+
@warden = Schema::Warden::NullWarden.new(context: self, schema: @schema)
|
111
|
+
else
|
112
|
+
@schema_subset = nil
|
113
|
+
@warden = warden
|
114
|
+
end
|
115
|
+
|
104
116
|
@subscription_topic = subscription_topic
|
105
117
|
@root_value = root_value
|
106
118
|
@fragments = nil
|
@@ -195,7 +207,14 @@ module GraphQL
|
|
195
207
|
def lookahead
|
196
208
|
@lookahead ||= begin
|
197
209
|
ast_node = selected_operation
|
198
|
-
root_type =
|
210
|
+
root_type = case ast_node.operation_type
|
211
|
+
when nil, "query"
|
212
|
+
types.query_root # rubocop:disable Development/ContextIsPassedCop
|
213
|
+
when "mutation"
|
214
|
+
types.mutation_root # rubocop:disable Development/ContextIsPassedCop
|
215
|
+
when "subscription"
|
216
|
+
types.subscription_root # rubocop:disable Development/ContextIsPassedCop
|
217
|
+
end
|
199
218
|
GraphQL::Execution::Lookahead.new(query: self, root_type: root_type, ast_nodes: [ast_node])
|
200
219
|
end
|
201
220
|
end
|
@@ -330,6 +349,10 @@ module GraphQL
|
|
330
349
|
|
331
350
|
def_delegators :warden, :get_type, :get_field, :possible_types, :root_type_for_operation
|
332
351
|
|
352
|
+
def types
|
353
|
+
@schema_subset || warden.schema_subset
|
354
|
+
end
|
355
|
+
|
333
356
|
# @param abstract_type [GraphQL::UnionType, GraphQL::InterfaceType]
|
334
357
|
# @param value [Object] Any runtime value
|
335
358
|
# @return [GraphQL::ObjectType, nil] The runtime type of `value` from {Schema#resolve_type}
|
data/lib/graphql/schema/enum.rb
CHANGED
@@ -130,7 +130,7 @@ module GraphQL
|
|
130
130
|
end
|
131
131
|
|
132
132
|
def validate_non_null_input(value_name, ctx, max_errors: nil)
|
133
|
-
allowed_values = ctx.
|
133
|
+
allowed_values = ctx.types.enum_values(self)
|
134
134
|
matching_value = allowed_values.find { |v| v.graphql_name == value_name }
|
135
135
|
|
136
136
|
if matching_value.nil?
|
@@ -141,8 +141,8 @@ module GraphQL
|
|
141
141
|
end
|
142
142
|
|
143
143
|
def coerce_result(value, ctx)
|
144
|
-
|
145
|
-
all_values =
|
144
|
+
types = ctx.types
|
145
|
+
all_values = types ? types.enum_values(self) : values.each_value
|
146
146
|
enum_value = all_values.find { |val| val.value == value }
|
147
147
|
if enum_value
|
148
148
|
enum_value.graphql_name
|
@@ -152,7 +152,7 @@ module GraphQL
|
|
152
152
|
end
|
153
153
|
|
154
154
|
def coerce_input(value_name, ctx)
|
155
|
-
all_values = ctx.
|
155
|
+
all_values = ctx.types ? ctx.types.enum_values(self) : values.each_value
|
156
156
|
|
157
157
|
if v = all_values.find { |val| val.graphql_name == value_name }
|
158
158
|
v.value
|
data/lib/graphql/schema/field.rb
CHANGED
@@ -42,8 +42,12 @@ module GraphQL
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def directives
|
45
|
-
if @resolver_class
|
46
|
-
|
45
|
+
if @resolver_class && (r_dirs = @resolver_class.directives).any?
|
46
|
+
if (own_dirs = super).any?
|
47
|
+
own_dirs + r_dirs
|
48
|
+
else
|
49
|
+
r_dirs
|
50
|
+
end
|
47
51
|
else
|
48
52
|
super
|
49
53
|
end
|
@@ -614,7 +618,7 @@ module GraphQL
|
|
614
618
|
using_arg_values = false
|
615
619
|
end
|
616
620
|
|
617
|
-
args = context.
|
621
|
+
args = context.types.arguments(self)
|
618
622
|
args.each do |arg|
|
619
623
|
arg_key = arg.keyword
|
620
624
|
if arg_values.key?(arg_key)
|
@@ -149,7 +149,8 @@ module GraphQL
|
|
149
149
|
|
150
150
|
def authorize_arguments(args, values)
|
151
151
|
# remove the `input` wrapper to match values
|
152
|
-
|
152
|
+
input_type = args.find { |a| a.graphql_name == "input" }.type.unwrap
|
153
|
+
input_args = context.types.arguments(input_type)
|
153
154
|
super(input_args, values)
|
154
155
|
end
|
155
156
|
end
|