graphql 1.7.14 → 1.8.0.pre1
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 +5 -5
- 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 +1 -6
- data/lib/generators/graphql/templates/function.erb +2 -2
- data/lib/generators/graphql/templates/loader.erb +2 -2
- data/lib/graphql.rb +2 -0
- data/lib/graphql/argument.rb +0 -1
- data/lib/graphql/backwards_compatibility.rb +2 -3
- data/lib/graphql/base_type.rb +18 -16
- data/lib/graphql/compatibility/query_parser_specification.rb +0 -117
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -14
- data/lib/graphql/define/assign_object_field.rb +5 -12
- data/lib/graphql/deprecated_dsl.rb +28 -0
- data/lib/graphql/directive.rb +0 -1
- data/lib/graphql/enum_type.rb +1 -3
- data/lib/graphql/execution.rb +0 -1
- data/lib/graphql/execution/multiplex.rb +29 -12
- data/lib/graphql/field.rb +5 -20
- data/lib/graphql/function.rb +12 -0
- data/lib/graphql/input_object_type.rb +1 -3
- data/lib/graphql/internal_representation/node.rb +14 -26
- data/lib/graphql/internal_representation/visit.rb +6 -3
- data/lib/graphql/introspection/arguments_field.rb +0 -1
- data/lib/graphql/introspection/enum_values_field.rb +0 -1
- data/lib/graphql/introspection/fields_field.rb +0 -1
- data/lib/graphql/introspection/input_fields_field.rb +0 -1
- data/lib/graphql/introspection/interfaces_field.rb +0 -1
- data/lib/graphql/introspection/of_type_field.rb +0 -1
- data/lib/graphql/introspection/possible_types_field.rb +0 -1
- data/lib/graphql/introspection/schema_field.rb +0 -1
- data/lib/graphql/introspection/type_by_name_field.rb +0 -1
- data/lib/graphql/introspection/typename_field.rb +0 -1
- data/lib/graphql/language.rb +0 -3
- data/lib/graphql/language/generation.rb +182 -3
- data/lib/graphql/language/lexer.rb +69 -144
- data/lib/graphql/language/lexer.rl +4 -15
- data/lib/graphql/language/nodes.rb +76 -136
- data/lib/graphql/language/parser.rb +621 -668
- data/lib/graphql/language/parser.y +11 -17
- data/lib/graphql/language/token.rb +3 -10
- data/lib/graphql/object_type.rb +6 -1
- data/lib/graphql/query.rb +13 -8
- data/lib/graphql/query/arguments.rb +33 -48
- data/lib/graphql/query/context.rb +1 -0
- data/lib/graphql/query/literal_input.rb +1 -4
- data/lib/graphql/relay/connection_resolve.rb +3 -0
- data/lib/graphql/relay/global_id_resolve.rb +5 -1
- data/lib/graphql/relay/relation_connection.rb +19 -14
- data/lib/graphql/schema.rb +219 -12
- data/lib/graphql/schema/argument.rb +33 -0
- data/lib/graphql/schema/build_from_definition.rb +18 -64
- data/lib/graphql/schema/enum.rb +76 -0
- data/lib/graphql/schema/field.rb +127 -0
- data/lib/graphql/schema/field/dynamic_resolve.rb +63 -0
- data/lib/graphql/schema/field/unwrapped_resolve.rb +20 -0
- data/lib/graphql/schema/input_object.rb +61 -0
- data/lib/graphql/schema/interface.rb +32 -0
- data/lib/graphql/schema/loader.rb +2 -2
- data/lib/graphql/schema/member.rb +97 -0
- data/lib/graphql/schema/member/build_type.rb +106 -0
- data/lib/graphql/schema/member/has_fields.rb +56 -0
- data/lib/graphql/schema/member/instrumentation.rb +113 -0
- data/lib/graphql/schema/member/list_type_proxy.rb +21 -0
- data/lib/graphql/schema/member/non_null_type_proxy.rb +21 -0
- data/lib/graphql/schema/object.rb +65 -0
- data/lib/graphql/schema/printer.rb +266 -33
- data/lib/graphql/schema/scalar.rb +25 -0
- data/lib/graphql/schema/traversal.rb +26 -17
- data/lib/graphql/schema/union.rb +48 -0
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +1 -5
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +8 -15
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +1 -11
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +5 -7
- data/lib/graphql/tracing.rb +0 -1
- data/lib/graphql/tracing/platform_tracing.rb +7 -20
- data/lib/graphql/tracing/scout_tracing.rb +2 -2
- data/lib/graphql/unresolved_type_error.rb +2 -3
- data/lib/graphql/version.rb +1 -1
- data/readme.md +1 -1
- data/spec/dummy/app/channels/graphql_channel.rb +1 -22
- data/spec/dummy/log/development.log +0 -239
- data/spec/dummy/log/test.log +0 -204
- data/spec/dummy/test/system/action_cable_subscription_test.rb +0 -4
- data/spec/dummy/tmp/screenshots/failures_test_it_handles_subscriptions.png +0 -0
- data/spec/generators/graphql/function_generator_spec.rb +0 -26
- data/spec/generators/graphql/loader_generator_spec.rb +0 -24
- 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/backtrace_spec.rb +0 -10
- data/spec/graphql/base_type_spec.rb +5 -19
- data/spec/graphql/boolean_type_spec.rb +3 -3
- data/spec/graphql/directive_spec.rb +1 -3
- data/spec/graphql/enum_type_spec.rb +5 -18
- data/spec/graphql/execution/execute_spec.rb +1 -1
- data/spec/graphql/execution/multiplex_spec.rb +2 -2
- 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 -15
- 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 +0 -1
- data/spec/graphql/language/generation_spec.rb +186 -21
- data/spec/graphql/language/lexer_spec.rb +1 -21
- data/spec/graphql/language/nodes_spec.rb +12 -21
- data/spec/graphql/language/parser_spec.rb +1 -1
- data/spec/graphql/query/arguments_spec.rb +15 -37
- data/spec/graphql/query/serial_execution/value_resolution_spec.rb +2 -2
- data/spec/graphql/query/variables_spec.rb +1 -1
- data/spec/graphql/query_spec.rb +5 -31
- data/spec/graphql/rake_task_spec.rb +1 -3
- data/spec/graphql/relay/base_connection_spec.rb +1 -1
- data/spec/graphql/relay/connection_instrumentation_spec.rb +2 -2
- 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 +1 -65
- data/spec/graphql/schema/build_from_definition_spec.rb +4 -86
- data/spec/graphql/schema/enum_spec.rb +60 -0
- data/spec/graphql/schema/field_spec.rb +14 -0
- data/spec/graphql/schema/input_object_spec.rb +43 -0
- data/spec/graphql/schema/interface_spec.rb +98 -0
- data/spec/graphql/schema/object_spec.rb +119 -0
- data/spec/graphql/schema/printer_spec.rb +15 -92
- data/spec/graphql/schema/scalar_spec.rb +40 -0
- data/spec/graphql/schema/union_spec.rb +35 -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 +25 -23
- data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +2 -10
- data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +2 -2
- 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 +1 -60
- data/spec/support/dummy/schema.rb +25 -39
- data/spec/support/jazz.rb +334 -0
- data/spec/support/lazy_helpers.rb +21 -23
- data/spec/support/star_wars/data.rb +7 -6
- data/spec/support/star_wars/schema.rb +109 -142
- metadata +39 -33
- data/lib/graphql/execution/instrumentation.rb +0 -82
- data/lib/graphql/language/block_string.rb +0 -47
- data/lib/graphql/language/document_from_schema_definition.rb +0 -277
- data/lib/graphql/language/printer.rb +0 -351
- data/lib/graphql/tracing/data_dog_tracing.rb +0 -49
- data/spec/graphql/execution/instrumentation_spec.rb +0 -165
- data/spec/graphql/language/block_string_spec.rb +0 -70
- data/spec/graphql/language/document_from_schema_definition_spec.rb +0 -770
- data/spec/graphql/language/printer_spec.rb +0 -203
@@ -1,351 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
module Language
|
4
|
-
class Printer
|
5
|
-
# Turn an arbitrary AST node back into a string.
|
6
|
-
#
|
7
|
-
# @example Turning a document into a query string
|
8
|
-
# document = GraphQL.parse(query_string)
|
9
|
-
# GraphQL::Language::Printer.new.print(document)
|
10
|
-
# # => "{ ... }"
|
11
|
-
#
|
12
|
-
#
|
13
|
-
# @example Building a custom printer
|
14
|
-
#
|
15
|
-
# class MyPrinter < GraphQL::Language::Printer
|
16
|
-
# def print_argument(arg)
|
17
|
-
# "#{arg.name}: <HIDDEN>"
|
18
|
-
# end
|
19
|
-
# end
|
20
|
-
#
|
21
|
-
# MyPrinter.new.print(document)
|
22
|
-
# # => "mutation { pay(creditCard: <HIDDEN>) { success } }"
|
23
|
-
#
|
24
|
-
#
|
25
|
-
# @param indent [String] Whitespace to add to the printed node
|
26
|
-
# @return [String] Valid GraphQL for `node`
|
27
|
-
def print(node, indent: "")
|
28
|
-
print_node(node, indent: indent)
|
29
|
-
end
|
30
|
-
|
31
|
-
protected
|
32
|
-
|
33
|
-
def print_document(document)
|
34
|
-
document.definitions.map { |d| print_node(d) }.join("\n\n")
|
35
|
-
end
|
36
|
-
|
37
|
-
def print_argument(argument)
|
38
|
-
"#{argument.name}: #{print_node(argument.value)}".dup
|
39
|
-
end
|
40
|
-
|
41
|
-
def print_directive(directive)
|
42
|
-
out = "@#{directive.name}".dup
|
43
|
-
|
44
|
-
if directive.arguments.any?
|
45
|
-
out << "(#{directive.arguments.map { |a| print_argument(a) }.join(", ")})"
|
46
|
-
end
|
47
|
-
|
48
|
-
out
|
49
|
-
end
|
50
|
-
|
51
|
-
def print_enum(enum)
|
52
|
-
"#{enum.name}".dup
|
53
|
-
end
|
54
|
-
|
55
|
-
def print_null_value
|
56
|
-
"null".dup
|
57
|
-
end
|
58
|
-
|
59
|
-
def print_field(field, indent: "")
|
60
|
-
out = "#{indent}".dup
|
61
|
-
out << "#{field.alias}: " if field.alias
|
62
|
-
out << "#{field.name}"
|
63
|
-
out << "(#{field.arguments.map { |a| print_argument(a) }.join(", ")})" if field.arguments.any?
|
64
|
-
out << print_directives(field.directives)
|
65
|
-
out << print_selections(field.selections, indent: indent)
|
66
|
-
out
|
67
|
-
end
|
68
|
-
|
69
|
-
def print_fragment_definition(fragment_def, indent: "")
|
70
|
-
out = "#{indent}fragment #{fragment_def.name}".dup
|
71
|
-
if fragment_def.type
|
72
|
-
out << " on #{print_node(fragment_def.type)}"
|
73
|
-
end
|
74
|
-
out << print_directives(fragment_def.directives)
|
75
|
-
out << print_selections(fragment_def.selections, indent: indent)
|
76
|
-
out
|
77
|
-
end
|
78
|
-
|
79
|
-
def print_fragment_spread(fragment_spread, indent: "")
|
80
|
-
out = "#{indent}...#{fragment_spread.name}".dup
|
81
|
-
out << print_directives(fragment_spread.directives)
|
82
|
-
out
|
83
|
-
end
|
84
|
-
|
85
|
-
def print_inline_fragment(inline_fragment, indent: "")
|
86
|
-
out = "#{indent}...".dup
|
87
|
-
if inline_fragment.type
|
88
|
-
out << " on #{print_node(inline_fragment.type)}"
|
89
|
-
end
|
90
|
-
out << print_directives(inline_fragment.directives)
|
91
|
-
out << print_selections(inline_fragment.selections, indent: indent)
|
92
|
-
out
|
93
|
-
end
|
94
|
-
|
95
|
-
def print_input_object(input_object)
|
96
|
-
"{#{input_object.arguments.map { |a| "#{a.name}: #{print(a.value)}" }.join(", ")}}"
|
97
|
-
end
|
98
|
-
|
99
|
-
def print_list_type(list_type)
|
100
|
-
"[#{print_node(list_type.of_type)}]".dup
|
101
|
-
end
|
102
|
-
|
103
|
-
def print_non_null_type(non_null_type)
|
104
|
-
"#{print_node(non_null_type.of_type)}!".dup
|
105
|
-
end
|
106
|
-
|
107
|
-
def print_operation_definition(operation_definition, indent: "")
|
108
|
-
out = "#{indent}#{operation_definition.operation_type}".dup
|
109
|
-
out << " #{operation_definition.name}" if operation_definition.name
|
110
|
-
|
111
|
-
if operation_definition.variables.any?
|
112
|
-
out << "(#{operation_definition.variables.map { |v| print_variable_definition(v) }.join(", ")})"
|
113
|
-
end
|
114
|
-
|
115
|
-
out << print_directives(operation_definition.directives)
|
116
|
-
out << print_selections(operation_definition.selections, indent: indent)
|
117
|
-
out
|
118
|
-
end
|
119
|
-
|
120
|
-
def print_type_name(type_name)
|
121
|
-
"#{type_name.name}".dup
|
122
|
-
end
|
123
|
-
|
124
|
-
def print_variable_definition(variable_definition)
|
125
|
-
out = "$#{variable_definition.name}: #{print_node(variable_definition.type)}".dup
|
126
|
-
out << " = #{print_node(variable_definition.default_value)}" unless variable_definition.default_value.nil?
|
127
|
-
out
|
128
|
-
end
|
129
|
-
|
130
|
-
def print_variable_identifier(variable_identifier)
|
131
|
-
"$#{variable_identifier.name}".dup
|
132
|
-
end
|
133
|
-
|
134
|
-
def print_schema_definition(schema)
|
135
|
-
if (schema.query.nil? || schema.query == 'Query') &&
|
136
|
-
(schema.mutation.nil? || schema.mutation == 'Mutation') &&
|
137
|
-
(schema.subscription.nil? || schema.subscription == 'Subscription')
|
138
|
-
return
|
139
|
-
end
|
140
|
-
|
141
|
-
out = "schema {\n".dup
|
142
|
-
out << " query: #{schema.query}\n" if schema.query
|
143
|
-
out << " mutation: #{schema.mutation}\n" if schema.mutation
|
144
|
-
out << " subscription: #{schema.subscription}\n" if schema.subscription
|
145
|
-
out << "}"
|
146
|
-
end
|
147
|
-
|
148
|
-
def print_scalar_type_definition(scalar_type)
|
149
|
-
out = print_description(scalar_type)
|
150
|
-
out << "scalar #{scalar_type.name}"
|
151
|
-
out << print_directives(scalar_type.directives)
|
152
|
-
end
|
153
|
-
|
154
|
-
def print_object_type_definition(object_type)
|
155
|
-
out = print_description(object_type)
|
156
|
-
out << "type #{object_type.name}"
|
157
|
-
out << " implements " << object_type.interfaces.map(&:name).join(" & ") unless object_type.interfaces.empty?
|
158
|
-
out << print_directives(object_type.directives)
|
159
|
-
out << print_field_definitions(object_type.fields)
|
160
|
-
end
|
161
|
-
|
162
|
-
def print_input_value_definition(input_value)
|
163
|
-
out = "#{input_value.name}: #{print_node(input_value.type)}".dup
|
164
|
-
out << " = #{print_node(input_value.default_value)}" unless input_value.default_value.nil?
|
165
|
-
out << print_directives(input_value.directives)
|
166
|
-
end
|
167
|
-
|
168
|
-
def print_arguments(arguments, indent: "")
|
169
|
-
if arguments.all?{ |arg| !arg.description }
|
170
|
-
return "(#{arguments.map{ |arg| print_input_value_definition(arg) }.join(", ")})"
|
171
|
-
end
|
172
|
-
|
173
|
-
out = "(\n".dup
|
174
|
-
out << arguments.map.with_index{ |arg, i|
|
175
|
-
"#{print_description(arg, indent: " " + indent, first_in_block: i == 0)} #{indent}"\
|
176
|
-
"#{print_input_value_definition(arg)}"
|
177
|
-
}.join("\n")
|
178
|
-
out << "\n#{indent})"
|
179
|
-
end
|
180
|
-
|
181
|
-
def print_field_definition(field)
|
182
|
-
out = field.name.dup
|
183
|
-
unless field.arguments.empty?
|
184
|
-
out << print_arguments(field.arguments, indent: " ")
|
185
|
-
end
|
186
|
-
out << ": #{print_node(field.type)}"
|
187
|
-
out << print_directives(field.directives)
|
188
|
-
end
|
189
|
-
|
190
|
-
def print_interface_type_definition(interface_type)
|
191
|
-
out = print_description(interface_type)
|
192
|
-
out << "interface #{interface_type.name}"
|
193
|
-
out << print_directives(interface_type.directives)
|
194
|
-
out << print_field_definitions(interface_type.fields)
|
195
|
-
end
|
196
|
-
|
197
|
-
def print_union_type_definition(union_type)
|
198
|
-
out = print_description(union_type)
|
199
|
-
out << "union #{union_type.name}"
|
200
|
-
out << print_directives(union_type.directives)
|
201
|
-
out << " = " + union_type.types.map(&:name).join(" | ")
|
202
|
-
end
|
203
|
-
|
204
|
-
def print_enum_type_definition(enum_type)
|
205
|
-
out = print_description(enum_type)
|
206
|
-
out << "enum #{enum_type.name}#{print_directives(enum_type.directives)} {\n"
|
207
|
-
enum_type.values.each.with_index do |value, i|
|
208
|
-
out << print_description(value, indent: ' ', first_in_block: i == 0)
|
209
|
-
out << print_enum_value_definition(value)
|
210
|
-
end
|
211
|
-
out << "}"
|
212
|
-
end
|
213
|
-
|
214
|
-
def print_enum_value_definition(enum_value)
|
215
|
-
out = " #{enum_value.name}".dup
|
216
|
-
out << print_directives(enum_value.directives)
|
217
|
-
out << "\n"
|
218
|
-
end
|
219
|
-
|
220
|
-
def print_input_object_type_definition(input_object_type)
|
221
|
-
out = print_description(input_object_type)
|
222
|
-
out << "input #{input_object_type.name}"
|
223
|
-
out << print_directives(input_object_type.directives)
|
224
|
-
out << " {\n"
|
225
|
-
input_object_type.fields.each.with_index do |field, i|
|
226
|
-
out << print_description(field, indent: ' ', first_in_block: i == 0)
|
227
|
-
out << " #{print_input_value_definition(field)}\n"
|
228
|
-
end
|
229
|
-
out << "}"
|
230
|
-
end
|
231
|
-
|
232
|
-
def print_directive_definition(directive)
|
233
|
-
out = print_description(directive)
|
234
|
-
out << "directive @#{directive.name}"
|
235
|
-
|
236
|
-
if directive.arguments.any?
|
237
|
-
out << print_arguments(directive.arguments)
|
238
|
-
end
|
239
|
-
|
240
|
-
out << " on #{directive.locations.join(' | ')}"
|
241
|
-
end
|
242
|
-
|
243
|
-
def print_description(node, indent: "", first_in_block: true)
|
244
|
-
return ''.dup unless node.description
|
245
|
-
|
246
|
-
description = indent != '' && !first_in_block ? "\n".dup : "".dup
|
247
|
-
description << GraphQL::Language::Comments.commentize(node.description, indent: indent)
|
248
|
-
end
|
249
|
-
|
250
|
-
def print_field_definitions(fields)
|
251
|
-
out = " {\n".dup
|
252
|
-
fields.each.with_index do |field, i|
|
253
|
-
out << print_description(field, indent: ' ', first_in_block: i == 0)
|
254
|
-
out << " #{print_field_definition(field)}\n"
|
255
|
-
end
|
256
|
-
out << "}"
|
257
|
-
end
|
258
|
-
|
259
|
-
def print_directives(directives)
|
260
|
-
if directives.any?
|
261
|
-
directives.map { |d| " #{print_directive(d)}" }.join
|
262
|
-
else
|
263
|
-
""
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
|
-
def print_selections(selections, indent: "")
|
268
|
-
if selections.any?
|
269
|
-
out = " {\n".dup
|
270
|
-
selections.each do |selection|
|
271
|
-
out << print_node(selection, indent: indent + " ") << "\n"
|
272
|
-
end
|
273
|
-
out << "#{indent}}"
|
274
|
-
else
|
275
|
-
""
|
276
|
-
end
|
277
|
-
end
|
278
|
-
|
279
|
-
def print_node(node, indent: "")
|
280
|
-
case node
|
281
|
-
when Nodes::Document
|
282
|
-
print_document(node)
|
283
|
-
when Nodes::Argument
|
284
|
-
print_argument(node)
|
285
|
-
when Nodes::Directive
|
286
|
-
print_directive(node)
|
287
|
-
when Nodes::Enum
|
288
|
-
print_enum(node)
|
289
|
-
when Nodes::NullValue
|
290
|
-
print_null_value
|
291
|
-
when Nodes::Field
|
292
|
-
print_field(node, indent: indent)
|
293
|
-
when Nodes::FragmentDefinition
|
294
|
-
print_fragment_definition(node, indent: indent)
|
295
|
-
when Nodes::FragmentSpread
|
296
|
-
print_fragment_spread(node, indent: indent)
|
297
|
-
when Nodes::InlineFragment
|
298
|
-
print_inline_fragment(node, indent: indent)
|
299
|
-
when Nodes::InputObject
|
300
|
-
print_input_object(node)
|
301
|
-
when Nodes::ListType
|
302
|
-
print_list_type(node)
|
303
|
-
when Nodes::NonNullType
|
304
|
-
print_non_null_type(node)
|
305
|
-
when Nodes::OperationDefinition
|
306
|
-
print_operation_definition(node, indent: indent)
|
307
|
-
when Nodes::TypeName
|
308
|
-
print_type_name(node)
|
309
|
-
when Nodes::VariableDefinition
|
310
|
-
print_variable_definition(node)
|
311
|
-
when Nodes::VariableIdentifier
|
312
|
-
print_variable_identifier(node)
|
313
|
-
when Nodes::SchemaDefinition
|
314
|
-
print_schema_definition(node)
|
315
|
-
when Nodes::ScalarTypeDefinition
|
316
|
-
print_scalar_type_definition(node)
|
317
|
-
when Nodes::ObjectTypeDefinition
|
318
|
-
print_object_type_definition(node)
|
319
|
-
when Nodes::InputValueDefinition
|
320
|
-
print_input_value_definition(node)
|
321
|
-
when Nodes::FieldDefinition
|
322
|
-
print_field_definition(node)
|
323
|
-
when Nodes::InterfaceTypeDefinition
|
324
|
-
print_interface_type_definition(node)
|
325
|
-
when Nodes::UnionTypeDefinition
|
326
|
-
print_union_type_definition(node)
|
327
|
-
when Nodes::EnumTypeDefinition
|
328
|
-
print_enum_type_definition(node)
|
329
|
-
when Nodes::EnumValueDefinition
|
330
|
-
print_enum_value_definition(node)
|
331
|
-
when Nodes::InputObjectTypeDefinition
|
332
|
-
print_input_object_type_definition(node)
|
333
|
-
when Nodes::DirectiveDefinition
|
334
|
-
print_directive_definition(node)
|
335
|
-
when FalseClass, Float, Integer, NilClass, String, TrueClass, Symbol
|
336
|
-
GraphQL::Language.serialize(node)
|
337
|
-
when Array
|
338
|
-
"[#{node.map { |v| print_node(v) }.join(", ")}]".dup
|
339
|
-
when Hash
|
340
|
-
"{#{node.map { |k, v| "#{k}: #{print_node(v)}" }.join(", ")}}".dup
|
341
|
-
else
|
342
|
-
GraphQL::Language.serialize(node.to_s)
|
343
|
-
end
|
344
|
-
end
|
345
|
-
|
346
|
-
private
|
347
|
-
|
348
|
-
attr_reader :node
|
349
|
-
end
|
350
|
-
end
|
351
|
-
end
|
@@ -1,49 +0,0 @@
|
|
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
|
-
tracer.trace(platform_key, service: service_name) do |span|
|
19
|
-
span.span_type = 'custom'
|
20
|
-
|
21
|
-
if key == 'execute_multiplex'
|
22
|
-
operations = data[:multiplex].queries.map(&:selected_operation_name).join(', ')
|
23
|
-
span.resource = operations unless operations.empty?
|
24
|
-
end
|
25
|
-
|
26
|
-
if key == 'execute_query'
|
27
|
-
span.set_tag(:selected_operation_name, data[:query].selected_operation_name)
|
28
|
-
span.set_tag(:selected_operation_type, data[:query].selected_operation.operation_type)
|
29
|
-
span.set_tag(:query_string, data[:query].query_string)
|
30
|
-
end
|
31
|
-
|
32
|
-
yield
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def service_name
|
37
|
-
options.fetch(:service, 'ruby-graphql')
|
38
|
-
end
|
39
|
-
|
40
|
-
def tracer
|
41
|
-
options.fetch(:tracer, Datadog.tracer)
|
42
|
-
end
|
43
|
-
|
44
|
-
def platform_field_key(type, field)
|
45
|
-
"#{type.name}.#{field.name}"
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
@@ -1,165 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require "spec_helper"
|
3
|
-
|
4
|
-
describe GraphQL::Schema do
|
5
|
-
describe "instrumentation teardown bug" do
|
6
|
-
# This instrumenter records that it ran,
|
7
|
-
# or raises an error if instructed to do so
|
8
|
-
class InstrumenterError < StandardError
|
9
|
-
attr_reader :key
|
10
|
-
def initialize(key)
|
11
|
-
@key = key
|
12
|
-
super()
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
class LogInstrumenter
|
17
|
-
def before_query(unit_of_work)
|
18
|
-
run_hook(unit_of_work, "begin")
|
19
|
-
end
|
20
|
-
|
21
|
-
def after_query(unit_of_work)
|
22
|
-
run_hook(unit_of_work, "end")
|
23
|
-
end
|
24
|
-
|
25
|
-
alias :before_multiplex :before_query
|
26
|
-
alias :after_multiplex :after_query
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def run_hook(unit_of_work, event_name)
|
31
|
-
unit_of_work.context[log_key(event_name)] = true
|
32
|
-
if unit_of_work.context[raise_key(event_name)]
|
33
|
-
raise InstrumenterError.new(log_key(event_name))
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def log_key(event_name)
|
38
|
-
context_key("did_#{event_name}")
|
39
|
-
end
|
40
|
-
|
41
|
-
def raise_key(event_name)
|
42
|
-
context_key("should_raise_#{event_name}")
|
43
|
-
end
|
44
|
-
|
45
|
-
def context_key(suffix)
|
46
|
-
prefix = self.class.name.sub("Instrumenter", "").downcase
|
47
|
-
:"#{prefix}_instrumenter_#{suffix}"
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
class FirstInstrumenter < LogInstrumenter; end
|
52
|
-
class SecondInstrumenter < LogInstrumenter; end
|
53
|
-
|
54
|
-
let(:query_type) {
|
55
|
-
GraphQL::ObjectType.define do
|
56
|
-
name "Query"
|
57
|
-
field :int, types.Int do
|
58
|
-
argument :value, types.Int
|
59
|
-
resolve ->(obj, args, ctx) { args.value }
|
60
|
-
end
|
61
|
-
end
|
62
|
-
}
|
63
|
-
|
64
|
-
let(:schema) {
|
65
|
-
spec = self
|
66
|
-
GraphQL::Schema.define do
|
67
|
-
query(spec.query_type)
|
68
|
-
instrument(:query, FirstInstrumenter.new)
|
69
|
-
instrument(:query, SecondInstrumenter.new)
|
70
|
-
end
|
71
|
-
}
|
72
|
-
|
73
|
-
describe "query instrumenters" do
|
74
|
-
it "before_query of the 2nd instrumenter does not run but after_query does" do
|
75
|
-
context = {second_instrumenter_should_raise_begin: true}
|
76
|
-
assert_raises InstrumenterError do
|
77
|
-
schema.execute(" { int(value: 2) } ", context: context)
|
78
|
-
end
|
79
|
-
assert context[:first_instrumenter_did_begin]
|
80
|
-
assert context[:first_instrumenter_did_end]
|
81
|
-
assert context[:second_instrumenter_did_begin]
|
82
|
-
refute context[:second_instrumenter_did_end]
|
83
|
-
end
|
84
|
-
|
85
|
-
it "runs after_query even if a previous after_query raised an error" do
|
86
|
-
context = {second_instrumenter_should_raise_end: true}
|
87
|
-
err = assert_raises InstrumenterError do
|
88
|
-
schema.execute(" { int(value: 2) } ", context: context)
|
89
|
-
end
|
90
|
-
# The error came from the second instrumenter:
|
91
|
-
assert_equal :second_instrumenter_did_end, err.key
|
92
|
-
# But the first instrumenter still got a chance to teardown
|
93
|
-
assert context[:first_instrumenter_did_begin]
|
94
|
-
assert context[:first_instrumenter_did_end]
|
95
|
-
assert context[:second_instrumenter_did_begin]
|
96
|
-
assert context[:second_instrumenter_did_end]
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
describe "within a multiplex" do
|
101
|
-
let(:multiplex_schema) {
|
102
|
-
schema.redefine {
|
103
|
-
instrument(:multiplex, FirstInstrumenter.new)
|
104
|
-
instrument(:multiplex, SecondInstrumenter.new)
|
105
|
-
}
|
106
|
-
}
|
107
|
-
|
108
|
-
it "only runs after_multiplex if before_multiplex finished" do
|
109
|
-
multiplex_ctx = {second_instrumenter_should_raise_begin: true}
|
110
|
-
query_1_ctx = {}
|
111
|
-
query_2_ctx = {}
|
112
|
-
assert_raises InstrumenterError do
|
113
|
-
multiplex_schema.multiplex(
|
114
|
-
[
|
115
|
-
{query: "{int(value: 1)}", context: query_1_ctx},
|
116
|
-
{query: "{int(value: 2)}", context: query_2_ctx},
|
117
|
-
],
|
118
|
-
context: multiplex_ctx
|
119
|
-
)
|
120
|
-
end
|
121
|
-
|
122
|
-
assert multiplex_ctx[:first_instrumenter_did_begin]
|
123
|
-
assert multiplex_ctx[:first_instrumenter_did_end]
|
124
|
-
assert multiplex_ctx[:second_instrumenter_did_begin]
|
125
|
-
refute multiplex_ctx[:second_instrumenter_did_end]
|
126
|
-
# No query instrumentation was run at all
|
127
|
-
assert_equal 0, query_1_ctx.size
|
128
|
-
assert_equal 0, query_2_ctx.size
|
129
|
-
end
|
130
|
-
|
131
|
-
it "does full and partial query runs" do
|
132
|
-
multiplex_ctx = {}
|
133
|
-
query_1_ctx = {}
|
134
|
-
query_2_ctx = {second_instrumenter_should_raise_begin: true}
|
135
|
-
assert_raises InstrumenterError do
|
136
|
-
multiplex_schema.multiplex(
|
137
|
-
[
|
138
|
-
{ query: " { int(value: 2) } ", context: query_1_ctx },
|
139
|
-
{ query: " { int(value: 2) } ", context: query_2_ctx },
|
140
|
-
],
|
141
|
-
context: multiplex_ctx
|
142
|
-
)
|
143
|
-
end
|
144
|
-
|
145
|
-
# multiplex got a full run
|
146
|
-
assert multiplex_ctx[:first_instrumenter_did_begin]
|
147
|
-
assert multiplex_ctx[:first_instrumenter_did_end]
|
148
|
-
assert multiplex_ctx[:second_instrumenter_did_begin]
|
149
|
-
assert multiplex_ctx[:second_instrumenter_did_end]
|
150
|
-
|
151
|
-
# query 1 got a full run
|
152
|
-
assert query_1_ctx[:first_instrumenter_did_begin]
|
153
|
-
assert query_1_ctx[:first_instrumenter_did_end]
|
154
|
-
assert query_1_ctx[:second_instrumenter_did_begin]
|
155
|
-
assert query_1_ctx[:second_instrumenter_did_end]
|
156
|
-
|
157
|
-
# query 2 got a partial run
|
158
|
-
assert query_2_ctx[:first_instrumenter_did_begin]
|
159
|
-
assert query_2_ctx[:first_instrumenter_did_end]
|
160
|
-
assert query_2_ctx[:second_instrumenter_did_begin]
|
161
|
-
refute query_2_ctx[:second_instrumenter_did_end]
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
165
|
-
end
|