graphql 2.3.7 → 2.4.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/generators/graphql/install_generator.rb +46 -0
- data/lib/generators/graphql/orm_mutations_base.rb +1 -1
- data/lib/generators/graphql/templates/base_resolver.erb +2 -0
- data/lib/generators/graphql/type_generator.rb +1 -1
- data/lib/graphql/analysis/field_usage.rb +1 -1
- data/lib/graphql/analysis/query_complexity.rb +3 -3
- data/lib/graphql/analysis/visitor.rb +8 -7
- data/lib/graphql/analysis.rb +4 -4
- data/lib/graphql/autoload.rb +38 -0
- data/lib/graphql/current.rb +52 -0
- data/lib/graphql/dataloader/async_dataloader.rb +7 -6
- data/lib/graphql/dataloader/source.rb +7 -4
- data/lib/graphql/dataloader.rb +40 -19
- data/lib/graphql/execution/interpreter/arguments_cache.rb +5 -10
- data/lib/graphql/execution/interpreter/resolve.rb +13 -9
- data/lib/graphql/execution/interpreter/runtime.rb +35 -31
- data/lib/graphql/execution/interpreter.rb +9 -5
- data/lib/graphql/execution/lookahead.rb +18 -11
- data/lib/graphql/introspection/directive_type.rb +1 -1
- data/lib/graphql/introspection/entry_points.rb +2 -2
- data/lib/graphql/introspection/field_type.rb +1 -1
- data/lib/graphql/introspection/schema_type.rb +6 -11
- data/lib/graphql/introspection/type_type.rb +5 -5
- data/lib/graphql/invalid_null_error.rb +1 -1
- data/lib/graphql/language/cache.rb +13 -0
- data/lib/graphql/language/comment.rb +18 -0
- data/lib/graphql/language/document_from_schema_definition.rb +62 -34
- data/lib/graphql/language/lexer.rb +18 -15
- data/lib/graphql/language/nodes.rb +24 -16
- data/lib/graphql/language/parser.rb +14 -1
- data/lib/graphql/language/printer.rb +31 -15
- data/lib/graphql/language/sanitized_printer.rb +1 -1
- data/lib/graphql/language.rb +6 -6
- data/lib/graphql/pagination/connection.rb +1 -1
- data/lib/graphql/query/context/scoped_context.rb +1 -1
- data/lib/graphql/query/context.rb +13 -6
- data/lib/graphql/query/null_context.rb +3 -5
- data/lib/graphql/query/variable_validation_error.rb +1 -1
- data/lib/graphql/query.rb +72 -18
- data/lib/graphql/railtie.rb +7 -0
- data/lib/graphql/rubocop/graphql/field_type_in_block.rb +144 -0
- data/lib/graphql/rubocop/graphql/root_types_in_block.rb +38 -0
- data/lib/graphql/rubocop.rb +2 -0
- data/lib/graphql/schema/addition.rb +2 -1
- data/lib/graphql/schema/always_visible.rb +6 -2
- data/lib/graphql/schema/argument.rb +14 -1
- data/lib/graphql/schema/build_from_definition.rb +9 -1
- data/lib/graphql/schema/directive/flagged.rb +2 -2
- data/lib/graphql/schema/directive.rb +1 -1
- data/lib/graphql/schema/enum.rb +71 -23
- data/lib/graphql/schema/enum_value.rb +10 -2
- data/lib/graphql/schema/field/connection_extension.rb +1 -1
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +102 -47
- data/lib/graphql/schema/field_extension.rb +1 -1
- data/lib/graphql/schema/has_single_input_argument.rb +5 -2
- data/lib/graphql/schema/input_object.rb +90 -39
- data/lib/graphql/schema/interface.rb +22 -5
- data/lib/graphql/schema/introspection_system.rb +5 -16
- data/lib/graphql/schema/loader.rb +1 -1
- data/lib/graphql/schema/member/base_dsl_methods.rb +15 -0
- data/lib/graphql/schema/member/has_arguments.rb +36 -23
- data/lib/graphql/schema/member/has_directives.rb +3 -3
- data/lib/graphql/schema/member/has_fields.rb +26 -6
- data/lib/graphql/schema/member/has_interfaces.rb +4 -4
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +5 -1
- data/lib/graphql/schema/member/has_validators.rb +1 -1
- data/lib/graphql/schema/object.rb +8 -0
- data/lib/graphql/schema/printer.rb +1 -0
- data/lib/graphql/schema/relay_classic_mutation.rb +0 -1
- data/lib/graphql/schema/resolver.rb +12 -14
- data/lib/graphql/schema/subscription.rb +52 -6
- data/lib/graphql/schema/type_expression.rb +2 -2
- data/lib/graphql/schema/union.rb +1 -1
- data/lib/graphql/schema/validator/all_validator.rb +62 -0
- data/lib/graphql/schema/validator/required_validator.rb +28 -4
- data/lib/graphql/schema/validator.rb +3 -1
- data/lib/graphql/schema/visibility/migration.rb +188 -0
- data/lib/graphql/schema/visibility/profile.rb +359 -0
- data/lib/graphql/schema/visibility/visit.rb +190 -0
- data/lib/graphql/schema/visibility.rb +294 -0
- data/lib/graphql/schema/warden.rb +179 -16
- data/lib/graphql/schema.rb +348 -94
- data/lib/graphql/static_validation/base_visitor.rb +6 -5
- data/lib/graphql/static_validation/literal_validator.rb +4 -4
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
- data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +1 -1
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +3 -2
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +3 -3
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +2 -0
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +12 -2
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +2 -2
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +8 -7
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +12 -2
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
- data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +1 -1
- data/lib/graphql/static_validation/rules/query_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -4
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +3 -3
- data/lib/graphql/static_validation/rules/subscription_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +18 -27
- data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +2 -2
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +11 -2
- data/lib/graphql/static_validation/validation_context.rb +18 -2
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +3 -2
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +10 -4
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +12 -10
- data/lib/graphql/subscriptions/event.rb +13 -2
- data/lib/graphql/subscriptions/serialize.rb +2 -0
- data/lib/graphql/subscriptions.rb +6 -4
- data/lib/graphql/testing/helpers.rb +10 -6
- data/lib/graphql/tracing/active_support_notifications_trace.rb +1 -1
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +1 -1
- data/lib/graphql/tracing/appoptics_trace.rb +2 -0
- data/lib/graphql/tracing/appoptics_tracing.rb +2 -0
- data/lib/graphql/tracing/appsignal_trace.rb +2 -0
- data/lib/graphql/tracing/appsignal_tracing.rb +2 -0
- data/lib/graphql/tracing/call_legacy_tracers.rb +66 -0
- data/lib/graphql/tracing/data_dog_trace.rb +2 -0
- data/lib/graphql/tracing/data_dog_tracing.rb +2 -0
- data/lib/graphql/tracing/legacy_hooks_trace.rb +1 -0
- data/lib/graphql/tracing/legacy_trace.rb +4 -61
- data/lib/graphql/tracing/new_relic_trace.rb +2 -0
- data/lib/graphql/tracing/new_relic_tracing.rb +2 -0
- data/lib/graphql/tracing/notifications_trace.rb +2 -2
- data/lib/graphql/tracing/notifications_tracing.rb +2 -0
- data/lib/graphql/tracing/null_trace.rb +9 -0
- data/lib/graphql/tracing/prometheus_trace/graphql_collector.rb +2 -0
- data/lib/graphql/tracing/prometheus_trace.rb +5 -0
- data/lib/graphql/tracing/prometheus_tracing.rb +2 -0
- data/lib/graphql/tracing/scout_trace.rb +2 -0
- data/lib/graphql/tracing/scout_tracing.rb +2 -0
- data/lib/graphql/tracing/sentry_trace.rb +2 -0
- data/lib/graphql/tracing/statsd_trace.rb +2 -0
- data/lib/graphql/tracing/statsd_tracing.rb +2 -0
- data/lib/graphql/tracing/trace.rb +3 -0
- data/lib/graphql/tracing.rb +28 -30
- data/lib/graphql/types/relay/connection_behaviors.rb +12 -2
- data/lib/graphql/types/relay/edge_behaviors.rb +11 -1
- data/lib/graphql/types/relay/page_info_behaviors.rb +4 -0
- data/lib/graphql/types.rb +18 -11
- data/lib/graphql/unauthorized_enum_value_error.rb +13 -0
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +53 -45
- metadata +33 -8
- data/lib/graphql/language/token.rb +0 -34
- data/lib/graphql/schema/invalid_type_error.rb +0 -7
@@ -18,21 +18,15 @@ module GraphQL
|
|
18
18
|
include_built_in_directives: false, include_built_in_scalars: false, always_include_schema: false
|
19
19
|
)
|
20
20
|
@schema = schema
|
21
|
+
@context = context
|
21
22
|
@always_include_schema = always_include_schema
|
22
23
|
@include_introspection_types = include_introspection_types
|
23
24
|
@include_built_in_scalars = include_built_in_scalars
|
24
25
|
@include_built_in_directives = include_built_in_directives
|
25
26
|
@include_one_of = false
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
@warden = @schema.warden_class.new(
|
31
|
-
schema: @schema,
|
32
|
-
context: schema_context,
|
33
|
-
)
|
34
|
-
|
35
|
-
schema_context.warden = @warden
|
28
|
+
dummy_query = @schema.query_class.new(@schema, "{ __typename }", validate: false, context: context)
|
29
|
+
@types = dummy_query.types # rubocop:disable Development/ContextIsPassedCop
|
36
30
|
end
|
37
31
|
|
38
32
|
def document
|
@@ -44,9 +38,9 @@ module GraphQL
|
|
44
38
|
def build_schema_node
|
45
39
|
if !schema_respects_root_name_conventions?(@schema)
|
46
40
|
GraphQL::Language::Nodes::SchemaDefinition.new(
|
47
|
-
query:
|
48
|
-
mutation:
|
49
|
-
subscription:
|
41
|
+
query: @types.query_root&.graphql_name,
|
42
|
+
mutation: @types.mutation_root&.graphql_name,
|
43
|
+
subscription: @types.subscription_root&.graphql_name,
|
50
44
|
directives: definition_directives(@schema, :schema_directives)
|
51
45
|
)
|
52
46
|
else
|
@@ -57,16 +51,17 @@ module GraphQL
|
|
57
51
|
end
|
58
52
|
|
59
53
|
def build_object_type_node(object_type)
|
60
|
-
ints =
|
61
|
-
if ints.
|
54
|
+
ints = @types.interfaces(object_type)
|
55
|
+
if !ints.empty?
|
62
56
|
ints.sort_by!(&:graphql_name)
|
63
57
|
ints.map! { |iface| build_type_name_node(iface) }
|
64
58
|
end
|
65
59
|
|
66
60
|
GraphQL::Language::Nodes::ObjectTypeDefinition.new(
|
67
61
|
name: object_type.graphql_name,
|
62
|
+
comment: object_type.comment,
|
68
63
|
interfaces: ints,
|
69
|
-
fields: build_field_nodes(
|
64
|
+
fields: build_field_nodes(@types.fields(object_type)),
|
70
65
|
description: object_type.description,
|
71
66
|
directives: directives(object_type),
|
72
67
|
)
|
@@ -75,7 +70,8 @@ module GraphQL
|
|
75
70
|
def build_field_node(field)
|
76
71
|
GraphQL::Language::Nodes::FieldDefinition.new(
|
77
72
|
name: field.graphql_name,
|
78
|
-
|
73
|
+
comment: field.comment,
|
74
|
+
arguments: build_argument_nodes(@types.arguments(field)),
|
79
75
|
type: build_type_name_node(field.type),
|
80
76
|
description: field.description,
|
81
77
|
directives: directives(field),
|
@@ -85,8 +81,9 @@ module GraphQL
|
|
85
81
|
def build_union_type_node(union_type)
|
86
82
|
GraphQL::Language::Nodes::UnionTypeDefinition.new(
|
87
83
|
name: union_type.graphql_name,
|
84
|
+
comment: union_type.comment,
|
88
85
|
description: union_type.description,
|
89
|
-
types:
|
86
|
+
types: @types.possible_types(union_type).sort_by(&:graphql_name).map { |type| build_type_name_node(type) },
|
90
87
|
directives: directives(union_type),
|
91
88
|
)
|
92
89
|
end
|
@@ -94,9 +91,10 @@ module GraphQL
|
|
94
91
|
def build_interface_type_node(interface_type)
|
95
92
|
GraphQL::Language::Nodes::InterfaceTypeDefinition.new(
|
96
93
|
name: interface_type.graphql_name,
|
97
|
-
|
94
|
+
comment: interface_type.comment,
|
95
|
+
interfaces: @types.interfaces(interface_type).sort_by(&:graphql_name).map { |type| build_type_name_node(type) },
|
98
96
|
description: interface_type.description,
|
99
|
-
fields: build_field_nodes(
|
97
|
+
fields: build_field_nodes(@types.fields(interface_type)),
|
100
98
|
directives: directives(interface_type),
|
101
99
|
)
|
102
100
|
end
|
@@ -104,7 +102,8 @@ module GraphQL
|
|
104
102
|
def build_enum_type_node(enum_type)
|
105
103
|
GraphQL::Language::Nodes::EnumTypeDefinition.new(
|
106
104
|
name: enum_type.graphql_name,
|
107
|
-
|
105
|
+
comment: enum_type.comment,
|
106
|
+
values: @types.enum_values(enum_type).sort_by(&:graphql_name).map do |enum_value|
|
108
107
|
build_enum_value_node(enum_value)
|
109
108
|
end,
|
110
109
|
description: enum_type.description,
|
@@ -115,6 +114,7 @@ module GraphQL
|
|
115
114
|
def build_enum_value_node(enum_value)
|
116
115
|
GraphQL::Language::Nodes::EnumValueDefinition.new(
|
117
116
|
name: enum_value.graphql_name,
|
117
|
+
comment: enum_value.comment,
|
118
118
|
description: enum_value.description,
|
119
119
|
directives: directives(enum_value),
|
120
120
|
)
|
@@ -123,6 +123,7 @@ module GraphQL
|
|
123
123
|
def build_scalar_type_node(scalar_type)
|
124
124
|
GraphQL::Language::Nodes::ScalarTypeDefinition.new(
|
125
125
|
name: scalar_type.graphql_name,
|
126
|
+
comment: scalar_type.comment,
|
126
127
|
description: scalar_type.description,
|
127
128
|
directives: directives(scalar_type),
|
128
129
|
)
|
@@ -137,6 +138,7 @@ module GraphQL
|
|
137
138
|
|
138
139
|
argument_node = GraphQL::Language::Nodes::InputValueDefinition.new(
|
139
140
|
name: argument.graphql_name,
|
141
|
+
comment: argument.comment,
|
140
142
|
description: argument.description,
|
141
143
|
type: build_type_name_node(argument.type),
|
142
144
|
default_value: default_value,
|
@@ -149,7 +151,8 @@ module GraphQL
|
|
149
151
|
def build_input_object_node(input_object)
|
150
152
|
GraphQL::Language::Nodes::InputObjectTypeDefinition.new(
|
151
153
|
name: input_object.graphql_name,
|
152
|
-
|
154
|
+
comment: input_object.comment,
|
155
|
+
fields: build_argument_nodes(@types.arguments(input_object)),
|
153
156
|
description: input_object.description,
|
154
157
|
directives: directives(input_object),
|
155
158
|
)
|
@@ -159,7 +162,7 @@ module GraphQL
|
|
159
162
|
GraphQL::Language::Nodes::DirectiveDefinition.new(
|
160
163
|
name: directive.graphql_name,
|
161
164
|
repeatable: directive.repeatable?,
|
162
|
-
arguments: build_argument_nodes(
|
165
|
+
arguments: build_argument_nodes(@types.arguments(directive)),
|
163
166
|
locations: build_directive_location_nodes(directive.locations),
|
164
167
|
description: directive.description,
|
165
168
|
)
|
@@ -204,7 +207,7 @@ module GraphQL
|
|
204
207
|
when "INPUT_OBJECT"
|
205
208
|
GraphQL::Language::Nodes::InputObject.new(
|
206
209
|
arguments: default_value.to_h.map do |arg_name, arg_value|
|
207
|
-
args = @
|
210
|
+
args = @types.arguments(type)
|
208
211
|
arg = args.find { |a| a.keyword.to_s == arg_name.to_s }
|
209
212
|
if arg.nil?
|
210
213
|
raise ArgumentError, "No argument definition on #{type.graphql_name} for argument: #{arg_name.inspect} (expected one of: #{args.map(&:keyword)})"
|
@@ -244,7 +247,7 @@ module GraphQL
|
|
244
247
|
end
|
245
248
|
|
246
249
|
def build_argument_nodes(arguments)
|
247
|
-
if arguments.
|
250
|
+
if !arguments.empty?
|
248
251
|
nodes = arguments.map { |arg| build_argument_node(arg) }
|
249
252
|
nodes.sort_by!(&:name)
|
250
253
|
nodes
|
@@ -260,13 +263,39 @@ module GraphQL
|
|
260
263
|
end
|
261
264
|
|
262
265
|
def build_definition_nodes
|
263
|
-
dirs_to_build =
|
266
|
+
dirs_to_build = @types.directives
|
264
267
|
if !include_built_in_directives
|
265
268
|
dirs_to_build = dirs_to_build.reject { |directive| directive.default_directive? }
|
266
269
|
end
|
267
270
|
definitions = build_directive_nodes(dirs_to_build)
|
271
|
+
all_types = @types.all_types
|
272
|
+
type_nodes = build_type_definition_nodes(all_types)
|
273
|
+
|
274
|
+
if !(ex_t = schema.extra_types).empty?
|
275
|
+
dummy_query = Class.new(GraphQL::Schema::Object) do
|
276
|
+
graphql_name "DummyQuery"
|
277
|
+
(all_types + ex_t).each_with_index do |type, idx|
|
278
|
+
if !type.kind.input_object? && !type.introspection?
|
279
|
+
field "f#{idx}", type
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
extra_types_schema = Class.new(GraphQL::Schema) do
|
285
|
+
query(dummy_query)
|
286
|
+
end
|
287
|
+
|
288
|
+
extra_types_types = GraphQL::Query.new(extra_types_schema, "{ __typename }", context: @context).types # rubocop:disable Development/ContextIsPassedCop
|
289
|
+
# Temporarily replace `@types` with something from this example schema.
|
290
|
+
# It'd be much nicer to pass this in, but that would be a big refactor :S
|
291
|
+
prev_types = @types
|
292
|
+
@types = extra_types_types
|
293
|
+
type_nodes += build_type_definition_nodes(ex_t)
|
294
|
+
@types = prev_types
|
295
|
+
end
|
296
|
+
|
297
|
+
type_nodes.sort_by!(&:name)
|
268
298
|
|
269
|
-
type_nodes = build_type_definition_nodes(warden.reachable_types + schema.extra_types)
|
270
299
|
if @include_one_of
|
271
300
|
# This may have been set to true when iterating over all types
|
272
301
|
definitions.concat(build_directive_nodes([GraphQL::Schema::Directive::OneOf]))
|
@@ -289,9 +318,7 @@ module GraphQL
|
|
289
318
|
types = types.reject { |type| type.kind.scalar? && type.default_scalar? }
|
290
319
|
end
|
291
320
|
|
292
|
-
types
|
293
|
-
.map { |type| build_type_definition_node(type) }
|
294
|
-
.sort_by(&:name)
|
321
|
+
types.map { |type| build_type_definition_node(type) }
|
295
322
|
end
|
296
323
|
|
297
324
|
def build_field_nodes(fields)
|
@@ -319,10 +346,11 @@ module GraphQL
|
|
319
346
|
end
|
320
347
|
|
321
348
|
def definition_directives(member, directives_method)
|
322
|
-
|
349
|
+
if !member.respond_to?(directives_method) || member.directives.empty?
|
323
350
|
EmptyObjects::EMPTY_ARRAY
|
324
351
|
else
|
325
|
-
member.public_send(directives_method).
|
352
|
+
visible_directives = member.public_send(directives_method).select { |dir| @types.directive_exists?(dir.graphql_name) }
|
353
|
+
visible_directives.map! do |dir|
|
326
354
|
args = []
|
327
355
|
dir.arguments.argument_values.each_value do |arg_value| # rubocop:disable Development/ContextIsPassedCop -- directive instance method
|
328
356
|
arg_defn = arg_value.definition
|
@@ -346,12 +374,12 @@ module GraphQL
|
|
346
374
|
arguments: args
|
347
375
|
)
|
348
376
|
end
|
349
|
-
end
|
350
377
|
|
351
|
-
|
378
|
+
visible_directives
|
379
|
+
end
|
352
380
|
end
|
353
381
|
|
354
|
-
attr_reader :schema, :
|
382
|
+
attr_reader :schema, :always_include_schema,
|
355
383
|
:include_introspection_types, :include_built_in_directives, :include_built_in_scalars
|
356
384
|
end
|
357
385
|
end
|
@@ -19,7 +19,7 @@ module GraphQL
|
|
19
19
|
@scanner.eos?
|
20
20
|
end
|
21
21
|
|
22
|
-
attr_reader :pos
|
22
|
+
attr_reader :pos, :tokens_count
|
23
23
|
|
24
24
|
def advance
|
25
25
|
@scanner.skip(IGNORE_REGEXP)
|
@@ -57,20 +57,26 @@ module GraphQL
|
|
57
57
|
@scanner.skip(IDENTIFIER_REGEXP)
|
58
58
|
:IDENTIFIER
|
59
59
|
when ByteFor::NUMBER
|
60
|
-
@scanner.skip(NUMERIC_REGEXP)
|
60
|
+
if len = @scanner.skip(NUMERIC_REGEXP)
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
62
|
+
if GraphQL.reject_numbers_followed_by_names
|
63
|
+
new_pos = @scanner.pos
|
64
|
+
peek_byte = @string.getbyte(new_pos)
|
65
|
+
next_first_byte = FIRST_BYTES[peek_byte]
|
66
|
+
if next_first_byte == ByteFor::NAME || next_first_byte == ByteFor::IDENTIFIER
|
67
|
+
number_part = token_value
|
68
|
+
name_part = @scanner.scan(IDENTIFIER_REGEXP)
|
69
|
+
raise_parse_error("Name after number is not allowed (in `#{number_part}#{name_part}`)")
|
70
|
+
end
|
70
71
|
end
|
72
|
+
# Check for a matched decimal:
|
73
|
+
@scanner[1] ? :FLOAT : :INT
|
74
|
+
else
|
75
|
+
# Attempt to find the part after the `-`
|
76
|
+
value = @scanner.scan(/-\s?[a-z0-9]*/i)
|
77
|
+
invalid_byte_for_number_error_message = "Expected type 'number', but it was malformed#{value.nil? ? "" : ": #{value.inspect}"}."
|
78
|
+
raise_parse_error(invalid_byte_for_number_error_message)
|
71
79
|
end
|
72
|
-
# Check for a matched decimal:
|
73
|
-
@scanner[1] ? :FLOAT : :INT
|
74
80
|
when ByteFor::ELLIPSIS
|
75
81
|
if @string.getbyte(@pos + 1) != 46 || @string.getbyte(@pos + 2) != 46
|
76
82
|
raise_parse_error("Expected `...`, actual: #{@string[@pos..@pos + 2].inspect}")
|
@@ -345,17 +351,14 @@ module GraphQL
|
|
345
351
|
def self.tokenize(string)
|
346
352
|
lexer = GraphQL::Language::Lexer.new(string)
|
347
353
|
tokens = []
|
348
|
-
prev_token = nil
|
349
354
|
while (token_name = lexer.advance)
|
350
355
|
new_token = [
|
351
356
|
token_name,
|
352
357
|
lexer.line_number,
|
353
358
|
lexer.column_number,
|
354
359
|
lexer.debug_token_value(token_name),
|
355
|
-
prev_token,
|
356
360
|
]
|
357
361
|
tokens << new_token
|
358
|
-
prev_token = new_token
|
359
362
|
end
|
360
363
|
tokens
|
361
364
|
end
|
@@ -34,11 +34,11 @@ module GraphQL
|
|
34
34
|
attr_reader :filename
|
35
35
|
|
36
36
|
def line
|
37
|
-
@line ||= @source
|
37
|
+
@line ||= @source&.line_at(@pos)
|
38
38
|
end
|
39
39
|
|
40
40
|
def col
|
41
|
-
@col ||= @source
|
41
|
+
@col ||= @source&.column_at(@pos)
|
42
42
|
end
|
43
43
|
|
44
44
|
def definition_line
|
@@ -270,15 +270,17 @@ module GraphQL
|
|
270
270
|
"col: nil",
|
271
271
|
"pos: nil",
|
272
272
|
"filename: nil",
|
273
|
-
"source: nil"
|
273
|
+
"source: nil"
|
274
274
|
]
|
275
275
|
|
276
|
+
IGNORED_MARSHALLING_KEYWORDS = [:comment]
|
277
|
+
|
276
278
|
def generate_initialize
|
277
279
|
return if method_defined?(:marshal_load, false) # checking for `:initialize` doesn't work right
|
278
280
|
|
279
281
|
scalar_method_names = @scalar_methods
|
280
282
|
# TODO: These probably should be scalar methods, but `types` returns an array
|
281
|
-
[:types, :description].each do |extra_method|
|
283
|
+
[:types, :description, :comment].each do |extra_method|
|
282
284
|
if method_defined?(extra_method)
|
283
285
|
scalar_method_names += [extra_method]
|
284
286
|
end
|
@@ -307,6 +309,12 @@ module GraphQL
|
|
307
309
|
keywords = scalar_method_names.map { |m| "#{m}: #{m}"} +
|
308
310
|
children_method_names.map { |m| "#{m}: #{m}" }
|
309
311
|
|
312
|
+
ignored_keywords = IGNORED_MARSHALLING_KEYWORDS.map do |keyword|
|
313
|
+
"#{keyword.to_s}: nil"
|
314
|
+
end
|
315
|
+
|
316
|
+
marshalling_method_names = all_method_names - IGNORED_MARSHALLING_KEYWORDS
|
317
|
+
|
310
318
|
module_eval <<-RUBY, __FILE__, __LINE__
|
311
319
|
def initialize(#{arguments.join(", ")})
|
312
320
|
@line = line
|
@@ -317,7 +325,7 @@ module GraphQL
|
|
317
325
|
#{assignments.join("\n")}
|
318
326
|
end
|
319
327
|
|
320
|
-
def self.from_a(filename, line, col, #{
|
328
|
+
def self.from_a(filename, line, col, #{marshalling_method_names.join(", ")}, #{ignored_keywords.join(", ")})
|
321
329
|
self.new(filename: filename, line: line, col: col, #{keywords.join(", ")})
|
322
330
|
end
|
323
331
|
|
@@ -325,12 +333,12 @@ module GraphQL
|
|
325
333
|
[
|
326
334
|
line, col, # use methods here to force them to be calculated
|
327
335
|
@filename,
|
328
|
-
#{
|
336
|
+
#{marshalling_method_names.map { |n| "@#{n}," }.join}
|
329
337
|
]
|
330
338
|
end
|
331
339
|
|
332
340
|
def marshal_load(values)
|
333
|
-
@line, @col, @filename #{
|
341
|
+
@line, @col, @filename #{marshalling_method_names.map { |n| ", @#{n}"}.join} = values
|
334
342
|
end
|
335
343
|
RUBY
|
336
344
|
end
|
@@ -635,7 +643,7 @@ module GraphQL
|
|
635
643
|
end
|
636
644
|
|
637
645
|
class ScalarTypeDefinition < AbstractNode
|
638
|
-
attr_reader :description
|
646
|
+
attr_reader :description, :comment
|
639
647
|
scalar_methods :name
|
640
648
|
children_methods({
|
641
649
|
directives: GraphQL::Language::Nodes::Directive,
|
@@ -652,7 +660,7 @@ module GraphQL
|
|
652
660
|
end
|
653
661
|
|
654
662
|
class InputValueDefinition < AbstractNode
|
655
|
-
attr_reader :description
|
663
|
+
attr_reader :description, :comment
|
656
664
|
scalar_methods :name, :type, :default_value
|
657
665
|
children_methods({
|
658
666
|
directives: GraphQL::Language::Nodes::Directive,
|
@@ -661,7 +669,7 @@ module GraphQL
|
|
661
669
|
end
|
662
670
|
|
663
671
|
class FieldDefinition < AbstractNode
|
664
|
-
attr_reader :description
|
672
|
+
attr_reader :description, :comment
|
665
673
|
scalar_methods :name, :type
|
666
674
|
children_methods({
|
667
675
|
arguments: GraphQL::Language::Nodes::InputValueDefinition,
|
@@ -681,7 +689,7 @@ module GraphQL
|
|
681
689
|
end
|
682
690
|
|
683
691
|
class ObjectTypeDefinition < AbstractNode
|
684
|
-
attr_reader :description
|
692
|
+
attr_reader :description, :comment
|
685
693
|
scalar_methods :name, :interfaces
|
686
694
|
children_methods({
|
687
695
|
directives: GraphQL::Language::Nodes::Directive,
|
@@ -700,7 +708,7 @@ module GraphQL
|
|
700
708
|
end
|
701
709
|
|
702
710
|
class InterfaceTypeDefinition < AbstractNode
|
703
|
-
attr_reader :description
|
711
|
+
attr_reader :description, :comment
|
704
712
|
scalar_methods :name
|
705
713
|
children_methods({
|
706
714
|
interfaces: GraphQL::Language::Nodes::TypeName,
|
@@ -721,7 +729,7 @@ module GraphQL
|
|
721
729
|
end
|
722
730
|
|
723
731
|
class UnionTypeDefinition < AbstractNode
|
724
|
-
attr_reader :description, :types
|
732
|
+
attr_reader :description, :comment, :types
|
725
733
|
scalar_methods :name
|
726
734
|
children_methods({
|
727
735
|
directives: GraphQL::Language::Nodes::Directive,
|
@@ -739,7 +747,7 @@ module GraphQL
|
|
739
747
|
end
|
740
748
|
|
741
749
|
class EnumValueDefinition < AbstractNode
|
742
|
-
attr_reader :description
|
750
|
+
attr_reader :description, :comment
|
743
751
|
scalar_methods :name
|
744
752
|
children_methods({
|
745
753
|
directives: GraphQL::Language::Nodes::Directive,
|
@@ -748,7 +756,7 @@ module GraphQL
|
|
748
756
|
end
|
749
757
|
|
750
758
|
class EnumTypeDefinition < AbstractNode
|
751
|
-
attr_reader :description
|
759
|
+
attr_reader :description, :comment
|
752
760
|
scalar_methods :name
|
753
761
|
children_methods({
|
754
762
|
directives: GraphQL::Language::Nodes::Directive,
|
@@ -767,7 +775,7 @@ module GraphQL
|
|
767
775
|
end
|
768
776
|
|
769
777
|
class InputObjectTypeDefinition < AbstractNode
|
770
|
-
attr_reader :description
|
778
|
+
attr_reader :description, :comment
|
771
779
|
scalar_methods :name
|
772
780
|
children_methods({
|
773
781
|
directives: GraphQL::Language::Nodes::Directive,
|
@@ -49,6 +49,11 @@ module GraphQL
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
+
def tokens_count
|
53
|
+
parse
|
54
|
+
@lexer.tokens_count
|
55
|
+
end
|
56
|
+
|
52
57
|
def line_at(pos)
|
53
58
|
line = lines_at.bsearch_index { |l| l >= pos }
|
54
59
|
if line.nil?
|
@@ -141,7 +146,12 @@ module GraphQL
|
|
141
146
|
parse_operation_type
|
142
147
|
end
|
143
148
|
|
144
|
-
op_name =
|
149
|
+
op_name = case token_name
|
150
|
+
when :LPAREN, :LCURLY, :DIR_SIGN
|
151
|
+
nil
|
152
|
+
else
|
153
|
+
parse_name
|
154
|
+
end
|
145
155
|
|
146
156
|
variable_definitions = if at?(:LPAREN)
|
147
157
|
expect_token(:LPAREN)
|
@@ -398,6 +408,9 @@ module GraphQL
|
|
398
408
|
def parse_union_members
|
399
409
|
if at?(:EQUALS)
|
400
410
|
expect_token :EQUALS
|
411
|
+
if at?(:PIPE)
|
412
|
+
advance_token
|
413
|
+
end
|
401
414
|
list = [parse_type_name]
|
402
415
|
while at?(:PIPE)
|
403
416
|
advance_token
|
@@ -92,7 +92,7 @@ module GraphQL
|
|
92
92
|
print_string("@")
|
93
93
|
print_string(directive.name)
|
94
94
|
|
95
|
-
if directive.arguments.
|
95
|
+
if !directive.arguments.empty?
|
96
96
|
print_string("(")
|
97
97
|
directive.arguments.each_with_index do |a, i|
|
98
98
|
print_argument(a)
|
@@ -117,7 +117,7 @@ module GraphQL
|
|
117
117
|
print_string(": ")
|
118
118
|
end
|
119
119
|
print_string(field.name)
|
120
|
-
if field.arguments.
|
120
|
+
if !field.arguments.empty?
|
121
121
|
print_string("(")
|
122
122
|
field.arguments.each_with_index do |a, i|
|
123
123
|
print_argument(a)
|
@@ -182,7 +182,7 @@ module GraphQL
|
|
182
182
|
print_string(operation_definition.name)
|
183
183
|
end
|
184
184
|
|
185
|
-
if operation_definition.variables.
|
185
|
+
if !operation_definition.variables.empty?
|
186
186
|
print_string("(")
|
187
187
|
operation_definition.variables.each_with_index do |v, i|
|
188
188
|
print_variable_definition(v)
|
@@ -230,7 +230,7 @@ module GraphQL
|
|
230
230
|
|
231
231
|
extension ? print_string("extend schema") : print_string("schema")
|
232
232
|
|
233
|
-
if schema.directives.
|
233
|
+
if !schema.directives.empty?
|
234
234
|
schema.directives.each do |dir|
|
235
235
|
print_string("\n ")
|
236
236
|
print_node(dir)
|
@@ -255,14 +255,14 @@ module GraphQL
|
|
255
255
|
|
256
256
|
|
257
257
|
def print_scalar_type_definition(scalar_type, extension: false)
|
258
|
-
extension ? print_string("extend ") :
|
258
|
+
extension ? print_string("extend ") : print_description_and_comment(scalar_type)
|
259
259
|
print_string("scalar ")
|
260
260
|
print_string(scalar_type.name)
|
261
261
|
print_directives(scalar_type.directives)
|
262
262
|
end
|
263
263
|
|
264
264
|
def print_object_type_definition(object_type, extension: false)
|
265
|
-
extension ? print_string("extend ") :
|
265
|
+
extension ? print_string("extend ") : print_description_and_comment(object_type)
|
266
266
|
print_string("type ")
|
267
267
|
print_string(object_type.name)
|
268
268
|
print_implements(object_type) unless object_type.interfaces.empty?
|
@@ -294,7 +294,7 @@ module GraphQL
|
|
294
294
|
end
|
295
295
|
|
296
296
|
def print_arguments(arguments, indent: "")
|
297
|
-
if arguments.all? { |arg| !arg.description }
|
297
|
+
if arguments.all? { |arg| !arg.description && !arg.comment }
|
298
298
|
print_string("(")
|
299
299
|
arguments.each_with_index do |arg, i|
|
300
300
|
print_input_value_definition(arg)
|
@@ -306,6 +306,7 @@ module GraphQL
|
|
306
306
|
|
307
307
|
print_string("(\n")
|
308
308
|
arguments.each_with_index do |arg, i|
|
309
|
+
print_comment(arg, indent: " " + indent, first_in_block: i == 0)
|
309
310
|
print_description(arg, indent: " " + indent, first_in_block: i == 0)
|
310
311
|
print_string(" ")
|
311
312
|
print_string(indent)
|
@@ -328,20 +329,20 @@ module GraphQL
|
|
328
329
|
end
|
329
330
|
|
330
331
|
def print_interface_type_definition(interface_type, extension: false)
|
331
|
-
extension ? print_string("extend ") :
|
332
|
+
extension ? print_string("extend ") : print_description_and_comment(interface_type)
|
332
333
|
print_string("interface ")
|
333
334
|
print_string(interface_type.name)
|
334
|
-
print_implements(interface_type) if interface_type.interfaces.
|
335
|
+
print_implements(interface_type) if !interface_type.interfaces.empty?
|
335
336
|
print_directives(interface_type.directives)
|
336
337
|
print_field_definitions(interface_type.fields)
|
337
338
|
end
|
338
339
|
|
339
340
|
def print_union_type_definition(union_type, extension: false)
|
340
|
-
extension ? print_string("extend ") :
|
341
|
+
extension ? print_string("extend ") : print_description_and_comment(union_type)
|
341
342
|
print_string("union ")
|
342
343
|
print_string(union_type.name)
|
343
344
|
print_directives(union_type.directives)
|
344
|
-
if union_type.types.
|
345
|
+
if !union_type.types.empty?
|
345
346
|
print_string(" = ")
|
346
347
|
i = 0
|
347
348
|
union_type.types.each do |t|
|
@@ -355,14 +356,15 @@ module GraphQL
|
|
355
356
|
end
|
356
357
|
|
357
358
|
def print_enum_type_definition(enum_type, extension: false)
|
358
|
-
extension ? print_string("extend ") :
|
359
|
+
extension ? print_string("extend ") : print_description_and_comment(enum_type)
|
359
360
|
print_string("enum ")
|
360
361
|
print_string(enum_type.name)
|
361
362
|
print_directives(enum_type.directives)
|
362
|
-
if enum_type.values.
|
363
|
+
if !enum_type.values.empty?
|
363
364
|
print_string(" {\n")
|
364
365
|
enum_type.values.each.with_index do |value, i|
|
365
366
|
print_description(value, indent: " ", first_in_block: i == 0)
|
367
|
+
print_comment(value, indent: " ", first_in_block: i == 0)
|
366
368
|
print_enum_value_definition(value)
|
367
369
|
end
|
368
370
|
print_string("}")
|
@@ -377,7 +379,7 @@ module GraphQL
|
|
377
379
|
end
|
378
380
|
|
379
381
|
def print_input_object_type_definition(input_object_type, extension: false)
|
380
|
-
extension ? print_string("extend ") :
|
382
|
+
extension ? print_string("extend ") : print_description_and_comment(input_object_type)
|
381
383
|
print_string("input ")
|
382
384
|
print_string(input_object_type.name)
|
383
385
|
print_directives(input_object_type.directives)
|
@@ -385,6 +387,7 @@ module GraphQL
|
|
385
387
|
print_string(" {\n")
|
386
388
|
input_object_type.fields.each.with_index do |field, i|
|
387
389
|
print_description(field, indent: " ", first_in_block: i == 0)
|
390
|
+
print_comment(field, indent: " ", first_in_block: i == 0)
|
388
391
|
print_string(" ")
|
389
392
|
print_input_value_definition(field)
|
390
393
|
print_string("\n")
|
@@ -398,7 +401,7 @@ module GraphQL
|
|
398
401
|
print_string("directive @")
|
399
402
|
print_string(directive.name)
|
400
403
|
|
401
|
-
if directive.arguments.
|
404
|
+
if !directive.arguments.empty?
|
402
405
|
print_arguments(directive.arguments)
|
403
406
|
end
|
404
407
|
|
@@ -424,6 +427,18 @@ module GraphQL
|
|
424
427
|
print_string(GraphQL::Language::BlockString.print(node.description, indent: indent))
|
425
428
|
end
|
426
429
|
|
430
|
+
def print_comment(node, indent: "", first_in_block: true)
|
431
|
+
return unless node.comment
|
432
|
+
|
433
|
+
print_string("\n") if indent != "" && !first_in_block
|
434
|
+
print_string(GraphQL::Language::Comment.print(node.comment, indent: indent))
|
435
|
+
end
|
436
|
+
|
437
|
+
def print_description_and_comment(node)
|
438
|
+
print_description(node)
|
439
|
+
print_comment(node)
|
440
|
+
end
|
441
|
+
|
427
442
|
def print_field_definitions(fields)
|
428
443
|
return if fields.empty?
|
429
444
|
|
@@ -431,6 +446,7 @@ module GraphQL
|
|
431
446
|
i = 0
|
432
447
|
fields.each do |field|
|
433
448
|
print_description(field, indent: " ", first_in_block: i == 0)
|
449
|
+
print_comment(field, indent: " ", first_in_block: i == 0)
|
434
450
|
print_string(" ")
|
435
451
|
print_field_definition(field)
|
436
452
|
print_string("\n")
|
@@ -113,7 +113,7 @@ module GraphQL
|
|
113
113
|
end
|
114
114
|
|
115
115
|
def print_field(field, indent: "")
|
116
|
-
@current_field = query.
|
116
|
+
@current_field = query.types.field(@current_type, field.name)
|
117
117
|
old_type = @current_type
|
118
118
|
@current_type = @current_field.type.unwrap
|
119
119
|
super
|