graphql 2.2.17 → 2.5.16
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/generators/graphql/install/mutation_root_generator.rb +2 -2
- 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/templates/schema.erb +3 -0
- data/lib/generators/graphql/type_generator.rb +1 -1
- data/lib/graphql/analysis/analyzer.rb +90 -0
- data/lib/graphql/analysis/field_usage.rb +82 -0
- data/lib/graphql/analysis/max_query_complexity.rb +20 -0
- data/lib/graphql/analysis/max_query_depth.rb +20 -0
- data/lib/graphql/analysis/query_complexity.rb +263 -0
- data/lib/graphql/analysis/{ast/query_depth.rb → query_depth.rb} +23 -25
- data/lib/graphql/analysis/visitor.rb +280 -0
- data/lib/graphql/analysis.rb +95 -1
- data/lib/graphql/autoload.rb +38 -0
- data/lib/graphql/backtrace/table.rb +118 -55
- data/lib/graphql/backtrace.rb +1 -19
- data/lib/graphql/current.rb +57 -0
- data/lib/graphql/dashboard/detailed_traces.rb +47 -0
- data/lib/graphql/dashboard/installable.rb +22 -0
- data/lib/graphql/dashboard/limiters.rb +93 -0
- data/lib/graphql/dashboard/operation_store.rb +199 -0
- data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.css +6 -0
- data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.js +7 -0
- data/lib/graphql/dashboard/statics/charts.min.css +1 -0
- data/lib/graphql/dashboard/statics/dashboard.css +30 -0
- data/lib/graphql/dashboard/statics/dashboard.js +143 -0
- data/lib/graphql/dashboard/statics/header-icon.png +0 -0
- data/lib/graphql/dashboard/statics/icon.png +0 -0
- data/lib/graphql/dashboard/subscriptions.rb +96 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/detailed_traces/traces/index.html.erb +45 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/landings/show.html.erb +18 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/limiters/limiters/show.html.erb +62 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/not_installed.html.erb +18 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/_form.html.erb +23 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/edit.html.erb +21 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/index.html.erb +69 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/new.html.erb +7 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/index.html.erb +39 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/show.html.erb +32 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/index.html.erb +81 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/show.html.erb +71 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/subscriptions/show.html.erb +41 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/index.html.erb +55 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/show.html.erb +40 -0
- data/lib/graphql/dashboard/views/layouts/graphql/dashboard/application.html.erb +108 -0
- data/lib/graphql/dashboard.rb +158 -0
- data/lib/graphql/dataloader/active_record_association_source.rb +84 -0
- data/lib/graphql/dataloader/active_record_source.rb +47 -0
- data/lib/graphql/dataloader/async_dataloader.rb +46 -19
- data/lib/graphql/dataloader/null_dataloader.rb +51 -10
- data/lib/graphql/dataloader/source.rb +20 -9
- data/lib/graphql/dataloader.rb +153 -45
- data/lib/graphql/date_encoding_error.rb +1 -1
- data/lib/graphql/dig.rb +2 -1
- data/lib/graphql/execution/interpreter/argument_value.rb +5 -1
- data/lib/graphql/execution/interpreter/arguments_cache.rb +5 -10
- data/lib/graphql/execution/interpreter/resolve.rb +23 -25
- data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +63 -5
- data/lib/graphql/execution/interpreter/runtime.rb +321 -222
- data/lib/graphql/execution/interpreter.rb +23 -30
- data/lib/graphql/execution/lookahead.rb +18 -11
- data/lib/graphql/execution/multiplex.rb +6 -5
- data/lib/graphql/introspection/directive_location_enum.rb +1 -1
- 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_name_error.rb +1 -1
- data/lib/graphql/invalid_null_error.rb +20 -17
- 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 +64 -35
- data/lib/graphql/language/lexer.rb +72 -42
- data/lib/graphql/language/nodes.rb +93 -52
- data/lib/graphql/language/parser.rb +168 -61
- data/lib/graphql/language/printer.rb +31 -15
- data/lib/graphql/language/sanitized_printer.rb +1 -1
- data/lib/graphql/language.rb +61 -1
- data/lib/graphql/pagination/connection.rb +1 -1
- data/lib/graphql/query/context/scoped_context.rb +1 -1
- data/lib/graphql/query/context.rb +46 -47
- data/lib/graphql/query/null_context.rb +3 -5
- data/lib/graphql/query/partial.rb +179 -0
- data/lib/graphql/query/validation_pipeline.rb +2 -2
- data/lib/graphql/query/variable_validation_error.rb +1 -1
- data/lib/graphql/query.rb +123 -69
- data/lib/graphql/railtie.rb +7 -0
- data/lib/graphql/rubocop/graphql/base_cop.rb +1 -1
- 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 +26 -13
- data/lib/graphql/schema/always_visible.rb +7 -2
- data/lib/graphql/schema/argument.rb +57 -8
- data/lib/graphql/schema/build_from_definition.rb +116 -49
- data/lib/graphql/schema/directive/flagged.rb +4 -2
- data/lib/graphql/schema/directive.rb +54 -2
- data/lib/graphql/schema/enum.rb +107 -24
- 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 +134 -45
- data/lib/graphql/schema/field_extension.rb +1 -1
- data/lib/graphql/schema/has_single_input_argument.rb +6 -2
- data/lib/graphql/schema/input_object.rb +122 -64
- data/lib/graphql/schema/interface.rb +23 -5
- data/lib/graphql/schema/introspection_system.rb +6 -17
- data/lib/graphql/schema/late_bound_type.rb +4 -0
- data/lib/graphql/schema/list.rb +3 -3
- data/lib/graphql/schema/loader.rb +3 -2
- data/lib/graphql/schema/member/base_dsl_methods.rb +15 -0
- data/lib/graphql/schema/member/has_arguments.rb +44 -58
- data/lib/graphql/schema/member/has_dataloader.rb +62 -0
- data/lib/graphql/schema/member/has_deprecation_reason.rb +15 -0
- data/lib/graphql/schema/member/has_directives.rb +4 -4
- data/lib/graphql/schema/member/has_fields.rb +26 -6
- data/lib/graphql/schema/member/has_interfaces.rb +6 -6
- 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/member/relay_shortcuts.rb +1 -1
- data/lib/graphql/schema/member/type_system_helpers.rb +17 -4
- data/lib/graphql/schema/member.rb +1 -0
- data/lib/graphql/schema/mutation.rb +7 -0
- data/lib/graphql/schema/object.rb +25 -8
- data/lib/graphql/schema/printer.rb +1 -0
- data/lib/graphql/schema/ractor_shareable.rb +79 -0
- data/lib/graphql/schema/relay_classic_mutation.rb +0 -1
- data/lib/graphql/schema/resolver.rb +29 -23
- data/lib/graphql/schema/scalar.rb +1 -6
- data/lib/graphql/schema/subscription.rb +52 -6
- data/lib/graphql/schema/timeout.rb +19 -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 +92 -11
- data/lib/graphql/schema/validator.rb +3 -1
- data/lib/graphql/schema/visibility/migration.rb +188 -0
- data/lib/graphql/schema/visibility/profile.rb +445 -0
- data/lib/graphql/schema/visibility/visit.rb +190 -0
- data/lib/graphql/schema/visibility.rb +311 -0
- data/lib/graphql/schema/warden.rb +190 -20
- data/lib/graphql/schema.rb +695 -167
- data/lib/graphql/static_validation/all_rules.rb +2 -2
- 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 +47 -13
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +88 -25
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +10 -2
- 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/not_single_subscription_error.rb +25 -0
- 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_and_single_subscription_selection.rb +26 -0
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +7 -3
- 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/static_validation/validator.rb +6 -1
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +5 -3
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +11 -5
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +12 -10
- data/lib/graphql/subscriptions/event.rb +13 -2
- data/lib/graphql/subscriptions/serialize.rb +1 -1
- data/lib/graphql/subscriptions.rb +7 -5
- data/lib/graphql/testing/helpers.rb +48 -16
- data/lib/graphql/testing/mock_action_cable.rb +111 -0
- data/lib/graphql/testing.rb +1 -0
- data/lib/graphql/tracing/active_support_notifications_trace.rb +14 -3
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +1 -1
- data/lib/graphql/tracing/appoptics_trace.rb +5 -1
- data/lib/graphql/tracing/appoptics_tracing.rb +7 -0
- data/lib/graphql/tracing/appsignal_trace.rb +32 -59
- data/lib/graphql/tracing/appsignal_tracing.rb +2 -0
- data/lib/graphql/tracing/call_legacy_tracers.rb +66 -0
- data/lib/graphql/tracing/data_dog_trace.rb +46 -162
- data/lib/graphql/tracing/data_dog_tracing.rb +2 -0
- data/lib/graphql/tracing/detailed_trace/memory_backend.rb +60 -0
- data/lib/graphql/tracing/detailed_trace/redis_backend.rb +72 -0
- data/lib/graphql/tracing/detailed_trace.rb +141 -0
- data/lib/graphql/tracing/legacy_hooks_trace.rb +1 -0
- data/lib/graphql/tracing/legacy_trace.rb +4 -61
- data/lib/graphql/tracing/monitor_trace.rb +283 -0
- data/lib/graphql/tracing/new_relic_trace.rb +47 -54
- data/lib/graphql/tracing/new_relic_tracing.rb +2 -0
- data/lib/graphql/tracing/notifications_trace.rb +183 -37
- data/lib/graphql/tracing/notifications_tracing.rb +2 -0
- data/lib/graphql/tracing/null_trace.rb +9 -0
- data/lib/graphql/tracing/perfetto_trace/trace.proto +141 -0
- data/lib/graphql/tracing/perfetto_trace/trace_pb.rb +33 -0
- data/lib/graphql/tracing/perfetto_trace.rb +818 -0
- data/lib/graphql/tracing/platform_tracing.rb +1 -1
- data/lib/graphql/tracing/prometheus_trace/graphql_collector.rb +2 -0
- data/lib/graphql/tracing/prometheus_trace.rb +73 -73
- data/lib/graphql/tracing/prometheus_tracing.rb +2 -0
- data/lib/graphql/tracing/scout_trace.rb +32 -58
- data/lib/graphql/tracing/scout_tracing.rb +2 -0
- data/lib/graphql/tracing/sentry_trace.rb +64 -98
- data/lib/graphql/tracing/statsd_trace.rb +33 -45
- data/lib/graphql/tracing/statsd_tracing.rb +2 -0
- data/lib/graphql/tracing/trace.rb +111 -1
- data/lib/graphql/tracing.rb +31 -30
- data/lib/graphql/type_kinds.rb +2 -1
- 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 +64 -54
- metadata +197 -22
- data/lib/graphql/analysis/ast/analyzer.rb +0 -91
- data/lib/graphql/analysis/ast/field_usage.rb +0 -82
- data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -22
- data/lib/graphql/analysis/ast/max_query_depth.rb +0 -22
- data/lib/graphql/analysis/ast/query_complexity.rb +0 -182
- data/lib/graphql/analysis/ast/visitor.rb +0 -276
- data/lib/graphql/analysis/ast.rb +0 -94
- data/lib/graphql/backtrace/inspect_result.rb +0 -50
- data/lib/graphql/backtrace/trace.rb +0 -93
- data/lib/graphql/backtrace/tracer.rb +0 -80
- data/lib/graphql/language/token.rb +0 -34
- data/lib/graphql/schema/invalid_type_error.rb +0 -7
- data/lib/graphql/schema/null_mask.rb +0 -11
- data/lib/graphql/static_validation/rules/subscription_root_exists.rb +0 -17
|
@@ -20,30 +20,37 @@ module GraphQL
|
|
|
20
20
|
# @param queries [Array<GraphQL::Query, Hash>]
|
|
21
21
|
# @param context [Hash]
|
|
22
22
|
# @param max_complexity [Integer, nil]
|
|
23
|
-
# @return [Array<
|
|
23
|
+
# @return [Array<GraphQL::Query::Result>] One result per query
|
|
24
24
|
def run_all(schema, query_options, context: {}, max_complexity: schema.max_complexity)
|
|
25
25
|
queries = query_options.map do |opts|
|
|
26
|
-
case opts
|
|
26
|
+
query = case opts
|
|
27
27
|
when Hash
|
|
28
28
|
schema.query_class.new(schema, nil, **opts)
|
|
29
|
-
when GraphQL::Query
|
|
29
|
+
when GraphQL::Query, GraphQL::Query::Partial
|
|
30
30
|
opts
|
|
31
31
|
else
|
|
32
32
|
raise "Expected Hash or GraphQL::Query, not #{opts.class} (#{opts.inspect})"
|
|
33
33
|
end
|
|
34
|
+
query
|
|
34
35
|
end
|
|
35
36
|
|
|
37
|
+
return GraphQL::EmptyObjects::EMPTY_ARRAY if queries.empty?
|
|
38
|
+
|
|
36
39
|
multiplex = Execution::Multiplex.new(schema: schema, queries: queries, context: context, max_complexity: max_complexity)
|
|
37
|
-
multiplex.current_trace
|
|
40
|
+
trace = multiplex.current_trace
|
|
41
|
+
Fiber[:__graphql_current_multiplex] = multiplex
|
|
42
|
+
trace.execute_multiplex(multiplex: multiplex) do
|
|
38
43
|
schema = multiplex.schema
|
|
39
44
|
queries = multiplex.queries
|
|
40
|
-
lazies_at_depth = Hash.new { |h, k| h[k] = [] }
|
|
41
45
|
multiplex_analyzers = schema.multiplex_analyzers
|
|
42
46
|
if multiplex.max_complexity
|
|
43
|
-
multiplex_analyzers += [GraphQL::Analysis::
|
|
47
|
+
multiplex_analyzers += [GraphQL::Analysis::MaxQueryComplexity]
|
|
44
48
|
end
|
|
45
49
|
|
|
50
|
+
trace.begin_analyze_multiplex(multiplex, multiplex_analyzers)
|
|
46
51
|
schema.analysis_engine.analyze_multiplex(multiplex, multiplex_analyzers)
|
|
52
|
+
trace.end_analyze_multiplex(multiplex, multiplex_analyzers)
|
|
53
|
+
|
|
47
54
|
begin
|
|
48
55
|
# Since this is basically the batching context,
|
|
49
56
|
# share it for a whole multiplex
|
|
@@ -52,18 +59,20 @@ module GraphQL
|
|
|
52
59
|
results = []
|
|
53
60
|
queries.each_with_index do |query, idx|
|
|
54
61
|
if query.subscription? && !query.subscription_update?
|
|
55
|
-
query.context.namespace(:subscriptions)
|
|
62
|
+
subs_namespace = query.context.namespace(:subscriptions)
|
|
63
|
+
subs_namespace[:events] = []
|
|
64
|
+
subs_namespace[:subscriptions] = {}
|
|
56
65
|
end
|
|
57
66
|
multiplex.dataloader.append_job {
|
|
58
67
|
operation = query.selected_operation
|
|
59
|
-
result = if operation.nil? || !query.valid? || query.context.errors.
|
|
68
|
+
result = if operation.nil? || !query.valid? || !query.context.errors.empty?
|
|
60
69
|
NO_OPERATION
|
|
61
70
|
else
|
|
62
71
|
begin
|
|
63
72
|
# Although queries in a multiplex _share_ an Interpreter instance,
|
|
64
73
|
# they also have another item of state, which is private to that query
|
|
65
74
|
# in particular, assign it here:
|
|
66
|
-
runtime = Runtime.new(query: query
|
|
75
|
+
runtime = Runtime.new(query: query)
|
|
67
76
|
query.context.namespace(:interpreter_runtime)[:runtime] = runtime
|
|
68
77
|
|
|
69
78
|
query.current_trace.execute_query(query: query) do
|
|
@@ -71,40 +80,23 @@ module GraphQL
|
|
|
71
80
|
end
|
|
72
81
|
rescue GraphQL::ExecutionError => err
|
|
73
82
|
query.context.errors << err
|
|
74
|
-
NO_OPERATION
|
|
75
83
|
end
|
|
76
84
|
end
|
|
77
85
|
results[idx] = result
|
|
78
86
|
}
|
|
79
87
|
end
|
|
80
88
|
|
|
81
|
-
multiplex.dataloader.run
|
|
82
|
-
|
|
83
|
-
# Then, work through lazy results in a breadth-first way
|
|
84
|
-
multiplex.dataloader.append_job {
|
|
85
|
-
query = multiplex.queries.length == 1 ? multiplex.queries[0] : nil
|
|
86
|
-
queries = multiplex ? multiplex.queries : [query]
|
|
87
|
-
final_values = queries.map do |query|
|
|
88
|
-
runtime = query.context.namespace(:interpreter_runtime)[:runtime]
|
|
89
|
-
# it might not be present if the query has an error
|
|
90
|
-
runtime ? runtime.final_result : nil
|
|
91
|
-
end
|
|
92
|
-
final_values.compact!
|
|
93
|
-
multiplex.current_trace.execute_query_lazy(multiplex: multiplex, query: query) do
|
|
94
|
-
Interpreter::Resolve.resolve_each_depth(lazies_at_depth, multiplex.dataloader)
|
|
95
|
-
end
|
|
96
|
-
}
|
|
97
|
-
multiplex.dataloader.run
|
|
89
|
+
multiplex.dataloader.run(trace_query_lazy: multiplex)
|
|
98
90
|
|
|
99
91
|
# Then, find all errors and assign the result to the query object
|
|
100
92
|
results.each_with_index do |data_result, idx|
|
|
101
93
|
query = queries[idx]
|
|
102
|
-
if (events = query.context.namespace(:subscriptions)[:events]) && events.
|
|
94
|
+
if (events = query.context.namespace(:subscriptions)[:events]) && !events.empty?
|
|
103
95
|
schema.subscriptions.write_subscription(query, events)
|
|
104
96
|
end
|
|
105
97
|
# Assign the result so that it can be accessed in instrumentation
|
|
106
98
|
query.result_values = if data_result.equal?(NO_OPERATION)
|
|
107
|
-
if !query.valid? || query.context.errors.
|
|
99
|
+
if !query.valid? || !query.context.errors.empty?
|
|
108
100
|
# A bit weird, but `Query#static_errors` _includes_ `query.context.errors`
|
|
109
101
|
{ "errors" => query.static_errors.map(&:to_h) }
|
|
110
102
|
else
|
|
@@ -113,7 +105,7 @@ module GraphQL
|
|
|
113
105
|
else
|
|
114
106
|
result = {}
|
|
115
107
|
|
|
116
|
-
if query.context.errors.
|
|
108
|
+
if !query.context.errors.empty?
|
|
117
109
|
error_result = query.context.errors.map(&:to_h)
|
|
118
110
|
result["errors"] = error_result
|
|
119
111
|
end
|
|
@@ -136,6 +128,7 @@ module GraphQL
|
|
|
136
128
|
queries.map { |q| q.result_values ||= {} }
|
|
137
129
|
raise
|
|
138
130
|
ensure
|
|
131
|
+
Fiber[:__graphql_current_multiplex] = nil
|
|
139
132
|
queries.map { |query|
|
|
140
133
|
runtime = query.context.namespace(:interpreter_runtime)[:runtime]
|
|
141
134
|
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
|
|
@@ -32,14 +32,15 @@ module GraphQL
|
|
|
32
32
|
@queries = queries
|
|
33
33
|
@queries.each { |q| q.multiplex = self }
|
|
34
34
|
@context = context
|
|
35
|
-
@current_trace = @context[:trace] || schema.new_trace(multiplex: self)
|
|
36
35
|
@dataloader = @context[:dataloader] ||= @schema.dataloader_class.new
|
|
37
36
|
@tracers = schema.tracers + (context[:tracers] || [])
|
|
38
|
-
# Support `context: {backtrace: true}`
|
|
39
|
-
if context[:backtrace] && !@tracers.include?(GraphQL::Backtrace::Tracer)
|
|
40
|
-
@tracers << GraphQL::Backtrace::Tracer
|
|
41
|
-
end
|
|
42
37
|
@max_complexity = max_complexity
|
|
38
|
+
@current_trace = context[:trace] ||= schema.new_trace(multiplex: self)
|
|
39
|
+
@logger = nil
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def logger
|
|
43
|
+
@logger ||= @schema.logger_for(context)
|
|
43
44
|
end
|
|
44
45
|
end
|
|
45
46
|
end
|
|
@@ -7,7 +7,7 @@ module GraphQL
|
|
|
7
7
|
"a __DirectiveLocation describes one such possible adjacencies."
|
|
8
8
|
|
|
9
9
|
GraphQL::Schema::Directive::LOCATIONS.each do |location|
|
|
10
|
-
value(location.to_s, GraphQL::Schema::Directive::LOCATION_DESCRIPTIONS[location], value: location)
|
|
10
|
+
value(location.to_s, GraphQL::Schema::Directive::LOCATION_DESCRIPTIONS[location], value: location, value_method: false)
|
|
11
11
|
end
|
|
12
12
|
introspection true
|
|
13
13
|
end
|
|
@@ -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
|
|
@@ -2,31 +2,34 @@
|
|
|
2
2
|
module GraphQL
|
|
3
3
|
# Raised automatically when a field's resolve function returns `nil`
|
|
4
4
|
# for a non-null field.
|
|
5
|
-
class InvalidNullError < GraphQL::
|
|
5
|
+
class InvalidNullError < GraphQL::Error
|
|
6
6
|
# @return [GraphQL::BaseType] The owner of {#field}
|
|
7
7
|
attr_reader :parent_type
|
|
8
8
|
|
|
9
9
|
# @return [GraphQL::Field] The field which failed to return a value
|
|
10
10
|
attr_reader :field
|
|
11
11
|
|
|
12
|
-
# @return [
|
|
13
|
-
attr_reader :
|
|
12
|
+
# @return [GraphQL::Language::Nodes::Field] the field where the error occurred
|
|
13
|
+
attr_reader :ast_node
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
# @return [Boolean] indicates an array result caused the error
|
|
16
|
+
attr_reader :is_from_array
|
|
17
|
+
|
|
18
|
+
def initialize(parent_type, field, ast_node, is_from_array: false)
|
|
16
19
|
@parent_type = parent_type
|
|
17
20
|
@field = field
|
|
18
|
-
@
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
21
|
+
@ast_node = ast_node
|
|
22
|
+
@is_from_array = is_from_array
|
|
23
|
+
|
|
24
|
+
# For List elements, identify the non-null error is for an
|
|
25
|
+
# element and the required element type so it's not ambiguous
|
|
26
|
+
# whether it was caused by a null instead of the list or a
|
|
27
|
+
# null element.
|
|
28
|
+
if @is_from_array
|
|
29
|
+
super("Cannot return null for non-nullable element of type '#{@field.type.of_type.of_type.to_type_signature}' for #{@parent_type.graphql_name}.#{@field.graphql_name}")
|
|
30
|
+
else
|
|
31
|
+
super("Cannot return null for non-nullable field #{@parent_type.graphql_name}.#{@field.graphql_name}")
|
|
32
|
+
end
|
|
30
33
|
end
|
|
31
34
|
|
|
32
35
|
class << self
|
|
@@ -39,7 +42,7 @@ module GraphQL
|
|
|
39
42
|
end
|
|
40
43
|
|
|
41
44
|
def inspect
|
|
42
|
-
if (name.nil? || parent_class
|
|
45
|
+
if (name.nil? || parent_class&.name.nil?) && parent_class.respond_to?(:mutation) && (mutation = parent_class.mutation)
|
|
43
46
|
"#{mutation.inspect}::#{parent_class.graphql_name}::InvalidNullError"
|
|
44
47
|
else
|
|
45
48
|
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
|