graphql 1.8.0.pre1 → 1.8.0.pre2
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 +4 -4
- data/lib/generators/graphql/function_generator.rb +1 -1
- data/lib/generators/graphql/loader_generator.rb +1 -1
- data/lib/generators/graphql/mutation_generator.rb +6 -1
- data/lib/generators/graphql/templates/function.erb +2 -2
- data/lib/generators/graphql/templates/loader.erb +2 -2
- data/lib/graphql.rb +1 -0
- data/lib/graphql/execution.rb +1 -0
- data/lib/graphql/execution/instrumentation.rb +82 -0
- data/lib/graphql/execution/multiplex.rb +11 -28
- data/lib/graphql/field.rb +5 -0
- data/lib/graphql/internal_representation/node.rb +1 -1
- data/lib/graphql/language.rb +1 -0
- data/lib/graphql/language/document_from_schema_definition.rb +185 -0
- data/lib/graphql/language/lexer.rb +3 -3
- data/lib/graphql/language/lexer.rl +2 -2
- data/lib/graphql/language/token.rb +9 -2
- data/lib/graphql/query.rb +4 -0
- data/lib/graphql/railtie.rb +83 -0
- data/lib/graphql/relay/relation_connection.rb +13 -18
- data/lib/graphql/schema.rb +6 -0
- data/lib/graphql/schema/argument.rb +1 -1
- data/lib/graphql/schema/build_from_definition.rb +2 -0
- data/lib/graphql/schema/field.rb +5 -2
- data/lib/graphql/schema/input_object.rb +2 -2
- data/lib/graphql/schema/member.rb +10 -0
- data/lib/graphql/schema/member/build_type.rb +8 -0
- data/lib/graphql/schema/member/instrumentation.rb +3 -3
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +6 -4
- data/lib/graphql/tracing.rb +1 -0
- data/lib/graphql/tracing/data_dog_tracing.rb +45 -0
- data/lib/graphql/tracing/platform_tracing.rb +20 -7
- data/lib/graphql/upgrader/member.rb +111 -0
- data/lib/graphql/upgrader/schema.rb +37 -0
- data/lib/graphql/version.rb +1 -1
- data/readme.md +1 -1
- data/spec/dummy/app/channels/graphql_channel.rb +22 -1
- data/spec/dummy/log/development.log +239 -0
- data/spec/dummy/log/test.log +204 -0
- data/spec/dummy/test/system/action_cable_subscription_test.rb +4 -0
- data/spec/dummy/tmp/screenshots/failures_test_it_handles_subscriptions.png +0 -0
- data/spec/generators/graphql/function_generator_spec.rb +26 -0
- data/spec/generators/graphql/loader_generator_spec.rb +24 -0
- data/spec/graphql/analysis/max_query_complexity_spec.rb +3 -3
- data/spec/graphql/analysis/max_query_depth_spec.rb +3 -3
- data/spec/graphql/base_type_spec.rb +12 -0
- data/spec/graphql/boolean_type_spec.rb +3 -3
- data/spec/graphql/execution/execute_spec.rb +1 -1
- data/spec/graphql/execution/instrumentation_spec.rb +165 -0
- data/spec/graphql/execution/multiplex_spec.rb +1 -1
- data/spec/graphql/float_type_spec.rb +2 -2
- data/spec/graphql/id_type_spec.rb +1 -1
- data/spec/graphql/input_object_type_spec.rb +2 -2
- data/spec/graphql/int_type_spec.rb +2 -2
- data/spec/graphql/internal_representation/rewrite_spec.rb +2 -2
- data/spec/graphql/introspection/schema_type_spec.rb +1 -0
- data/spec/graphql/language/document_from_schema_definition_spec.rb +337 -0
- data/spec/graphql/language/lexer_spec.rb +12 -1
- data/spec/graphql/language/parser_spec.rb +1 -1
- data/spec/graphql/query/arguments_spec.rb +3 -3
- data/spec/graphql/query/variables_spec.rb +1 -1
- data/spec/graphql/query_spec.rb +4 -4
- data/spec/graphql/relay/base_connection_spec.rb +1 -1
- data/spec/graphql/relay/connection_resolve_spec.rb +1 -1
- data/spec/graphql/relay/connection_type_spec.rb +1 -1
- data/spec/graphql/relay/mutation_spec.rb +3 -3
- data/spec/graphql/relay/relation_connection_spec.rb +58 -0
- data/spec/graphql/schema/build_from_definition_spec.rb +14 -0
- data/spec/graphql/schema/field_spec.rb +5 -1
- data/spec/graphql/schema/instrumentation_spec.rb +39 -0
- data/spec/graphql/schema/validation_spec.rb +1 -1
- data/spec/graphql/schema/warden_spec.rb +11 -11
- data/spec/graphql/schema_spec.rb +8 -1
- data/spec/graphql/string_type_spec.rb +3 -3
- data/spec/graphql/subscriptions_spec.rb +1 -1
- data/spec/graphql/tracing/platform_tracing_spec.rb +59 -0
- data/spec/graphql/upgrader/member_spec.rb +222 -0
- data/spec/graphql/upgrader/schema_spec.rb +82 -0
- data/spec/support/dummy/schema.rb +19 -0
- data/spec/support/jazz.rb +14 -14
- data/spec/support/star_wars/data.rb +1 -2
- metadata +18 -2
| @@ -387,7 +387,7 @@ def self.run_lexer(query_string) | |
| 387 387 | 
             
            									begin
         | 
| 388 388 | 
             
            										te = p+1;
         | 
| 389 389 | 
             
            										begin
         | 
| 390 | 
            -
            											emit_string(ts + 1, te | 
| 390 | 
            +
            											emit_string(ts + 1, te, meta) 
         | 
| 391 391 | 
             
            										end
         | 
| 392 392 |  | 
| 393 393 | 
             
            									end
         | 
| @@ -791,7 +791,7 @@ def self.run_lexer(query_string) | |
| 791 791 | 
             
            										begin
         | 
| 792 792 | 
             
            											p = ((te))-1;
         | 
| 793 793 | 
             
            											begin
         | 
| 794 | 
            -
            												emit_string(ts + 1, te | 
| 794 | 
            +
            												emit_string(ts + 1, te, meta) 
         | 
| 795 795 | 
             
            											end
         | 
| 796 796 |  | 
| 797 797 | 
             
            										end
         | 
| @@ -1304,7 +1304,7 @@ PACK_DIRECTIVE = "c*" | |
| 1304 1304 | 
             
            UTF_8_ENCODING = "UTF-8"
         | 
| 1305 1305 |  | 
| 1306 1306 | 
             
            def self.emit_string(ts, te, meta)
         | 
| 1307 | 
            -
            value = meta[:data][ts...te].pack(PACK_DIRECTIVE).force_encoding(UTF_8_ENCODING)
         | 
| 1307 | 
            +
            value = meta[:data][ts...te - 1].pack(PACK_DIRECTIVE).force_encoding(UTF_8_ENCODING)
         | 
| 1308 1308 | 
             
            if value !~ VALID_STRING
         | 
| 1309 1309 | 
             
            meta[:tokens] << token = GraphQL::Language::Token.new(
         | 
| 1310 1310 | 
             
            name: :BAD_UNICODE_ESCAPE,
         | 
| @@ -75,7 +75,7 @@ | |
| 75 75 | 
             
                RBRACKET      => { emit(:RBRACKET, ts, te, meta) };
         | 
| 76 76 | 
             
                LBRACKET      => { emit(:LBRACKET, ts, te, meta) };
         | 
| 77 77 | 
             
                COLON         => { emit(:COLON, ts, te, meta) };
         | 
| 78 | 
            -
                QUOTED_STRING => { emit_string(ts + 1, te | 
| 78 | 
            +
                QUOTED_STRING => { emit_string(ts + 1, te, meta) };
         | 
| 79 79 | 
             
                VAR_SIGN      => { emit(:VAR_SIGN, ts, te, meta) };
         | 
| 80 80 | 
             
                DIR_SIGN      => { emit(:DIR_SIGN, ts, te, meta) };
         | 
| 81 81 | 
             
                ELLIPSIS      => { emit(:ELLIPSIS, ts, te, meta) };
         | 
| @@ -189,7 +189,7 @@ module GraphQL | |
| 189 189 | 
             
                  UTF_8_ENCODING = "UTF-8"
         | 
| 190 190 |  | 
| 191 191 | 
             
                  def self.emit_string(ts, te, meta)
         | 
| 192 | 
            -
                    value = meta[:data][ts...te].pack(PACK_DIRECTIVE).force_encoding(UTF_8_ENCODING)
         | 
| 192 | 
            +
                    value = meta[:data][ts...te - 1].pack(PACK_DIRECTIVE).force_encoding(UTF_8_ENCODING)
         | 
| 193 193 | 
             
                    if value !~ VALID_STRING
         | 
| 194 194 | 
             
                      meta[:tokens] << token = GraphQL::Language::Token.new(
         | 
| 195 195 | 
             
                        name: :BAD_UNICODE_ESCAPE,
         | 
| @@ -5,7 +5,10 @@ module GraphQL | |
| 5 5 | 
             
                # Contains type, value and position data.
         | 
| 6 6 | 
             
                class Token
         | 
| 7 7 | 
             
                  # @return [Symbol] The kind of token this is
         | 
| 8 | 
            -
                  attr_reader :name | 
| 8 | 
            +
                  attr_reader :name
         | 
| 9 | 
            +
                  # @return [String] The text of this token
         | 
| 10 | 
            +
                  attr_reader :value
         | 
| 11 | 
            +
                  attr_reader :prev_token, :line, :col
         | 
| 9 12 |  | 
| 10 13 | 
             
                  def initialize(value:, name:, line:, col:, prev_token:)
         | 
| 11 14 | 
             
                    @name = name
         | 
| @@ -15,13 +18,17 @@ module GraphQL | |
| 15 18 | 
             
                    @prev_token = prev_token
         | 
| 16 19 | 
             
                  end
         | 
| 17 20 |  | 
| 18 | 
            -
                   | 
| 21 | 
            +
                  alias to_s value
         | 
| 19 22 | 
             
                  def to_i; @value.to_i; end
         | 
| 20 23 | 
             
                  def to_f; @value.to_f; end
         | 
| 21 24 |  | 
| 22 25 | 
             
                  def line_and_column
         | 
| 23 26 | 
             
                    [@line, @col]
         | 
| 24 27 | 
             
                  end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  def inspect
         | 
| 30 | 
            +
                    "(#{@name} #{@value.inspect} [#{@line}:#{@col}])"
         | 
| 31 | 
            +
                  end
         | 
| 25 32 | 
             
                end
         | 
| 26 33 | 
             
              end
         | 
| 27 34 | 
             
            end
         | 
    
        data/lib/graphql/query.rb
    CHANGED
    
    
| @@ -0,0 +1,83 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require_relative './upgrader/member'
         | 
| 4 | 
            +
            require_relative './upgrader/schema'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module GraphQL
         | 
| 7 | 
            +
              class Railtie < Rails::Railtie
         | 
| 8 | 
            +
                rake_tasks do
         | 
| 9 | 
            +
                  namespace :graphql do
         | 
| 10 | 
            +
                    task :upgrade, [:dir] do |t, args|
         | 
| 11 | 
            +
                      unless (dir = args[:dir])
         | 
| 12 | 
            +
                        fail 'You have to give me a directory where your GraphQL schema and types live. ' \
         | 
| 13 | 
            +
                         'For example: `bin/rake graphql:upgrade[app/graphql/**/*]`'
         | 
| 14 | 
            +
                      end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                      Dir[dir].each do |file|
         | 
| 17 | 
            +
                        # Members (types, interfaces, etc.)
         | 
| 18 | 
            +
                        if file =~ /.*_(type|interface|enum|union|)\.rb$/
         | 
| 19 | 
            +
                          Rake::Task["graphql:upgrade:member"].execute(Struct.new(:member_file).new(file))
         | 
| 20 | 
            +
                        end
         | 
| 21 | 
            +
                      end
         | 
| 22 | 
            +
                    end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                    namespace :upgrade do
         | 
| 25 | 
            +
                      task :create_base_objects, [:base_dir] do |t, args|
         | 
| 26 | 
            +
                        base_dir = args.base_dir
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                        destination_file = File.join(base_dir, "types", "base_enum.rb")
         | 
| 29 | 
            +
                        unless File.exists?(destination_file)
         | 
| 30 | 
            +
                          FileUtils.mkdir_p(File.dirname(destination_file))
         | 
| 31 | 
            +
                          File.open(destination_file, 'w') do |f|
         | 
| 32 | 
            +
                            f.write "class Types::BaseEnum < GraphQL::Schema::Enum; end"
         | 
| 33 | 
            +
                          end
         | 
| 34 | 
            +
                        end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                        destination_file = File.join(base_dir, "types", "base_union.rb")
         | 
| 37 | 
            +
                        unless File.exists?(destination_file)
         | 
| 38 | 
            +
                          FileUtils.mkdir_p(File.dirname(destination_file))
         | 
| 39 | 
            +
                          File.open(destination_file, 'w') do |f|
         | 
| 40 | 
            +
                            f.write "class Types::BaseUnion < GraphQL::Schema::Union; end"
         | 
| 41 | 
            +
                          end
         | 
| 42 | 
            +
                        end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                        destination_file = File.join(base_dir, "types", "base_interface.rb")
         | 
| 45 | 
            +
                        unless File.exists?(destination_file)
         | 
| 46 | 
            +
                          FileUtils.mkdir_p(File.dirname(destination_file))
         | 
| 47 | 
            +
                          File.open(destination_file, 'w') do |f|
         | 
| 48 | 
            +
                            f.write "class Types::BaseInterface < GraphQL::Schema::Interface; end"
         | 
| 49 | 
            +
                          end
         | 
| 50 | 
            +
                        end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                        destination_file = File.join(base_dir, "types", "base_object.rb")
         | 
| 53 | 
            +
                        unless File.exists?(destination_file)
         | 
| 54 | 
            +
                          File.open(destination_file, 'w') do |f|
         | 
| 55 | 
            +
                            f.write "class Types::BaseObject < GraphQL::Schema::Object; end"
         | 
| 56 | 
            +
                          end
         | 
| 57 | 
            +
                        end
         | 
| 58 | 
            +
                      end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                      task :schema, [:schema_file] do |t, args|
         | 
| 61 | 
            +
                        schema_file = args.schema_file
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                        upgrader = GraphQL::Upgrader::Schema.new File.read(schema_file)
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                        puts "- Transforming schema #{schema_file}"
         | 
| 66 | 
            +
                        File.open(schema_file, 'w') { |f| f.write upgrader.upgrade }
         | 
| 67 | 
            +
                      end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                      task :member, [:member_file] do |t, args|
         | 
| 70 | 
            +
                        member_file = args.member_file
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                        upgrader = GraphQL::Upgrader::Member.new File.read(member_file)
         | 
| 73 | 
            +
                        next unless upgrader.upgradeable?
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                        puts "- Transforming member #{member_file}"
         | 
| 76 | 
            +
                        File.open(member_file, 'w') { |f| f.write upgrader.upgrade }
         | 
| 77 | 
            +
                      end
         | 
| 78 | 
            +
                    end
         | 
| 79 | 
            +
                  end
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
              end
         | 
| 82 | 
            +
            end
         | 
| 83 | 
            +
             | 
| @@ -7,11 +7,11 @@ module GraphQL | |
| 7 7 | 
             
                # - `Sequel::Dataset`
         | 
| 8 8 | 
             
                class RelationConnection < BaseConnection
         | 
| 9 9 | 
             
                  def cursor_from_node(item)
         | 
| 10 | 
            -
                    item_index =  | 
| 10 | 
            +
                    item_index = paged_nodes.index(item)
         | 
| 11 11 | 
             
                    if item_index.nil?
         | 
| 12 12 | 
             
                      raise("Can't generate cursor, item not found in connection: #{item}")
         | 
| 13 13 | 
             
                    else
         | 
| 14 | 
            -
                      offset = item_index + 1 + (( | 
| 14 | 
            +
                      offset = item_index + 1 + ((paged_nodes_offset || 0) - (relation_offset(sliced_nodes) || 0))
         | 
| 15 15 |  | 
| 16 16 | 
             
                      if after
         | 
| 17 17 | 
             
                        offset += offset_from_cursor(after)
         | 
| @@ -25,7 +25,7 @@ module GraphQL | |
| 25 25 |  | 
| 26 26 | 
             
                  def has_next_page
         | 
| 27 27 | 
             
                    if first
         | 
| 28 | 
            -
                       | 
| 28 | 
            +
                      paged_nodes.length >= first && sliced_nodes_count > first
         | 
| 29 29 | 
             
                    elsif GraphQL::Relay::ConnectionType.bidirectional_pagination && last
         | 
| 30 30 | 
             
                      sliced_nodes_count > last
         | 
| 31 31 | 
             
                    else
         | 
| @@ -35,7 +35,7 @@ module GraphQL | |
| 35 35 |  | 
| 36 36 | 
             
                  def has_previous_page
         | 
| 37 37 | 
             
                    if last
         | 
| 38 | 
            -
                       | 
| 38 | 
            +
                      paged_nodes.length >= last && sliced_nodes_count > last
         | 
| 39 39 | 
             
                    elsif GraphQL::Relay::ConnectionType.bidirectional_pagination && after
         | 
| 40 40 | 
             
                      # We've already paginated through the collection a bit,
         | 
| 41 41 | 
             
                      # there are nodes behind us
         | 
| @@ -64,6 +64,7 @@ module GraphQL | |
| 64 64 | 
             
                  private
         | 
| 65 65 |  | 
| 66 66 | 
             
                  # apply first / last limit results
         | 
| 67 | 
            +
                  # @return [Array]
         | 
| 67 68 | 
             
                  def paged_nodes
         | 
| 68 69 | 
             
                    return @paged_nodes if defined? @paged_nodes
         | 
| 69 70 |  | 
| @@ -94,7 +95,14 @@ module GraphQL | |
| 94 95 | 
             
                      end
         | 
| 95 96 | 
             
                    end
         | 
| 96 97 |  | 
| 97 | 
            -
                     | 
| 98 | 
            +
                    # Store this here so we can convert the relation to an Array
         | 
| 99 | 
            +
                    # (this avoids an extra DB call on Sequel)
         | 
| 100 | 
            +
                    @paged_nodes_offset = relation_offset(items)
         | 
| 101 | 
            +
                    @paged_nodes = items.to_a
         | 
| 102 | 
            +
                  end
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                  def paged_nodes_offset
         | 
| 105 | 
            +
                    paged_nodes && @paged_nodes_offset
         | 
| 98 106 | 
             
                  end
         | 
| 99 107 |  | 
| 100 108 | 
             
                  def relation_offset(relation)
         | 
| @@ -166,19 +174,6 @@ module GraphQL | |
| 166 174 | 
             
                  def offset_from_cursor(cursor)
         | 
| 167 175 | 
             
                    decode(cursor).to_i
         | 
| 168 176 | 
             
                  end
         | 
| 169 | 
            -
             | 
| 170 | 
            -
                  def paged_nodes_array
         | 
| 171 | 
            -
                    return @paged_nodes_array if defined?(@paged_nodes_array)
         | 
| 172 | 
            -
                    @paged_nodes_array = paged_nodes.to_a
         | 
| 173 | 
            -
                  end
         | 
| 174 | 
            -
             | 
| 175 | 
            -
                  def paged_nodes_length
         | 
| 176 | 
            -
                    if paged_nodes.respond_to?(:length)
         | 
| 177 | 
            -
                      paged_nodes.length
         | 
| 178 | 
            -
                    else
         | 
| 179 | 
            -
                      paged_nodes_array.length
         | 
| 180 | 
            -
                    end
         | 
| 181 | 
            -
                  end
         | 
| 182 177 | 
             
                end
         | 
| 183 178 |  | 
| 184 179 | 
             
                if defined?(ActiveRecord::Relation)
         | 
    
        data/lib/graphql/schema.rb
    CHANGED
    
    | @@ -570,6 +570,12 @@ module GraphQL | |
| 570 570 | 
             
                  GraphQL::Schema::Printer.print_schema(self, only: only, except: except, context: context)
         | 
| 571 571 | 
             
                end
         | 
| 572 572 |  | 
| 573 | 
            +
                # Return the GraphQL::Language::Document IDL AST for the schema
         | 
| 574 | 
            +
                # @return [GraphQL::Language::Document]
         | 
| 575 | 
            +
                def to_document
         | 
| 576 | 
            +
                  GraphQL::Language::DocumentFromSchemaDefinition.new(self).document
         | 
| 577 | 
            +
                end
         | 
| 578 | 
            +
             | 
| 573 579 | 
             
                # Return the Hash response of {Introspection::INTROSPECTION_QUERY}.
         | 
| 574 580 | 
             
                # @param context [Hash]
         | 
| 575 581 | 
             
                # @param only [<#call(member, ctx)>]
         | 
    
        data/lib/graphql/schema/field.rb
    CHANGED
    
    | @@ -16,7 +16,7 @@ module GraphQL | |
| 16 16 | 
             
                  def initialize(name, return_type_expr = nil, desc = nil, null: nil, field: nil, function: nil, deprecation_reason: nil, method: nil, connection: nil, max_page_size: nil, resolve: nil, &args_block)
         | 
| 17 17 | 
             
                    if !(field || function)
         | 
| 18 18 | 
             
                      if return_type_expr.nil?
         | 
| 19 | 
            -
                        raise ArgumentError "missing  | 
| 19 | 
            +
                        raise ArgumentError, "missing positional argument `type`"
         | 
| 20 20 | 
             
                      end
         | 
| 21 21 | 
             
                      if null.nil?
         | 
| 22 22 | 
             
                        raise ArgumentError, "missing keyword argument null:"
         | 
| @@ -47,7 +47,8 @@ module GraphQL | |
| 47 47 | 
             
                    else
         | 
| 48 48 | 
             
                      GraphQL::Field.new
         | 
| 49 49 | 
             
                    end
         | 
| 50 | 
            -
             | 
| 50 | 
            +
             | 
| 51 | 
            +
                    field_defn.name = Member::BuildType.camelize(name)
         | 
| 51 52 |  | 
| 52 53 | 
             
                    if @return_type_expr
         | 
| 53 54 | 
             
                      return_type_name = Member::BuildType.to_type_name(@return_type_expr)
         | 
| @@ -96,6 +97,8 @@ module GraphQL | |
| 96 97 | 
             
                    field_defn
         | 
| 97 98 | 
             
                  end
         | 
| 98 99 |  | 
| 100 | 
            +
                  private
         | 
| 101 | 
            +
             | 
| 99 102 | 
             
                  class << self
         | 
| 100 103 | 
             
                    def argument_class(new_arg_class = nil)
         | 
| 101 104 | 
             
                      if new_arg_class
         | 
| @@ -20,7 +20,7 @@ module GraphQL | |
| 20 20 | 
             
                    def argument(*args)
         | 
| 21 21 | 
             
                      argument = GraphQL::Schema::Argument.new(*args)
         | 
| 22 22 | 
             
                      own_arguments << argument
         | 
| 23 | 
            -
                      arg_name = argument.name
         | 
| 23 | 
            +
                      arg_name = argument.graphql_definition.name
         | 
| 24 24 | 
             
                      # Add a method access
         | 
| 25 25 | 
             
                      define_method(Member::BuildType.underscore(arg_name)) do
         | 
| 26 26 | 
             
                        @arguments.public_send(arg_name)
         | 
| @@ -47,7 +47,7 @@ module GraphQL | |
| 47 47 | 
             
                      type_defn.name = graphql_name
         | 
| 48 48 | 
             
                      type_defn.description = description
         | 
| 49 49 | 
             
                      arguments.each do |arg|
         | 
| 50 | 
            -
                        type_defn.arguments[arg.name] = arg.graphql_definition
         | 
| 50 | 
            +
                        type_defn.arguments[arg.graphql_definition.name] = arg.graphql_definition
         | 
| 51 51 | 
             
                      end
         | 
| 52 52 | 
             
                      # Make a reference to a classic-style Arguments class
         | 
| 53 53 | 
             
                      self.arguments_class = GraphQL::Query::Arguments.construct_arguments_class(type_defn)
         | 
| @@ -62,6 +62,16 @@ module GraphQL | |
| 62 62 | 
             
                      end
         | 
| 63 63 | 
             
                    end
         | 
| 64 64 |  | 
| 65 | 
            +
                    # Just a convenience method to point out that people should use graphql_name instead
         | 
| 66 | 
            +
                    def name(new_name = nil)
         | 
| 67 | 
            +
                      return super() if new_name.nil?
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                      fail(
         | 
| 70 | 
            +
                        "The new name override method is `graphql_name`, not `name`. Usage: "\
         | 
| 71 | 
            +
                        "graphql_name \"#{new_name}\""
         | 
| 72 | 
            +
                      )
         | 
| 73 | 
            +
                    end
         | 
| 74 | 
            +
             | 
| 65 75 | 
             
                    # Call this method to provide a new description; OR
         | 
| 66 76 | 
             
                    # call it without an argument to get the description
         | 
| 67 77 | 
             
                    # @param new_description [String]
         | 
| @@ -94,6 +94,14 @@ module GraphQL | |
| 94 94 | 
             
                      end
         | 
| 95 95 | 
             
                    end
         | 
| 96 96 |  | 
| 97 | 
            +
                    def camelize(string)
         | 
| 98 | 
            +
                      return string unless string.include?('_')
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                      string.split('_').map(&:capitalize).join.tap do |camelized|
         | 
| 101 | 
            +
                        camelized[0] = camelized[0].downcase
         | 
| 102 | 
            +
                      end
         | 
| 103 | 
            +
                    end
         | 
| 104 | 
            +
             | 
| 97 105 | 
             
                    def underscore(string)
         | 
| 98 106 | 
             
                      string
         | 
| 99 107 | 
             
                        .gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2') # URLDecoder -> URL_Decoder
         | 
| @@ -85,10 +85,10 @@ module GraphQL | |
| 85 85 | 
             
                      private
         | 
| 86 86 |  | 
| 87 87 | 
             
                      def proxy_to_depth(obj, depth, type, ctx)
         | 
| 88 | 
            -
                        if  | 
| 89 | 
            -
                          obj.map { |inner_obj| proxy_to_depth(inner_obj, depth - 1, type, ctx) }
         | 
| 90 | 
            -
                        elsif obj.nil?
         | 
| 88 | 
            +
                        if obj.nil?
         | 
| 91 89 | 
             
                          obj
         | 
| 90 | 
            +
                        elsif depth > 0
         | 
| 91 | 
            +
                          obj.map { |inner_obj| proxy_to_depth(inner_obj, depth - 1, type, ctx) }
         | 
| 92 92 | 
             
                        else
         | 
| 93 93 | 
             
                          concrete_type = case type
         | 
| 94 94 | 
             
                          when GraphQL::UnionType, GraphQL::InterfaceType
         | 
| @@ -62,19 +62,21 @@ module GraphQL | |
| 62 62 | 
             
                class ActionCableSubscriptions < GraphQL::Subscriptions
         | 
| 63 63 | 
             
                  SUBSCRIPTION_PREFIX = "graphql-subscription:"
         | 
| 64 64 | 
             
                  EVENT_PREFIX = "graphql-event:"
         | 
| 65 | 
            -
             | 
| 65 | 
            +
             | 
| 66 | 
            +
                  # @param serializer [<#dump(obj), #load(string)] Used for serializing messages before handing them to `.broadcast(msg)`
         | 
| 67 | 
            +
                  def initialize(serializer: Serialize, **rest)
         | 
| 66 68 | 
             
                    # A per-process map of subscriptions to deliver.
         | 
| 67 69 | 
             
                    # This is provided by Rails, so let's use it
         | 
| 68 70 | 
             
                    @subscriptions = Concurrent::Map.new
         | 
| 71 | 
            +
                    @serializer = serializer
         | 
| 69 72 | 
             
                    super
         | 
| 70 73 | 
             
                  end
         | 
| 71 74 |  | 
| 72 75 | 
             
                  # An event was triggered; Push the data over ActionCable.
         | 
| 73 76 | 
             
                  # Subscribers will re-evaluate locally.
         | 
| 74 | 
            -
                  # TODO: this method name is a smell
         | 
| 75 77 | 
             
                  def execute_all(event, object)
         | 
| 76 78 | 
             
                    stream = EVENT_PREFIX + event.topic
         | 
| 77 | 
            -
                    message =  | 
| 79 | 
            +
                    message = @serializer.dump(object)
         | 
| 78 80 | 
             
                    ActionCable.server.broadcast(stream, message)
         | 
| 79 81 | 
             
                  end
         | 
| 80 82 |  | 
| @@ -97,7 +99,7 @@ module GraphQL | |
| 97 99 | 
             
                    @subscriptions[subscription_id] = query
         | 
| 98 100 | 
             
                    events.each do |event|
         | 
| 99 101 | 
             
                      channel.stream_from(EVENT_PREFIX + event.topic, coder: ActiveSupport::JSON) do |message|
         | 
| 100 | 
            -
                        execute(subscription_id, event,  | 
| 102 | 
            +
                        execute(subscription_id, event, @serializer.load(message))
         | 
| 101 103 | 
             
                        nil
         | 
| 102 104 | 
             
                      end
         | 
| 103 105 | 
             
                    end
         | 
    
        data/lib/graphql/tracing.rb
    CHANGED
    
    | @@ -2,6 +2,7 @@ | |
| 2 2 | 
             
            require "graphql/tracing/active_support_notifications_tracing"
         | 
| 3 3 | 
             
            require "graphql/tracing/platform_tracing"
         | 
| 4 4 | 
             
            require "graphql/tracing/appsignal_tracing"
         | 
| 5 | 
            +
            require "graphql/tracing/data_dog_tracing"
         | 
| 5 6 | 
             
            require "graphql/tracing/new_relic_tracing"
         | 
| 6 7 | 
             
            require "graphql/tracing/scout_tracing"
         | 
| 7 8 | 
             
            require "graphql/tracing/skylight_tracing"
         | 
| @@ -0,0 +1,45 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module GraphQL
         | 
| 4 | 
            +
              module Tracing
         | 
| 5 | 
            +
                class DataDogTracing < PlatformTracing
         | 
| 6 | 
            +
                  self.platform_keys = {
         | 
| 7 | 
            +
                    'lex' => 'lex.graphql',
         | 
| 8 | 
            +
                    'parse' => 'parse.graphql',
         | 
| 9 | 
            +
                    'validate' => 'validate.graphql',
         | 
| 10 | 
            +
                    'analyze_query' => 'analyze.graphql',
         | 
| 11 | 
            +
                    'analyze_multiplex' => 'analyze.graphql',
         | 
| 12 | 
            +
                    'execute_multiplex' => 'execute.graphql',
         | 
| 13 | 
            +
                    'execute_query' => 'execute.graphql',
         | 
| 14 | 
            +
                    'execute_query_lazy' => 'execute.graphql',
         | 
| 15 | 
            +
                  }
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  def platform_trace(platform_key, key, data)
         | 
| 18 | 
            +
                    service = options.fetch(:service, 'ruby-graphql')
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                    pin = Datadog::Pin.get_from(self)
         | 
| 21 | 
            +
                    unless pin
         | 
| 22 | 
            +
                      pin = Datadog::Pin.new(service)
         | 
| 23 | 
            +
                      pin.onto(self)
         | 
| 24 | 
            +
                    end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                    pin.tracer.trace(platform_key, service: pin.service) do |span|
         | 
| 27 | 
            +
                      if key == 'execute_multiplex'
         | 
| 28 | 
            +
                        span.resource = data[:multiplex].queries.map(&:selected_operation_name).join(', ')
         | 
| 29 | 
            +
                      end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                      if key == 'execute_query'
         | 
| 32 | 
            +
                        span.set_tag(:selected_operation_name, data[:query].selected_operation_name)
         | 
| 33 | 
            +
                        span.set_tag(:selected_operation_type, data[:query].selected_operation.operation_type)
         | 
| 34 | 
            +
                        span.set_tag(:query_string, data[:query].query_string)
         | 
| 35 | 
            +
                      end
         | 
| 36 | 
            +
                      yield
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  def platform_field_key(type, field)
         | 
| 41 | 
            +
                    "#{type.name}.#{field.name}"
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
            end
         |