graphql 1.13.25 → 2.0.0
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/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 +1 -1
- data/lib/graphql/analysis/ast.rb +0 -10
- data/lib/graphql/analysis.rb +0 -7
- data/lib/graphql/backtrace/table.rb +0 -18
- data/lib/graphql/backtrace/tracer.rb +1 -2
- data/lib/graphql/backtrace.rb +2 -8
- data/lib/graphql/dig.rb +1 -1
- data/lib/graphql/execution/errors.rb +1 -9
- data/lib/graphql/execution/interpreter/runtime.rb +6 -13
- data/lib/graphql/execution/interpreter.rb +0 -22
- data/lib/graphql/execution/lazy.rb +1 -1
- data/lib/graphql/execution/lookahead.rb +6 -13
- data/lib/graphql/execution/multiplex.rb +50 -107
- data/lib/graphql/execution.rb +11 -3
- 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 +5 -5
- data/lib/graphql/language/document_from_schema_definition.rb +0 -17
- data/lib/graphql/language/nodes.rb +0 -3
- data/lib/graphql/pagination/connections.rb +2 -28
- data/lib/graphql/pagination/relation_connection.rb +0 -2
- data/lib/graphql/query/context.rb +1 -185
- data/lib/graphql/query/input_validation_result.rb +0 -9
- data/lib/graphql/query/literal_input.rb +8 -13
- data/lib/graphql/query/validation_pipeline.rb +6 -34
- data/lib/graphql/query/variable_validation_error.rb +2 -2
- data/lib/graphql/query/variables.rb +8 -31
- data/lib/graphql/query.rb +5 -34
- data/lib/graphql/railtie.rb +0 -104
- data/lib/graphql/relay/range_add.rb +0 -4
- data/lib/graphql/relay.rb +0 -15
- data/lib/graphql/schema/addition.rb +1 -8
- data/lib/graphql/schema/argument.rb +6 -28
- data/lib/graphql/schema/build_from_definition.rb +7 -9
- data/lib/graphql/schema/directive.rb +1 -22
- data/lib/graphql/schema/enum.rb +3 -19
- data/lib/graphql/schema/enum_value.rb +1 -23
- data/lib/graphql/schema/field.rb +22 -221
- data/lib/graphql/schema/input_object.rb +17 -65
- data/lib/graphql/schema/interface.rb +1 -30
- data/lib/graphql/schema/introspection_system.rb +3 -8
- data/lib/graphql/schema/late_bound_type.rb +2 -2
- data/lib/graphql/schema/list.rb +3 -24
- data/lib/graphql/schema/loader.rb +0 -1
- data/lib/graphql/schema/member/base_dsl_methods.rb +1 -6
- data/lib/graphql/schema/member/build_type.rb +4 -6
- data/lib/graphql/schema/member/has_arguments.rb +16 -20
- data/lib/graphql/schema/member/has_fields.rb +3 -3
- data/lib/graphql/schema/member/has_interfaces.rb +1 -13
- data/lib/graphql/schema/member/validates_input.rb +2 -2
- 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 +0 -40
- data/lib/graphql/schema/relay_classic_mutation.rb +17 -28
- data/lib/graphql/schema/scalar.rb +1 -16
- data/lib/graphql/schema/union.rb +0 -16
- data/lib/graphql/schema/warden.rb +3 -12
- data/lib/graphql/schema/wrapper.rb +0 -5
- data/lib/graphql/schema.rb +106 -945
- data/lib/graphql/static_validation/base_visitor.rb +4 -21
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +12 -12
- data/lib/graphql/static_validation/validator.rb +2 -24
- data/lib/graphql/static_validation.rb +0 -2
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +38 -1
- data/lib/graphql/subscriptions/event.rb +1 -1
- data/lib/graphql/subscriptions/instrumentation.rb +0 -51
- data/lib/graphql/subscriptions.rb +4 -13
- data/lib/graphql/tracing/data_dog_tracing.rb +16 -20
- data/lib/graphql/tracing/platform_tracing.rb +4 -32
- data/lib/graphql/tracing.rb +0 -1
- data/lib/graphql/types/relay/connection_behaviors.rb +2 -6
- data/lib/graphql/types/relay/default_relay.rb +0 -10
- data/lib/graphql/types/relay/node_behaviors.rb +5 -1
- data/lib/graphql/types/relay.rb +0 -2
- data/lib/graphql/types/string.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +1 -66
- metadata +28 -164
- 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/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/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/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/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
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require_relative "./query_complexity"
|
3
|
-
module GraphQL
|
4
|
-
module Analysis
|
5
|
-
# Used under the hood to implement complexity validation,
|
6
|
-
# see {Schema#max_complexity} and {Query#max_complexity}
|
7
|
-
#
|
8
|
-
# @example Assert max complexity of 10
|
9
|
-
# # DON'T actually do this, graphql-ruby
|
10
|
-
# # Does this for you based on your `max_complexity` setting
|
11
|
-
# MySchema.query_analyzers << GraphQL::Analysis::MaxQueryComplexity.new(10)
|
12
|
-
#
|
13
|
-
class MaxQueryComplexity < GraphQL::Analysis::QueryComplexity
|
14
|
-
def initialize(max_complexity)
|
15
|
-
disallow_excessive_complexity = ->(query, complexity) {
|
16
|
-
if complexity > max_complexity
|
17
|
-
GraphQL::AnalysisError.new("Query has complexity of #{complexity}, which exceeds max complexity of #{max_complexity}")
|
18
|
-
else
|
19
|
-
nil
|
20
|
-
end
|
21
|
-
}
|
22
|
-
super(&disallow_excessive_complexity)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require_relative "./query_depth"
|
3
|
-
module GraphQL
|
4
|
-
module Analysis
|
5
|
-
# Used under the hood to implement depth validation,
|
6
|
-
# see {Schema#max_depth} and {Query#max_depth}
|
7
|
-
#
|
8
|
-
# @example Assert max depth of 10
|
9
|
-
# # DON'T actually do this, graphql-ruby
|
10
|
-
# # Does this for you based on your `max_depth` setting
|
11
|
-
# MySchema.query_analyzers << GraphQL::Analysis::MaxQueryDepth.new(10)
|
12
|
-
#
|
13
|
-
class MaxQueryDepth < GraphQL::Analysis::QueryDepth
|
14
|
-
def initialize(max_depth)
|
15
|
-
disallow_excessive_depth = ->(query, depth) {
|
16
|
-
if depth > max_depth
|
17
|
-
GraphQL::AnalysisError.new("Query has depth of #{depth}, which exceeds max depth of #{max_depth}")
|
18
|
-
else
|
19
|
-
nil
|
20
|
-
end
|
21
|
-
}
|
22
|
-
super(&disallow_excessive_depth)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,88 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
module Analysis
|
4
|
-
# Calculate the complexity of a query, using {Field#complexity} values.
|
5
|
-
#
|
6
|
-
# @example Log the complexity of incoming queries
|
7
|
-
# MySchema.query_analyzers << GraphQL::Analysis::QueryComplexity.new do |query, complexity|
|
8
|
-
# Rails.logger.info("Complexity: #{complexity}")
|
9
|
-
# end
|
10
|
-
#
|
11
|
-
class QueryComplexity
|
12
|
-
# @yield [query, complexity] Called for each query analyzed by the schema, before executing it
|
13
|
-
# @yieldparam query [GraphQL::Query] The query that was analyzed
|
14
|
-
# @yieldparam complexity [Numeric] The complexity for this query
|
15
|
-
def initialize(&block)
|
16
|
-
@complexity_handler = block
|
17
|
-
end
|
18
|
-
|
19
|
-
# State for the query complexity calcuation:
|
20
|
-
# - `target` is passed to handler
|
21
|
-
# - `complexities_on_type` holds complexity scores for each type in an IRep node
|
22
|
-
def initial_value(target)
|
23
|
-
{
|
24
|
-
target: target,
|
25
|
-
complexities_on_type: [TypeComplexity.new],
|
26
|
-
}
|
27
|
-
end
|
28
|
-
|
29
|
-
# Implement the query analyzer API
|
30
|
-
def call(memo, visit_type, irep_node)
|
31
|
-
if irep_node.ast_node.is_a?(GraphQL::Language::Nodes::Field)
|
32
|
-
if visit_type == :enter
|
33
|
-
memo[:complexities_on_type].push(TypeComplexity.new)
|
34
|
-
else
|
35
|
-
type_complexities = memo[:complexities_on_type].pop
|
36
|
-
child_complexity = type_complexities.max_possible_complexity
|
37
|
-
own_complexity = get_complexity(irep_node, child_complexity)
|
38
|
-
memo[:complexities_on_type].last.merge(irep_node.owner_type, own_complexity)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
memo
|
42
|
-
end
|
43
|
-
|
44
|
-
# Send the query and complexity to the block
|
45
|
-
# @return [Object, GraphQL::AnalysisError] Whatever the handler returns
|
46
|
-
def final_value(reduced_value)
|
47
|
-
total_complexity = reduced_value[:complexities_on_type].last.max_possible_complexity
|
48
|
-
@complexity_handler.call(reduced_value[:target], total_complexity)
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
# Get a complexity value for a field,
|
54
|
-
# by getting the number or calling its proc
|
55
|
-
def get_complexity(irep_node, child_complexity)
|
56
|
-
field_defn = irep_node.definition
|
57
|
-
defined_complexity = field_defn.complexity
|
58
|
-
case defined_complexity
|
59
|
-
when Proc
|
60
|
-
defined_complexity.call(irep_node.query.context, irep_node.arguments, child_complexity)
|
61
|
-
when Numeric
|
62
|
-
defined_complexity + (child_complexity || 0)
|
63
|
-
else
|
64
|
-
raise("Invalid complexity: #{defined_complexity.inspect} on #{field_defn.name}")
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
# Selections on an object may apply differently depending on what is _actually_ returned by the resolve function.
|
69
|
-
# Find the maximum possible complexity among those combinations.
|
70
|
-
class TypeComplexity
|
71
|
-
def initialize
|
72
|
-
@types = Hash.new(0)
|
73
|
-
end
|
74
|
-
|
75
|
-
# Return the max possible complexity for types in this selection
|
76
|
-
def max_possible_complexity
|
77
|
-
@types.each_value.max || 0
|
78
|
-
end
|
79
|
-
|
80
|
-
# Store the complexity for the branch on `type_defn`.
|
81
|
-
# Later we will see if this is the max complexity among branches.
|
82
|
-
def merge(type_defn, complexity)
|
83
|
-
@types[type_defn] += complexity
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
module Analysis
|
4
|
-
# A query reducer for measuring the depth of a given query.
|
5
|
-
#
|
6
|
-
# @example Logging the depth of a query
|
7
|
-
# Schema.query_analyzers << GraphQL::Analysis::QueryDepth.new { |query, depth| puts "GraphQL query depth: #{depth}" }
|
8
|
-
# Schema.execute(query_str)
|
9
|
-
# # GraphQL query depth: 8
|
10
|
-
#
|
11
|
-
class QueryDepth
|
12
|
-
def initialize(&block)
|
13
|
-
@depth_handler = block
|
14
|
-
end
|
15
|
-
|
16
|
-
def initial_value(query)
|
17
|
-
{
|
18
|
-
max_depth: 0,
|
19
|
-
current_depth: 0,
|
20
|
-
query: query,
|
21
|
-
}
|
22
|
-
end
|
23
|
-
|
24
|
-
def call(memo, visit_type, irep_node)
|
25
|
-
if irep_node.ast_node.is_a?(GraphQL::Language::Nodes::Field)
|
26
|
-
if visit_type == :enter
|
27
|
-
memo[:current_depth] += 1
|
28
|
-
else
|
29
|
-
if memo[:max_depth] < memo[:current_depth]
|
30
|
-
memo[:max_depth] = memo[:current_depth]
|
31
|
-
end
|
32
|
-
memo[:current_depth] -= 1
|
33
|
-
end
|
34
|
-
end
|
35
|
-
memo
|
36
|
-
end
|
37
|
-
|
38
|
-
def final_value(memo)
|
39
|
-
@depth_handler.call(memo[:query], memo[:max_depth])
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
@@ -1,48 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
module Analysis
|
4
|
-
class ReducerState
|
5
|
-
attr_reader :reducer
|
6
|
-
attr_accessor :memo, :errors
|
7
|
-
|
8
|
-
def initialize(reducer, query)
|
9
|
-
@reducer = reducer
|
10
|
-
@memo = initialize_reducer(reducer, query)
|
11
|
-
@errors = []
|
12
|
-
end
|
13
|
-
|
14
|
-
def call(visit_type, irep_node)
|
15
|
-
@memo = @reducer.call(@memo, visit_type, irep_node)
|
16
|
-
rescue AnalysisError => err
|
17
|
-
@errors << err
|
18
|
-
end
|
19
|
-
|
20
|
-
# Respond with any errors, if found. Otherwise, if the reducer accepts
|
21
|
-
# `final_value`, send it the last memo value.
|
22
|
-
# Otherwise, use the last value from the traversal.
|
23
|
-
# @return [Any] final memo value
|
24
|
-
def finalize_reducer
|
25
|
-
if @errors.any?
|
26
|
-
@errors
|
27
|
-
elsif reducer.respond_to?(:final_value)
|
28
|
-
reducer.final_value(@memo)
|
29
|
-
else
|
30
|
-
@memo
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
# If the reducer has an `initial_value` method, call it and store
|
37
|
-
# the result as `memo`. Otherwise, use `nil` as memo.
|
38
|
-
# @return [Any] initial memo value
|
39
|
-
def initialize_reducer(reducer, query)
|
40
|
-
if reducer.respond_to?(:initial_value)
|
41
|
-
reducer.initial_value(query)
|
42
|
-
else
|
43
|
-
nil
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
data/lib/graphql/argument.rb
DELETED
@@ -1,131 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
# @api deprecated
|
4
|
-
class Argument
|
5
|
-
include GraphQL::Define::InstanceDefinable
|
6
|
-
deprecated_accepts_definitions :name, :type, :description, :default_value, :as, :prepare, :method_access, :deprecation_reason
|
7
|
-
attr_reader :default_value
|
8
|
-
attr_accessor :description, :name, :as, :deprecation_reason
|
9
|
-
attr_accessor :ast_node
|
10
|
-
attr_accessor :method_access
|
11
|
-
alias :graphql_name :name
|
12
|
-
|
13
|
-
ensure_defined(:name, :description, :default_value, :type=, :type, :as, :expose_as, :prepare, :method_access, :deprecation_reason)
|
14
|
-
|
15
|
-
# @api private
|
16
|
-
module DefaultPrepare
|
17
|
-
def self.call(value, ctx); value; end
|
18
|
-
end
|
19
|
-
|
20
|
-
def initialize
|
21
|
-
@prepare_proc = DefaultPrepare
|
22
|
-
end
|
23
|
-
|
24
|
-
def initialize_copy(other)
|
25
|
-
@expose_as = nil
|
26
|
-
end
|
27
|
-
|
28
|
-
def default_value?
|
29
|
-
!!@has_default_value
|
30
|
-
end
|
31
|
-
|
32
|
-
def method_access?
|
33
|
-
# Treat unset as true -- only `false` should override
|
34
|
-
@method_access != false
|
35
|
-
end
|
36
|
-
|
37
|
-
def default_value=(new_default_value)
|
38
|
-
if new_default_value == NO_DEFAULT_VALUE
|
39
|
-
@has_default_value = false
|
40
|
-
@default_value = nil
|
41
|
-
else
|
42
|
-
@has_default_value = true
|
43
|
-
@default_value = GraphQL::Argument.deep_stringify(new_default_value)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# @!attribute name
|
48
|
-
# @return [String] The name of this argument on its {GraphQL::Field} or {GraphQL::InputObjectType}
|
49
|
-
|
50
|
-
# @param new_input_type [GraphQL::BaseType, Proc] Assign a new input type for this argument (if it's a proc, it will be called after schema initialization)
|
51
|
-
def type=(new_input_type)
|
52
|
-
@clean_type = nil
|
53
|
-
@dirty_type = new_input_type
|
54
|
-
end
|
55
|
-
|
56
|
-
# @return [GraphQL::BaseType] the input type for this argument
|
57
|
-
def type
|
58
|
-
@clean_type ||= GraphQL::BaseType.resolve_related_type(@dirty_type)
|
59
|
-
end
|
60
|
-
|
61
|
-
# @return [String] The name of this argument inside `resolve` functions
|
62
|
-
def expose_as
|
63
|
-
@expose_as ||= (@as || @name).to_s
|
64
|
-
end
|
65
|
-
|
66
|
-
# Backport this to support legacy-style directives
|
67
|
-
def keyword
|
68
|
-
@keyword ||= GraphQL::Schema::Member::BuildType.underscore(expose_as).to_sym
|
69
|
-
end
|
70
|
-
|
71
|
-
# @param value [Object] The incoming value from variables or query string literal
|
72
|
-
# @param ctx [GraphQL::Query::Context]
|
73
|
-
# @return [Object] The prepared `value` for this argument or `value` itself if no `prepare` function exists.
|
74
|
-
def prepare(value, ctx)
|
75
|
-
@prepare_proc.call(value, ctx)
|
76
|
-
end
|
77
|
-
|
78
|
-
# Assign a `prepare` function to prepare this argument's value before `resolve` functions are called.
|
79
|
-
# @param prepare_proc [#<call(value, ctx)>]
|
80
|
-
def prepare=(prepare_proc)
|
81
|
-
@prepare_proc = BackwardsCompatibility.wrap_arity(prepare_proc, from: 1, to: 2, name: "Argument#prepare(value, ctx)")
|
82
|
-
end
|
83
|
-
|
84
|
-
def type_class
|
85
|
-
metadata[:type_class]
|
86
|
-
end
|
87
|
-
|
88
|
-
NO_DEFAULT_VALUE = Object.new
|
89
|
-
# @api private
|
90
|
-
def self.from_dsl(name, type_or_argument = nil, description = nil, default_value: NO_DEFAULT_VALUE, as: nil, prepare: DefaultPrepare, **kwargs, &block)
|
91
|
-
name_s = name.to_s
|
92
|
-
|
93
|
-
# Move some positional args into keywords if they're present
|
94
|
-
description && kwargs[:description] ||= description
|
95
|
-
kwargs[:name] ||= name_s
|
96
|
-
kwargs[:default_value] ||= default_value
|
97
|
-
kwargs[:as] ||= as
|
98
|
-
|
99
|
-
unless prepare == DefaultPrepare
|
100
|
-
kwargs[:prepare] ||= prepare
|
101
|
-
end
|
102
|
-
|
103
|
-
if !type_or_argument.nil? && !type_or_argument.is_a?(GraphQL::Argument)
|
104
|
-
# Maybe a string, proc or BaseType
|
105
|
-
kwargs[:type] = type_or_argument
|
106
|
-
end
|
107
|
-
|
108
|
-
if type_or_argument.is_a?(GraphQL::Argument)
|
109
|
-
type_or_argument.redefine(**kwargs, &block)
|
110
|
-
else
|
111
|
-
GraphQL::Argument.define(**kwargs, &block)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
# @api private
|
116
|
-
def self.deep_stringify(val)
|
117
|
-
case val
|
118
|
-
when Array
|
119
|
-
val.map { |v| deep_stringify(v) }
|
120
|
-
when Hash
|
121
|
-
new_val = {}
|
122
|
-
val.each do |k, v|
|
123
|
-
new_val[k.to_s] = deep_stringify(v)
|
124
|
-
end
|
125
|
-
new_val
|
126
|
-
else
|
127
|
-
val
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
@@ -1,82 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
module Authorization
|
4
|
-
class InaccessibleFieldsError < GraphQL::AnalysisError
|
5
|
-
# @return [Array<Schema::Field, GraphQL::Field>] Fields that failed `.accessible?` checks
|
6
|
-
attr_reader :fields
|
7
|
-
|
8
|
-
# @return [GraphQL::Query::Context] The current query's context
|
9
|
-
attr_reader :context
|
10
|
-
|
11
|
-
# @return [Array<GraphQL::InternalRepresentation::Node>] The visited nodes that failed `.accessible?` checks
|
12
|
-
# @see {#fields} for the Field definitions
|
13
|
-
attr_reader :irep_nodes
|
14
|
-
|
15
|
-
def initialize(fields:, irep_nodes:, context:)
|
16
|
-
@fields = fields
|
17
|
-
@irep_nodes = irep_nodes
|
18
|
-
@context = context
|
19
|
-
super("Some fields in this query are not accessible: #{fields.map(&:graphql_name).join(", ")}")
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
# @deprecated authorization at query runtime is generally a better idea.
|
24
|
-
module Analyzer
|
25
|
-
module_function
|
26
|
-
def initial_value(query)
|
27
|
-
{
|
28
|
-
schema: query.schema,
|
29
|
-
context: query.context,
|
30
|
-
inaccessible_nodes: [],
|
31
|
-
}
|
32
|
-
end
|
33
|
-
|
34
|
-
def call(memo, visit_type, irep_node)
|
35
|
-
if visit_type == :enter
|
36
|
-
field = irep_node.definition
|
37
|
-
if field
|
38
|
-
schema = memo[:schema]
|
39
|
-
ctx = memo[:context]
|
40
|
-
next_field_accessible = schema.accessible?(field, ctx)
|
41
|
-
if !next_field_accessible
|
42
|
-
memo[:inaccessible_nodes] << irep_node
|
43
|
-
else
|
44
|
-
arg_accessible = true
|
45
|
-
irep_node.arguments.argument_values.each do |name, arg_value|
|
46
|
-
arg_accessible = schema.accessible?(arg_value.definition, ctx)
|
47
|
-
if !arg_accessible
|
48
|
-
memo[:inaccessible_nodes] << irep_node
|
49
|
-
break
|
50
|
-
end
|
51
|
-
end
|
52
|
-
if arg_accessible
|
53
|
-
return_type = field.type.unwrap
|
54
|
-
next_type_accessible = schema.accessible?(return_type, ctx)
|
55
|
-
if !next_type_accessible
|
56
|
-
memo[:inaccessible_nodes] << irep_node
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
memo
|
63
|
-
end
|
64
|
-
|
65
|
-
def final_value(memo)
|
66
|
-
nodes = memo[:inaccessible_nodes]
|
67
|
-
if nodes.any?
|
68
|
-
fields = nodes.map do |node|
|
69
|
-
field_inst = node.definition
|
70
|
-
# Get the "source of truth" for this field
|
71
|
-
field_inst.metadata[:type_class] || field_inst
|
72
|
-
end
|
73
|
-
context = memo[:context]
|
74
|
-
err = InaccessibleFieldsError.new(fields: fields, irep_nodes: nodes, context: context)
|
75
|
-
context.schema.inaccessible_fields(err)
|
76
|
-
else
|
77
|
-
nil
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
@@ -1,56 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
class Backtrace
|
4
|
-
module LegacyTracer
|
5
|
-
module_function
|
6
|
-
|
7
|
-
# Implement the {GraphQL::Tracing} API.
|
8
|
-
def trace(key, metadata)
|
9
|
-
case key
|
10
|
-
when "lex", "parse"
|
11
|
-
# No context here, don't have a query yet
|
12
|
-
nil
|
13
|
-
when "execute_multiplex", "analyze_multiplex"
|
14
|
-
# No query context yet
|
15
|
-
nil
|
16
|
-
when "validate", "analyze_query", "execute_query", "execute_query_lazy"
|
17
|
-
query = metadata[:query] || metadata[:queries].first
|
18
|
-
push_data = query
|
19
|
-
multiplex = query.multiplex
|
20
|
-
when "execute_field", "execute_field_lazy"
|
21
|
-
# The interpreter passes `query:`, legacy passes `context:`
|
22
|
-
context = metadata[:context] || ((q = metadata[:query]) && q.context)
|
23
|
-
push_data = context
|
24
|
-
multiplex = context.query.multiplex
|
25
|
-
else
|
26
|
-
# Custom key, no backtrace data for this
|
27
|
-
nil
|
28
|
-
end
|
29
|
-
|
30
|
-
if push_data
|
31
|
-
multiplex.context[:last_graphql_backtrace_context] = push_data
|
32
|
-
end
|
33
|
-
|
34
|
-
if key == "execute_multiplex"
|
35
|
-
begin
|
36
|
-
yield
|
37
|
-
rescue StandardError => err
|
38
|
-
# This is an unhandled error from execution,
|
39
|
-
# Re-raise it with a GraphQL trace.
|
40
|
-
potential_context = metadata[:multiplex].context[:last_graphql_backtrace_context]
|
41
|
-
|
42
|
-
if potential_context.is_a?(GraphQL::Query::Context) || potential_context.is_a?(GraphQL::Query::Context::FieldResolutionContext)
|
43
|
-
raise TracedError.new(err, potential_context)
|
44
|
-
else
|
45
|
-
raise
|
46
|
-
end
|
47
|
-
ensure
|
48
|
-
metadata[:multiplex].context.delete(:last_graphql_backtrace_context)
|
49
|
-
end
|
50
|
-
else
|
51
|
-
yield
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
# Helpers for migrating in a backwards-compatible way
|
4
|
-
# Remove this in GraphQL-Ruby 2.0, when all users of it will be gone.
|
5
|
-
# @api private
|
6
|
-
module BackwardsCompatibility
|
7
|
-
module_function
|
8
|
-
# Given a callable whose API used to take `from` arguments,
|
9
|
-
# check its arity, and if needed, apply a wrapper so that
|
10
|
-
# it can be called with `to` arguments.
|
11
|
-
# If a wrapper is applied, warn the application with `name`.
|
12
|
-
#
|
13
|
-
# If `last`, then use the last arguments to call the function.
|
14
|
-
def wrap_arity(callable, from:, to:, name:, last: false)
|
15
|
-
arity = get_arity(callable)
|
16
|
-
if arity == to || arity < 0
|
17
|
-
# It already matches, return it as is
|
18
|
-
callable
|
19
|
-
elsif arity == from
|
20
|
-
# It has the old arity, so wrap it with an arity converter
|
21
|
-
message ="#{name} with #{from} arguments is deprecated, it now accepts #{to} arguments, see:"
|
22
|
-
backtrace = caller(0, 20)
|
23
|
-
# Find the first line in the trace that isn't library internals:
|
24
|
-
user_line = backtrace.find {|l| l !~ /lib\/graphql/ }
|
25
|
-
GraphQL::Deprecation.warn(message + "\n" + user_line + "\n")
|
26
|
-
wrapper = last ? LastArgumentsWrapper : FirstArgumentsWrapper
|
27
|
-
wrapper.new(callable, from)
|
28
|
-
else
|
29
|
-
raise "Can't wrap #{callable} (arity: #{arity}) to have arity #{to}"
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def get_arity(callable)
|
34
|
-
case callable
|
35
|
-
when Method, Proc
|
36
|
-
callable.arity
|
37
|
-
else
|
38
|
-
callable.method(:call).arity
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
class FirstArgumentsWrapper
|
43
|
-
def initialize(callable, old_arity)
|
44
|
-
@callable = callable
|
45
|
-
@old_arity = old_arity
|
46
|
-
end
|
47
|
-
|
48
|
-
def call(*args)
|
49
|
-
backwards_compat_args = args.first(@old_arity)
|
50
|
-
@callable.call(*backwards_compat_args)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
class LastArgumentsWrapper < FirstArgumentsWrapper
|
55
|
-
def call(*args)
|
56
|
-
backwards_compat_args = args.last(@old_arity)
|
57
|
-
@callable.call(*backwards_compat_args)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|