graphql 2.2.5 → 2.3.1
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/templates/schema.erb +3 -0
- data/lib/graphql/analysis/ast/field_usage.rb +36 -9
- data/lib/graphql/analysis/ast/visitor.rb +8 -0
- data/lib/graphql/analysis/ast.rb +10 -1
- data/lib/graphql/backtrace/inspect_result.rb +0 -12
- data/lib/graphql/coercion_error.rb +1 -9
- data/lib/graphql/dataloader/request.rb +5 -0
- data/lib/graphql/execution/interpreter/argument_value.rb +5 -1
- data/lib/graphql/execution/interpreter/runtime.rb +9 -0
- data/lib/graphql/execution/interpreter.rb +90 -150
- data/lib/graphql/introspection/entry_points.rb +9 -3
- data/lib/graphql/introspection/schema_type.rb +3 -1
- data/lib/graphql/language/document_from_schema_definition.rb +2 -3
- data/lib/graphql/language/lexer.rb +48 -30
- data/lib/graphql/language/nodes.rb +1 -1
- data/lib/graphql/language/parser.rb +25 -11
- data/lib/graphql/language/printer.rb +4 -0
- data/lib/graphql/language.rb +60 -0
- data/lib/graphql/pagination/array_connection.rb +6 -6
- data/lib/graphql/query/context.rb +30 -33
- data/lib/graphql/query/validation_pipeline.rb +2 -2
- data/lib/graphql/query/variables.rb +3 -3
- data/lib/graphql/query.rb +3 -3
- data/lib/graphql/schema/argument.rb +1 -0
- data/lib/graphql/schema/base_64_encoder.rb +3 -5
- data/lib/graphql/schema/build_from_definition.rb +9 -1
- data/lib/graphql/schema/field.rb +33 -30
- data/lib/graphql/schema/input_object.rb +1 -2
- data/lib/graphql/schema/interface.rb +5 -1
- data/lib/graphql/schema/loader.rb +2 -1
- data/lib/graphql/schema/member/has_arguments.rb +2 -2
- data/lib/graphql/schema/mutation.rb +7 -0
- data/lib/graphql/schema/resolver.rb +19 -10
- data/lib/graphql/schema/unique_within_type.rb +1 -1
- data/lib/graphql/schema.rb +119 -28
- data/lib/graphql/static_validation/literal_validator.rb +1 -2
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +1 -1
- data/lib/graphql/static_validation/validator.rb +3 -0
- data/lib/graphql/subscriptions/serialize.rb +2 -0
- data/lib/graphql/subscriptions.rb +0 -3
- data/lib/graphql/testing/helpers.rb +32 -6
- data/lib/graphql/tracing/data_dog_trace.rb +21 -34
- data/lib/graphql/tracing/data_dog_tracing.rb +7 -21
- data/lib/graphql/tracing/legacy_hooks_trace.rb +74 -0
- data/lib/graphql/tracing/platform_tracing.rb +3 -1
- data/lib/graphql/tracing/{prometheus_tracing → prometheus_trace}/graphql_collector.rb +3 -1
- data/lib/graphql/tracing/prometheus_trace.rb +2 -2
- data/lib/graphql/tracing/sentry_trace.rb +112 -0
- data/lib/graphql/tracing.rb +3 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +10 -2
- metadata +38 -23
- data/lib/graphql/schema/base_64_bp.rb +0 -26
- data/lib/graphql/subscriptions/instrumentation.rb +0 -28
| @@ -3,20 +3,18 @@ | |
| 3 3 | 
             
            module GraphQL
         | 
| 4 4 | 
             
              module Tracing
         | 
| 5 5 | 
             
                module DataDogTrace
         | 
| 6 | 
            +
                  # @param tracer [#trace] Deprecated
         | 
| 6 7 | 
             
                  # @param analytics_enabled [Boolean] Deprecated
         | 
| 7 8 | 
             
                  # @param analytics_sample_rate [Float] Deprecated
         | 
| 8 | 
            -
                  def initialize(tracer: nil, analytics_enabled: false, analytics_sample_rate: 1.0, service:  | 
| 9 | 
            +
                  def initialize(tracer: nil, analytics_enabled: false, analytics_sample_rate: 1.0, service: nil, **rest)
         | 
| 9 10 | 
             
                    if tracer.nil?
         | 
| 10 11 | 
             
                      tracer = defined?(Datadog::Tracing) ? Datadog::Tracing : Datadog.tracer
         | 
| 11 12 | 
             
                    end
         | 
| 12 13 | 
             
                    @tracer = tracer
         | 
| 13 14 |  | 
| 14 | 
            -
                     | 
| 15 | 
            -
                        && Datadog::Contrib::Analytics.respond_to?(:enabled?) \
         | 
| 16 | 
            -
                        && Datadog::Contrib::Analytics.respond_to?(:set_sample_rate)
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                    @analytics_enabled = analytics_available && Datadog::Contrib::Analytics.enabled?(analytics_enabled)
         | 
| 15 | 
            +
                    @analytics_enabled = analytics_enabled
         | 
| 19 16 | 
             
                    @analytics_sample_rate = analytics_sample_rate
         | 
| 17 | 
            +
             | 
| 20 18 | 
             
                    @service_name = service
         | 
| 21 19 | 
             
                    @has_prepare_span = respond_to?(:prepare_span)
         | 
| 22 20 | 
             
                    super
         | 
| @@ -34,12 +32,9 @@ module GraphQL | |
| 34 32 | 
             
                  }.each do |trace_method, trace_key|
         | 
| 35 33 | 
             
                    module_eval <<-RUBY, __FILE__, __LINE__
         | 
| 36 34 | 
             
                      def #{trace_method}(**data)
         | 
| 37 | 
            -
                        @tracer.trace("#{trace_key}", service: @service_name) do |span|
         | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
                            span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT, 'graphql')
         | 
| 41 | 
            -
                            span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION, '#{trace_method}')
         | 
| 42 | 
            -
                          end
         | 
| 35 | 
            +
                        @tracer.trace("#{trace_key}", service: @service_name, type: 'custom') do |span|
         | 
| 36 | 
            +
                            span.set_tag('component', 'graphql')
         | 
| 37 | 
            +
                            span.set_tag('operation', '#{trace_method}')
         | 
| 43 38 |  | 
| 44 39 | 
             
                          #{
         | 
| 45 40 | 
             
                            if trace_method == 'execute_multiplex'
         | 
| @@ -54,10 +49,8 @@ module GraphQL | |
| 54 49 | 
             
                              end
         | 
| 55 50 | 
             
                              span.resource = resource if resource
         | 
| 56 51 |  | 
| 57 | 
            -
                              #  | 
| 58 | 
            -
                              if @analytics_enabled
         | 
| 59 | 
            -
                                Datadog::Contrib::Analytics.set_sample_rate(span, @analytics_sample_rate)
         | 
| 60 | 
            -
                              end
         | 
| 52 | 
            +
                              # [Deprecated] will be removed in the future
         | 
| 53 | 
            +
                              span.set_metric('_dd1.sr.eausr', @analytics_sample_rate) if @analytics_enabled
         | 
| 61 54 | 
             
                              RUBY
         | 
| 62 55 | 
             
                            elsif trace_method == 'execute_query'
         | 
| 63 56 | 
             
                              <<-RUBY
         | 
| @@ -89,12 +82,10 @@ module GraphQL | |
| 89 82 | 
             
                      nil
         | 
| 90 83 | 
             
                    end
         | 
| 91 84 | 
             
                    if platform_key && trace_field
         | 
| 92 | 
            -
                      @tracer.trace(platform_key, service: @service_name) do |span|
         | 
| 93 | 
            -
                        span. | 
| 94 | 
            -
                         | 
| 95 | 
            -
             | 
| 96 | 
            -
                          span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION, span_key)
         | 
| 97 | 
            -
                        end
         | 
| 85 | 
            +
                      @tracer.trace(platform_key, service: @service_name, type: 'custom') do |span|
         | 
| 86 | 
            +
                        span.set_tag('component', 'graphql')
         | 
| 87 | 
            +
                        span.set_tag('operation', span_key)
         | 
| 88 | 
            +
             | 
| 98 89 | 
             
                        if @has_prepare_span
         | 
| 99 90 | 
             
                          prepare_span_data = { query: query, field: field, ast_node: ast_node, arguments: arguments, object: object }
         | 
| 100 91 | 
             
                          prepare_span(span_key, prepare_span_data, span)
         | 
| @@ -125,12 +116,10 @@ module GraphQL | |
| 125 116 |  | 
| 126 117 | 
             
                  def authorized_span(span_key, object, type, query)
         | 
| 127 118 | 
             
                    platform_key = @platform_key_cache[DataDogTrace].platform_authorized_key_cache[type]
         | 
| 128 | 
            -
                    @tracer.trace(platform_key, service: @service_name) do |span|
         | 
| 129 | 
            -
                      span. | 
| 130 | 
            -
                       | 
| 131 | 
            -
             | 
| 132 | 
            -
                        span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION, span_key)
         | 
| 133 | 
            -
                      end
         | 
| 119 | 
            +
                    @tracer.trace(platform_key, service: @service_name, type: 'custom') do |span|
         | 
| 120 | 
            +
                      span.set_tag('component', 'graphql')
         | 
| 121 | 
            +
                      span.set_tag('operation', span_key)
         | 
| 122 | 
            +
             | 
| 134 123 | 
             
                      if @has_prepare_span
         | 
| 135 124 | 
             
                        prepare_span(span_key, {object: object, type: type, query: query}, span)
         | 
| 136 125 | 
             
                      end
         | 
| @@ -158,12 +147,10 @@ module GraphQL | |
| 158 147 |  | 
| 159 148 | 
             
                  def resolve_type_span(span_key, object, type, query)
         | 
| 160 149 | 
             
                    platform_key = @platform_key_cache[DataDogTrace].platform_resolve_type_key_cache[type]
         | 
| 161 | 
            -
                    @tracer.trace(platform_key, service: @service_name) do |span|
         | 
| 162 | 
            -
                      span. | 
| 163 | 
            -
                       | 
| 164 | 
            -
             | 
| 165 | 
            -
                        span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION, span_key)
         | 
| 166 | 
            -
                      end
         | 
| 150 | 
            +
                    @tracer.trace(platform_key, service: @service_name, type: 'custom') do |span|
         | 
| 151 | 
            +
                      span.set_tag('component', 'graphql')
         | 
| 152 | 
            +
                      span.set_tag('operation', span_key)
         | 
| 153 | 
            +
             | 
| 167 154 | 
             
                      if @has_prepare_span
         | 
| 168 155 | 
             
                        prepare_span(span_key, {object: object, type: type, query: query}, span)
         | 
| 169 156 | 
             
                      end
         | 
| @@ -15,12 +15,9 @@ module GraphQL | |
| 15 15 | 
             
                  }
         | 
| 16 16 |  | 
| 17 17 | 
             
                  def platform_trace(platform_key, key, data)
         | 
| 18 | 
            -
                    tracer.trace(platform_key, service:  | 
| 19 | 
            -
                      span. | 
| 20 | 
            -
                       | 
| 21 | 
            -
                        span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT, 'graphql')
         | 
| 22 | 
            -
                        span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION, key)
         | 
| 23 | 
            -
                      end
         | 
| 18 | 
            +
                    tracer.trace(platform_key, service: options[:service], type: 'custom') do |span|
         | 
| 19 | 
            +
                      span.set_tag('component', 'graphql')
         | 
| 20 | 
            +
                      span.set_tag('operation', key)
         | 
| 24 21 |  | 
| 25 22 | 
             
                      if key == 'execute_multiplex'
         | 
| 26 23 | 
             
                        operations = data[:multiplex].queries.map(&:selected_operation_name).join(', ')
         | 
| @@ -33,10 +30,8 @@ module GraphQL | |
| 33 30 | 
             
                        end
         | 
| 34 31 | 
             
                        span.resource = resource if resource
         | 
| 35 32 |  | 
| 36 | 
            -
                        #  | 
| 37 | 
            -
                        if analytics_enabled?
         | 
| 38 | 
            -
                          Datadog::Contrib::Analytics.set_sample_rate(span, analytics_sample_rate)
         | 
| 39 | 
            -
                        end
         | 
| 33 | 
            +
                        # [Deprecated] will be removed in the future
         | 
| 34 | 
            +
                        span.set_metric('_dd1.sr.eausr', analytics_sample_rate) if analytics_enabled?
         | 
| 40 35 | 
             
                      end
         | 
| 41 36 |  | 
| 42 37 | 
             
                      if key == 'execute_query'
         | 
| @@ -51,10 +46,6 @@ module GraphQL | |
| 51 46 | 
             
                    end
         | 
| 52 47 | 
             
                  end
         | 
| 53 48 |  | 
| 54 | 
            -
                  def service_name
         | 
| 55 | 
            -
                    options.fetch(:service, 'ruby-graphql')
         | 
| 56 | 
            -
                  end
         | 
| 57 | 
            -
             | 
| 58 49 | 
             
                  # Implement this method in a subclass to apply custom tags to datadog spans
         | 
| 59 50 | 
             
                  # @param key [String] The event being traced
         | 
| 60 51 | 
             
                  # @param data [Hash] The runtime data for this event (@see GraphQL::Tracing for keys for each event)
         | 
| @@ -65,18 +56,13 @@ module GraphQL | |
| 65 56 | 
             
                  def tracer
         | 
| 66 57 | 
             
                    default_tracer = defined?(Datadog::Tracing) ? Datadog::Tracing : Datadog.tracer
         | 
| 67 58 |  | 
| 59 | 
            +
                    # [Deprecated] options[:tracer] will be removed in the future
         | 
| 68 60 | 
             
                    options.fetch(:tracer, default_tracer)
         | 
| 69 61 | 
             
                  end
         | 
| 70 62 |  | 
| 71 | 
            -
                  def analytics_available?
         | 
| 72 | 
            -
                    defined?(Datadog::Contrib::Analytics) \
         | 
| 73 | 
            -
                      && Datadog::Contrib::Analytics.respond_to?(:enabled?) \
         | 
| 74 | 
            -
                      && Datadog::Contrib::Analytics.respond_to?(:set_sample_rate)
         | 
| 75 | 
            -
                  end
         | 
| 76 | 
            -
             | 
| 77 63 | 
             
                  def analytics_enabled?
         | 
| 78 64 | 
             
                    # [Deprecated] options[:analytics_enabled] will be removed in the future
         | 
| 79 | 
            -
                     | 
| 65 | 
            +
                    options.fetch(:analytics_enabled, false)
         | 
| 80 66 | 
             
                  end
         | 
| 81 67 |  | 
| 82 68 | 
             
                  def analytics_sample_rate
         | 
| @@ -0,0 +1,74 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
            module GraphQL
         | 
| 3 | 
            +
              module Tracing
         | 
| 4 | 
            +
                module LegacyHooksTrace
         | 
| 5 | 
            +
                  def execute_multiplex(multiplex:)
         | 
| 6 | 
            +
                    multiplex_instrumenters = multiplex.schema.instrumenters[:multiplex]
         | 
| 7 | 
            +
                    query_instrumenters = multiplex.schema.instrumenters[:query]
         | 
| 8 | 
            +
                    # First, run multiplex instrumentation, then query instrumentation for each query
         | 
| 9 | 
            +
                    RunHooks.call_hooks(multiplex_instrumenters, multiplex, :before_multiplex, :after_multiplex) do
         | 
| 10 | 
            +
                      RunHooks.each_query_call_hooks(query_instrumenters, multiplex.queries) do
         | 
| 11 | 
            +
                        super
         | 
| 12 | 
            +
                      end
         | 
| 13 | 
            +
                    end
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  module RunHooks
         | 
| 17 | 
            +
                    module_function
         | 
| 18 | 
            +
                    # Call the before_ hooks of each query,
         | 
| 19 | 
            +
                    # Then yield if no errors.
         | 
| 20 | 
            +
                    # `call_hooks` takes care of appropriate cleanup.
         | 
| 21 | 
            +
                    def each_query_call_hooks(instrumenters, queries, i = 0)
         | 
| 22 | 
            +
                      if i >= queries.length
         | 
| 23 | 
            +
                        yield
         | 
| 24 | 
            +
                      else
         | 
| 25 | 
            +
                        query = queries[i]
         | 
| 26 | 
            +
                        call_hooks(instrumenters, query, :before_query, :after_query) {
         | 
| 27 | 
            +
                          each_query_call_hooks(instrumenters, queries, i + 1) {
         | 
| 28 | 
            +
                            yield
         | 
| 29 | 
            +
                          }
         | 
| 30 | 
            +
                        }
         | 
| 31 | 
            +
                      end
         | 
| 32 | 
            +
                    end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                    # Call each before hook, and if they all succeed, yield.
         | 
| 35 | 
            +
                    # If they don't all succeed, call after_ for each one that succeeded.
         | 
| 36 | 
            +
                    def call_hooks(instrumenters, object, before_hook_name, after_hook_name)
         | 
| 37 | 
            +
                      begin
         | 
| 38 | 
            +
                        successful = []
         | 
| 39 | 
            +
                        instrumenters.each do |instrumenter|
         | 
| 40 | 
            +
                          instrumenter.public_send(before_hook_name, object)
         | 
| 41 | 
            +
                          successful << instrumenter
         | 
| 42 | 
            +
                        end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                        # if any before hooks raise an exception, quit calling before hooks,
         | 
| 45 | 
            +
                        # but call the after hooks on anything that succeeded but also
         | 
| 46 | 
            +
                        # raise the exception that came from the before hook.
         | 
| 47 | 
            +
                      rescue GraphQL::ExecutionError => err
         | 
| 48 | 
            +
                        object.context.errors << err
         | 
| 49 | 
            +
                      rescue => e
         | 
| 50 | 
            +
                        raise call_after_hooks(successful, object, after_hook_name, e)
         | 
| 51 | 
            +
                      end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                      begin
         | 
| 54 | 
            +
                        yield # Call the user code
         | 
| 55 | 
            +
                      ensure
         | 
| 56 | 
            +
                        ex = call_after_hooks(successful, object, after_hook_name, nil)
         | 
| 57 | 
            +
                        raise ex if ex
         | 
| 58 | 
            +
                      end
         | 
| 59 | 
            +
                    end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                    def call_after_hooks(instrumenters, object, after_hook_name, ex)
         | 
| 62 | 
            +
                      instrumenters.reverse_each do |instrumenter|
         | 
| 63 | 
            +
                        begin
         | 
| 64 | 
            +
                          instrumenter.public_send(after_hook_name, object)
         | 
| 65 | 
            +
                        rescue => e
         | 
| 66 | 
            +
                          ex = e
         | 
| 67 | 
            +
                        end
         | 
| 68 | 
            +
                      end
         | 
| 69 | 
            +
                      ex
         | 
| 70 | 
            +
                    end
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
            end
         | 
| @@ -81,10 +81,12 @@ module GraphQL | |
| 81 81 | 
             
                      trace_name = tracing_name.sub("Tracing", "Trace")
         | 
| 82 82 | 
             
                      if GraphQL::Tracing.const_defined?(trace_name, false)
         | 
| 83 83 | 
             
                        trace_module = GraphQL::Tracing.const_get(trace_name)
         | 
| 84 | 
            +
                        warn("`use(#{self.name})` is deprecated, use the equivalent `trace_with(#{trace_module.name})` instead. More info: https://graphql-ruby.org/queries/tracing.html")
         | 
| 84 85 | 
             
                        schema_defn.trace_with(trace_module, **options)
         | 
| 85 86 | 
             
                      else
         | 
| 87 | 
            +
                        warn("`use(#{self.name})` and `Tracing::PlatformTracing` are deprecated. Use a `trace_with(...)` module instead. More info: https://graphql-ruby.org/queries/tracing.html. Please open an issue on the GraphQL-Ruby repo if you want to discuss further!")
         | 
| 86 88 | 
             
                        tracer = self.new(**options)
         | 
| 87 | 
            -
             | 
| 89 | 
            +
                      schema_defn.tracer(tracer, silence_deprecation_warning: true)
         | 
| 88 90 | 
             
                      end
         | 
| 89 91 | 
             
                    end
         | 
| 90 92 | 
             
                  end
         | 
| @@ -2,7 +2,7 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            module GraphQL
         | 
| 4 4 | 
             
              module Tracing
         | 
| 5 | 
            -
                 | 
| 5 | 
            +
                module PrometheusTrace
         | 
| 6 6 | 
             
                  class GraphQLCollector < ::PrometheusExporter::Server::TypeCollector
         | 
| 7 7 | 
             
                    def initialize
         | 
| 8 8 | 
             
                      @graphql_gauge = PrometheusExporter::Metric::Base.default_aggregation.new(
         | 
| @@ -28,5 +28,7 @@ module GraphQL | |
| 28 28 | 
             
                    end
         | 
| 29 29 | 
             
                  end
         | 
| 30 30 | 
             
                end
         | 
| 31 | 
            +
                # Backwards-compat:
         | 
| 32 | 
            +
                PrometheusTracing::GraphQLCollector = PrometheusTrace::GraphQLCollector
         | 
| 31 33 | 
             
              end
         | 
| 32 34 | 
             
            end
         | 
| @@ -24,8 +24,8 @@ module GraphQL | |
| 24 24 | 
             
                    'execute_query_lazy' => "graphql.execute",
         | 
| 25 25 | 
             
                  }.each do |trace_method, platform_key|
         | 
| 26 26 | 
             
                    module_eval <<-RUBY, __FILE__, __LINE__
         | 
| 27 | 
            -
                      def #{trace_method}(**data | 
| 28 | 
            -
                        instrument_execution("#{platform_key}", "#{trace_method}" | 
| 27 | 
            +
                      def #{trace_method}(**data)
         | 
| 28 | 
            +
                        instrument_execution("#{platform_key}", "#{trace_method}") { super }
         | 
| 29 29 | 
             
                      end
         | 
| 30 30 | 
             
                    RUBY
         | 
| 31 31 | 
             
                  end
         | 
| @@ -0,0 +1,112 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module GraphQL
         | 
| 4 | 
            +
              module Tracing
         | 
| 5 | 
            +
                module SentryTrace
         | 
| 6 | 
            +
                  include PlatformTrace
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  # @param set_transaction_name [Boolean] If true, the GraphQL operation name will be used as the transaction name.
         | 
| 9 | 
            +
                  #   This is not advised if you run more than one query per HTTP request, for example, with `graphql-client` or multiplexing.
         | 
| 10 | 
            +
                  #   It can also be specified per-query with `context[:set_sentry_transaction_name]`.
         | 
| 11 | 
            +
                  def initialize(set_transaction_name: false, **_rest)
         | 
| 12 | 
            +
                    @set_transaction_name = set_transaction_name
         | 
| 13 | 
            +
                    super
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
                  
         | 
| 16 | 
            +
                  def execute_query(**data)
         | 
| 17 | 
            +
                    set_this_txn_name = data[:query].context[:set_sentry_transaction_name]
         | 
| 18 | 
            +
                    if set_this_txn_name == true || (set_this_txn_name.nil? && @set_transaction_name)
         | 
| 19 | 
            +
                      Sentry.configure_scope do |scope|
         | 
| 20 | 
            +
                        scope.set_transaction_name(transaction_name(data[:query]))
         | 
| 21 | 
            +
                      end
         | 
| 22 | 
            +
                    end
         | 
| 23 | 
            +
                    instrument_execution("graphql.execute", "execute_query", data) { super }
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  {
         | 
| 27 | 
            +
                    "lex" => "graphql.lex",
         | 
| 28 | 
            +
                    "parse" => "graphql.parse",
         | 
| 29 | 
            +
                    "validate" => "graphql.validate",
         | 
| 30 | 
            +
                    "analyze_query" => "graphql.analyze",
         | 
| 31 | 
            +
                    "analyze_multiplex" => "graphql.analyze_multiplex",
         | 
| 32 | 
            +
                    "execute_multiplex" => "graphql.execute_multiplex",
         | 
| 33 | 
            +
                    "execute_query_lazy" => "graphql.execute"
         | 
| 34 | 
            +
                  }.each do |trace_method, platform_key|
         | 
| 35 | 
            +
                    module_eval <<-RUBY, __FILE__, __LINE__
         | 
| 36 | 
            +
                    def #{trace_method}(**data)
         | 
| 37 | 
            +
                      instrument_execution("#{platform_key}", "#{trace_method}", data) { super }
         | 
| 38 | 
            +
                    end
         | 
| 39 | 
            +
                    RUBY
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  def platform_execute_field(platform_key, &block)
         | 
| 43 | 
            +
                    instrument_execution(platform_key, "execute_field", &block)
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  def platform_execute_field_lazy(platform_key, &block)
         | 
| 47 | 
            +
                    instrument_execution(platform_key, "execute_field_lazy", &block)
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  def platform_authorized(platform_key, &block)
         | 
| 51 | 
            +
                    instrument_execution(platform_key, "authorized", &block)
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  def platform_authorized_lazy(platform_key, &block)
         | 
| 55 | 
            +
                    instrument_execution(platform_key, "authorized_lazy", &block)
         | 
| 56 | 
            +
                  end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                  def platform_resolve_type(platform_key, &block)
         | 
| 59 | 
            +
                    instrument_execution(platform_key, "resolve_type", &block)
         | 
| 60 | 
            +
                  end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                  def platform_resolve_type_lazy(platform_key, &block)
         | 
| 63 | 
            +
                    instrument_execution(platform_key, "resolve_type_lazy", &block)
         | 
| 64 | 
            +
                  end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                  def platform_field_key(field)
         | 
| 67 | 
            +
                    "graphql.field.#{field.path}"
         | 
| 68 | 
            +
                  end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                  def platform_authorized_key(type)
         | 
| 71 | 
            +
                    "graphql.authorized.#{type.graphql_name}"
         | 
| 72 | 
            +
                  end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                  def platform_resolve_type_key(type)
         | 
| 75 | 
            +
                    "graphql.resolve_type.#{type.graphql_name}"
         | 
| 76 | 
            +
                  end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                  private
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                  def instrument_execution(platform_key, trace_method, data=nil, &block)
         | 
| 81 | 
            +
                    return yield unless Sentry.initialized?
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                    Sentry.with_child_span(op: platform_key, start_timestamp: Sentry.utc_now.to_f) do |span|
         | 
| 84 | 
            +
                      result = yield
         | 
| 85 | 
            +
                      return result unless span
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                      span.finish
         | 
| 88 | 
            +
                      if trace_method == "execute_multiplex" && data.key?(:multiplex)
         | 
| 89 | 
            +
                        operation_names = data[:multiplex].queries.map{|q| operation_name(q) }
         | 
| 90 | 
            +
                        span.set_description(operation_names.join(", "))
         | 
| 91 | 
            +
                      elsif trace_method == "execute_query" && data.key?(:query)
         | 
| 92 | 
            +
                        span.set_description(operation_name(data[:query]))
         | 
| 93 | 
            +
                        span.set_data('graphql.document', data[:query].query_string)
         | 
| 94 | 
            +
                        span.set_data('graphql.operation.name', data[:query].selected_operation_name) if data[:query].selected_operation_name
         | 
| 95 | 
            +
                        span.set_data('graphql.operation.type', data[:query].selected_operation.operation_type)
         | 
| 96 | 
            +
                      end
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                      result
         | 
| 99 | 
            +
                    end
         | 
| 100 | 
            +
                  end
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                  def operation_name(query)
         | 
| 103 | 
            +
                    selected_op = query.selected_operation
         | 
| 104 | 
            +
                    if selected_op
         | 
| 105 | 
            +
                      [selected_op.operation_type, selected_op.name].compact.join(' ')
         | 
| 106 | 
            +
                    else
         | 
| 107 | 
            +
                      'GraphQL Operation'
         | 
| 108 | 
            +
                    end
         | 
| 109 | 
            +
                  end
         | 
| 110 | 
            +
                end
         | 
| 111 | 
            +
              end
         | 
| 112 | 
            +
            end
         | 
    
        data/lib/graphql/tracing.rb
    CHANGED
    
    | @@ -1,6 +1,7 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 | 
             
            require "graphql/tracing/trace"
         | 
| 3 3 | 
             
            require "graphql/tracing/legacy_trace"
         | 
| 4 | 
            +
            require "graphql/tracing/legacy_hooks_trace"
         | 
| 4 5 |  | 
| 5 6 | 
             
            # Legacy tracing:
         | 
| 6 7 | 
             
            require "graphql/tracing/active_support_notifications_tracing"
         | 
| @@ -21,11 +22,12 @@ require "graphql/tracing/appsignal_trace" | |
| 21 22 | 
             
            require "graphql/tracing/data_dog_trace"
         | 
| 22 23 | 
             
            require "graphql/tracing/new_relic_trace"
         | 
| 23 24 | 
             
            require "graphql/tracing/notifications_trace"
         | 
| 25 | 
            +
            require "graphql/tracing/sentry_trace"
         | 
| 24 26 | 
             
            require "graphql/tracing/scout_trace"
         | 
| 25 27 | 
             
            require "graphql/tracing/statsd_trace"
         | 
| 26 28 | 
             
            require "graphql/tracing/prometheus_trace"
         | 
| 27 29 | 
             
            if defined?(PrometheusExporter::Server)
         | 
| 28 | 
            -
              require "graphql/tracing/ | 
| 30 | 
            +
              require "graphql/tracing/prometheus_trace/graphql_collector"
         | 
| 29 31 | 
             
            end
         | 
| 30 32 |  | 
| 31 33 | 
             
            module GraphQL
         | 
    
        data/lib/graphql/version.rb
    CHANGED
    
    
    
        data/lib/graphql.rb
    CHANGED
    
    | @@ -42,8 +42,8 @@ This is probably a bug in GraphQL-Ruby, please report this error on GitHub: http | |
| 42 42 | 
             
              # Turn a query string or schema definition into an AST
         | 
| 43 43 | 
             
              # @param graphql_string [String] a GraphQL query string or schema definition
         | 
| 44 44 | 
             
              # @return [GraphQL::Language::Nodes::Document]
         | 
| 45 | 
            -
              def self.parse(graphql_string, trace: GraphQL::Tracing::NullTrace)
         | 
| 46 | 
            -
                default_parser.parse(graphql_string, trace: trace)
         | 
| 45 | 
            +
              def self.parse(graphql_string, trace: GraphQL::Tracing::NullTrace, filename: nil, max_tokens: nil)
         | 
| 46 | 
            +
                default_parser.parse(graphql_string, trace: trace, filename: filename, max_tokens: max_tokens)
         | 
| 47 47 | 
             
              end
         | 
| 48 48 |  | 
| 49 49 | 
             
              # Read the contents of `filename` and parse them as GraphQL
         | 
| @@ -60,6 +60,7 @@ This is probably a bug in GraphQL-Ruby, please report this error on GitHub: http | |
| 60 60 | 
             
              end
         | 
| 61 61 |  | 
| 62 62 | 
             
              def self.parse_with_racc(string, filename: nil, trace: GraphQL::Tracing::NullTrace)
         | 
| 63 | 
            +
                warn "`GraphQL.parse_with_racc` is deprecated; GraphQL-Ruby no longer uses racc for parsing. Call `GraphQL.parse` or `GraphQL::Language::Parser.parse` instead."
         | 
| 63 64 | 
             
                GraphQL::Language::Parser.parse(string, filename: filename, trace: trace)
         | 
| 64 65 | 
             
              end
         | 
| 65 66 |  | 
| @@ -73,6 +74,13 @@ This is probably a bug in GraphQL-Ruby, please report this error on GitHub: http | |
| 73 74 | 
             
                EMPTY_HASH = {}.freeze
         | 
| 74 75 | 
             
                EMPTY_ARRAY = [].freeze
         | 
| 75 76 | 
             
              end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
              class << self
         | 
| 79 | 
            +
                # If true, the parser should raise when an integer or float is followed immediately by an identifier (instead of a space or punctuation)
         | 
| 80 | 
            +
                attr_accessor :reject_numbers_followed_by_names
         | 
| 81 | 
            +
              end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
              self.reject_numbers_followed_by_names = false
         | 
| 76 84 | 
             
            end
         | 
| 77 85 |  | 
| 78 86 | 
             
            # Order matters for these:
         | 
    
        metadata
    CHANGED
    
    | @@ -1,29 +1,29 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: graphql
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2. | 
| 4 | 
            +
              version: 2.3.1
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Robert Mosolgo
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2024- | 
| 11 | 
            +
            date: 2024-04-22 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 | 
            -
              name:  | 
| 14 | 
            +
              name: base64
         | 
| 15 15 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 16 | 
             
                requirements:
         | 
| 17 | 
            -
                - - " | 
| 17 | 
            +
                - - ">="
         | 
| 18 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            -
                    version: ' | 
| 19 | 
            +
                    version: '0'
         | 
| 20 20 | 
             
              type: :runtime
         | 
| 21 21 | 
             
              prerelease: false
         | 
| 22 22 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 23 | 
             
                requirements:
         | 
| 24 | 
            -
                - - " | 
| 24 | 
            +
                - - ">="
         | 
| 25 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            -
                    version: ' | 
| 26 | 
            +
                    version: '0'
         | 
| 27 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 28 | 
             
              name: benchmark-ips
         | 
| 29 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -52,6 +52,20 @@ dependencies: | |
| 52 52 | 
             
                - - "~>"
         | 
| 53 53 | 
             
                  - !ruby/object:Gem::Version
         | 
| 54 54 | 
             
                    version: '1.0'
         | 
| 55 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 56 | 
            +
              name: graphql-batch
         | 
| 57 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 58 | 
            +
                requirements:
         | 
| 59 | 
            +
                - - ">="
         | 
| 60 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 61 | 
            +
                    version: '0'
         | 
| 62 | 
            +
              type: :development
         | 
| 63 | 
            +
              prerelease: false
         | 
| 64 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 65 | 
            +
                requirements:
         | 
| 66 | 
            +
                - - ">="
         | 
| 67 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 68 | 
            +
                    version: '0'
         | 
| 55 69 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 56 70 | 
             
              name: memory_profiler
         | 
| 57 71 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -70,44 +84,44 @@ dependencies: | |
| 70 84 | 
             
              name: minitest
         | 
| 71 85 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 72 86 | 
             
                requirements:
         | 
| 73 | 
            -
                - - " | 
| 87 | 
            +
                - - ">="
         | 
| 74 88 | 
             
                  - !ruby/object:Gem::Version
         | 
| 75 | 
            -
                    version:  | 
| 89 | 
            +
                    version: '0'
         | 
| 76 90 | 
             
              type: :development
         | 
| 77 91 | 
             
              prerelease: false
         | 
| 78 92 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 79 93 | 
             
                requirements:
         | 
| 80 | 
            -
                - - " | 
| 94 | 
            +
                - - ">="
         | 
| 81 95 | 
             
                  - !ruby/object:Gem::Version
         | 
| 82 | 
            -
                    version:  | 
| 96 | 
            +
                    version: '0'
         | 
| 83 97 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 84 98 | 
             
              name: minitest-focus
         | 
| 85 99 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 86 100 | 
             
                requirements:
         | 
| 87 | 
            -
                - - " | 
| 101 | 
            +
                - - ">="
         | 
| 88 102 | 
             
                  - !ruby/object:Gem::Version
         | 
| 89 | 
            -
                    version: ' | 
| 103 | 
            +
                    version: '0'
         | 
| 90 104 | 
             
              type: :development
         | 
| 91 105 | 
             
              prerelease: false
         | 
| 92 106 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 93 107 | 
             
                requirements:
         | 
| 94 | 
            -
                - - " | 
| 108 | 
            +
                - - ">="
         | 
| 95 109 | 
             
                  - !ruby/object:Gem::Version
         | 
| 96 | 
            -
                    version: ' | 
| 110 | 
            +
                    version: '0'
         | 
| 97 111 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 98 112 | 
             
              name: minitest-reporters
         | 
| 99 113 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 100 114 | 
             
                requirements:
         | 
| 101 | 
            -
                - - " | 
| 115 | 
            +
                - - ">="
         | 
| 102 116 | 
             
                  - !ruby/object:Gem::Version
         | 
| 103 | 
            -
                    version: ' | 
| 117 | 
            +
                    version: '0'
         | 
| 104 118 | 
             
              type: :development
         | 
| 105 119 | 
             
              prerelease: false
         | 
| 106 120 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 107 121 | 
             
                requirements:
         | 
| 108 | 
            -
                - - " | 
| 122 | 
            +
                - - ">="
         | 
| 109 123 | 
             
                  - !ruby/object:Gem::Version
         | 
| 110 | 
            -
                    version: ' | 
| 124 | 
            +
                    version: '0'
         | 
| 111 125 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 112 126 | 
             
              name: rake
         | 
| 113 127 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -400,7 +414,6 @@ files: | |
| 400 414 | 
             
            - lib/graphql/schema/addition.rb
         | 
| 401 415 | 
             
            - lib/graphql/schema/always_visible.rb
         | 
| 402 416 | 
             
            - lib/graphql/schema/argument.rb
         | 
| 403 | 
            -
            - lib/graphql/schema/base_64_bp.rb
         | 
| 404 417 | 
             
            - lib/graphql/schema/base_64_encoder.rb
         | 
| 405 418 | 
             
            - lib/graphql/schema/build_from_definition.rb
         | 
| 406 419 | 
             
            - lib/graphql/schema/build_from_definition/resolve_map.rb
         | 
| @@ -550,7 +563,6 @@ files: | |
| 550 563 | 
             
            - lib/graphql/subscriptions/broadcast_analyzer.rb
         | 
| 551 564 | 
             
            - lib/graphql/subscriptions/default_subscription_resolve_extension.rb
         | 
| 552 565 | 
             
            - lib/graphql/subscriptions/event.rb
         | 
| 553 | 
            -
            - lib/graphql/subscriptions/instrumentation.rb
         | 
| 554 566 | 
             
            - lib/graphql/subscriptions/serialize.rb
         | 
| 555 567 | 
             
            - lib/graphql/testing.rb
         | 
| 556 568 | 
             
            - lib/graphql/testing/helpers.rb
         | 
| @@ -563,6 +575,7 @@ files: | |
| 563 575 | 
             
            - lib/graphql/tracing/appsignal_tracing.rb
         | 
| 564 576 | 
             
            - lib/graphql/tracing/data_dog_trace.rb
         | 
| 565 577 | 
             
            - lib/graphql/tracing/data_dog_tracing.rb
         | 
| 578 | 
            +
            - lib/graphql/tracing/legacy_hooks_trace.rb
         | 
| 566 579 | 
             
            - lib/graphql/tracing/legacy_trace.rb
         | 
| 567 580 | 
             
            - lib/graphql/tracing/new_relic_trace.rb
         | 
| 568 581 | 
             
            - lib/graphql/tracing/new_relic_tracing.rb
         | 
| @@ -571,10 +584,11 @@ files: | |
| 571 584 | 
             
            - lib/graphql/tracing/platform_trace.rb
         | 
| 572 585 | 
             
            - lib/graphql/tracing/platform_tracing.rb
         | 
| 573 586 | 
             
            - lib/graphql/tracing/prometheus_trace.rb
         | 
| 587 | 
            +
            - lib/graphql/tracing/prometheus_trace/graphql_collector.rb
         | 
| 574 588 | 
             
            - lib/graphql/tracing/prometheus_tracing.rb
         | 
| 575 | 
            -
            - lib/graphql/tracing/prometheus_tracing/graphql_collector.rb
         | 
| 576 589 | 
             
            - lib/graphql/tracing/scout_trace.rb
         | 
| 577 590 | 
             
            - lib/graphql/tracing/scout_tracing.rb
         | 
| 591 | 
            +
            - lib/graphql/tracing/sentry_trace.rb
         | 
| 578 592 | 
             
            - lib/graphql/tracing/statsd_trace.rb
         | 
| 579 593 | 
             
            - lib/graphql/tracing/statsd_tracing.rb
         | 
| 580 594 | 
             
            - lib/graphql/tracing/trace.rb
         | 
| @@ -615,6 +629,7 @@ metadata: | |
| 615 629 | 
             
              source_code_uri: https://github.com/rmosolgo/graphql-ruby
         | 
| 616 630 | 
             
              bug_tracker_uri: https://github.com/rmosolgo/graphql-ruby/issues
         | 
| 617 631 | 
             
              mailing_list_uri: https://buttondown.email/graphql-ruby
         | 
| 632 | 
            +
              rubygems_mfa_required: 'true'
         | 
| 618 633 | 
             
            post_install_message:
         | 
| 619 634 | 
             
            rdoc_options: []
         | 
| 620 635 | 
             
            require_paths:
         | 
| @@ -630,7 +645,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 630 645 | 
             
                - !ruby/object:Gem::Version
         | 
| 631 646 | 
             
                  version: '0'
         | 
| 632 647 | 
             
            requirements: []
         | 
| 633 | 
            -
            rubygems_version: 3. | 
| 648 | 
            +
            rubygems_version: 3.5.3
         | 
| 634 649 | 
             
            signing_key:
         | 
| 635 650 | 
             
            specification_version: 4
         | 
| 636 651 | 
             
            summary: A GraphQL language and runtime for Ruby
         | 
| @@ -1,26 +0,0 @@ | |
| 1 | 
            -
            # frozen_string_literal: true
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            require 'base64'
         | 
| 4 | 
            -
             | 
| 5 | 
            -
            # backport from ruby v2.5 to v2.2 that has no `padding` things
         | 
| 6 | 
            -
            # @api private
         | 
| 7 | 
            -
            module Base64Bp
         | 
| 8 | 
            -
              extend Base64
         | 
| 9 | 
            -
             | 
| 10 | 
            -
              module_function
         | 
| 11 | 
            -
             | 
| 12 | 
            -
              def urlsafe_encode64(bin, padding:)
         | 
| 13 | 
            -
                str = strict_encode64(bin)
         | 
| 14 | 
            -
                str.tr!("+/", "-_")
         | 
| 15 | 
            -
                str.delete!("=") unless padding
         | 
| 16 | 
            -
                str
         | 
| 17 | 
            -
              end
         | 
| 18 | 
            -
             | 
| 19 | 
            -
              def urlsafe_decode64(str)
         | 
| 20 | 
            -
                str = str.tr("-_", "+/")
         | 
| 21 | 
            -
                if !str.end_with?("=") && str.length % 4 != 0
         | 
| 22 | 
            -
                  str = str.ljust((str.length + 3) & ~3, "=")
         | 
| 23 | 
            -
                end
         | 
| 24 | 
            -
                strict_decode64(str)
         | 
| 25 | 
            -
              end
         | 
| 26 | 
            -
            end
         |