graphql 1.9.15 → 1.9.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml 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