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
|