graphql 2.3.14 → 2.4.0
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/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.rb +1 -1
- data/lib/graphql/dataloader/async_dataloader.rb +3 -2
- data/lib/graphql/dataloader/source.rb +1 -1
- data/lib/graphql/dataloader.rb +31 -10
- data/lib/graphql/execution/interpreter/resolve.rb +10 -6
- data/lib/graphql/invalid_null_error.rb +1 -1
- data/lib/graphql/language/comment.rb +18 -0
- data/lib/graphql/language/document_from_schema_definition.rb +38 -4
- data/lib/graphql/language/lexer.rb +15 -12
- data/lib/graphql/language/nodes.rb +22 -14
- data/lib/graphql/language/parser.rb +5 -0
- data/lib/graphql/language/printer.rb +23 -7
- data/lib/graphql/language.rb +6 -5
- data/lib/graphql/query/null_context.rb +1 -1
- data/lib/graphql/query.rb +49 -16
- data/lib/graphql/rubocop/graphql/field_type_in_block.rb +23 -8
- data/lib/graphql/schema/always_visible.rb +6 -3
- data/lib/graphql/schema/argument.rb +14 -1
- data/lib/graphql/schema/build_from_definition.rb +1 -0
- data/lib/graphql/schema/enum.rb +3 -0
- data/lib/graphql/schema/enum_value.rb +9 -1
- data/lib/graphql/schema/field.rb +35 -14
- data/lib/graphql/schema/input_object.rb +20 -7
- data/lib/graphql/schema/interface.rb +1 -0
- data/lib/graphql/schema/member/base_dsl_methods.rb +15 -0
- data/lib/graphql/schema/member/has_arguments.rb +2 -2
- data/lib/graphql/schema/member/has_fields.rb +2 -2
- data/lib/graphql/schema/printer.rb +1 -0
- data/lib/graphql/schema/resolver.rb +3 -4
- data/lib/graphql/schema/validator/required_validator.rb +28 -4
- data/lib/graphql/schema/visibility/migration.rb +186 -0
- data/lib/graphql/schema/visibility/profile.rb +523 -0
- data/lib/graphql/schema/visibility.rb +75 -0
- data/lib/graphql/schema/warden.rb +77 -15
- data/lib/graphql/schema.rb +203 -61
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +2 -1
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +2 -1
- 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 +2 -1
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +1 -0
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +11 -1
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +10 -1
- data/lib/graphql/static_validation/validation_context.rb +15 -0
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +2 -1
- data/lib/graphql/subscriptions.rb +3 -1
- data/lib/graphql/testing/helpers.rb +2 -1
- data/lib/graphql/tracing/notifications_trace.rb +2 -2
- data/lib/graphql/version.rb +1 -1
- metadata +11 -9
- data/lib/graphql/schema/subset.rb +0 -509
- data/lib/graphql/schema/types_migration.rb +0 -187
data/lib/graphql/language.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require "graphql/language/block_string"
|
3
|
+
require "graphql/language/comment"
|
3
4
|
require "graphql/language/printer"
|
4
5
|
require "graphql/language/sanitized_printer"
|
5
6
|
require "graphql/language/document_from_schema_definition"
|
@@ -48,19 +49,19 @@ module GraphQL
|
|
48
49
|
inside_single_quoted_string = false
|
49
50
|
new_query_str = nil
|
50
51
|
while !scanner.eos?
|
51
|
-
if
|
52
|
-
new_query_str <<
|
53
|
-
elsif scanner.
|
52
|
+
if scanner.skip(/(?:\\"|[^"\n\r]|""")+/m)
|
53
|
+
new_query_str && (new_query_str << scanner.matched)
|
54
|
+
elsif scanner.skip('"')
|
54
55
|
new_query_str && (new_query_str << '"')
|
55
56
|
inside_single_quoted_string = !inside_single_quoted_string
|
56
|
-
elsif scanner.
|
57
|
+
elsif scanner.skip("\n")
|
57
58
|
if inside_single_quoted_string
|
58
59
|
new_query_str ||= query_str[0, scanner.pos - 1]
|
59
60
|
new_query_str << '\\n'
|
60
61
|
else
|
61
62
|
new_query_str && (new_query_str << "\n")
|
62
63
|
end
|
63
|
-
elsif scanner.
|
64
|
+
elsif scanner.skip("\r")
|
64
65
|
if inside_single_quoted_string
|
65
66
|
new_query_str ||= query_str[0, scanner.pos - 1]
|
66
67
|
new_query_str << '\\r'
|
data/lib/graphql/query.rb
CHANGED
@@ -95,21 +95,24 @@ module GraphQL
|
|
95
95
|
# @param root_value [Object] the object used to resolve fields on the root type
|
96
96
|
# @param max_depth [Numeric] the maximum number of nested selections allowed for this query (falls back to schema-level value)
|
97
97
|
# @param max_complexity [Numeric] the maximum field complexity for this query (falls back to schema-level value)
|
98
|
-
|
98
|
+
# @param visibility_profile [Symbol]
|
99
|
+
def initialize(schema, query_string = nil, query: nil, document: nil, context: nil, variables: nil, validate: true, static_validator: nil, visibility_profile: nil, subscription_topic: nil, operation_name: nil, root_value: nil, max_depth: schema.max_depth, max_complexity: schema.max_complexity, warden: nil, use_visibility_profile: nil)
|
99
100
|
# Even if `variables: nil` is passed, use an empty hash for simpler logic
|
100
101
|
variables ||= {}
|
101
102
|
@schema = schema
|
102
103
|
@context = schema.context_class.new(query: self, values: context)
|
103
104
|
|
104
|
-
if
|
105
|
-
|
105
|
+
if use_visibility_profile.nil?
|
106
|
+
use_visibility_profile = warden ? false : schema.use_visibility_profile?
|
106
107
|
end
|
107
108
|
|
108
|
-
|
109
|
-
|
109
|
+
@visibility_profile = visibility_profile
|
110
|
+
|
111
|
+
if use_visibility_profile
|
112
|
+
@visibility_profile = @schema.visibility.profile_for(@context, visibility_profile)
|
110
113
|
@warden = Schema::Warden::NullWarden.new(context: @context, schema: @schema)
|
111
114
|
else
|
112
|
-
@
|
115
|
+
@visibility_profile = nil
|
113
116
|
@warden = warden
|
114
117
|
end
|
115
118
|
|
@@ -187,6 +190,9 @@ module GraphQL
|
|
187
190
|
@query_string ||= (document ? document.to_query_string : nil)
|
188
191
|
end
|
189
192
|
|
193
|
+
# @return [Symbol, nil]
|
194
|
+
attr_reader :visibility_profile
|
195
|
+
|
190
196
|
attr_accessor :multiplex
|
191
197
|
|
192
198
|
# @return [GraphQL::Tracing::Trace]
|
@@ -203,15 +209,19 @@ module GraphQL
|
|
203
209
|
def lookahead
|
204
210
|
@lookahead ||= begin
|
205
211
|
ast_node = selected_operation
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
212
|
+
if ast_node.nil?
|
213
|
+
GraphQL::Execution::Lookahead::NULL_LOOKAHEAD
|
214
|
+
else
|
215
|
+
root_type = case ast_node.operation_type
|
216
|
+
when nil, "query"
|
217
|
+
types.query_root # rubocop:disable Development/ContextIsPassedCop
|
218
|
+
when "mutation"
|
219
|
+
types.mutation_root # rubocop:disable Development/ContextIsPassedCop
|
220
|
+
when "subscription"
|
221
|
+
types.subscription_root # rubocop:disable Development/ContextIsPassedCop
|
222
|
+
end
|
223
|
+
GraphQL::Execution::Lookahead.new(query: self, root_type: root_type, ast_nodes: [ast_node])
|
213
224
|
end
|
214
|
-
GraphQL::Execution::Lookahead.new(query: self, root_type: root_type, ast_nodes: [ast_node])
|
215
225
|
end
|
216
226
|
end
|
217
227
|
|
@@ -343,10 +353,33 @@ module GraphQL
|
|
343
353
|
with_prepared_ast { @warden }
|
344
354
|
end
|
345
355
|
|
346
|
-
|
356
|
+
def get_type(type_name)
|
357
|
+
types.type(type_name) # rubocop:disable Development/ContextIsPassedCop
|
358
|
+
end
|
359
|
+
|
360
|
+
def get_field(owner, field_name)
|
361
|
+
types.field(owner, field_name) # rubocop:disable Development/ContextIsPassedCop
|
362
|
+
end
|
363
|
+
|
364
|
+
def possible_types(type)
|
365
|
+
types.possible_types(type) # rubocop:disable Development/ContextIsPassedCop
|
366
|
+
end
|
367
|
+
|
368
|
+
def root_type_for_operation(op_type)
|
369
|
+
case op_type
|
370
|
+
when "query"
|
371
|
+
types.query_root # rubocop:disable Development/ContextIsPassedCop
|
372
|
+
when "mutation"
|
373
|
+
types.mutation_root # rubocop:disable Development/ContextIsPassedCop
|
374
|
+
when "subscription"
|
375
|
+
types.subscription_root # rubocop:disable Development/ContextIsPassedCop
|
376
|
+
else
|
377
|
+
raise ArgumentError, "unexpected root type name: #{op_type.inspect}; expected 'query', 'mutation', or 'subscription'"
|
378
|
+
end
|
379
|
+
end
|
347
380
|
|
348
381
|
def types
|
349
|
-
@
|
382
|
+
@visibility_profile || warden.visibility_profile
|
350
383
|
end
|
351
384
|
|
352
385
|
# @param abstract_type [GraphQL::UnionType, GraphQL::InterfaceType]
|
@@ -29,7 +29,7 @@ module GraphQL
|
|
29
29
|
def_node_matcher :field_config_with_inline_type_and_block, <<-Pattern
|
30
30
|
(
|
31
31
|
block
|
32
|
-
(send {nil? _} :field sym ${const array}) ...
|
32
|
+
(send {nil? _} :field sym ${const array} ...) ...
|
33
33
|
(args)
|
34
34
|
_
|
35
35
|
|
@@ -37,8 +37,8 @@ module GraphQL
|
|
37
37
|
Pattern
|
38
38
|
|
39
39
|
def on_block(node)
|
40
|
+
ignore_node(node)
|
40
41
|
field_config_with_inline_type_and_block(node) do |type_const|
|
41
|
-
ignore_node(type_const)
|
42
42
|
type_const_str = get_type_argument_str(node, type_const)
|
43
43
|
if ignore_inline_type_str?(type_const_str)
|
44
44
|
# Do nothing ...
|
@@ -54,8 +54,8 @@ module GraphQL
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def on_send(node)
|
57
|
+
return if part_of_ignored_node?(node)
|
57
58
|
field_config_with_inline_type(node) do |type_const|
|
58
|
-
return if ignored_node?(type_const)
|
59
59
|
type_const_str = get_type_argument_str(node, type_const)
|
60
60
|
if ignore_inline_type_str?(type_const_str)
|
61
61
|
# Do nothing -- not loading from another file
|
@@ -74,7 +74,13 @@ module GraphQL
|
|
74
74
|
private
|
75
75
|
|
76
76
|
def ignore_inline_type_str?(type_str)
|
77
|
-
BUILT_IN_SCALAR_NAMES.include?(type_str)
|
77
|
+
if BUILT_IN_SCALAR_NAMES.include?(type_str)
|
78
|
+
true
|
79
|
+
elsif (inner_type_str = type_str.sub(/\[([A-Za-z]+)(, null: (true|false))?\]/, '\1')) && BUILT_IN_SCALAR_NAMES.include?(inner_type_str)
|
80
|
+
true
|
81
|
+
else
|
82
|
+
false
|
83
|
+
end
|
78
84
|
end
|
79
85
|
|
80
86
|
def get_type_argument_str(send_node, type_const)
|
@@ -110,11 +116,20 @@ module GraphQL
|
|
110
116
|
end
|
111
117
|
|
112
118
|
def determine_field_indent(send_node)
|
113
|
-
|
114
|
-
|
115
|
-
|
119
|
+
type_defn_node = send_node
|
120
|
+
|
121
|
+
while (type_defn_node && !(type_defn_node.class_definition? || type_defn_node.module_definition?))
|
122
|
+
type_defn_node = type_defn_node.parent
|
123
|
+
end
|
124
|
+
|
125
|
+
if type_defn_node.nil?
|
126
|
+
raise "Invariant: Something went wrong in GraphQL-Ruby, couldn't find surrounding class definition for field (#{send_node}).\n\nPlease report this error on GitHub."
|
127
|
+
end
|
128
|
+
|
129
|
+
type_defn_source = type_defn_node.source
|
130
|
+
indent_test_idx = send_node.location.expression.begin_pos - type_defn_node.source_range.begin_pos - 1
|
116
131
|
field_indent = "".dup
|
117
|
-
while
|
132
|
+
while type_defn_source[indent_test_idx] == " "
|
118
133
|
field_indent << " "
|
119
134
|
indent_test_idx -= 1
|
120
135
|
if indent_test_idx == 0
|
@@ -1,10 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module GraphQL
|
3
3
|
class Schema
|
4
|
-
|
4
|
+
module AlwaysVisible
|
5
5
|
def self.use(schema, **opts)
|
6
|
-
schema.
|
7
|
-
|
6
|
+
schema.extend(self)
|
7
|
+
end
|
8
|
+
|
9
|
+
def visible?(_member, _context)
|
10
|
+
true
|
8
11
|
end
|
9
12
|
end
|
10
13
|
end
|
@@ -50,11 +50,12 @@ module GraphQL
|
|
50
50
|
# @param deprecation_reason [String]
|
51
51
|
# @param validates [Hash, nil] Options for building validators, if any should be applied
|
52
52
|
# @param replace_null_with_default [Boolean] if `true`, incoming values of `null` will be replaced with the configured `default_value`
|
53
|
-
def initialize(arg_name = nil, type_expr = nil, desc = nil, required: true, type: nil, name: nil, loads: nil, description: nil, ast_node: nil, default_value: NOT_CONFIGURED, as: nil, from_resolver: false, camelize: true, prepare: nil, owner:, validates: nil, directives: nil, deprecation_reason: nil, replace_null_with_default: false, &definition_block)
|
53
|
+
def initialize(arg_name = nil, type_expr = nil, desc = nil, required: true, type: nil, name: nil, loads: nil, description: nil, comment: nil, ast_node: nil, default_value: NOT_CONFIGURED, as: nil, from_resolver: false, camelize: true, prepare: nil, owner:, validates: nil, directives: nil, deprecation_reason: nil, replace_null_with_default: false, &definition_block)
|
54
54
|
arg_name ||= name
|
55
55
|
@name = -(camelize ? Member::BuildType.camelize(arg_name.to_s) : arg_name.to_s)
|
56
56
|
@type_expr = type_expr || type
|
57
57
|
@description = desc || description
|
58
|
+
@comment = comment
|
58
59
|
@null = required != true
|
59
60
|
@default_value = default_value
|
60
61
|
if replace_null_with_default
|
@@ -129,6 +130,17 @@ module GraphQL
|
|
129
130
|
end
|
130
131
|
end
|
131
132
|
|
133
|
+
attr_writer :comment
|
134
|
+
|
135
|
+
# @return [String] Comment for this argument
|
136
|
+
def comment(text = nil)
|
137
|
+
if text
|
138
|
+
@comment = text
|
139
|
+
else
|
140
|
+
@comment
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
132
144
|
# @return [String] Deprecation reason for this argument
|
133
145
|
def deprecation_reason(text = nil)
|
134
146
|
if text
|
@@ -352,6 +364,7 @@ module GraphQL
|
|
352
364
|
|
353
365
|
# @api private
|
354
366
|
def validate_default_value
|
367
|
+
return unless default_value?
|
355
368
|
coerced_default_value = begin
|
356
369
|
# This is weird, but we should accept single-item default values for list-type arguments.
|
357
370
|
# If we used `coerce_isolated_input` below, it would do this for us, but it's not really
|
data/lib/graphql/schema/enum.rb
CHANGED
@@ -59,6 +59,7 @@ module GraphQL
|
|
59
59
|
# Define a value for this enum
|
60
60
|
# @option kwargs [String, Symbol] :graphql_name the GraphQL value for this, usually `SCREAMING_CASE`
|
61
61
|
# @option kwargs [String] :description, the GraphQL description for this value, present in documentation
|
62
|
+
# @option kwargs [String] :comment, the GraphQL comment for this value, present in documentation
|
62
63
|
# @option kwargs [::Object] :value the translated Ruby value for this object (defaults to `graphql_name`)
|
63
64
|
# @option kwargs [String] :deprecation_reason if this object is deprecated, include a message here
|
64
65
|
# @return [void]
|
@@ -152,6 +153,8 @@ module GraphQL
|
|
152
153
|
else
|
153
154
|
nil
|
154
155
|
end
|
156
|
+
# rescue MissingValuesError
|
157
|
+
# nil
|
155
158
|
end
|
156
159
|
|
157
160
|
# Called by the runtime when a field returns a value to give back to the client.
|
@@ -30,10 +30,11 @@ module GraphQL
|
|
30
30
|
# @return [Class] The enum type that owns this value
|
31
31
|
attr_reader :owner
|
32
32
|
|
33
|
-
def initialize(graphql_name, desc = nil, owner:, ast_node: nil, directives: nil, description: nil, value: NOT_CONFIGURED, deprecation_reason: nil, &block)
|
33
|
+
def initialize(graphql_name, desc = nil, owner:, ast_node: nil, directives: nil, description: nil, comment: nil, value: NOT_CONFIGURED, deprecation_reason: nil, &block)
|
34
34
|
@graphql_name = graphql_name.to_s
|
35
35
|
GraphQL::NameValidator.validate!(@graphql_name)
|
36
36
|
@description = desc || description
|
37
|
+
@comment = comment
|
37
38
|
@value = value == NOT_CONFIGURED ? @graphql_name : value
|
38
39
|
if deprecation_reason
|
39
40
|
self.deprecation_reason = deprecation_reason
|
@@ -58,6 +59,13 @@ module GraphQL
|
|
58
59
|
@description
|
59
60
|
end
|
60
61
|
|
62
|
+
def comment(new_comment = nil)
|
63
|
+
if new_comment
|
64
|
+
@comment = new_comment
|
65
|
+
end
|
66
|
+
@comment
|
67
|
+
end
|
68
|
+
|
61
69
|
def value(new_val = nil)
|
62
70
|
unless new_val.nil?
|
63
71
|
@value = new_val
|
data/lib/graphql/schema/field.rb
CHANGED
@@ -106,7 +106,7 @@ module GraphQL
|
|
106
106
|
# @param subscription [Class] A {GraphQL::Schema::Subscription} class to use for field configuration
|
107
107
|
# @return [GraphQL::Schema:Field] an instance of `self`
|
108
108
|
# @see {.initialize} for other options
|
109
|
-
def self.from_options(name = nil, type = nil, desc = nil, resolver: nil, mutation: nil, subscription: nil,**kwargs, &block)
|
109
|
+
def self.from_options(name = nil, type = nil, desc = nil, comment: nil, resolver: nil, mutation: nil, subscription: nil,**kwargs, &block)
|
110
110
|
if (resolver_class = resolver || mutation || subscription)
|
111
111
|
# Add a reference to that parent class
|
112
112
|
kwargs[:resolver_class] = resolver_class
|
@@ -116,6 +116,10 @@ module GraphQL
|
|
116
116
|
kwargs[:name] = name
|
117
117
|
end
|
118
118
|
|
119
|
+
if comment
|
120
|
+
kwargs[:comment] = comment
|
121
|
+
end
|
122
|
+
|
119
123
|
if !type.nil?
|
120
124
|
if desc
|
121
125
|
if kwargs[:description]
|
@@ -212,6 +216,7 @@ module GraphQL
|
|
212
216
|
# @param owner [Class] The type that this field belongs to
|
213
217
|
# @param null [Boolean] (defaults to `true`) `true` if this field may return `null`, `false` if it is never `null`
|
214
218
|
# @param description [String] Field description
|
219
|
+
# @param comment [String] Field comment
|
215
220
|
# @param deprecation_reason [String] If present, the field is marked "deprecated" with this message
|
216
221
|
# @param method [Symbol] The method to call on the underlying object to resolve this field (defaults to `name`)
|
217
222
|
# @param hash_key [String, Symbol] The hash key to lookup on the underlying object (if its a Hash) to resolve this field (defaults to `name` or `name.to_s`)
|
@@ -236,7 +241,7 @@ module GraphQL
|
|
236
241
|
# @param method_conflict_warning [Boolean] If false, skip the warning if this field's method conflicts with a built-in method
|
237
242
|
# @param validates [Array<Hash>] Configurations for validating this field
|
238
243
|
# @param fallback_value [Object] A fallback value if the method is not defined
|
239
|
-
def initialize(type: nil, name: nil, owner: nil, null: nil, description: NOT_CONFIGURED, deprecation_reason: nil, method: nil, hash_key: nil, dig: nil, resolver_method: nil, connection: nil, max_page_size: NOT_CONFIGURED, default_page_size: NOT_CONFIGURED, scope: nil, introspection: false, camelize: true, trace: nil, complexity: nil, ast_node: nil, extras: EMPTY_ARRAY, extensions: EMPTY_ARRAY, connection_extension: self.class.connection_extension, resolver_class: nil, subscription_scope: nil, relay_node_field: false, relay_nodes_field: false, method_conflict_warning: true, broadcastable: NOT_CONFIGURED, arguments: EMPTY_HASH, directives: EMPTY_HASH, validates: EMPTY_ARRAY, fallback_value: NOT_CONFIGURED, dynamic_introspection: false, &definition_block)
|
244
|
+
def initialize(type: nil, name: nil, owner: nil, null: nil, description: NOT_CONFIGURED, comment: NOT_CONFIGURED, deprecation_reason: nil, method: nil, hash_key: nil, dig: nil, resolver_method: nil, connection: nil, max_page_size: NOT_CONFIGURED, default_page_size: NOT_CONFIGURED, scope: nil, introspection: false, camelize: true, trace: nil, complexity: nil, ast_node: nil, extras: EMPTY_ARRAY, extensions: EMPTY_ARRAY, connection_extension: self.class.connection_extension, resolver_class: nil, subscription_scope: nil, relay_node_field: false, relay_nodes_field: false, method_conflict_warning: true, broadcastable: NOT_CONFIGURED, arguments: EMPTY_HASH, directives: EMPTY_HASH, validates: EMPTY_ARRAY, fallback_value: NOT_CONFIGURED, dynamic_introspection: false, &definition_block)
|
240
245
|
if name.nil?
|
241
246
|
raise ArgumentError, "missing first `name` argument or keyword `name:`"
|
242
247
|
end
|
@@ -252,6 +257,7 @@ module GraphQL
|
|
252
257
|
@name = -(camelize ? Member::BuildType.camelize(name_s) : name_s)
|
253
258
|
|
254
259
|
@description = description
|
260
|
+
@comment = comment
|
255
261
|
@type = @owner_type = @own_validators = @own_directives = @own_arguments = @arguments_statically_coercible = nil # these will be prepared later if necessary
|
256
262
|
|
257
263
|
self.deprecation_reason = deprecation_reason
|
@@ -307,7 +313,7 @@ module GraphQL
|
|
307
313
|
@ast_node = ast_node
|
308
314
|
@method_conflict_warning = method_conflict_warning
|
309
315
|
@fallback_value = fallback_value
|
310
|
-
@definition_block =
|
316
|
+
@definition_block = definition_block
|
311
317
|
|
312
318
|
arguments.each do |name, arg|
|
313
319
|
case arg
|
@@ -326,14 +332,15 @@ module GraphQL
|
|
326
332
|
@subscription_scope = subscription_scope
|
327
333
|
|
328
334
|
@extensions = EMPTY_ARRAY
|
335
|
+
@call_after_define = false
|
329
336
|
set_pagination_extensions(connection_extension: connection_extension)
|
330
337
|
# Do this last so we have as much context as possible when initializing them:
|
331
338
|
if extensions.any?
|
332
|
-
self.extensions(extensions
|
339
|
+
self.extensions(extensions)
|
333
340
|
end
|
334
341
|
|
335
342
|
if resolver_class && resolver_class.extensions.any?
|
336
|
-
self.extensions(resolver_class.extensions
|
343
|
+
self.extensions(resolver_class.extensions)
|
337
344
|
end
|
338
345
|
|
339
346
|
if directives.any?
|
@@ -346,10 +353,9 @@ module GraphQL
|
|
346
353
|
self.validates(validates)
|
347
354
|
end
|
348
355
|
|
349
|
-
if
|
350
|
-
@definition_block = definition_block
|
351
|
-
else
|
356
|
+
if @definition_block.nil?
|
352
357
|
self.extensions.each(&:after_define_apply)
|
358
|
+
@call_after_define = true
|
353
359
|
end
|
354
360
|
end
|
355
361
|
|
@@ -366,6 +372,7 @@ module GraphQL
|
|
366
372
|
instance_eval(&@definition_block)
|
367
373
|
end
|
368
374
|
self.extensions.each(&:after_define_apply)
|
375
|
+
@call_after_define = true
|
369
376
|
@definition_block = nil
|
370
377
|
end
|
371
378
|
self
|
@@ -400,6 +407,20 @@ module GraphQL
|
|
400
407
|
end
|
401
408
|
end
|
402
409
|
|
410
|
+
# @param text [String]
|
411
|
+
# @return [String, nil]
|
412
|
+
def comment(text = nil)
|
413
|
+
if text
|
414
|
+
@comment = text
|
415
|
+
elsif !NOT_CONFIGURED.equal?(@comment)
|
416
|
+
@comment
|
417
|
+
elsif @resolver_class
|
418
|
+
@resolver_class.comment
|
419
|
+
else
|
420
|
+
nil
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
403
424
|
# Read extension instances from this field,
|
404
425
|
# or add new classes/options to be initialized on this field.
|
405
426
|
# Extensions are executed in the order they are added.
|
@@ -415,14 +436,14 @@ module GraphQL
|
|
415
436
|
#
|
416
437
|
# @param extensions [Array<Class, Hash<Class => Hash>>] Add extensions to this field. For hash elements, only the first key/value is used.
|
417
438
|
# @return [Array<GraphQL::Schema::FieldExtension>] extensions to apply to this field
|
418
|
-
def extensions(new_extensions = nil
|
439
|
+
def extensions(new_extensions = nil)
|
419
440
|
if new_extensions
|
420
441
|
new_extensions.each do |extension_config|
|
421
442
|
if extension_config.is_a?(Hash)
|
422
443
|
extension_class, options = *extension_config.to_a[0]
|
423
|
-
self.extension(extension_class,
|
444
|
+
self.extension(extension_class, **options)
|
424
445
|
else
|
425
|
-
self.extension(extension_config
|
446
|
+
self.extension(extension_config)
|
426
447
|
end
|
427
448
|
end
|
428
449
|
end
|
@@ -440,12 +461,12 @@ module GraphQL
|
|
440
461
|
# @param extension_class [Class] subclass of {Schema::FieldExtension}
|
441
462
|
# @param options [Hash] if provided, given as `options:` when initializing `extension`.
|
442
463
|
# @return [void]
|
443
|
-
def extension(extension_class,
|
464
|
+
def extension(extension_class, **options)
|
444
465
|
extension_inst = extension_class.new(field: self, options: options)
|
445
466
|
if @extensions.frozen?
|
446
467
|
@extensions = @extensions.dup
|
447
468
|
end
|
448
|
-
if call_after_define
|
469
|
+
if @call_after_define
|
449
470
|
extension_inst.after_define_apply
|
450
471
|
end
|
451
472
|
@extensions << extension_inst
|
@@ -490,7 +511,7 @@ module GraphQL
|
|
490
511
|
if arguments[:last] && (max_possible_page_size.nil? || arguments[:last] > max_possible_page_size)
|
491
512
|
max_possible_page_size = arguments[:last]
|
492
513
|
end
|
493
|
-
elsif arguments.is_a?(GraphQL::UnauthorizedError)
|
514
|
+
elsif arguments.is_a?(GraphQL::ExecutionError) || arguments.is_a?(GraphQL::UnauthorizedError)
|
494
515
|
raise arguments
|
495
516
|
end
|
496
517
|
|
@@ -133,12 +133,14 @@ module GraphQL
|
|
133
133
|
end
|
134
134
|
# Add a method access
|
135
135
|
method_name = argument_defn.keyword
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
136
|
+
suppress_redefinition_warning do
|
137
|
+
class_eval <<-RUBY, __FILE__, __LINE__
|
138
|
+
def #{method_name}
|
139
|
+
self[#{method_name.inspect}]
|
140
|
+
end
|
141
|
+
alias_method :#{method_name}, :#{method_name}
|
142
|
+
RUBY
|
143
|
+
end
|
142
144
|
argument_defn
|
143
145
|
end
|
144
146
|
|
@@ -163,7 +165,7 @@ module GraphQL
|
|
163
165
|
|
164
166
|
# Inject missing required arguments
|
165
167
|
missing_required_inputs = ctx.types.arguments(self).reduce({}) do |m, (argument)|
|
166
|
-
if !input.key?(argument.graphql_name) && argument.type.non_null? && types.argument(self, argument.graphql_name)
|
168
|
+
if !input.key?(argument.graphql_name) && argument.type.non_null? && !argument.default_value? && types.argument(self, argument.graphql_name)
|
167
169
|
m[argument.graphql_name] = nil
|
168
170
|
end
|
169
171
|
|
@@ -243,6 +245,17 @@ module GraphQL
|
|
243
245
|
|
244
246
|
result
|
245
247
|
end
|
248
|
+
|
249
|
+
private
|
250
|
+
|
251
|
+
# Suppress redefinition warning for objectId arguments
|
252
|
+
def suppress_redefinition_warning
|
253
|
+
verbose = $VERBOSE
|
254
|
+
$VERBOSE = nil
|
255
|
+
yield
|
256
|
+
ensure
|
257
|
+
$VERBOSE = verbose
|
258
|
+
end
|
246
259
|
end
|
247
260
|
|
248
261
|
private
|
@@ -63,6 +63,7 @@ module GraphQL
|
|
63
63
|
|
64
64
|
child_class.introspection(introspection)
|
65
65
|
child_class.description(description)
|
66
|
+
child_class.comment(nil)
|
66
67
|
# If interfaces are mixed into each other, only define this class once
|
67
68
|
if !child_class.const_defined?(:UnresolvedTypeError, false)
|
68
69
|
add_unresolved_type_error(child_class)
|
@@ -50,12 +50,27 @@ module GraphQL
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
+
# Call this method to provide a new comment; OR
|
54
|
+
# call it without an argument to get the comment
|
55
|
+
# @param new_comment [String]
|
56
|
+
# @return [String, nil]
|
57
|
+
def comment(new_comment = NOT_CONFIGURED)
|
58
|
+
if !NOT_CONFIGURED.equal?(new_comment)
|
59
|
+
@comment = new_comment
|
60
|
+
elsif defined?(@comment)
|
61
|
+
@comment
|
62
|
+
else
|
63
|
+
nil
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
53
67
|
# This pushes some configurations _down_ the inheritance tree,
|
54
68
|
# in order to prevent repetitive lookups at runtime.
|
55
69
|
module ConfigurationExtension
|
56
70
|
def inherited(child_class)
|
57
71
|
child_class.introspection(introspection)
|
58
72
|
child_class.description(description)
|
73
|
+
child_class.comment(nil)
|
59
74
|
child_class.default_graphql_name = nil
|
60
75
|
|
61
76
|
if defined?(@graphql_name) && @graphql_name && (self.name.nil? || graphql_name != default_graphql_name)
|
@@ -135,7 +135,7 @@ module GraphQL
|
|
135
135
|
|
136
136
|
def get_argument(argument_name, context = GraphQL::Query::NullContext.instance)
|
137
137
|
warden = Warden.from_context(context)
|
138
|
-
skip_visible = context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::
|
138
|
+
skip_visible = context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::Visibility::Profile)
|
139
139
|
for ancestor in ancestors
|
140
140
|
if ancestor.respond_to?(:own_arguments) &&
|
141
141
|
(a = ancestor.own_arguments[argument_name]) &&
|
@@ -210,7 +210,7 @@ module GraphQL
|
|
210
210
|
# @return [GraphQL::Schema::Argument, nil] Argument defined on this thing, fetched by name.
|
211
211
|
def get_argument(argument_name, context = GraphQL::Query::NullContext.instance)
|
212
212
|
warden = Warden.from_context(context)
|
213
|
-
if (arg_config = own_arguments[argument_name]) && ((context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::
|
213
|
+
if (arg_config = own_arguments[argument_name]) && ((context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::Visibility::Profile)) || (visible_arg = Warden.visible_entry?(:visible_argument?, arg_config, context, warden)))
|
214
214
|
visible_arg || arg_config
|
215
215
|
elsif defined?(@resolver_class) && @resolver_class
|
216
216
|
@resolver_class.get_field_argument(argument_name, context)
|
@@ -99,7 +99,7 @@ module GraphQL
|
|
99
99
|
module InterfaceMethods
|
100
100
|
def get_field(field_name, context = GraphQL::Query::NullContext.instance)
|
101
101
|
warden = Warden.from_context(context)
|
102
|
-
skip_visible = context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::
|
102
|
+
skip_visible = context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::Visibility::Profile)
|
103
103
|
for ancestor in ancestors
|
104
104
|
if ancestor.respond_to?(:own_fields) &&
|
105
105
|
(f_entry = ancestor.own_fields[field_name]) &&
|
@@ -135,7 +135,7 @@ module GraphQL
|
|
135
135
|
# Objects need to check that the interface implementation is visible, too
|
136
136
|
warden = Warden.from_context(context)
|
137
137
|
ancs = ancestors
|
138
|
-
skip_visible = context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::
|
138
|
+
skip_visible = context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::Visibility::Profile)
|
139
139
|
i = 0
|
140
140
|
while (ancestor = ancs[i])
|
141
141
|
if ancestor.respond_to?(:own_fields) &&
|
@@ -8,6 +8,7 @@ module GraphQL
|
|
8
8
|
# - Arguments, via `.argument(...)` helper, which will be applied to the field.
|
9
9
|
# - Return type, via `.type(..., null: ...)`, which will be applied to the field.
|
10
10
|
# - Description, via `.description(...)`, which will be applied to the field
|
11
|
+
# - Comment, via `.comment(...)`, which will be applied to the field
|
11
12
|
# - Resolution, via `#resolve(**args)` method, which will be called to resolve the field.
|
12
13
|
# - `#object` and `#context` accessors for use during `#resolve`.
|
13
14
|
#
|
@@ -19,7 +20,7 @@ module GraphQL
|
|
19
20
|
# @see {GraphQL::Function} `Resolver` is a replacement for `GraphQL::Function`
|
20
21
|
class Resolver
|
21
22
|
include Schema::Member::GraphQLTypeNames
|
22
|
-
# Really we only need description from here, but:
|
23
|
+
# Really we only need description & comment from here, but:
|
23
24
|
extend Schema::Member::BaseDSLMethods
|
24
25
|
extend GraphQL::Schema::Member::HasArguments
|
25
26
|
extend GraphQL::Schema::Member::HasValidators
|
@@ -408,9 +409,7 @@ module GraphQL
|
|
408
409
|
|
409
410
|
private
|
410
411
|
|
411
|
-
|
412
|
-
@own_extensions
|
413
|
-
end
|
412
|
+
attr_reader :own_extensions
|
414
413
|
end
|
415
414
|
end
|
416
415
|
end
|