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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2f0505024fefcdebc975dad9259c3f3470f883b4251380e759de60ba380b3314
4
- data.tar.gz: d92149e0da6aa4e110525a38badaf2163bf887205e2c6dd75c327302e0cfabb4
3
+ metadata.gz: 75a0bed671ca4979601036351265dfb7a0ce502b4f6937938084f2b9efaa7cd3
4
+ data.tar.gz: c43fd98af6355bde57ca2e66b1c98831498f3ac71792176063d934f968c1355f
5
5
  SHA512:
6
- metadata.gz: 47b920de6ba95b4c15ebc4aace97d74931cc24efee8c3fb6a6291ea68a13b3ef46b9c613658306e1ff100d0917433431c129baba12553a94dc96a4184cbc5435
7
- data.tar.gz: 0e9c03e45fd3b3cb40a9b6b948ee1f71952f618511254acb3840195ff9c054036308636c7b2a42858096e70d1764e38458b88b0f2f369f699c7f71cdd0afd415
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
@@ -24,6 +24,7 @@ module Graphql
24
24
  # - query_type.rb
25
25
  # - loaders/
26
26
  # - mutations/
27
+ # - base_mutation.rb
27
28
  # - {app_name}_schema.rb
28
29
  # ```
29
30
  #
@@ -45,7 +45,7 @@ module Graphql
45
45
  private
46
46
 
47
47
  def assign_names!(name)
48
- @field_name = name.camelize(:lower)
48
+ @field_name = name.camelize.underscore
49
49
  @mutation_name = name.camelize(:upper)
50
50
  @file_name = name.camelize.underscore
51
51
  end
@@ -0,0 +1,8 @@
1
+ module Mutations
2
+ class BaseMutation < GraphQL::Schema::RelayClassicMutation
3
+ argument_class Types::BaseArgument
4
+ field_class Types::BaseField
5
+ input_object_class Types::BaseInputObject
6
+ object_class Types::BaseObject
7
+ end
8
+ end
@@ -1,5 +1,5 @@
1
1
  module Mutations
2
- class <%= mutation_name %> < GraphQL::Schema::RelayClassicMutation
2
+ class <%= mutation_name %> < BaseMutation
3
3
  # TODO: define return fields
4
4
  # field :post, Types::PostType, null: false
5
5
 
@@ -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 [void]
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
- # @param [GraphQL::Query] The query to analyze
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(query)
11
- @query = query
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 query.max_complexity.nil?
10
+ return if subject.max_complexity.nil?
11
11
 
12
12
  total_complexity = max_possible_complexity
13
13
 
14
- if total_complexity > query.max_complexity
15
- GraphQL::AnalysisError.new("Query has complexity of #{total_complexity}, which exceeds max complexity of #{query.max_complexity}")
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
- return unless query.max_depth
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 > query.max_depth
10
- GraphQL::AnalysisError.new("Query has depth of #{@max_depth}, which exceeds max depth of #{query.max_depth}")
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.first.empty?
35
+ while lines.size > 0 && lines[0].empty?
36
36
  lines.shift
37
37
  end
38
- while lines.last.empty?
38
+ while lines.size > 0 && lines[-1].empty?
39
39
  lines.pop
40
40
  end
41
41
 
@@ -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? || result.is_a?(GraphQL::ExecutionError) || ctx.wrapped_object
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
- self.class.extras.each do |ext|
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
- def initialize(object:, context:)
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
- timeout_at = ns[:timeout_at] ||= Time.now + @max_seconds
38
+ now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
39
+ timeout_at = ns[:timeout_at] ||= now + @max_seconds
39
40
 
40
- if timeout_at < Time.now
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
- str_k = GraphQL::Schema::Member::BuildType.camelize(k.to_s)
64
- next_args[str_k] = stringify_args(v)
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
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "1.9.15"
3
+ VERSION = "1.9.16"
4
4
  end
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.15
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-10-30 00:00:00.000000000 Z
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