graphql 1.9.15 → 1.9.16
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/generators/graphql/core.rb +1 -0
- data/lib/generators/graphql/install_generator.rb +1 -0
- data/lib/generators/graphql/mutation_generator.rb +1 -1
- data/lib/generators/graphql/templates/base_mutation.erb +8 -0
- data/lib/generators/graphql/templates/mutation.erb +1 -1
- data/lib/graphql/analysis/ast.rb +2 -2
- data/lib/graphql/analysis/ast/analyzer.rb +22 -3
- data/lib/graphql/analysis/ast/max_query_complexity.rb +3 -3
- data/lib/graphql/analysis/ast/max_query_depth.rb +7 -3
- data/lib/graphql/analysis/ast/query_complexity.rb +2 -2
- data/lib/graphql/language/block_string.rb +2 -2
- data/lib/graphql/schema/field.rb +2 -2
- data/lib/graphql/schema/member/instrumentation.rb +6 -1
- data/lib/graphql/schema/relay_classic_mutation.rb +5 -1
- data/lib/graphql/schema/resolver.rb +6 -1
- data/lib/graphql/schema/subscription.rb +1 -1
- data/lib/graphql/schema/timeout_middleware.rb +3 -2
- data/lib/graphql/subscriptions/event.rb +19 -5
- data/lib/graphql/tracing/skylight_tracing.rb +1 -0
- data/lib/graphql/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 75a0bed671ca4979601036351265dfb7a0ce502b4f6937938084f2b9efaa7cd3
|
4
|
+
data.tar.gz: c43fd98af6355bde57ca2e66b1c98831498f3ac71792176063d934f968c1355f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '096f8f6cfa0aa0465f13a54297e10e5564555e5f7937ab1ea2c10d4af49db84b3a4dcf2ca30692aac5b55a6df09e163db62e8e2d712ea3ef7763b20230b642e0'
|
7
|
+
data.tar.gz: aa41d320f6ecf571c81d9243179fc5ffd7b53da4f12b741670caed08fb9405725a30dd56c1db5b6e6a20985e7e506a7ee2c1548097fb8a35e71e0094fbe307ff
|
@@ -25,6 +25,7 @@ module Graphql
|
|
25
25
|
|
26
26
|
def create_mutation_root_type
|
27
27
|
create_dir("#{options[:directory]}/mutations")
|
28
|
+
template("base_mutation.erb", "#{options[:directory]}/mutations/base_mutation.rb", { skip: true })
|
28
29
|
template("mutation_type.erb", "#{options[:directory]}/types/mutation_type.rb", { skip: true })
|
29
30
|
insert_root_type('mutation', 'MutationType')
|
30
31
|
end
|
data/lib/graphql/analysis/ast.rb
CHANGED
@@ -23,7 +23,7 @@ module GraphQL
|
|
23
23
|
#
|
24
24
|
# @param multiplex [GraphQL::Execution::Multiplex]
|
25
25
|
# @param analyzers [Array<GraphQL::Analysis::AST::Analyzer>]
|
26
|
-
# @return [
|
26
|
+
# @return [Array<Any>] Results from multiplex analyzers
|
27
27
|
def analyze_multiplex(multiplex, analyzers)
|
28
28
|
multiplex_analyzers = analyzers.map { |analyzer| analyzer.new(multiplex) }
|
29
29
|
|
@@ -46,8 +46,8 @@ module GraphQL
|
|
46
46
|
multiplex.queries.each_with_index do |query, idx|
|
47
47
|
query.analysis_errors = multiplex_errors + analysis_errors(query_results[idx])
|
48
48
|
end
|
49
|
+
multiplex_results
|
49
50
|
end
|
50
|
-
nil
|
51
51
|
end
|
52
52
|
|
53
53
|
# @param query [GraphQL::Query]
|
@@ -5,10 +5,21 @@ module GraphQL
|
|
5
5
|
# Query analyzer for query ASTs. Query analyzers respond to visitor style methods
|
6
6
|
# but are prefixed by `enter` and `leave`.
|
7
7
|
#
|
8
|
-
#
|
8
|
+
# When an analyzer is initialized with a Multiplex, you can always get the current query from
|
9
|
+
# `visitor.query` in the visit methods.
|
10
|
+
#
|
11
|
+
# @param [GraphQL::Query, GraphQL::Execution::Multiplex] The query or multiplex to analyze
|
9
12
|
class Analyzer
|
10
|
-
def initialize(
|
11
|
-
@
|
13
|
+
def initialize(subject)
|
14
|
+
@subject = subject
|
15
|
+
|
16
|
+
if subject.is_a?(GraphQL::Query)
|
17
|
+
@query = subject
|
18
|
+
@multiplex = nil
|
19
|
+
else
|
20
|
+
@multiplex = subject
|
21
|
+
@query = nil
|
22
|
+
end
|
12
23
|
end
|
13
24
|
|
14
25
|
# Analyzer hook to decide at analysis time whether a query should
|
@@ -58,7 +69,15 @@ module GraphQL
|
|
58
69
|
|
59
70
|
protected
|
60
71
|
|
72
|
+
# @return [GraphQL::Query, GraphQL::Execution::Multiplex] Whatever this analyzer is analyzing
|
73
|
+
attr_reader :subject
|
74
|
+
|
75
|
+
# @return [GraphQL::Query, nil] `nil` if this analyzer is visiting a multiplex
|
76
|
+
# (When this is `nil`, use `visitor.query` inside visit methods to get the current query)
|
61
77
|
attr_reader :query
|
78
|
+
|
79
|
+
# @return [GraphQL::Execution::Multiplex, nil] `nil` if this analyzer is visiting a query
|
80
|
+
attr_reader :multiplex
|
62
81
|
end
|
63
82
|
end
|
64
83
|
end
|
@@ -7,12 +7,12 @@ module GraphQL
|
|
7
7
|
# see {Schema#max_complexity} and {Query#max_complexity}
|
8
8
|
class MaxQueryComplexity < QueryComplexity
|
9
9
|
def result
|
10
|
-
return if
|
10
|
+
return if subject.max_complexity.nil?
|
11
11
|
|
12
12
|
total_complexity = max_possible_complexity
|
13
13
|
|
14
|
-
if total_complexity >
|
15
|
-
GraphQL::AnalysisError.new("Query has complexity of #{total_complexity}, which exceeds max complexity of #{
|
14
|
+
if total_complexity > subject.max_complexity
|
15
|
+
GraphQL::AnalysisError.new("Query has complexity of #{total_complexity}, which exceeds max complexity of #{subject.max_complexity}")
|
16
16
|
else
|
17
17
|
nil
|
18
18
|
end
|
@@ -4,10 +4,14 @@ module GraphQL
|
|
4
4
|
module AST
|
5
5
|
class MaxQueryDepth < QueryDepth
|
6
6
|
def result
|
7
|
-
|
7
|
+
configured_max_depth = if query
|
8
|
+
query.max_depth
|
9
|
+
else
|
10
|
+
multiplex.schema.max_depth
|
11
|
+
end
|
8
12
|
|
9
|
-
if @max_depth >
|
10
|
-
GraphQL::AnalysisError.new("Query has depth of #{@max_depth}, which exceeds max depth of #{
|
13
|
+
if configured_max_depth && @max_depth > configured_max_depth
|
14
|
+
GraphQL::AnalysisError.new("Query has depth of #{@max_depth}, which exceeds max depth of #{configured_max_depth}")
|
11
15
|
else
|
12
16
|
nil
|
13
17
|
end
|
@@ -42,7 +42,7 @@ module GraphQL
|
|
42
42
|
if @complexities_on_type.last.is_a?(AbstractTypeComplexity)
|
43
43
|
key = selection_key(visitor.response_path, visitor.query)
|
44
44
|
parent_type = visitor.parent_type_definition
|
45
|
-
query.possible_types(parent_type).each do |type|
|
45
|
+
visitor.query.possible_types(parent_type).each do |type|
|
46
46
|
@complexities_on_type.last.merge(type, key, own_complexity)
|
47
47
|
end
|
48
48
|
else
|
@@ -74,7 +74,7 @@ module GraphQL
|
|
74
74
|
|
75
75
|
case defined_complexity
|
76
76
|
when Proc
|
77
|
-
defined_complexity.call(query.context, arguments, child_complexity)
|
77
|
+
defined_complexity.call(visitor.query.context, arguments, child_complexity)
|
78
78
|
when Numeric
|
79
79
|
defined_complexity + (child_complexity || 0)
|
80
80
|
else
|
@@ -32,10 +32,10 @@ module GraphQL
|
|
32
32
|
end
|
33
33
|
|
34
34
|
# Remove leading & trailing blank lines
|
35
|
-
while lines.
|
35
|
+
while lines.size > 0 && lines[0].empty?
|
36
36
|
lines.shift
|
37
37
|
end
|
38
|
-
while lines.
|
38
|
+
while lines.size > 0 && lines[-1].empty?
|
39
39
|
lines.pop
|
40
40
|
end
|
41
41
|
|
data/lib/graphql/schema/field.rb
CHANGED
@@ -525,7 +525,7 @@ module GraphQL
|
|
525
525
|
else
|
526
526
|
extended_obj
|
527
527
|
end
|
528
|
-
@resolver_class.new(object: resolver_obj, context: ctx)
|
528
|
+
@resolver_class.new(object: resolver_obj, context: ctx, field: self)
|
529
529
|
else
|
530
530
|
extended_obj
|
531
531
|
end
|
@@ -642,7 +642,7 @@ module GraphQL
|
|
642
642
|
if extended_obj.is_a?(GraphQL::Schema::Object)
|
643
643
|
extended_obj = extended_obj.object
|
644
644
|
end
|
645
|
-
extended_obj = @resolver_class.new(object: extended_obj, context: query_ctx)
|
645
|
+
extended_obj = @resolver_class.new(object: extended_obj, context: query_ctx, field: self)
|
646
646
|
end
|
647
647
|
|
648
648
|
if extended_obj.respond_to?(@resolver_method)
|
@@ -78,7 +78,7 @@ module GraphQL
|
|
78
78
|
|
79
79
|
def call(obj, args, ctx)
|
80
80
|
result = @inner_resolve.call(obj, args, ctx)
|
81
|
-
if ctx.skip == result || ctx.schema.lazy?(result) || result.nil? ||
|
81
|
+
if ctx.skip == result || ctx.schema.lazy?(result) || result.nil? || execution_errors?(result) || ctx.wrapped_object
|
82
82
|
result
|
83
83
|
else
|
84
84
|
ctx.wrapped_object = true
|
@@ -88,6 +88,11 @@ module GraphQL
|
|
88
88
|
|
89
89
|
private
|
90
90
|
|
91
|
+
def execution_errors?(result)
|
92
|
+
result.is_a?(GraphQL::ExecutionError) ||
|
93
|
+
(result.is_a?(Array) && result.any? && result.all? { |v| v.is_a?(GraphQL::ExecutionError) })
|
94
|
+
end
|
95
|
+
|
91
96
|
def proxy_to_depth(inner_obj, depth, ctx)
|
92
97
|
if depth > 0
|
93
98
|
inner_obj.map { |i| proxy_to_depth(i, depth - 1, ctx) }
|
@@ -33,9 +33,13 @@ module GraphQL
|
|
33
33
|
# But when using the interpreter, no instrumenters are applied.
|
34
34
|
if context.interpreter?
|
35
35
|
input = inputs[:input].to_kwargs
|
36
|
+
|
37
|
+
new_extras = field ? field.extras : []
|
38
|
+
all_extras = self.class.extras + new_extras
|
39
|
+
|
36
40
|
# Transfer these from the top-level hash to the
|
37
41
|
# shortcutted `input:` object
|
38
|
-
|
42
|
+
all_extras.each do |ext|
|
39
43
|
# It's possible that the `extra` was not passed along by this point,
|
40
44
|
# don't re-add it if it wasn't given here.
|
41
45
|
if inputs.key?(ext)
|
@@ -29,9 +29,11 @@ module GraphQL
|
|
29
29
|
|
30
30
|
# @param object [Object] the initialize object, pass to {Query.initialize} as `root_value`
|
31
31
|
# @param context [GraphQL::Query::Context]
|
32
|
-
|
32
|
+
# @param field [GraphQL::Schema::Field]
|
33
|
+
def initialize(object:, context:, field:)
|
33
34
|
@object = object
|
34
35
|
@context = context
|
36
|
+
@field = field
|
35
37
|
# Since this hash is constantly rebuilt, cache it for this call
|
36
38
|
@arguments_by_keyword = {}
|
37
39
|
self.class.arguments.each do |name, arg|
|
@@ -46,6 +48,9 @@ module GraphQL
|
|
46
48
|
# @return [GraphQL::Query::Context]
|
47
49
|
attr_reader :context
|
48
50
|
|
51
|
+
# @return [GraphQL::Schema::Field]
|
52
|
+
attr_reader :field
|
53
|
+
|
49
54
|
# This method is _actually_ called by the runtime,
|
50
55
|
# it does some preparation and then eventually calls
|
51
56
|
# the user-defined `#resolve` method.
|
@@ -29,7 +29,7 @@ module GraphQL
|
|
29
29
|
# propagate null.
|
30
30
|
null false
|
31
31
|
|
32
|
-
def initialize(object:, context:)
|
32
|
+
def initialize(object:, context:, field:)
|
33
33
|
super
|
34
34
|
# Figure out whether this is an update or an initial subscription
|
35
35
|
@mode = context.query.subscription_update? ? :update : :subscribe
|
@@ -35,9 +35,10 @@ module GraphQL
|
|
35
35
|
|
36
36
|
def call(parent_type, parent_object, field_definition, field_args, query_context)
|
37
37
|
ns = query_context.namespace(self.class)
|
38
|
-
|
38
|
+
now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
39
|
+
timeout_at = ns[:timeout_at] ||= now + @max_seconds
|
39
40
|
|
40
|
-
if timeout_at <
|
41
|
+
if timeout_at < now
|
41
42
|
on_timeout(parent_type, parent_object, field_definition, field_args, query_context)
|
42
43
|
else
|
43
44
|
yield
|
@@ -37,7 +37,7 @@ module GraphQL
|
|
37
37
|
arguments
|
38
38
|
when Hash
|
39
39
|
if field.is_a?(GraphQL::Schema::Field)
|
40
|
-
stringify_args(arguments)
|
40
|
+
stringify_args(field, arguments)
|
41
41
|
else
|
42
42
|
GraphQL::Query::LiteralInput.from_arguments(
|
43
43
|
arguments,
|
@@ -55,21 +55,35 @@ module GraphQL
|
|
55
55
|
|
56
56
|
class << self
|
57
57
|
private
|
58
|
-
def stringify_args(args)
|
58
|
+
def stringify_args(arg_owner, args)
|
59
59
|
case args
|
60
60
|
when Hash
|
61
61
|
next_args = {}
|
62
62
|
args.each do |k, v|
|
63
|
-
|
64
|
-
|
63
|
+
arg_name = k.to_s
|
64
|
+
camelized_arg_name = GraphQL::Schema::Member::BuildType.camelize(arg_name)
|
65
|
+
arg_defn = get_arg_definition(arg_owner, camelized_arg_name)
|
66
|
+
|
67
|
+
if arg_defn
|
68
|
+
normalized_arg_name = camelized_arg_name
|
69
|
+
else
|
70
|
+
normalized_arg_name = arg_name
|
71
|
+
arg_defn = get_arg_definition(arg_owner, normalized_arg_name)
|
72
|
+
end
|
73
|
+
|
74
|
+
next_args[normalized_arg_name] = stringify_args(arg_defn[1].type, v)
|
65
75
|
end
|
66
76
|
next_args
|
67
77
|
when Array
|
68
|
-
args.map { |a| stringify_args(a) }
|
78
|
+
args.map { |a| stringify_args(arg_owner, a) }
|
69
79
|
else
|
70
80
|
args
|
71
81
|
end
|
72
82
|
end
|
83
|
+
|
84
|
+
def get_arg_definition(arg_owner, arg_name)
|
85
|
+
arg_owner.arguments.find { |k, v| k == arg_name || v.keyword.to_s == arg_name }
|
86
|
+
end
|
73
87
|
end
|
74
88
|
end
|
75
89
|
end
|
@@ -18,6 +18,7 @@ module GraphQL
|
|
18
18
|
# This is not advised if you run more than one query per HTTP request, for example, with `graphql-client` or multiplexing.
|
19
19
|
# It can also be specified per-query with `context[:set_skylight_endpoint_name]`.
|
20
20
|
def initialize(options = {})
|
21
|
+
warn("GraphQL::Tracing::SkylightTracing is deprecated, please enable Skylight's GraphQL probe instead: https://www.skylight.io/support/getting-more-from-skylight#graphql.")
|
21
22
|
@set_endpoint_name = options.fetch(:set_endpoint_name, false)
|
22
23
|
super
|
23
24
|
end
|
data/lib/graphql/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.9.
|
4
|
+
version: 1.9.16
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Mosolgo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-12-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: benchmark-ips
|
@@ -340,6 +340,7 @@ files:
|
|
340
340
|
- lib/generators/graphql/templates/base_field.erb
|
341
341
|
- lib/generators/graphql/templates/base_input_object.erb
|
342
342
|
- lib/generators/graphql/templates/base_interface.erb
|
343
|
+
- lib/generators/graphql/templates/base_mutation.erb
|
343
344
|
- lib/generators/graphql/templates/base_object.erb
|
344
345
|
- lib/generators/graphql/templates/base_scalar.erb
|
345
346
|
- lib/generators/graphql/templates/base_union.erb
|