graphql 2.3.7 → 2.4.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/generators/graphql/install_generator.rb +46 -0
- data/lib/generators/graphql/orm_mutations_base.rb +1 -1
- data/lib/generators/graphql/templates/base_resolver.erb +2 -0
- data/lib/generators/graphql/type_generator.rb +1 -1
- data/lib/graphql/analysis/field_usage.rb +1 -1
- data/lib/graphql/analysis/query_complexity.rb +3 -3
- data/lib/graphql/analysis/visitor.rb +8 -7
- data/lib/graphql/analysis.rb +4 -4
- data/lib/graphql/autoload.rb +37 -0
- data/lib/graphql/current.rb +52 -0
- data/lib/graphql/dataloader/async_dataloader.rb +7 -6
- data/lib/graphql/dataloader/source.rb +7 -4
- data/lib/graphql/dataloader.rb +40 -19
- data/lib/graphql/execution/interpreter/arguments_cache.rb +5 -10
- data/lib/graphql/execution/interpreter/resolve.rb +13 -9
- data/lib/graphql/execution/interpreter/runtime.rb +35 -31
- data/lib/graphql/execution/interpreter.rb +6 -4
- data/lib/graphql/execution/lookahead.rb +18 -11
- 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 +6 -11
- data/lib/graphql/introspection/type_type.rb +5 -5
- data/lib/graphql/invalid_null_error.rb +1 -1
- data/lib/graphql/language/cache.rb +13 -0
- data/lib/graphql/language/comment.rb +18 -0
- data/lib/graphql/language/document_from_schema_definition.rb +62 -34
- data/lib/graphql/language/lexer.rb +18 -15
- data/lib/graphql/language/nodes.rb +24 -16
- data/lib/graphql/language/parser.rb +14 -1
- data/lib/graphql/language/printer.rb +31 -15
- data/lib/graphql/language/sanitized_printer.rb +1 -1
- data/lib/graphql/language.rb +6 -6
- data/lib/graphql/pagination/connection.rb +1 -1
- data/lib/graphql/query/context/scoped_context.rb +1 -1
- data/lib/graphql/query/context.rb +13 -6
- data/lib/graphql/query/null_context.rb +3 -5
- data/lib/graphql/query/variable_validation_error.rb +1 -1
- data/lib/graphql/query.rb +72 -18
- data/lib/graphql/railtie.rb +7 -0
- data/lib/graphql/rubocop/graphql/field_type_in_block.rb +144 -0
- data/lib/graphql/rubocop/graphql/root_types_in_block.rb +38 -0
- data/lib/graphql/rubocop.rb +2 -0
- data/lib/graphql/schema/addition.rb +2 -1
- data/lib/graphql/schema/always_visible.rb +6 -2
- data/lib/graphql/schema/argument.rb +14 -1
- data/lib/graphql/schema/build_from_definition.rb +9 -1
- data/lib/graphql/schema/directive/flagged.rb +2 -2
- data/lib/graphql/schema/directive.rb +1 -1
- data/lib/graphql/schema/enum.rb +71 -23
- data/lib/graphql/schema/enum_value.rb +10 -2
- data/lib/graphql/schema/field/connection_extension.rb +1 -1
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +102 -47
- data/lib/graphql/schema/field_extension.rb +1 -1
- data/lib/graphql/schema/has_single_input_argument.rb +5 -2
- data/lib/graphql/schema/input_object.rb +90 -39
- data/lib/graphql/schema/interface.rb +22 -5
- data/lib/graphql/schema/introspection_system.rb +5 -16
- data/lib/graphql/schema/loader.rb +1 -1
- data/lib/graphql/schema/member/base_dsl_methods.rb +15 -0
- data/lib/graphql/schema/member/has_arguments.rb +25 -20
- data/lib/graphql/schema/member/has_directives.rb +3 -3
- data/lib/graphql/schema/member/has_fields.rb +26 -6
- data/lib/graphql/schema/member/has_interfaces.rb +4 -4
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +5 -1
- data/lib/graphql/schema/member/has_validators.rb +1 -1
- data/lib/graphql/schema/object.rb +8 -0
- data/lib/graphql/schema/printer.rb +1 -0
- data/lib/graphql/schema/relay_classic_mutation.rb +0 -1
- data/lib/graphql/schema/resolver.rb +12 -14
- data/lib/graphql/schema/subscription.rb +2 -2
- data/lib/graphql/schema/type_expression.rb +2 -2
- data/lib/graphql/schema/union.rb +1 -1
- data/lib/graphql/schema/validator/all_validator.rb +62 -0
- data/lib/graphql/schema/validator/required_validator.rb +28 -4
- data/lib/graphql/schema/validator.rb +3 -1
- data/lib/graphql/schema/visibility/migration.rb +187 -0
- data/lib/graphql/schema/visibility/profile.rb +353 -0
- data/lib/graphql/schema/visibility/visit.rb +190 -0
- data/lib/graphql/schema/visibility.rb +294 -0
- data/lib/graphql/schema/warden.rb +166 -16
- data/lib/graphql/schema.rb +348 -94
- 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/argument_names_are_unique.rb +1 -1
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +3 -2
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +3 -3
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +2 -0
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +12 -2
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +2 -2
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +8 -7
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +12 -2
- 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/no_definitions_are_present.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 +4 -4
- 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/unique_directives_per_location.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +18 -27
- data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +2 -2
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +11 -2
- data/lib/graphql/static_validation/validation_context.rb +18 -2
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +3 -2
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +10 -4
- data/lib/graphql/subscriptions/event.rb +1 -1
- data/lib/graphql/subscriptions.rb +6 -4
- data/lib/graphql/testing/helpers.rb +10 -6
- data/lib/graphql/tracing/notifications_trace.rb +2 -2
- data/lib/graphql/types/relay/connection_behaviors.rb +12 -2
- data/lib/graphql/types/relay/edge_behaviors.rb +11 -1
- data/lib/graphql/types/relay/page_info_behaviors.rb +4 -0
- data/lib/graphql/types.rb +18 -11
- data/lib/graphql/unauthorized_enum_value_error.rb +13 -0
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +81 -45
- metadata +31 -8
- data/lib/graphql/language/token.rb +0 -34
- data/lib/graphql/schema/invalid_type_error.rb +0 -7
@@ -53,8 +53,7 @@ module GraphQL
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
# { Class => Boolean }
|
56
|
-
@lazy_cache = {}
|
57
|
-
@lazy_cache.compare_by_identity
|
56
|
+
@lazy_cache = {}.compare_by_identity
|
58
57
|
end
|
59
58
|
|
60
59
|
def final_result
|
@@ -143,7 +142,7 @@ module GraphQL
|
|
143
142
|
end
|
144
143
|
else
|
145
144
|
# This is an InlineFragment or a FragmentSpread
|
146
|
-
if
|
145
|
+
if !@runtime_directive_names.empty? && node.directives.any? { |d| @runtime_directive_names.include?(d.name) }
|
147
146
|
next_selections = {}
|
148
147
|
next_selections[:graphql_directives] = node.directives
|
149
148
|
if selections_to_run
|
@@ -160,9 +159,9 @@ module GraphQL
|
|
160
159
|
case node
|
161
160
|
when GraphQL::Language::Nodes::InlineFragment
|
162
161
|
if node.type
|
163
|
-
type_defn =
|
162
|
+
type_defn = query.types.type(node.type.name)
|
164
163
|
|
165
|
-
if query.
|
164
|
+
if query.types.possible_types(type_defn).include?(owner_type)
|
166
165
|
result = gather_selections(owner_object, owner_type, node.selections, selections_to_run, next_selections)
|
167
166
|
if !result.equal?(next_selections)
|
168
167
|
selections_to_run = result
|
@@ -177,8 +176,8 @@ module GraphQL
|
|
177
176
|
end
|
178
177
|
when GraphQL::Language::Nodes::FragmentSpread
|
179
178
|
fragment_def = query.fragments[node.name]
|
180
|
-
type_defn = query.
|
181
|
-
if query.
|
179
|
+
type_defn = query.types.type(fragment_def.type.name)
|
180
|
+
if query.types.possible_types(type_defn).include?(owner_type)
|
182
181
|
result = gather_selections(owner_object, owner_type, fragment_def.selections, selections_to_run, next_selections)
|
183
182
|
if !result.equal?(next_selections)
|
184
183
|
selections_to_run = result
|
@@ -208,22 +207,32 @@ module GraphQL
|
|
208
207
|
finished_jobs = 0
|
209
208
|
enqueued_jobs = gathered_selections.size
|
210
209
|
gathered_selections.each do |result_name, field_ast_nodes_or_ast_node|
|
211
|
-
|
212
|
-
evaluate_selection(
|
213
|
-
result_name, field_ast_nodes_or_ast_node, selections_result
|
214
|
-
)
|
215
|
-
finished_jobs += 1
|
216
|
-
if target_result && finished_jobs == enqueued_jobs
|
217
|
-
selections_result.merge_into(target_result)
|
218
|
-
end
|
219
|
-
}
|
210
|
+
|
220
211
|
# Field resolution may pause the fiber,
|
221
212
|
# so it wouldn't get to the `Resolve` call that happens below.
|
222
213
|
# So instead trigger a run from this outer context.
|
223
214
|
if selections_result.graphql_is_eager
|
224
215
|
@dataloader.clear_cache
|
225
|
-
@dataloader.
|
226
|
-
|
216
|
+
@dataloader.run_isolated {
|
217
|
+
evaluate_selection(
|
218
|
+
result_name, field_ast_nodes_or_ast_node, selections_result
|
219
|
+
)
|
220
|
+
finished_jobs += 1
|
221
|
+
if target_result && finished_jobs == enqueued_jobs
|
222
|
+
selections_result.merge_into(target_result)
|
223
|
+
end
|
224
|
+
@dataloader.clear_cache
|
225
|
+
}
|
226
|
+
else
|
227
|
+
@dataloader.append_job {
|
228
|
+
evaluate_selection(
|
229
|
+
result_name, field_ast_nodes_or_ast_node, selections_result
|
230
|
+
)
|
231
|
+
finished_jobs += 1
|
232
|
+
if target_result && finished_jobs == enqueued_jobs
|
233
|
+
selections_result.merge_into(target_result)
|
234
|
+
end
|
235
|
+
}
|
227
236
|
end
|
228
237
|
end
|
229
238
|
selections_result
|
@@ -245,7 +254,7 @@ module GraphQL
|
|
245
254
|
end
|
246
255
|
field_name = ast_node.name
|
247
256
|
owner_type = selections_result.graphql_result_type
|
248
|
-
field_defn = query.
|
257
|
+
field_defn = query.types.field(owner_type, field_name)
|
249
258
|
|
250
259
|
# Set this before calling `run_with_directives`, so that the directive can have the latest path
|
251
260
|
runtime_state = get_current_runtime_state
|
@@ -323,7 +332,7 @@ module GraphQL
|
|
323
332
|
extra_args[extra] = field_defn.fetch_extra(extra, context)
|
324
333
|
end
|
325
334
|
end
|
326
|
-
if extra_args.
|
335
|
+
if !extra_args.empty?
|
327
336
|
resolved_arguments = resolved_arguments.merge_extras(extra_args)
|
328
337
|
end
|
329
338
|
resolved_arguments.keyword_arguments
|
@@ -352,7 +361,7 @@ module GraphQL
|
|
352
361
|
end
|
353
362
|
|
354
363
|
field_result = call_method_on_directives(:resolve, object, directives) do
|
355
|
-
if directives.
|
364
|
+
if !directives.empty?
|
356
365
|
# This might be executed in a different context; reset this info
|
357
366
|
runtime_state = get_current_runtime_state
|
358
367
|
runtime_state.current_field = field_defn
|
@@ -516,7 +525,7 @@ module GraphQL
|
|
516
525
|
end
|
517
526
|
when Array
|
518
527
|
# It's an array full of execution errors; add them all.
|
519
|
-
if value.
|
528
|
+
if !value.empty? && value.all?(GraphQL::ExecutionError)
|
520
529
|
list_type_at_all = (field && (field.type.list?))
|
521
530
|
if selection_result.nil? || !selection_result.graphql_dead
|
522
531
|
value.each_with_index do |error, index|
|
@@ -579,7 +588,7 @@ module GraphQL
|
|
579
588
|
resolved_value = value
|
580
589
|
end
|
581
590
|
|
582
|
-
possible_types = query.possible_types(current_type)
|
591
|
+
possible_types = query.types.possible_types(current_type)
|
583
592
|
if !possible_types.include?(resolved_type)
|
584
593
|
parent_type = field.owner_type
|
585
594
|
err_class = current_type::UnresolvedTypeError
|
@@ -727,12 +736,7 @@ module GraphQL
|
|
727
736
|
end
|
728
737
|
|
729
738
|
def get_current_runtime_state
|
730
|
-
current_state =
|
731
|
-
per_query_state = {}
|
732
|
-
per_query_state.compare_by_identity
|
733
|
-
per_query_state
|
734
|
-
end
|
735
|
-
|
739
|
+
current_state = Fiber[:__graphql_runtime_info] ||= {}.compare_by_identity
|
736
740
|
current_state[@query] ||= CurrentState.new
|
737
741
|
end
|
738
742
|
|
@@ -817,11 +821,11 @@ module GraphQL
|
|
817
821
|
end
|
818
822
|
|
819
823
|
def delete_all_interpreter_context
|
820
|
-
per_query_state =
|
824
|
+
per_query_state = Fiber[:__graphql_runtime_info]
|
821
825
|
if per_query_state
|
822
826
|
per_query_state.delete(@query)
|
823
827
|
if per_query_state.size == 0
|
824
|
-
|
828
|
+
Fiber[:__graphql_runtime_info] = nil
|
825
829
|
end
|
826
830
|
end
|
827
831
|
nil
|
@@ -34,6 +34,7 @@ module GraphQL
|
|
34
34
|
end
|
35
35
|
|
36
36
|
multiplex = Execution::Multiplex.new(schema: schema, queries: queries, context: context, max_complexity: max_complexity)
|
37
|
+
Fiber[:__graphql_current_multiplex] = multiplex
|
37
38
|
multiplex.current_trace.execute_multiplex(multiplex: multiplex) do
|
38
39
|
schema = multiplex.schema
|
39
40
|
queries = multiplex.queries
|
@@ -56,7 +57,7 @@ module GraphQL
|
|
56
57
|
end
|
57
58
|
multiplex.dataloader.append_job {
|
58
59
|
operation = query.selected_operation
|
59
|
-
result = if operation.nil? || !query.valid? || query.context.errors.
|
60
|
+
result = if operation.nil? || !query.valid? || !query.context.errors.empty?
|
60
61
|
NO_OPERATION
|
61
62
|
else
|
62
63
|
begin
|
@@ -99,12 +100,12 @@ module GraphQL
|
|
99
100
|
# Then, find all errors and assign the result to the query object
|
100
101
|
results.each_with_index do |data_result, idx|
|
101
102
|
query = queries[idx]
|
102
|
-
if (events = query.context.namespace(:subscriptions)[:events]) && events.
|
103
|
+
if (events = query.context.namespace(:subscriptions)[:events]) && !events.empty?
|
103
104
|
schema.subscriptions.write_subscription(query, events)
|
104
105
|
end
|
105
106
|
# Assign the result so that it can be accessed in instrumentation
|
106
107
|
query.result_values = if data_result.equal?(NO_OPERATION)
|
107
|
-
if !query.valid? || query.context.errors.
|
108
|
+
if !query.valid? || !query.context.errors.empty?
|
108
109
|
# A bit weird, but `Query#static_errors` _includes_ `query.context.errors`
|
109
110
|
{ "errors" => query.static_errors.map(&:to_h) }
|
110
111
|
else
|
@@ -113,7 +114,7 @@ module GraphQL
|
|
113
114
|
else
|
114
115
|
result = {}
|
115
116
|
|
116
|
-
if query.context.errors.
|
117
|
+
if !query.context.errors.empty?
|
117
118
|
error_result = query.context.errors.map(&:to_h)
|
118
119
|
result["errors"] = error_result
|
119
120
|
end
|
@@ -136,6 +137,7 @@ module GraphQL
|
|
136
137
|
queries.map { |q| q.result_values ||= {} }
|
137
138
|
raise
|
138
139
|
ensure
|
140
|
+
Fiber[:__graphql_current_multiplex] = nil
|
139
141
|
queries.map { |query|
|
140
142
|
runtime = query.context.namespace(:interpreter_runtime)[:runtime]
|
141
143
|
if runtime
|
@@ -56,7 +56,14 @@ module GraphQL
|
|
56
56
|
else
|
57
57
|
@arguments = if @field
|
58
58
|
@query.after_lazy(@query.arguments_for(@ast_nodes.first, @field)) do |args|
|
59
|
-
|
59
|
+
case args
|
60
|
+
when Execution::Interpreter::Arguments
|
61
|
+
args.keyword_arguments
|
62
|
+
when GraphQL::ExecutionError
|
63
|
+
EmptyObjects::EMPTY_HASH
|
64
|
+
else
|
65
|
+
args
|
66
|
+
end
|
60
67
|
end
|
61
68
|
else
|
62
69
|
nil
|
@@ -108,16 +115,16 @@ module GraphQL
|
|
108
115
|
def selection(field_name, selected_type: @selected_type, arguments: nil)
|
109
116
|
next_field_defn = case field_name
|
110
117
|
when String
|
111
|
-
@query.
|
118
|
+
@query.types.field(selected_type, field_name)
|
112
119
|
when Symbol
|
113
120
|
# Try to avoid the `.to_s` below, if possible
|
114
121
|
all_fields = if selected_type.kind.fields?
|
115
|
-
@query.
|
122
|
+
@query.types.fields(selected_type)
|
116
123
|
else
|
117
124
|
# Handle unions by checking possible
|
118
|
-
@query.
|
125
|
+
@query.types
|
119
126
|
.possible_types(selected_type)
|
120
|
-
.map { |t| @query.
|
127
|
+
.map { |t| @query.types.fields(t) }
|
121
128
|
.tap(&:flatten!)
|
122
129
|
end
|
123
130
|
|
@@ -128,7 +135,7 @@ module GraphQL
|
|
128
135
|
# Symbol#name is only present on 3.0+
|
129
136
|
sym_s = field_name.respond_to?(:name) ? field_name.name : field_name.to_s
|
130
137
|
guessed_name = Schema::Member::BuildType.camelize(sym_s)
|
131
|
-
@query.
|
138
|
+
@query.types.field(selected_type, guessed_name)
|
132
139
|
end
|
133
140
|
end
|
134
141
|
lookahead_for_selection(next_field_defn, selected_type, arguments)
|
@@ -144,7 +151,7 @@ module GraphQL
|
|
144
151
|
alias_node = lookup_alias_node(ast_nodes, alias_name)
|
145
152
|
return NULL_LOOKAHEAD unless alias_node
|
146
153
|
|
147
|
-
next_field_defn = @query.
|
154
|
+
next_field_defn = @query.types.field(selected_type, alias_node.name)
|
148
155
|
|
149
156
|
alias_arguments = @query.arguments_for(alias_node, next_field_defn)
|
150
157
|
if alias_arguments.is_a?(::GraphQL::Execution::Interpreter::Arguments)
|
@@ -183,7 +190,7 @@ module GraphQL
|
|
183
190
|
|
184
191
|
subselections_by_type.each do |type, ast_nodes_by_response_key|
|
185
192
|
ast_nodes_by_response_key.each do |response_key, ast_nodes|
|
186
|
-
field_defn = @query.
|
193
|
+
field_defn = @query.types.field(type, ast_nodes.first.name)
|
187
194
|
lookahead = Lookahead.new(query: @query, ast_nodes: ast_nodes, field: field_defn, owner_type: type)
|
188
195
|
subselections.push(lookahead)
|
189
196
|
end
|
@@ -266,7 +273,7 @@ module GraphQL
|
|
266
273
|
elsif arguments.nil? || arguments.empty?
|
267
274
|
selections_on_type[response_key] = [ast_selection]
|
268
275
|
else
|
269
|
-
field_defn = @query.
|
276
|
+
field_defn = @query.types.field(selected_type, ast_selection.name)
|
270
277
|
if arguments_match?(arguments, field_defn, ast_selection)
|
271
278
|
selections_on_type[response_key] = [ast_selection]
|
272
279
|
end
|
@@ -276,14 +283,14 @@ module GraphQL
|
|
276
283
|
subselections_on_type = selections_on_type
|
277
284
|
if (t = ast_selection.type)
|
278
285
|
# Assuming this is valid, that `t` will be found.
|
279
|
-
on_type = @query.
|
286
|
+
on_type = @query.types.type(t.name)
|
280
287
|
subselections_on_type = subselections_by_type[on_type] ||= {}
|
281
288
|
end
|
282
289
|
find_selections(subselections_by_type, subselections_on_type, on_type, ast_selection.selections, arguments)
|
283
290
|
when GraphQL::Language::Nodes::FragmentSpread
|
284
291
|
frag_defn = lookup_fragment(ast_selection)
|
285
292
|
# Again, assuming a valid AST
|
286
|
-
on_type = @query.
|
293
|
+
on_type = @query.types.type(frag_defn.type.name)
|
287
294
|
subselections_on_type = subselections_by_type[on_type] ||= {}
|
288
295
|
find_selections(subselections_by_type, subselections_on_type, on_type, frag_defn.selections, arguments)
|
289
296
|
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
|
-
|
18
|
+
if context.types.reachable_type?(name) && (type = context.types.type(name))
|
19
|
+
type
|
20
20
|
elsif (type = context.schema.extra_types.find { |t| t.graphql_name == name })
|
21
21
|
type
|
22
22
|
else
|
@@ -20,31 +20,26 @@ 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
|
27
28
|
|
28
29
|
def query_type
|
29
|
-
|
30
|
+
@context.types.query_root
|
30
31
|
end
|
31
32
|
|
32
33
|
def mutation_type
|
33
|
-
|
34
|
+
@context.types.mutation_root
|
34
35
|
end
|
35
36
|
|
36
37
|
def subscription_type
|
37
|
-
|
38
|
+
@context.types.subscription_root
|
38
39
|
end
|
39
40
|
|
40
41
|
def directives
|
41
|
-
@context.
|
42
|
-
end
|
43
|
-
|
44
|
-
private
|
45
|
-
|
46
|
-
def permitted_root_type(op_type)
|
47
|
-
@context.warden.root_type_for_operation(op_type)
|
42
|
+
@context.types.directives.sort_by(&:graphql_name)
|
48
43
|
end
|
49
44
|
end
|
50
45
|
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
|
@@ -39,7 +39,7 @@ module GraphQL
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def inspect
|
42
|
-
if (name.nil? || parent_class
|
42
|
+
if (name.nil? || parent_class&.name.nil?) && parent_class.respond_to?(:mutation) && (mutation = parent_class.mutation)
|
43
43
|
"#{mutation.inspect}::#{parent_class.graphql_name}::InvalidNullError"
|
44
44
|
else
|
45
45
|
super
|
@@ -5,12 +5,25 @@ require 'digest/sha2'
|
|
5
5
|
|
6
6
|
module GraphQL
|
7
7
|
module Language
|
8
|
+
# This cache is used by {GraphQL::Language::Parser.parse_file} when it's enabled.
|
9
|
+
#
|
10
|
+
# With Rails, parser caching may enabled by setting `config.graphql.parser_cache = true` in your Rails application.
|
11
|
+
#
|
12
|
+
# The cache may be manually built by assigning `GraphQL::Language::Parser.cache = GraphQL::Language::Cache.new("some_dir")`.
|
13
|
+
# This will create a directory (`tmp/cache/graphql` by default) that stores a cache of parsed files.
|
14
|
+
#
|
15
|
+
# Much like [bootsnap](https://github.com/Shopify/bootsnap), the parser cache needs to be cleaned up manually.
|
16
|
+
# You will need to clear the cache directory for each new deployment of your application.
|
17
|
+
# Also note that the parser cache will grow as your schema is loaded, so the cache directory must be writable.
|
18
|
+
#
|
19
|
+
# @see GraphQL::Railtie for simple Rails integration
|
8
20
|
class Cache
|
9
21
|
def initialize(path)
|
10
22
|
@path = path
|
11
23
|
end
|
12
24
|
|
13
25
|
DIGEST = Digest::SHA256.new << GraphQL::VERSION
|
26
|
+
|
14
27
|
def fetch(filename)
|
15
28
|
hash = DIGEST.dup << filename
|
16
29
|
begin
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module Language
|
4
|
+
module Comment
|
5
|
+
def self.print(str, indent: '')
|
6
|
+
lines = str.split("\n").map do |line|
|
7
|
+
comment_str = "".dup
|
8
|
+
comment_str << indent
|
9
|
+
comment_str << "# "
|
10
|
+
comment_str << line
|
11
|
+
comment_str.rstrip
|
12
|
+
end
|
13
|
+
|
14
|
+
lines.join("\n") + "\n"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|