graphql 1.13.12 → 2.0.21
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.
Potentially problematic release.
This version of graphql might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/generators/graphql/install_generator.rb +1 -1
- data/lib/generators/graphql/relay.rb +3 -17
- data/lib/generators/graphql/templates/schema.erb +3 -0
- data/lib/graphql/analysis/ast/field_usage.rb +3 -1
- data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -1
- data/lib/graphql/analysis/ast/query_complexity.rb +1 -1
- data/lib/graphql/analysis/ast/query_depth.rb +0 -1
- data/lib/graphql/analysis/ast/visitor.rb +43 -36
- data/lib/graphql/analysis/ast.rb +2 -12
- data/lib/graphql/analysis.rb +0 -7
- data/lib/graphql/backtrace/table.rb +2 -20
- data/lib/graphql/backtrace/trace.rb +96 -0
- data/lib/graphql/backtrace/tracer.rb +2 -3
- data/lib/graphql/backtrace.rb +7 -8
- data/lib/graphql/dataloader/null_dataloader.rb +3 -1
- data/lib/graphql/dataloader/source.rb +9 -0
- data/lib/graphql/dataloader.rb +4 -1
- data/lib/graphql/dig.rb +1 -1
- data/lib/graphql/execution/errors.rb +12 -82
- data/lib/graphql/execution/interpreter/arguments.rb +1 -1
- data/lib/graphql/execution/interpreter/arguments_cache.rb +2 -3
- data/lib/graphql/execution/interpreter/resolve.rb +26 -0
- data/lib/graphql/execution/interpreter/runtime.rb +300 -222
- data/lib/graphql/execution/interpreter.rb +187 -78
- data/lib/graphql/execution/lazy.rb +7 -21
- data/lib/graphql/execution/lookahead.rb +44 -40
- data/lib/graphql/execution/multiplex.rb +3 -174
- data/lib/graphql/execution.rb +11 -4
- data/lib/graphql/filter.rb +7 -2
- data/lib/graphql/introspection/directive_type.rb +2 -2
- data/lib/graphql/introspection/dynamic_fields.rb +3 -8
- data/lib/graphql/introspection/entry_points.rb +2 -15
- data/lib/graphql/introspection/field_type.rb +1 -1
- data/lib/graphql/introspection/schema_type.rb +2 -2
- data/lib/graphql/introspection/type_type.rb +13 -6
- data/lib/graphql/introspection.rb +4 -3
- data/lib/graphql/language/document_from_schema_definition.rb +43 -44
- data/lib/graphql/language/lexer.rb +216 -1488
- data/lib/graphql/language/nodes.rb +66 -40
- data/lib/graphql/language/parser.rb +539 -510
- data/lib/graphql/language/parser.y +53 -44
- data/lib/graphql/language/printer.rb +37 -21
- data/lib/graphql/language/visitor.rb +191 -83
- data/lib/graphql/pagination/active_record_relation_connection.rb +0 -8
- data/lib/graphql/pagination/array_connection.rb +4 -2
- data/lib/graphql/pagination/connection.rb +33 -6
- data/lib/graphql/pagination/connections.rb +3 -28
- data/lib/graphql/pagination/relation_connection.rb +2 -0
- data/lib/graphql/query/context.rb +156 -196
- data/lib/graphql/query/input_validation_result.rb +10 -1
- data/lib/graphql/query/null_context.rb +1 -4
- data/lib/graphql/query/validation_pipeline.rb +12 -37
- data/lib/graphql/query/variable_validation_error.rb +2 -2
- data/lib/graphql/query/variables.rb +35 -21
- data/lib/graphql/query.rb +39 -46
- data/lib/graphql/railtie.rb +0 -104
- data/lib/graphql/rake_task/validate.rb +1 -1
- data/lib/graphql/rake_task.rb +29 -1
- data/lib/graphql/relay/range_add.rb +9 -20
- data/lib/graphql/relay.rb +0 -15
- data/lib/graphql/schema/addition.rb +7 -9
- data/lib/graphql/schema/argument.rb +38 -47
- data/lib/graphql/schema/build_from_definition.rb +47 -21
- data/lib/graphql/schema/directive/one_of.rb +12 -0
- data/lib/graphql/schema/directive/transform.rb +1 -1
- data/lib/graphql/schema/directive.rb +12 -23
- data/lib/graphql/schema/enum.rb +29 -41
- data/lib/graphql/schema/enum_value.rb +2 -25
- data/lib/graphql/schema/field/connection_extension.rb +4 -0
- data/lib/graphql/schema/field.rb +256 -349
- data/lib/graphql/schema/field_extension.rb +1 -4
- data/lib/graphql/schema/find_inherited_value.rb +2 -7
- data/lib/graphql/schema/input_object.rb +57 -69
- data/lib/graphql/schema/interface.rb +0 -35
- data/lib/graphql/schema/introspection_system.rb +3 -8
- data/lib/graphql/schema/late_bound_type.rb +8 -2
- data/lib/graphql/schema/list.rb +18 -9
- data/lib/graphql/schema/loader.rb +1 -2
- data/lib/graphql/schema/member/base_dsl_methods.rb +17 -19
- data/lib/graphql/schema/member/build_type.rb +5 -7
- data/lib/graphql/schema/member/has_arguments.rb +147 -56
- data/lib/graphql/schema/member/has_ast_node.rb +12 -0
- data/lib/graphql/schema/member/has_deprecation_reason.rb +3 -4
- data/lib/graphql/schema/member/has_directives.rb +81 -61
- data/lib/graphql/schema/member/has_fields.rb +97 -40
- data/lib/graphql/schema/member/has_interfaces.rb +49 -10
- data/lib/graphql/schema/member/has_validators.rb +32 -6
- data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
- data/lib/graphql/schema/member/type_system_helpers.rb +17 -0
- data/lib/graphql/schema/member/validates_input.rb +3 -3
- data/lib/graphql/schema/member.rb +0 -6
- data/lib/graphql/schema/mutation.rb +0 -9
- data/lib/graphql/schema/non_null.rb +3 -9
- data/lib/graphql/schema/object.rb +15 -52
- data/lib/graphql/schema/relay_classic_mutation.rb +53 -42
- data/lib/graphql/schema/resolver/has_payload_type.rb +20 -10
- data/lib/graphql/schema/resolver.rb +43 -44
- data/lib/graphql/schema/scalar.rb +8 -23
- data/lib/graphql/schema/subscription.rb +0 -7
- data/lib/graphql/schema/timeout.rb +24 -28
- data/lib/graphql/schema/type_membership.rb +3 -0
- data/lib/graphql/schema/union.rb +10 -17
- data/lib/graphql/schema/validator.rb +1 -1
- data/lib/graphql/schema/warden.rb +37 -9
- data/lib/graphql/schema/wrapper.rb +0 -5
- data/lib/graphql/schema.rb +265 -968
- data/lib/graphql/static_validation/all_rules.rb +1 -0
- data/lib/graphql/static_validation/base_visitor.rb +4 -21
- data/lib/graphql/static_validation/definition_dependencies.rb +7 -1
- data/lib/graphql/static_validation/error.rb +2 -2
- data/lib/graphql/static_validation/literal_validator.rb +19 -1
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +11 -5
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +12 -12
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +12 -4
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +2 -2
- data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
- data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +12 -6
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +1 -1
- data/lib/graphql/static_validation/validator.rb +3 -25
- data/lib/graphql/static_validation.rb +0 -2
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +7 -1
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +38 -1
- data/lib/graphql/subscriptions/event.rb +3 -8
- data/lib/graphql/subscriptions/instrumentation.rb +0 -51
- data/lib/graphql/subscriptions.rb +32 -20
- data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
- data/lib/graphql/tracing/appoptics_trace.rb +231 -0
- data/lib/graphql/tracing/appsignal_trace.rb +77 -0
- data/lib/graphql/tracing/data_dog_trace.rb +148 -0
- data/lib/graphql/tracing/data_dog_tracing.rb +21 -2
- data/lib/graphql/tracing/legacy_trace.rb +65 -0
- data/lib/graphql/tracing/new_relic_trace.rb +75 -0
- data/lib/graphql/tracing/notifications_trace.rb +42 -0
- data/lib/graphql/tracing/platform_trace.rb +109 -0
- data/lib/graphql/tracing/platform_tracing.rb +33 -43
- data/lib/graphql/tracing/prometheus_trace.rb +89 -0
- data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +1 -1
- data/lib/graphql/tracing/prometheus_tracing.rb +3 -3
- data/lib/graphql/tracing/scout_trace.rb +72 -0
- data/lib/graphql/tracing/statsd_trace.rb +56 -0
- data/lib/graphql/tracing/trace.rb +75 -0
- data/lib/graphql/tracing.rb +16 -40
- data/lib/graphql/type_kinds.rb +6 -3
- data/lib/graphql/types/iso_8601_date.rb +4 -1
- data/lib/graphql/types/iso_8601_date_time.rb +4 -0
- data/lib/graphql/types/relay/base_connection.rb +16 -6
- data/lib/graphql/types/relay/connection_behaviors.rb +29 -27
- data/lib/graphql/types/relay/edge_behaviors.rb +16 -5
- data/lib/graphql/types/relay/node_behaviors.rb +12 -2
- data/lib/graphql/types/relay/page_info_behaviors.rb +7 -2
- data/lib/graphql/types/relay.rb +0 -3
- data/lib/graphql/types/string.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +17 -74
- metadata +33 -133
- data/lib/graphql/analysis/analyze_query.rb +0 -98
- data/lib/graphql/analysis/field_usage.rb +0 -45
- data/lib/graphql/analysis/max_query_complexity.rb +0 -26
- data/lib/graphql/analysis/max_query_depth.rb +0 -26
- data/lib/graphql/analysis/query_complexity.rb +0 -88
- data/lib/graphql/analysis/query_depth.rb +0 -43
- data/lib/graphql/analysis/reducer_state.rb +0 -48
- data/lib/graphql/argument.rb +0 -131
- data/lib/graphql/authorization.rb +0 -82
- data/lib/graphql/backtrace/legacy_tracer.rb +0 -56
- data/lib/graphql/backwards_compatibility.rb +0 -61
- data/lib/graphql/base_type.rb +0 -232
- data/lib/graphql/boolean_type.rb +0 -2
- data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
- data/lib/graphql/compatibility/execution_specification.rb +0 -436
- data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
- data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -215
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
- data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
- data/lib/graphql/compatibility/query_parser_specification.rb +0 -266
- data/lib/graphql/compatibility/schema_parser_specification.rb +0 -682
- data/lib/graphql/compatibility.rb +0 -5
- data/lib/graphql/define/assign_argument.rb +0 -12
- data/lib/graphql/define/assign_connection.rb +0 -13
- data/lib/graphql/define/assign_enum_value.rb +0 -18
- data/lib/graphql/define/assign_global_id_field.rb +0 -11
- data/lib/graphql/define/assign_mutation_function.rb +0 -34
- data/lib/graphql/define/assign_object_field.rb +0 -42
- data/lib/graphql/define/defined_object_proxy.rb +0 -53
- data/lib/graphql/define/instance_definable.rb +0 -255
- data/lib/graphql/define/no_definition_error.rb +0 -7
- data/lib/graphql/define/non_null_with_bang.rb +0 -16
- data/lib/graphql/define/type_definer.rb +0 -31
- data/lib/graphql/define.rb +0 -31
- data/lib/graphql/deprecated_dsl.rb +0 -55
- data/lib/graphql/directive/deprecated_directive.rb +0 -2
- data/lib/graphql/directive/include_directive.rb +0 -2
- data/lib/graphql/directive/skip_directive.rb +0 -2
- data/lib/graphql/directive.rb +0 -107
- data/lib/graphql/enum_type.rb +0 -133
- data/lib/graphql/execution/execute.rb +0 -333
- data/lib/graphql/execution/flatten.rb +0 -40
- data/lib/graphql/execution/instrumentation.rb +0 -92
- data/lib/graphql/execution/lazy/resolve.rb +0 -91
- data/lib/graphql/execution/typecast.rb +0 -50
- data/lib/graphql/field/resolve.rb +0 -59
- data/lib/graphql/field.rb +0 -226
- data/lib/graphql/float_type.rb +0 -2
- data/lib/graphql/function.rb +0 -128
- data/lib/graphql/id_type.rb +0 -2
- data/lib/graphql/input_object_type.rb +0 -138
- data/lib/graphql/int_type.rb +0 -2
- data/lib/graphql/interface_type.rb +0 -72
- data/lib/graphql/internal_representation/document.rb +0 -27
- data/lib/graphql/internal_representation/node.rb +0 -206
- data/lib/graphql/internal_representation/print.rb +0 -51
- data/lib/graphql/internal_representation/rewrite.rb +0 -184
- data/lib/graphql/internal_representation/scope.rb +0 -88
- data/lib/graphql/internal_representation/visit.rb +0 -36
- data/lib/graphql/internal_representation.rb +0 -7
- data/lib/graphql/language/lexer.rl +0 -260
- data/lib/graphql/list_type.rb +0 -80
- data/lib/graphql/non_null_type.rb +0 -71
- data/lib/graphql/object_type.rb +0 -130
- data/lib/graphql/query/arguments.rb +0 -189
- data/lib/graphql/query/arguments_cache.rb +0 -24
- data/lib/graphql/query/executor.rb +0 -52
- data/lib/graphql/query/literal_input.rb +0 -136
- data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
- data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
- data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
- data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
- data/lib/graphql/query/serial_execution.rb +0 -40
- data/lib/graphql/relay/array_connection.rb +0 -83
- data/lib/graphql/relay/base_connection.rb +0 -189
- data/lib/graphql/relay/connection_instrumentation.rb +0 -54
- data/lib/graphql/relay/connection_resolve.rb +0 -43
- data/lib/graphql/relay/connection_type.rb +0 -54
- data/lib/graphql/relay/edge.rb +0 -27
- data/lib/graphql/relay/edge_type.rb +0 -19
- data/lib/graphql/relay/edges_instrumentation.rb +0 -39
- data/lib/graphql/relay/global_id_resolve.rb +0 -17
- data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
- data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
- data/lib/graphql/relay/mutation/resolve.rb +0 -56
- data/lib/graphql/relay/mutation/result.rb +0 -38
- data/lib/graphql/relay/mutation.rb +0 -106
- data/lib/graphql/relay/node.rb +0 -39
- data/lib/graphql/relay/page_info.rb +0 -7
- data/lib/graphql/relay/relation_connection.rb +0 -188
- data/lib/graphql/relay/type_extensions.rb +0 -32
- data/lib/graphql/scalar_type.rb +0 -91
- data/lib/graphql/schema/catchall_middleware.rb +0 -35
- data/lib/graphql/schema/default_parse_error.rb +0 -10
- data/lib/graphql/schema/default_type_error.rb +0 -17
- data/lib/graphql/schema/member/accepts_definition.rb +0 -164
- data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -58
- data/lib/graphql/schema/member/instrumentation.rb +0 -131
- data/lib/graphql/schema/middleware_chain.rb +0 -82
- data/lib/graphql/schema/possible_types.rb +0 -44
- data/lib/graphql/schema/rescue_middleware.rb +0 -60
- data/lib/graphql/schema/timeout_middleware.rb +0 -88
- data/lib/graphql/schema/traversal.rb +0 -228
- data/lib/graphql/schema/validation.rb +0 -313
- data/lib/graphql/static_validation/default_visitor.rb +0 -15
- data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
- data/lib/graphql/string_type.rb +0 -2
- data/lib/graphql/subscriptions/subscription_root.rb +0 -76
- data/lib/graphql/tracing/skylight_tracing.rb +0 -70
- data/lib/graphql/types/relay/default_relay.rb +0 -31
- data/lib/graphql/types/relay/node_field.rb +0 -24
- data/lib/graphql/types/relay/nodes_field.rb +0 -43
- data/lib/graphql/union_type.rb +0 -115
- data/lib/graphql/upgrader/member.rb +0 -937
- data/lib/graphql/upgrader/schema.rb +0 -38
@@ -23,18 +23,16 @@ module GraphQL
|
|
23
23
|
# @see {Schema#multiplex} for public API
|
24
24
|
# @api private
|
25
25
|
class Multiplex
|
26
|
-
# Used internally to signal that the query shouldn't be executed
|
27
|
-
# @api private
|
28
|
-
NO_OPERATION = {}.freeze
|
29
|
-
|
30
26
|
include Tracing::Traceable
|
31
27
|
|
32
|
-
attr_reader :context, :queries, :schema, :max_complexity, :dataloader
|
28
|
+
attr_reader :context, :queries, :schema, :max_complexity, :dataloader, :current_trace
|
29
|
+
|
33
30
|
def initialize(schema:, queries:, context:, max_complexity:)
|
34
31
|
@schema = schema
|
35
32
|
@queries = queries
|
36
33
|
@queries.each { |q| q.multiplex = self }
|
37
34
|
@context = context
|
35
|
+
@current_trace = @context[:trace] || schema.new_trace(multiplex: self)
|
38
36
|
@dataloader = @context[:dataloader] ||= @schema.dataloader_class.new
|
39
37
|
@tracers = schema.tracers + (context[:tracers] || [])
|
40
38
|
# Support `context: {backtrace: true}`
|
@@ -43,175 +41,6 @@ module GraphQL
|
|
43
41
|
end
|
44
42
|
@max_complexity = max_complexity
|
45
43
|
end
|
46
|
-
|
47
|
-
class << self
|
48
|
-
def run_all(schema, query_options, **kwargs)
|
49
|
-
queries = query_options.map { |opts| GraphQL::Query.new(schema, nil, **opts) }
|
50
|
-
run_queries(schema, queries, **kwargs)
|
51
|
-
end
|
52
|
-
|
53
|
-
# @param schema [GraphQL::Schema]
|
54
|
-
# @param queries [Array<GraphQL::Query>]
|
55
|
-
# @param context [Hash]
|
56
|
-
# @param max_complexity [Integer, nil]
|
57
|
-
# @return [Array<Hash>] One result per query
|
58
|
-
def run_queries(schema, queries, context: {}, max_complexity: schema.max_complexity)
|
59
|
-
multiplex = self.new(schema: schema, queries: queries, context: context, max_complexity: max_complexity)
|
60
|
-
multiplex.trace("execute_multiplex", { multiplex: multiplex }) do
|
61
|
-
if supports_multiplexing?(schema)
|
62
|
-
instrument_and_analyze(multiplex) do
|
63
|
-
run_as_multiplex(multiplex)
|
64
|
-
end
|
65
|
-
else
|
66
|
-
if queries.length != 1
|
67
|
-
raise ArgumentError, "Multiplexing doesn't support custom execution strategies, run one query at a time instead"
|
68
|
-
else
|
69
|
-
instrument_and_analyze(multiplex) do
|
70
|
-
[run_one_legacy(schema, queries.first)]
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
# @param query [GraphQL::Query]
|
78
|
-
def begin_query(results, idx, query, multiplex)
|
79
|
-
operation = query.selected_operation
|
80
|
-
result = if operation.nil? || !query.valid? || query.context.errors.any?
|
81
|
-
NO_OPERATION
|
82
|
-
else
|
83
|
-
begin
|
84
|
-
# These were checked to be the same in `#supports_multiplexing?`
|
85
|
-
query.schema.query_execution_strategy.begin_query(query, multiplex)
|
86
|
-
rescue GraphQL::ExecutionError => err
|
87
|
-
query.context.errors << err
|
88
|
-
NO_OPERATION
|
89
|
-
end
|
90
|
-
end
|
91
|
-
results[idx] = result
|
92
|
-
nil
|
93
|
-
end
|
94
|
-
|
95
|
-
private
|
96
|
-
|
97
|
-
def run_as_multiplex(multiplex)
|
98
|
-
|
99
|
-
multiplex.schema.query_execution_strategy.begin_multiplex(multiplex)
|
100
|
-
queries = multiplex.queries
|
101
|
-
# Do as much eager evaluation of the query as possible
|
102
|
-
results = []
|
103
|
-
queries.each_with_index do |query, idx|
|
104
|
-
multiplex.dataloader.append_job { begin_query(results, idx, query, multiplex) }
|
105
|
-
end
|
106
|
-
|
107
|
-
multiplex.dataloader.run
|
108
|
-
|
109
|
-
# Then, work through lazy results in a breadth-first way
|
110
|
-
multiplex.dataloader.append_job {
|
111
|
-
multiplex.schema.query_execution_strategy.finish_multiplex(results, multiplex)
|
112
|
-
}
|
113
|
-
multiplex.dataloader.run
|
114
|
-
|
115
|
-
# Then, find all errors and assign the result to the query object
|
116
|
-
results.each_with_index do |data_result, idx|
|
117
|
-
query = queries[idx]
|
118
|
-
finish_query(data_result, query, multiplex)
|
119
|
-
# Get the Query::Result, not the Hash
|
120
|
-
results[idx] = query.result
|
121
|
-
end
|
122
|
-
|
123
|
-
results
|
124
|
-
rescue Exception
|
125
|
-
# TODO rescue at a higher level so it will catch errors in analysis, too
|
126
|
-
# Assign values here so that the query's `@executed` becomes true
|
127
|
-
queries.map { |q| q.result_values ||= {} }
|
128
|
-
raise
|
129
|
-
end
|
130
|
-
|
131
|
-
# @param data_result [Hash] The result for the "data" key, if any
|
132
|
-
# @param query [GraphQL::Query] The query which was run
|
133
|
-
# @return [Hash] final result of this query, including all values and errors
|
134
|
-
def finish_query(data_result, query, multiplex)
|
135
|
-
# Assign the result so that it can be accessed in instrumentation
|
136
|
-
query.result_values = if data_result.equal?(NO_OPERATION)
|
137
|
-
if !query.valid? || query.context.errors.any?
|
138
|
-
# A bit weird, but `Query#static_errors` _includes_ `query.context.errors`
|
139
|
-
{ "errors" => query.static_errors.map(&:to_h) }
|
140
|
-
else
|
141
|
-
data_result
|
142
|
-
end
|
143
|
-
else
|
144
|
-
# Use `context.value` which was assigned during execution
|
145
|
-
result = query.schema.query_execution_strategy.finish_query(query, multiplex)
|
146
|
-
|
147
|
-
if query.context.errors.any?
|
148
|
-
error_result = query.context.errors.map(&:to_h)
|
149
|
-
result["errors"] = error_result
|
150
|
-
end
|
151
|
-
|
152
|
-
result
|
153
|
-
end
|
154
|
-
if query.context.namespace?(:__query_result_extensions__)
|
155
|
-
query.result_values["extensions"] = query.context.namespace(:__query_result_extensions__)
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
# use the old `query_execution_strategy` etc to run this query
|
160
|
-
def run_one_legacy(schema, query)
|
161
|
-
GraphQL::Deprecation.warn "Multiplex.run_one_legacy will be removed from GraphQL-Ruby 2.0, upgrade to the Interpreter to avoid this deprecated codepath: https://graphql-ruby.org/queries/interpreter.html"
|
162
|
-
|
163
|
-
query.result_values = if !query.valid?
|
164
|
-
all_errors = query.validation_errors + query.analysis_errors + query.context.errors
|
165
|
-
if all_errors.any?
|
166
|
-
{ "errors" => all_errors.map(&:to_h) }
|
167
|
-
else
|
168
|
-
nil
|
169
|
-
end
|
170
|
-
else
|
171
|
-
GraphQL::Query::Executor.new(query).result
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
DEFAULT_STRATEGIES = [
|
176
|
-
GraphQL::Execution::Execute,
|
177
|
-
GraphQL::Execution::Interpreter
|
178
|
-
]
|
179
|
-
# @return [Boolean] True if the schema is only using one strategy, and it's one that supports multiplexing.
|
180
|
-
def supports_multiplexing?(schema)
|
181
|
-
schema_strategies = [schema.query_execution_strategy, schema.mutation_execution_strategy, schema.subscription_execution_strategy]
|
182
|
-
schema_strategies.uniq!
|
183
|
-
schema_strategies.size == 1 && DEFAULT_STRATEGIES.include?(schema_strategies.first)
|
184
|
-
end
|
185
|
-
|
186
|
-
# Apply multiplex & query instrumentation to `queries`.
|
187
|
-
#
|
188
|
-
# It yields when the queries should be executed, then runs teardown.
|
189
|
-
def instrument_and_analyze(multiplex)
|
190
|
-
GraphQL::Execution::Instrumentation.apply_instrumenters(multiplex) do
|
191
|
-
schema = multiplex.schema
|
192
|
-
if schema.interpreter? && schema.analysis_engine != GraphQL::Analysis::AST
|
193
|
-
raise <<-ERR
|
194
|
-
Can't use `GraphQL::Execution::Interpreter` without `GraphQL::Analysis::AST`, please add this plugin to your schema:
|
195
|
-
|
196
|
-
use GraphQL::Analysis::AST
|
197
|
-
|
198
|
-
For information about the new analysis engine: https://graphql-ruby.org/queries/ast_analysis.html
|
199
|
-
ERR
|
200
|
-
end
|
201
|
-
multiplex_analyzers = schema.multiplex_analyzers
|
202
|
-
if multiplex.max_complexity
|
203
|
-
multiplex_analyzers += if schema.using_ast_analysis?
|
204
|
-
[GraphQL::Analysis::AST::MaxQueryComplexity]
|
205
|
-
else
|
206
|
-
[GraphQL::Analysis::MaxQueryComplexity.new(multiplex.max_complexity)]
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
schema.analysis_engine.analyze_multiplex(multiplex, multiplex_analyzers)
|
211
|
-
yield
|
212
|
-
end
|
213
|
-
end
|
214
|
-
end
|
215
44
|
end
|
216
45
|
end
|
217
46
|
end
|
data/lib/graphql/execution.rb
CHANGED
@@ -1,11 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require "graphql/execution/directive_checks"
|
3
|
-
require "graphql/execution/execute"
|
4
|
-
require "graphql/execution/flatten"
|
5
|
-
require "graphql/execution/instrumentation"
|
6
3
|
require "graphql/execution/interpreter"
|
7
4
|
require "graphql/execution/lazy"
|
8
5
|
require "graphql/execution/lookahead"
|
9
6
|
require "graphql/execution/multiplex"
|
10
|
-
require "graphql/execution/typecast"
|
11
7
|
require "graphql/execution/errors"
|
8
|
+
|
9
|
+
module GraphQL
|
10
|
+
module Execution
|
11
|
+
# @api private
|
12
|
+
class Skip < GraphQL::Error; end
|
13
|
+
|
14
|
+
# Just a singleton for implementing {Query::Context#skip}
|
15
|
+
# @api private
|
16
|
+
SKIP = Skip.new
|
17
|
+
end
|
18
|
+
end
|
data/lib/graphql/filter.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require "graphql/deprecation"
|
3
|
+
|
2
4
|
module GraphQL
|
3
5
|
# @api private
|
4
6
|
class Filter
|
5
|
-
def initialize(only: nil, except: nil)
|
7
|
+
def initialize(only: nil, except: nil, silence_deprecation_warning: false)
|
8
|
+
if !silence_deprecation_warning
|
9
|
+
GraphQL::Deprecation.warn("GraphQL::Filter is deprecated and will be removed in v2.1.0. Implement `visible?` on your schema members instead (https://graphql-ruby.org/authorization/visibility.html).")
|
10
|
+
end
|
6
11
|
@only = only
|
7
12
|
@except = except
|
8
13
|
end
|
@@ -17,7 +22,7 @@ module GraphQL
|
|
17
22
|
onlies = [self].concat(Array(only))
|
18
23
|
merged_only = MergedOnly.build(onlies)
|
19
24
|
merged_except = MergedExcept.build(Array(except))
|
20
|
-
self.class.new(only: merged_only, except: merged_except)
|
25
|
+
self.class.new(only: merged_only, except: merged_except, silence_deprecation_warning: true)
|
21
26
|
end
|
22
27
|
|
23
28
|
private
|
@@ -11,8 +11,8 @@ module GraphQL
|
|
11
11
|
"to the executor."
|
12
12
|
field :name, String, null: false, method: :graphql_name
|
13
13
|
field :description, String
|
14
|
-
field :locations, [GraphQL::Schema::LateBoundType.new("__DirectiveLocation")], null: false
|
15
|
-
field :args, [GraphQL::Schema::LateBoundType.new("__InputValue")], null: false do
|
14
|
+
field :locations, [GraphQL::Schema::LateBoundType.new("__DirectiveLocation")], null: false, scope: false
|
15
|
+
field :args, [GraphQL::Schema::LateBoundType.new("__InputValue")], null: false, scope: false do
|
16
16
|
argument :include_deprecated, Boolean, required: false, default_value: false
|
17
17
|
end
|
18
18
|
field :on_operation, Boolean, null: false, deprecation_reason: "Use `locations`.", method: :on_operation?
|
@@ -2,15 +2,10 @@
|
|
2
2
|
module GraphQL
|
3
3
|
module Introspection
|
4
4
|
class DynamicFields < Introspection::BaseObject
|
5
|
-
field :__typename, String, "The name of this type", null: false
|
5
|
+
field :__typename, String, "The name of this type", null: false
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
if context.interpreter?
|
10
|
-
object.class.graphql_name
|
11
|
-
else
|
12
|
-
irep_node.owner_type.name
|
13
|
-
end
|
7
|
+
def __typename
|
8
|
+
object.class.graphql_name
|
14
9
|
end
|
15
10
|
end
|
16
11
|
end
|
@@ -11,24 +11,11 @@ module GraphQL
|
|
11
11
|
# Apply wrapping manually since this field isn't wrapped by instrumentation
|
12
12
|
schema = @context.query.schema
|
13
13
|
schema_type = schema.introspection_system.types["__Schema"]
|
14
|
-
schema_type.
|
14
|
+
schema_type.authorized_new(schema, @context)
|
15
15
|
end
|
16
16
|
|
17
17
|
def __type(name:)
|
18
|
-
|
19
|
-
type = context.warden.get_type(name)
|
20
|
-
|
21
|
-
if type && context.interpreter? && !type.is_a?(Module)
|
22
|
-
type = type.type_class || raise("Invariant: interpreter requires class-based type for #{name}")
|
23
|
-
end
|
24
|
-
|
25
|
-
# The interpreter provides this wrapping, other execution doesnt, so support both.
|
26
|
-
if type && !context.interpreter?
|
27
|
-
# Apply wrapping manually since this field isn't wrapped by instrumentation
|
28
|
-
type_type = context.schema.introspection_system.types["__Type"]
|
29
|
-
type = type_type.type_class.authorized_new(type, context)
|
30
|
-
end
|
31
|
-
type
|
18
|
+
context.warden.reachable_type?(name) ? context.warden.get_type(name) : nil
|
32
19
|
end
|
33
20
|
end
|
34
21
|
end
|
@@ -7,7 +7,7 @@ module GraphQL
|
|
7
7
|
"a name, potentially a list of arguments, and a return type."
|
8
8
|
field :name, String, null: false
|
9
9
|
field :description, String
|
10
|
-
field :args, [GraphQL::Schema::LateBoundType.new("__InputValue")], null: false do
|
10
|
+
field :args, [GraphQL::Schema::LateBoundType.new("__InputValue")], null: false, scope: false do
|
11
11
|
argument :include_deprecated, Boolean, required: false, default_value: false
|
12
12
|
end
|
13
13
|
field :type, GraphQL::Schema::LateBoundType.new("__Type"), null: false
|
@@ -8,11 +8,11 @@ module GraphQL
|
|
8
8
|
"available types and directives on the server, as well as the entry points for "\
|
9
9
|
"query, mutation, and subscription operations."
|
10
10
|
|
11
|
-
field :types, [GraphQL::Schema::LateBoundType.new("__Type")], "A list of all types supported by this server.", null: false
|
11
|
+
field :types, [GraphQL::Schema::LateBoundType.new("__Type")], "A list of all types supported by this server.", null: false, scope: false
|
12
12
|
field :query_type, GraphQL::Schema::LateBoundType.new("__Type"), "The type that query operations will be rooted at.", null: false
|
13
13
|
field :mutation_type, GraphQL::Schema::LateBoundType.new("__Type"), "If this server supports mutation, the type that mutation operations will be rooted at."
|
14
14
|
field :subscription_type, GraphQL::Schema::LateBoundType.new("__Type"), "If this server support subscription, the type that subscription operations will be rooted at."
|
15
|
-
field :directives, [GraphQL::Schema::LateBoundType.new("__Directive")], "A list of all directives supported by this server.", null: false
|
15
|
+
field :directives, [GraphQL::Schema::LateBoundType.new("__Directive")], "A list of all directives supported by this server.", null: false, scope: false
|
16
16
|
field :description, String, resolver_method: :schema_description
|
17
17
|
|
18
18
|
def schema_description
|
@@ -14,20 +14,27 @@ module GraphQL
|
|
14
14
|
field :kind, GraphQL::Schema::LateBoundType.new("__TypeKind"), null: false
|
15
15
|
field :name, String, method: :graphql_name
|
16
16
|
field :description, String
|
17
|
-
field :fields, [GraphQL::Schema::LateBoundType.new("__Field")] do
|
17
|
+
field :fields, [GraphQL::Schema::LateBoundType.new("__Field")], scope: false do
|
18
18
|
argument :include_deprecated, Boolean, required: false, default_value: false
|
19
19
|
end
|
20
|
-
field :interfaces, [GraphQL::Schema::LateBoundType.new("__Type")]
|
21
|
-
field :possible_types, [GraphQL::Schema::LateBoundType.new("__Type")]
|
22
|
-
field :enum_values, [GraphQL::Schema::LateBoundType.new("__EnumValue")] do
|
20
|
+
field :interfaces, [GraphQL::Schema::LateBoundType.new("__Type")], scope: false
|
21
|
+
field :possible_types, [GraphQL::Schema::LateBoundType.new("__Type")], scope: false
|
22
|
+
field :enum_values, [GraphQL::Schema::LateBoundType.new("__EnumValue")], scope: false do
|
23
23
|
argument :include_deprecated, Boolean, required: false, default_value: false
|
24
24
|
end
|
25
|
-
field :input_fields, [GraphQL::Schema::LateBoundType.new("__InputValue")] do
|
25
|
+
field :input_fields, [GraphQL::Schema::LateBoundType.new("__InputValue")], scope: false do
|
26
26
|
argument :include_deprecated, Boolean, required: false, default_value: false
|
27
27
|
end
|
28
28
|
field :of_type, GraphQL::Schema::LateBoundType.new("__Type")
|
29
29
|
|
30
|
-
field :
|
30
|
+
field :specifiedByURL, String, resolver_method: :specified_by_url
|
31
|
+
|
32
|
+
field :is_one_of, Boolean, null: false
|
33
|
+
|
34
|
+
def is_one_of
|
35
|
+
object.kind.input_object? &&
|
36
|
+
object.directives.any? { |d| d.graphql_name == "oneOf" }
|
37
|
+
end
|
31
38
|
|
32
39
|
def specified_by_url
|
33
40
|
if object.kind.scalar?
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module GraphQL
|
3
3
|
module Introspection
|
4
|
-
def self.query(include_deprecated_args: false, include_schema_description: false, include_is_repeatable: false, include_specified_by_url: false)
|
4
|
+
def self.query(include_deprecated_args: false, include_schema_description: false, include_is_repeatable: false, include_specified_by_url: false, include_is_one_of: false)
|
5
5
|
# The introspection query to end all introspection queries, copied from
|
6
6
|
# https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js
|
7
|
-
<<-QUERY
|
7
|
+
<<-QUERY.gsub(/\n{2,}/, "\n")
|
8
8
|
query IntrospectionQuery {
|
9
9
|
__schema {
|
10
10
|
#{include_schema_description ? "description" : ""}
|
@@ -29,7 +29,8 @@ fragment FullType on __Type {
|
|
29
29
|
kind
|
30
30
|
name
|
31
31
|
description
|
32
|
-
#{include_specified_by_url ? "
|
32
|
+
#{include_specified_by_url ? "specifiedByURL" : ""}
|
33
|
+
#{include_is_one_of ? "isOneOf" : ""}
|
33
34
|
fields(includeDeprecated: true) {
|
34
35
|
name
|
35
36
|
description
|
@@ -22,8 +22,9 @@ module GraphQL
|
|
22
22
|
@include_introspection_types = include_introspection_types
|
23
23
|
@include_built_in_scalars = include_built_in_scalars
|
24
24
|
@include_built_in_directives = include_built_in_directives
|
25
|
+
@include_one_of = false
|
25
26
|
|
26
|
-
filter = GraphQL::Filter.new(only: only, except: except)
|
27
|
+
filter = GraphQL::Filter.new(only: only, except: except, silence_deprecation_warning: true)
|
27
28
|
if @schema.respond_to?(:visible?)
|
28
29
|
filter = filter.merge(only: @schema.method(:visible?))
|
29
30
|
end
|
@@ -44,16 +45,18 @@ module GraphQL
|
|
44
45
|
end
|
45
46
|
|
46
47
|
def build_schema_node
|
47
|
-
|
48
|
-
query: (q = warden.root_type_for_operation("query")) && q.graphql_name,
|
49
|
-
mutation: (m = warden.root_type_for_operation("mutation")) && m.graphql_name,
|
50
|
-
subscription: (s = warden.root_type_for_operation("subscription")) && s.graphql_name,
|
51
|
-
# This only supports directives from parsing,
|
52
|
-
# use a custom printer to add to this list.
|
53
|
-
#
|
48
|
+
schema_options = {
|
54
49
|
# `@schema.directives` is covered by `build_definition_nodes`
|
55
|
-
directives:
|
56
|
-
|
50
|
+
directives: definition_directives(@schema, :schema_directives),
|
51
|
+
}
|
52
|
+
if !schema_respects_root_name_conventions?(@schema)
|
53
|
+
schema_options.merge!({
|
54
|
+
query: (q = warden.root_type_for_operation("query")) && q.graphql_name,
|
55
|
+
mutation: (m = warden.root_type_for_operation("mutation")) && m.graphql_name,
|
56
|
+
subscription: (s = warden.root_type_for_operation("subscription")) && s.graphql_name,
|
57
|
+
})
|
58
|
+
end
|
59
|
+
GraphQL::Language::Nodes::SchemaDefinition.new(schema_options)
|
57
60
|
end
|
58
61
|
|
59
62
|
def build_object_type_node(object_type)
|
@@ -243,20 +246,30 @@ module GraphQL
|
|
243
246
|
end
|
244
247
|
|
245
248
|
def build_directive_nodes(directives)
|
246
|
-
if !include_built_in_directives
|
247
|
-
directives = directives.reject { |directive| directive.default_directive? }
|
248
|
-
end
|
249
|
-
|
250
249
|
directives
|
251
250
|
.map { |directive| build_directive_node(directive) }
|
252
251
|
.sort_by(&:name)
|
253
252
|
end
|
254
253
|
|
255
254
|
def build_definition_nodes
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
255
|
+
dirs_to_build = warden.directives
|
256
|
+
if !include_built_in_directives
|
257
|
+
dirs_to_build = dirs_to_build.reject { |directive| directive.default_directive? }
|
258
|
+
end
|
259
|
+
dir_nodes = build_directive_nodes(dirs_to_build)
|
260
|
+
|
261
|
+
type_nodes = build_type_definition_nodes(warden.reachable_types)
|
262
|
+
|
263
|
+
if @include_one_of
|
264
|
+
# This may have been set to true when iterating over all types
|
265
|
+
dir_nodes.concat(build_directive_nodes([GraphQL::Schema::Directive::OneOf]))
|
266
|
+
end
|
267
|
+
|
268
|
+
definitions = [*dir_nodes, *type_nodes]
|
269
|
+
if include_schema_node?
|
270
|
+
definitions.unshift(build_schema_node)
|
271
|
+
end
|
272
|
+
|
260
273
|
definitions
|
261
274
|
end
|
262
275
|
|
@@ -283,7 +296,9 @@ module GraphQL
|
|
283
296
|
private
|
284
297
|
|
285
298
|
def include_schema_node?
|
286
|
-
always_include_schema ||
|
299
|
+
always_include_schema ||
|
300
|
+
!schema_respects_root_name_conventions?(schema) ||
|
301
|
+
!schema.schema_directives.empty?
|
287
302
|
end
|
288
303
|
|
289
304
|
def schema_respects_root_name_conventions?(schema)
|
@@ -293,14 +308,14 @@ module GraphQL
|
|
293
308
|
end
|
294
309
|
|
295
310
|
def directives(member)
|
296
|
-
definition_directives(member)
|
311
|
+
definition_directives(member, :directives)
|
297
312
|
end
|
298
313
|
|
299
|
-
def definition_directives(member)
|
300
|
-
dirs = if !member.respond_to?(
|
314
|
+
def definition_directives(member, directives_method)
|
315
|
+
dirs = if !member.respond_to?(directives_method) || member.directives.empty?
|
301
316
|
[]
|
302
317
|
else
|
303
|
-
member.
|
318
|
+
member.public_send(directives_method).map do |dir|
|
304
319
|
args = []
|
305
320
|
dir.arguments.argument_values.each_value do |arg_value| # rubocop:disable Development/ContextIsPassedCop -- directive instance method
|
306
321
|
arg_defn = arg_value.definition
|
@@ -314,6 +329,11 @@ module GraphQL
|
|
314
329
|
)
|
315
330
|
end
|
316
331
|
end
|
332
|
+
|
333
|
+
# If this schema uses this built-in directive definition,
|
334
|
+
# include it in the print-out since it's not part of the spec yet.
|
335
|
+
@include_one_of ||= dir.class == GraphQL::Schema::Directive::OneOf
|
336
|
+
|
317
337
|
GraphQL::Language::Nodes::Directive.new(
|
318
338
|
name: dir.class.graphql_name,
|
319
339
|
arguments: args
|
@@ -321,30 +341,9 @@ module GraphQL
|
|
321
341
|
end
|
322
342
|
end
|
323
343
|
|
324
|
-
# This is just for printing legacy `.define { ... }` schemas, where `deprecation_reason` isn't added to `.directives`.
|
325
|
-
if !member.respond_to?(:directives) && member.respond_to?(:deprecation_reason) && (reason = member.deprecation_reason)
|
326
|
-
arguments = []
|
327
|
-
|
328
|
-
if reason != GraphQL::Schema::Directive::DEFAULT_DEPRECATION_REASON
|
329
|
-
arguments << GraphQL::Language::Nodes::Argument.new(
|
330
|
-
name: "reason",
|
331
|
-
value: reason
|
332
|
-
)
|
333
|
-
end
|
334
|
-
|
335
|
-
dirs << GraphQL::Language::Nodes::Directive.new(
|
336
|
-
name: GraphQL::Directive::DeprecatedDirective.graphql_name,
|
337
|
-
arguments: arguments
|
338
|
-
)
|
339
|
-
end
|
340
|
-
|
341
344
|
dirs
|
342
345
|
end
|
343
346
|
|
344
|
-
def ast_directives(member)
|
345
|
-
member.ast_node ? member.ast_node.directives : []
|
346
|
-
end
|
347
|
-
|
348
347
|
attr_reader :schema, :warden, :always_include_schema,
|
349
348
|
:include_introspection_types, :include_built_in_directives, :include_built_in_scalars
|
350
349
|
end
|