graphql 1.9.7 → 1.9.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 +2 -1
- data/lib/generators/graphql/templates/base_argument.erb +4 -0
- data/lib/generators/graphql/templates/base_field.erb +2 -0
- data/lib/generators/graphql/templates/base_input_object.erb +1 -0
- data/lib/graphql/analysis/ast/query_complexity.rb +34 -18
- data/lib/graphql/argument.rb +8 -2
- data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +1 -1
- data/lib/graphql/language/lexer.rb +24 -13
- data/lib/graphql/language/lexer.rl +23 -13
- data/lib/graphql/query/arguments.rb +16 -15
- data/lib/graphql/schema.rb +105 -48
- data/lib/graphql/schema/argument.rb +12 -1
- data/lib/graphql/schema/build_from_definition.rb +3 -0
- data/lib/graphql/schema/field.rb +3 -8
- data/lib/graphql/schema/find_inherited_value.rb +20 -0
- data/lib/graphql/schema/input_object.rb +1 -3
- data/lib/graphql/schema/loader.rb +1 -0
- data/lib/graphql/schema/member/base_dsl_methods.rb +7 -18
- data/lib/graphql/schema/member/has_arguments.rb +4 -9
- data/lib/graphql/schema/member/has_fields.rb +14 -0
- data/lib/graphql/schema/member/relay_shortcuts.rb +2 -2
- data/lib/graphql/schema/resolver.rb +31 -8
- data/lib/graphql/schema/resolver/has_payload_type.rb +3 -2
- data/lib/graphql/schema/subscription.rb +1 -1
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- data/spec/graphql/analysis/analyze_query_spec.rb +14 -25
- data/spec/graphql/analysis/ast/max_query_complexity_spec.rb +7 -19
- data/spec/graphql/analysis/ast/max_query_depth_spec.rb +5 -12
- data/spec/graphql/analysis/max_query_complexity_spec.rb +12 -20
- data/spec/graphql/analysis/max_query_depth_spec.rb +6 -13
- data/spec/graphql/language/lexer_spec.rb +19 -1
- data/spec/graphql/schema/argument_spec.rb +1 -1
- data/spec/graphql/schema/build_from_definition_spec.rb +10 -0
- data/spec/graphql/schema/catchall_middleware_spec.rb +6 -9
- data/spec/graphql/schema/input_object_spec.rb +25 -0
- data/spec/graphql/schema/loader_spec.rb +65 -1
- data/spec/graphql/schema/object_spec.rb +21 -0
- data/spec/graphql/schema/resolver_spec.rb +30 -1
- data/spec/graphql/schema_spec.rb +135 -0
- data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +25 -0
- data/spec/integration/rails/generators/graphql/install_generator_spec.rb +20 -0
- data/spec/integration/tmp/app/graphql/types/page_type.rb +5 -0
- data/spec/support/dummy/schema.rb +1 -1
- data/spec/support/lazy_helpers.rb +1 -1
- data/spec/support/parser/filename_example_invalid_utf8.graphql +1 -0
- metadata +10 -132
- data/spec/integration/tmp/app/graphql/types/date_type.rb +0 -14
- data/spec/integration/tmp/dummy/Gemfile +0 -50
- data/spec/integration/tmp/dummy/README.md +0 -24
- data/spec/integration/tmp/dummy/Rakefile +0 -6
- data/spec/integration/tmp/dummy/app/assets/config/manifest.js +0 -3
- data/spec/integration/tmp/dummy/app/assets/javascripts/application.js +0 -16
- data/spec/integration/tmp/dummy/app/assets/javascripts/cable.js +0 -13
- data/spec/integration/tmp/dummy/app/assets/stylesheets/application.css +0 -15
- data/spec/integration/tmp/dummy/app/channels/application_cable/channel.rb +0 -5
- data/spec/integration/tmp/dummy/app/channels/application_cable/connection.rb +0 -5
- data/spec/integration/tmp/dummy/app/controllers/application_controller.rb +0 -4
- data/spec/integration/tmp/dummy/app/controllers/graphql_controller.rb +0 -44
- data/spec/integration/tmp/dummy/app/helpers/application_helper.rb +0 -3
- data/spec/integration/tmp/dummy/app/jobs/application_job.rb +0 -3
- data/spec/integration/tmp/dummy/app/mailers/application_mailer.rb +0 -5
- data/spec/integration/tmp/dummy/app/mydirectory/dummy_schema.rb +0 -5
- data/spec/integration/tmp/dummy/app/mydirectory/mutations/update_name.rb +0 -15
- data/spec/integration/tmp/dummy/app/mydirectory/types/base_enum.rb +0 -5
- data/spec/integration/tmp/dummy/app/mydirectory/types/base_input_object.rb +0 -5
- data/spec/integration/tmp/dummy/app/mydirectory/types/base_interface.rb +0 -6
- data/spec/integration/tmp/dummy/app/mydirectory/types/base_object.rb +0 -5
- data/spec/integration/tmp/dummy/app/mydirectory/types/base_scalar.rb +0 -5
- data/spec/integration/tmp/dummy/app/mydirectory/types/base_union.rb +0 -5
- data/spec/integration/tmp/dummy/app/mydirectory/types/mutation_type.rb +0 -12
- data/spec/integration/tmp/dummy/app/mydirectory/types/query_type.rb +0 -14
- data/spec/integration/tmp/dummy/app/views/layouts/application.html.erb +0 -14
- data/spec/integration/tmp/dummy/app/views/layouts/mailer.html.erb +0 -13
- data/spec/integration/tmp/dummy/app/views/layouts/mailer.text.erb +0 -1
- data/spec/integration/tmp/dummy/bin/bundle +0 -3
- data/spec/integration/tmp/dummy/bin/rails +0 -4
- data/spec/integration/tmp/dummy/bin/rake +0 -4
- data/spec/integration/tmp/dummy/bin/setup +0 -34
- data/spec/integration/tmp/dummy/bin/update +0 -29
- data/spec/integration/tmp/dummy/config.ru +0 -5
- data/spec/integration/tmp/dummy/config/application.rb +0 -26
- data/spec/integration/tmp/dummy/config/boot.rb +0 -4
- data/spec/integration/tmp/dummy/config/cable.yml +0 -9
- data/spec/integration/tmp/dummy/config/environment.rb +0 -6
- data/spec/integration/tmp/dummy/config/environments/development.rb +0 -52
- data/spec/integration/tmp/dummy/config/environments/production.rb +0 -84
- data/spec/integration/tmp/dummy/config/environments/test.rb +0 -43
- data/spec/integration/tmp/dummy/config/initializers/application_controller_renderer.rb +0 -9
- data/spec/integration/tmp/dummy/config/initializers/assets.rb +0 -12
- data/spec/integration/tmp/dummy/config/initializers/backtrace_silencers.rb +0 -8
- data/spec/integration/tmp/dummy/config/initializers/cookies_serializer.rb +0 -6
- data/spec/integration/tmp/dummy/config/initializers/filter_parameter_logging.rb +0 -5
- data/spec/integration/tmp/dummy/config/initializers/inflections.rb +0 -17
- data/spec/integration/tmp/dummy/config/initializers/mime_types.rb +0 -5
- data/spec/integration/tmp/dummy/config/initializers/new_framework_defaults.rb +0 -24
- data/spec/integration/tmp/dummy/config/initializers/session_store.rb +0 -4
- data/spec/integration/tmp/dummy/config/initializers/wrap_parameters.rb +0 -10
- data/spec/integration/tmp/dummy/config/locales/en.yml +0 -23
- data/spec/integration/tmp/dummy/config/puma.rb +0 -48
- data/spec/integration/tmp/dummy/config/routes.rb +0 -9
- data/spec/integration/tmp/dummy/config/secrets.yml +0 -22
- data/spec/integration/tmp/dummy/db/seeds.rb +0 -8
- data/spec/integration/tmp/dummy/log/test.log +0 -0
- data/spec/integration/tmp/dummy/public/404.html +0 -67
- data/spec/integration/tmp/dummy/public/422.html +0 -67
- data/spec/integration/tmp/dummy/public/500.html +0 -66
- data/spec/integration/tmp/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/integration/tmp/dummy/public/apple-touch-icon.png +0 -0
- data/spec/integration/tmp/dummy/public/favicon.ico +0 -0
- data/spec/integration/tmp/dummy/public/robots.txt +0 -5
- data/spec/integration/tmp/dummy/test/test_helper.rb +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b6424d74c67296edb56f74eb9214313dd9556f1c1ba5e5797c58099afea8958
|
4
|
+
data.tar.gz: ae10d626a73f8dc873f2b9b2678bfc3ffc1cd80301ddd15a255e4447c728d285
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 51b253d7218b850a4189affeee6e298d1367e8781289ca2f828ab6bbd70d6a1de205f29531ff697d70807d8107f62c3b9cbfc6325f7847116836ab4f500206ce
|
7
|
+
data.tar.gz: f9a81a828f9835ce1222021d0ae3f251c576eba5845df2034e8330456765d2920a28850fa24b7f58cbc7d3e1442bd405995cc3a4bf8d7e17277a73ba8fdb8ab6
|
@@ -13,6 +13,7 @@ module Graphql
|
|
13
13
|
# - graphql/
|
14
14
|
# - resolvers/
|
15
15
|
# - types/
|
16
|
+
# - base_argument.rb
|
16
17
|
# - base_field.rb
|
17
18
|
# - base_enum.rb
|
18
19
|
# - base_input_object.rb
|
@@ -94,7 +95,7 @@ module Graphql
|
|
94
95
|
create_dir("#{options[:directory]}/types")
|
95
96
|
template("schema.erb", schema_file_path)
|
96
97
|
|
97
|
-
["base_object", "base_field", "base_enum", "base_input_object", "base_interface", "base_scalar", "base_union"].each do |base_type|
|
98
|
+
["base_object", "base_argument", "base_field", "base_enum", "base_input_object", "base_interface", "base_scalar", "base_union"].each do |base_type|
|
98
99
|
template("#{base_type}.erb", "#{options[:directory]}/types/#{base_type}.rb")
|
99
100
|
end
|
100
101
|
|
@@ -4,11 +4,11 @@ module GraphQL
|
|
4
4
|
# Calculate the complexity of a query, using {Field#complexity} values.
|
5
5
|
module AST
|
6
6
|
class QueryComplexity < Analyzer
|
7
|
-
# State for the query complexity
|
7
|
+
# State for the query complexity calculation:
|
8
8
|
# - `complexities_on_type` holds complexity scores for each type in an IRep node
|
9
9
|
def initialize(query)
|
10
10
|
super
|
11
|
-
@complexities_on_type = [
|
11
|
+
@complexities_on_type = [ConcreteTypeComplexity.new]
|
12
12
|
end
|
13
13
|
|
14
14
|
# Overide this method to use the complexity result
|
@@ -22,7 +22,11 @@ module GraphQL
|
|
22
22
|
return if visitor.visiting_fragment_definition?
|
23
23
|
return if visitor.skipping?
|
24
24
|
|
25
|
-
|
25
|
+
if visitor.type_definition.kind.abstract?
|
26
|
+
@complexities_on_type.push(AbstractTypeComplexity.new)
|
27
|
+
else
|
28
|
+
@complexities_on_type.push(ConcreteTypeComplexity.new)
|
29
|
+
end
|
26
30
|
end
|
27
31
|
|
28
32
|
def on_leave_field(node, parent, visitor)
|
@@ -35,17 +39,14 @@ module GraphQL
|
|
35
39
|
child_complexity = type_complexities.max_possible_complexity
|
36
40
|
own_complexity = get_complexity(node, visitor.field_definition, child_complexity, visitor)
|
37
41
|
|
38
|
-
|
39
|
-
|
40
|
-
|
42
|
+
if @complexities_on_type.last.is_a?(AbstractTypeComplexity)
|
43
|
+
key = selection_key(visitor.response_path, visitor.query)
|
44
|
+
parent_type = visitor.parent_type_definition
|
45
|
+
query.possible_types(parent_type).each do |type|
|
46
|
+
@complexities_on_type.last.merge(type, key, own_complexity)
|
47
|
+
end
|
41
48
|
else
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
key = selection_key(visitor.response_path, visitor.query)
|
46
|
-
|
47
|
-
possible_types.each do |type|
|
48
|
-
@complexities_on_type.last.merge(type, key, own_complexity)
|
49
|
+
@complexities_on_type.last.merge(own_complexity)
|
49
50
|
end
|
50
51
|
end
|
51
52
|
|
@@ -68,7 +69,7 @@ module GraphQL
|
|
68
69
|
# We add the query object id to support multiplex queries
|
69
70
|
# even if they have the same response path, they should
|
70
71
|
# always be added.
|
71
|
-
response_path.join(".")
|
72
|
+
"#{response_path.join(".")}-#{query.object_id}"
|
72
73
|
end
|
73
74
|
|
74
75
|
# Get a complexity value for a field,
|
@@ -91,16 +92,19 @@ module GraphQL
|
|
91
92
|
|
92
93
|
# Selections on an object may apply differently depending on what is _actually_ returned by the resolve function.
|
93
94
|
# Find the maximum possible complexity among those combinations.
|
94
|
-
class
|
95
|
+
class AbstractTypeComplexity
|
95
96
|
def initialize
|
96
97
|
@types = Hash.new { |h, k| h[k] = {} }
|
97
98
|
end
|
98
99
|
|
99
100
|
# Return the max possible complexity for types in this selection
|
100
101
|
def max_possible_complexity
|
101
|
-
|
102
|
-
|
103
|
-
|
102
|
+
max = 0
|
103
|
+
@types.each_value do |fields|
|
104
|
+
complexity = fields.each_value.inject(:+)
|
105
|
+
max = complexity if complexity > max
|
106
|
+
end
|
107
|
+
max
|
104
108
|
end
|
105
109
|
|
106
110
|
# Store the complexity for the branch on `type_defn`.
|
@@ -109,6 +113,18 @@ module GraphQL
|
|
109
113
|
@types[type_defn][key] = complexity
|
110
114
|
end
|
111
115
|
end
|
116
|
+
|
117
|
+
class ConcreteTypeComplexity
|
118
|
+
attr_reader :max_possible_complexity
|
119
|
+
|
120
|
+
def initialize
|
121
|
+
@max_possible_complexity = 0
|
122
|
+
end
|
123
|
+
|
124
|
+
def merge(complexity)
|
125
|
+
@max_possible_complexity += complexity
|
126
|
+
end
|
127
|
+
end
|
112
128
|
end
|
113
129
|
end
|
114
130
|
end
|
data/lib/graphql/argument.rb
CHANGED
@@ -35,13 +35,14 @@ module GraphQL
|
|
35
35
|
|
36
36
|
class Argument
|
37
37
|
include GraphQL::Define::InstanceDefinable
|
38
|
-
accepts_definitions :name, :type, :description, :default_value, :as, :prepare
|
38
|
+
accepts_definitions :name, :type, :description, :default_value, :as, :prepare, :method_access
|
39
39
|
attr_reader :default_value
|
40
40
|
attr_accessor :description, :name, :as
|
41
41
|
attr_accessor :ast_node
|
42
|
+
attr_accessor :method_access
|
42
43
|
alias :graphql_name :name
|
43
44
|
|
44
|
-
ensure_defined(:name, :description, :default_value, :type=, :type, :as, :expose_as, :prepare)
|
45
|
+
ensure_defined(:name, :description, :default_value, :type=, :type, :as, :expose_as, :prepare, :method_access)
|
45
46
|
|
46
47
|
# @api private
|
47
48
|
module DefaultPrepare
|
@@ -60,6 +61,11 @@ module GraphQL
|
|
60
61
|
!!@has_default_value
|
61
62
|
end
|
62
63
|
|
64
|
+
def method_access?
|
65
|
+
# Treat unset as true -- only `false` should override
|
66
|
+
@method_access != false
|
67
|
+
end
|
68
|
+
|
63
69
|
def default_value=(new_default_value)
|
64
70
|
if new_default_value == NO_DEFAULT_VALUE
|
65
71
|
@has_default_value = false
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GraphQL
|
2
4
|
module Language
|
3
5
|
module Lexer
|
@@ -1369,7 +1371,7 @@ end
|
|
1369
1371
|
def self.record_comment(ts, te, meta)
|
1370
1372
|
token = GraphQL::Language::Token.new(
|
1371
1373
|
name: :COMMENT,
|
1372
|
-
value: meta[:data][ts
|
1374
|
+
value: meta[:data][ts, te - ts].pack(PACK_DIRECTIVE).force_encoding(UTF_8_ENCODING),
|
1373
1375
|
line: meta[:line],
|
1374
1376
|
col: meta[:col],
|
1375
1377
|
prev_token: meta[:previous_token],
|
@@ -1383,7 +1385,7 @@ end
|
|
1383
1385
|
def self.emit(token_name, ts, te, meta)
|
1384
1386
|
meta[:tokens] << token = GraphQL::Language::Token.new(
|
1385
1387
|
name: token_name,
|
1386
|
-
value: meta[:data][ts
|
1388
|
+
value: meta[:data][ts, te - ts].pack(PACK_DIRECTIVE).force_encoding(UTF_8_ENCODING),
|
1387
1389
|
line: meta[:line],
|
1388
1390
|
col: meta[:col],
|
1389
1391
|
prev_token: meta[:previous_token],
|
@@ -1415,16 +1417,15 @@ UTF_8_ENCODING = "UTF-8"
|
|
1415
1417
|
|
1416
1418
|
def self.emit_string(ts, te, meta, block:)
|
1417
1419
|
quotes_length = block ? 3 : 1
|
1418
|
-
ts
|
1419
|
-
value = meta[:data][ts...te - quotes_length].pack(PACK_DIRECTIVE).force_encoding(UTF_8_ENCODING)
|
1420
|
+
value = meta[:data][ts + quotes_length, te - ts - 2 * quotes_length].pack(PACK_DIRECTIVE).force_encoding(UTF_8_ENCODING) || ''
|
1420
1421
|
line_incr = 0
|
1421
|
-
if block
|
1422
|
+
if block && !value.length.zero?
|
1422
1423
|
line_incr = value.count("\n")
|
1423
1424
|
value = GraphQL::Language::BlockString.trim_whitespace(value)
|
1424
1425
|
end
|
1425
1426
|
# TODO: replace with `String#match?` when we support only Ruby 2.4+
|
1426
1427
|
# (It's faster: https://bugs.ruby-lang.org/issues/8110)
|
1427
|
-
if value !~ VALID_STRING
|
1428
|
+
if !value.valid_encoding? || value !~ VALID_STRING
|
1428
1429
|
meta[:tokens] << token = GraphQL::Language::Token.new(
|
1429
1430
|
name: :BAD_UNICODE_ESCAPE,
|
1430
1431
|
value: value,
|
@@ -1435,13 +1436,23 @@ prev_token: meta[:previous_token],
|
|
1435
1436
|
else
|
1436
1437
|
replace_escaped_characters_in_place(value)
|
1437
1438
|
|
1438
|
-
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1439
|
+
if !value.valid_encoding?
|
1440
|
+
meta[:tokens] << token = GraphQL::Language::Token.new(
|
1441
|
+
name: :BAD_UNICODE_ESCAPE,
|
1442
|
+
value: value,
|
1443
|
+
line: meta[:line],
|
1444
|
+
col: meta[:col],
|
1445
|
+
prev_token: meta[:previous_token],
|
1446
|
+
)
|
1447
|
+
else
|
1448
|
+
meta[:tokens] << token = GraphQL::Language::Token.new(
|
1449
|
+
name: :STRING,
|
1450
|
+
value: value,
|
1451
|
+
line: meta[:line],
|
1452
|
+
col: meta[:col],
|
1453
|
+
prev_token: meta[:previous_token],
|
1454
|
+
)
|
1455
|
+
end
|
1445
1456
|
end
|
1446
1457
|
|
1447
1458
|
meta[:previous_token] = token
|
@@ -105,6 +105,7 @@
|
|
105
105
|
*|;
|
106
106
|
}%%
|
107
107
|
|
108
|
+
# frozen_string_literal: true
|
108
109
|
|
109
110
|
module GraphQL
|
110
111
|
module Language
|
@@ -152,7 +153,7 @@ module GraphQL
|
|
152
153
|
def self.record_comment(ts, te, meta)
|
153
154
|
token = GraphQL::Language::Token.new(
|
154
155
|
name: :COMMENT,
|
155
|
-
value: meta[:data][ts
|
156
|
+
value: meta[:data][ts, te - ts].pack(PACK_DIRECTIVE).force_encoding(UTF_8_ENCODING),
|
156
157
|
line: meta[:line],
|
157
158
|
col: meta[:col],
|
158
159
|
prev_token: meta[:previous_token],
|
@@ -166,7 +167,7 @@ module GraphQL
|
|
166
167
|
def self.emit(token_name, ts, te, meta)
|
167
168
|
meta[:tokens] << token = GraphQL::Language::Token.new(
|
168
169
|
name: token_name,
|
169
|
-
value: meta[:data][ts
|
170
|
+
value: meta[:data][ts, te - ts].pack(PACK_DIRECTIVE).force_encoding(UTF_8_ENCODING),
|
170
171
|
line: meta[:line],
|
171
172
|
col: meta[:col],
|
172
173
|
prev_token: meta[:previous_token],
|
@@ -198,16 +199,15 @@ module GraphQL
|
|
198
199
|
|
199
200
|
def self.emit_string(ts, te, meta, block:)
|
200
201
|
quotes_length = block ? 3 : 1
|
201
|
-
ts
|
202
|
-
value = meta[:data][ts...te - quotes_length].pack(PACK_DIRECTIVE).force_encoding(UTF_8_ENCODING)
|
202
|
+
value = meta[:data][ts + quotes_length, te - ts - 2 * quotes_length].pack(PACK_DIRECTIVE).force_encoding(UTF_8_ENCODING) || ''
|
203
203
|
line_incr = 0
|
204
|
-
if block
|
204
|
+
if block && !value.length.zero?
|
205
205
|
line_incr = value.count("\n")
|
206
206
|
value = GraphQL::Language::BlockString.trim_whitespace(value)
|
207
207
|
end
|
208
208
|
# TODO: replace with `String#match?` when we support only Ruby 2.4+
|
209
209
|
# (It's faster: https://bugs.ruby-lang.org/issues/8110)
|
210
|
-
if value !~ VALID_STRING
|
210
|
+
if !value.valid_encoding? || value !~ VALID_STRING
|
211
211
|
meta[:tokens] << token = GraphQL::Language::Token.new(
|
212
212
|
name: :BAD_UNICODE_ESCAPE,
|
213
213
|
value: value,
|
@@ -218,13 +218,23 @@ module GraphQL
|
|
218
218
|
else
|
219
219
|
replace_escaped_characters_in_place(value)
|
220
220
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
221
|
+
if !value.valid_encoding?
|
222
|
+
meta[:tokens] << token = GraphQL::Language::Token.new(
|
223
|
+
name: :BAD_UNICODE_ESCAPE,
|
224
|
+
value: value,
|
225
|
+
line: meta[:line],
|
226
|
+
col: meta[:col],
|
227
|
+
prev_token: meta[:previous_token],
|
228
|
+
)
|
229
|
+
else
|
230
|
+
meta[:tokens] << token = GraphQL::Language::Token.new(
|
231
|
+
name: :STRING,
|
232
|
+
value: value,
|
233
|
+
line: meta[:line],
|
234
|
+
col: meta[:col],
|
235
|
+
prev_token: meta[:previous_token],
|
236
|
+
)
|
237
|
+
end
|
228
238
|
end
|
229
239
|
|
230
240
|
meta[:previous_token] = token
|
@@ -14,21 +14,22 @@ module GraphQL
|
|
14
14
|
self.argument_definitions = argument_definitions
|
15
15
|
|
16
16
|
argument_definitions.each do |_arg_name, arg_definition|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
17
|
+
if arg_definition.method_access?
|
18
|
+
expose_as = arg_definition.expose_as.to_s.freeze
|
19
|
+
expose_as_underscored = GraphQL::Schema::Member::BuildType.underscore(expose_as).freeze
|
20
|
+
method_names = [expose_as, expose_as_underscored].uniq
|
21
|
+
method_names.each do |method_name|
|
22
|
+
# Don't define a helper method if it would override something.
|
23
|
+
if method_defined?(method_name)
|
24
|
+
warn(
|
25
|
+
"Unable to define a helper for argument with name '#{method_name}' "\
|
26
|
+
"as this is a reserved name. Add `method_access: false` to stop this warning."
|
27
|
+
)
|
28
|
+
else
|
29
|
+
define_method(method_name) do
|
30
|
+
# Always use `expose_as` here, since #[] doesn't accept underscored names
|
31
|
+
self[expose_as]
|
32
|
+
end
|
32
33
|
end
|
33
34
|
end
|
34
35
|
end
|
data/lib/graphql/schema.rb
CHANGED
@@ -3,6 +3,7 @@ require "graphql/schema/base_64_encoder"
|
|
3
3
|
require "graphql/schema/catchall_middleware"
|
4
4
|
require "graphql/schema/default_parse_error"
|
5
5
|
require "graphql/schema/default_type_error"
|
6
|
+
require "graphql/schema/find_inherited_value"
|
6
7
|
require "graphql/schema/finder"
|
7
8
|
require "graphql/schema/invalid_type_error"
|
8
9
|
require "graphql/schema/introspection_system"
|
@@ -81,6 +82,8 @@ module GraphQL
|
|
81
82
|
extend Forwardable
|
82
83
|
extend GraphQL::Schema::Member::AcceptsDefinition
|
83
84
|
include GraphQL::Define::InstanceDefinable
|
85
|
+
extend GraphQL::Schema::FindInheritedValue
|
86
|
+
|
84
87
|
accepts_definitions \
|
85
88
|
:query, :mutation, :subscription,
|
86
89
|
:query_execution_strategy, :mutation_execution_strategy, :subscription_execution_strategy,
|
@@ -159,7 +162,9 @@ module GraphQL
|
|
159
162
|
# @see {Query#tracers} for query-specific tracers
|
160
163
|
attr_reader :tracers
|
161
164
|
|
162
|
-
DYNAMIC_FIELDS = ["__type", "__typename", "__schema"]
|
165
|
+
DYNAMIC_FIELDS = ["__type", "__typename", "__schema"].freeze
|
166
|
+
EMPTY_ARRAY = [].freeze
|
167
|
+
EMPTY_HASH = {}.freeze
|
163
168
|
|
164
169
|
attr_reader :static_validator, :object_from_id_proc, :id_from_object_proc, :resolve_type_proc
|
165
170
|
|
@@ -728,11 +733,11 @@ module GraphQL
|
|
728
733
|
end
|
729
734
|
|
730
735
|
def use(plugin, options = {})
|
731
|
-
|
736
|
+
own_plugins << [plugin, options]
|
732
737
|
end
|
733
738
|
|
734
739
|
def plugins
|
735
|
-
|
740
|
+
find_inherited_value(:plugins, EMPTY_ARRAY) + own_plugins
|
736
741
|
end
|
737
742
|
|
738
743
|
def to_graphql
|
@@ -746,7 +751,7 @@ module GraphQL
|
|
746
751
|
schema_defn.max_depth = max_depth
|
747
752
|
schema_defn.default_max_page_size = default_max_page_size
|
748
753
|
schema_defn.orphan_types = orphan_types
|
749
|
-
schema_defn.disable_introspection_entry_points =
|
754
|
+
schema_defn.disable_introspection_entry_points = disable_introspection_entry_points?
|
750
755
|
|
751
756
|
prepped_dirs = {}
|
752
757
|
directives.each { |k, v| prepped_dirs[k] = v.graphql_definition}
|
@@ -758,15 +763,15 @@ module GraphQL
|
|
758
763
|
schema_defn.type_error = method(:type_error)
|
759
764
|
schema_defn.context_class = context_class
|
760
765
|
schema_defn.cursor_encoder = cursor_encoder
|
761
|
-
schema_defn.tracers.concat(
|
762
|
-
schema_defn.query_analyzers.concat(
|
766
|
+
schema_defn.tracers.concat(tracers)
|
767
|
+
schema_defn.query_analyzers.concat(query_analyzers)
|
763
768
|
|
764
|
-
schema_defn.middleware.concat(
|
765
|
-
schema_defn.multiplex_analyzers.concat(
|
769
|
+
schema_defn.middleware.concat(all_middleware)
|
770
|
+
schema_defn.multiplex_analyzers.concat(multiplex_analyzers)
|
766
771
|
schema_defn.query_execution_strategy = query_execution_strategy
|
767
772
|
schema_defn.mutation_execution_strategy = mutation_execution_strategy
|
768
773
|
schema_defn.subscription_execution_strategy = subscription_execution_strategy
|
769
|
-
|
774
|
+
all_instrumenters.each do |step, insts|
|
770
775
|
insts.each do |inst|
|
771
776
|
schema_defn.instrumenters[step] << inst
|
772
777
|
end
|
@@ -774,10 +779,8 @@ module GraphQL
|
|
774
779
|
lazy_classes.each do |lazy_class, value_method|
|
775
780
|
schema_defn.lazy_methods.set(lazy_class, value_method)
|
776
781
|
end
|
777
|
-
|
778
|
-
|
779
|
-
schema_defn.rescue_from(err_class, &handler)
|
780
|
-
end
|
782
|
+
rescues.each do |err_class, handler|
|
783
|
+
schema_defn.rescue_from(err_class, &handler)
|
781
784
|
end
|
782
785
|
|
783
786
|
if plugins.any?
|
@@ -806,7 +809,8 @@ module GraphQL
|
|
806
809
|
if new_query_object
|
807
810
|
@query_object = new_query_object
|
808
811
|
else
|
809
|
-
|
812
|
+
query_object = @query_object || find_inherited_value(:query)
|
813
|
+
query_object.respond_to?(:graphql_definition) ? query_object.graphql_definition : query_object
|
810
814
|
end
|
811
815
|
end
|
812
816
|
|
@@ -814,7 +818,8 @@ module GraphQL
|
|
814
818
|
if new_mutation_object
|
815
819
|
@mutation_object = new_mutation_object
|
816
820
|
else
|
817
|
-
|
821
|
+
mutation_object = @mutation_object || find_inherited_value(:mutation)
|
822
|
+
mutation_object.respond_to?(:graphql_definition) ? mutation_object.graphql_definition : mutation_object
|
818
823
|
end
|
819
824
|
end
|
820
825
|
|
@@ -822,7 +827,8 @@ module GraphQL
|
|
822
827
|
if new_subscription_object
|
823
828
|
@subscription_object = new_subscription_object
|
824
829
|
else
|
825
|
-
|
830
|
+
subscription_object = @subscription_object || find_inherited_value(:subscription)
|
831
|
+
subscription_object.respond_to?(:graphql_definition) ? subscription_object.graphql_definition : subscription_object
|
826
832
|
end
|
827
833
|
end
|
828
834
|
|
@@ -830,7 +836,7 @@ module GraphQL
|
|
830
836
|
if new_introspection_namespace
|
831
837
|
@introspection = new_introspection_namespace
|
832
838
|
else
|
833
|
-
@introspection
|
839
|
+
@introspection || find_inherited_value(:introspection)
|
834
840
|
end
|
835
841
|
end
|
836
842
|
|
@@ -838,14 +844,14 @@ module GraphQL
|
|
838
844
|
if new_encoder
|
839
845
|
@cursor_encoder = new_encoder
|
840
846
|
end
|
841
|
-
@cursor_encoder || Base64Encoder
|
847
|
+
@cursor_encoder || find_inherited_value(:cursor_encoder, Base64Encoder)
|
842
848
|
end
|
843
849
|
|
844
850
|
def default_max_page_size(new_default_max_page_size = nil)
|
845
851
|
if new_default_max_page_size
|
846
852
|
@default_max_page_size = new_default_max_page_size
|
847
853
|
else
|
848
|
-
@default_max_page_size
|
854
|
+
@default_max_page_size || find_inherited_value(:default_max_page_size)
|
849
855
|
end
|
850
856
|
end
|
851
857
|
|
@@ -853,7 +859,7 @@ module GraphQL
|
|
853
859
|
if new_query_execution_strategy
|
854
860
|
@query_execution_strategy = new_query_execution_strategy
|
855
861
|
else
|
856
|
-
@query_execution_strategy || self.default_execution_strategy
|
862
|
+
@query_execution_strategy || find_inherited_value(:query_execution_strategy, self.default_execution_strategy)
|
857
863
|
end
|
858
864
|
end
|
859
865
|
|
@@ -861,7 +867,7 @@ module GraphQL
|
|
861
867
|
if new_mutation_execution_strategy
|
862
868
|
@mutation_execution_strategy = new_mutation_execution_strategy
|
863
869
|
else
|
864
|
-
@mutation_execution_strategy || self.default_execution_strategy
|
870
|
+
@mutation_execution_strategy || find_inherited_value(:mutation_execution_strategy, self.default_execution_strategy)
|
865
871
|
end
|
866
872
|
end
|
867
873
|
|
@@ -869,7 +875,7 @@ module GraphQL
|
|
869
875
|
if new_subscription_execution_strategy
|
870
876
|
@subscription_execution_strategy = new_subscription_execution_strategy
|
871
877
|
else
|
872
|
-
@subscription_execution_strategy || self.default_execution_strategy
|
878
|
+
@subscription_execution_strategy || find_inherited_value(:subscription_execution_strategy, self.default_execution_strategy)
|
873
879
|
end
|
874
880
|
end
|
875
881
|
|
@@ -877,7 +883,7 @@ module GraphQL
|
|
877
883
|
if max_complexity
|
878
884
|
@max_complexity = max_complexity
|
879
885
|
else
|
880
|
-
@max_complexity
|
886
|
+
@max_complexity || find_inherited_value(:max_complexity)
|
881
887
|
end
|
882
888
|
end
|
883
889
|
|
@@ -885,7 +891,7 @@ module GraphQL
|
|
885
891
|
if !new_error_bubbling.nil?
|
886
892
|
@error_bubbling = new_error_bubbling
|
887
893
|
else
|
888
|
-
@error_bubbling
|
894
|
+
@error_bubbling.nil? ? find_inherited_value(:error_bubbling) : @error_bubbling
|
889
895
|
end
|
890
896
|
end
|
891
897
|
|
@@ -893,7 +899,7 @@ module GraphQL
|
|
893
899
|
if new_max_depth
|
894
900
|
@max_depth = new_max_depth
|
895
901
|
else
|
896
|
-
@max_depth
|
902
|
+
@max_depth || find_inherited_value(:max_depth)
|
897
903
|
end
|
898
904
|
end
|
899
905
|
|
@@ -901,12 +907,20 @@ module GraphQL
|
|
901
907
|
@disable_introspection_entry_points = true
|
902
908
|
end
|
903
909
|
|
910
|
+
def disable_introspection_entry_points?
|
911
|
+
if instance_variable_defined?(:@disable_introspection_entry_points)
|
912
|
+
@disable_introspection_entry_points
|
913
|
+
else
|
914
|
+
find_inherited_value(:disable_introspection_entry_points?, false)
|
915
|
+
end
|
916
|
+
end
|
917
|
+
|
904
918
|
def orphan_types(*new_orphan_types)
|
905
919
|
if new_orphan_types.any?
|
906
|
-
|
907
|
-
else
|
908
|
-
@orphan_types || []
|
920
|
+
own_orphan_types.concat(new_orphan_types.flatten)
|
909
921
|
end
|
922
|
+
|
923
|
+
find_inherited_value(:orphan_types, EMPTY_ARRAY) + own_orphan_types
|
910
924
|
end
|
911
925
|
|
912
926
|
def default_execution_strategy
|
@@ -921,17 +935,20 @@ module GraphQL
|
|
921
935
|
if new_context_class
|
922
936
|
@context_class = new_context_class
|
923
937
|
else
|
924
|
-
@context_class || GraphQL::Query::Context
|
938
|
+
@context_class || find_inherited_value(:context_class, GraphQL::Query::Context)
|
925
939
|
end
|
926
940
|
end
|
927
941
|
|
928
942
|
def rescue_from(*err_classes, &handler_block)
|
929
|
-
@rescues ||= {}
|
930
943
|
err_classes.each do |err_class|
|
931
|
-
|
944
|
+
own_rescues[err_class] = handler_block
|
932
945
|
end
|
933
946
|
end
|
934
947
|
|
948
|
+
def rescues
|
949
|
+
find_inherited_value(:rescues, EMPTY_HASH).merge(own_rescues)
|
950
|
+
end
|
951
|
+
|
935
952
|
def resolve_type(type, obj, ctx)
|
936
953
|
if type.kind.object?
|
937
954
|
type
|
@@ -1017,19 +1034,20 @@ module GraphQL
|
|
1017
1034
|
else
|
1018
1035
|
instrument_step
|
1019
1036
|
end
|
1020
|
-
|
1037
|
+
|
1038
|
+
own_instrumenters[step] << instrumenter
|
1021
1039
|
end
|
1022
1040
|
|
1023
1041
|
def directives(new_directives = nil)
|
1024
1042
|
if new_directives
|
1025
|
-
|
1043
|
+
new_directives.each {|d| directive(d) }
|
1026
1044
|
end
|
1027
1045
|
|
1028
|
-
|
1046
|
+
find_inherited_value(:directives, default_directives).merge(own_directives)
|
1029
1047
|
end
|
1030
1048
|
|
1031
1049
|
def directive(new_directive)
|
1032
|
-
|
1050
|
+
own_directives[new_directive.graphql_name] = new_directive
|
1033
1051
|
end
|
1034
1052
|
|
1035
1053
|
def default_directives
|
@@ -1041,26 +1059,38 @@ module GraphQL
|
|
1041
1059
|
end
|
1042
1060
|
|
1043
1061
|
def tracer(new_tracer)
|
1044
|
-
|
1062
|
+
own_tracers << new_tracer
|
1063
|
+
end
|
1064
|
+
|
1065
|
+
def tracers
|
1066
|
+
find_inherited_value(:tracers, EMPTY_ARRAY) + own_tracers
|
1045
1067
|
end
|
1046
1068
|
|
1047
1069
|
def query_analyzer(new_analyzer)
|
1048
1070
|
if new_analyzer == GraphQL::Authorization::Analyzer
|
1049
1071
|
warn("The Authorization query analyzer is deprecated. Authorizing at query runtime is generally a better idea.")
|
1050
1072
|
end
|
1051
|
-
|
1073
|
+
own_query_analyzers << new_analyzer
|
1074
|
+
end
|
1075
|
+
|
1076
|
+
def query_analyzers
|
1077
|
+
find_inherited_value(:query_analyzers, EMPTY_ARRAY) + own_query_analyzers
|
1052
1078
|
end
|
1053
1079
|
|
1054
1080
|
def middleware(new_middleware = nil)
|
1055
1081
|
if new_middleware
|
1056
|
-
|
1082
|
+
own_middleware << new_middleware
|
1057
1083
|
else
|
1058
1084
|
graphql_definition.middleware
|
1059
1085
|
end
|
1060
1086
|
end
|
1061
1087
|
|
1062
1088
|
def multiplex_analyzer(new_analyzer)
|
1063
|
-
|
1089
|
+
own_multiplex_analyzers << new_analyzer
|
1090
|
+
end
|
1091
|
+
|
1092
|
+
def multiplex_analyzers
|
1093
|
+
find_inherited_value(:multiplex_analyzers, EMPTY_ARRAY) + own_multiplex_analyzers
|
1064
1094
|
end
|
1065
1095
|
|
1066
1096
|
private
|
@@ -1069,24 +1099,51 @@ module GraphQL
|
|
1069
1099
|
@lazy_classes ||= {}
|
1070
1100
|
end
|
1071
1101
|
|
1072
|
-
def
|
1073
|
-
@
|
1102
|
+
def own_plugins
|
1103
|
+
@own_plugins ||= []
|
1104
|
+
end
|
1105
|
+
|
1106
|
+
def own_rescues
|
1107
|
+
@own_rescues ||= {}
|
1074
1108
|
end
|
1075
1109
|
|
1076
|
-
def
|
1077
|
-
@
|
1110
|
+
def own_orphan_types
|
1111
|
+
@own_orphan_types ||= []
|
1078
1112
|
end
|
1079
1113
|
|
1080
|
-
def
|
1114
|
+
def own_directives
|
1115
|
+
@own_directives ||= {}
|
1116
|
+
end
|
1117
|
+
|
1118
|
+
def all_instrumenters
|
1119
|
+
inherited_instrumenters = find_inherited_value(:all_instrumenters) || Hash.new { |h,k| h[k] = [] }
|
1120
|
+
inherited_instrumenters.merge(own_instrumenters) do |_step, inherited, own|
|
1121
|
+
inherited + own
|
1122
|
+
end
|
1123
|
+
end
|
1124
|
+
|
1125
|
+
def own_instrumenters
|
1126
|
+
@own_instrumenters ||= Hash.new { |h,k| h[k] = [] }
|
1127
|
+
end
|
1128
|
+
|
1129
|
+
def own_tracers
|
1130
|
+
@own_tracers ||= []
|
1131
|
+
end
|
1132
|
+
|
1133
|
+
def own_query_analyzers
|
1081
1134
|
@defined_query_analyzers ||= []
|
1082
1135
|
end
|
1083
1136
|
|
1084
|
-
def
|
1085
|
-
|
1137
|
+
def all_middleware
|
1138
|
+
find_inherited_value(:all_middleware, EMPTY_ARRAY) + own_middleware
|
1139
|
+
end
|
1140
|
+
|
1141
|
+
def own_middleware
|
1142
|
+
@own_middleware ||= []
|
1086
1143
|
end
|
1087
1144
|
|
1088
|
-
def
|
1089
|
-
@
|
1145
|
+
def own_multiplex_analyzers
|
1146
|
+
@own_multiplex_analyzers ||= []
|
1090
1147
|
end
|
1091
1148
|
|
1092
1149
|
# Given this schema member, find the class-based definition object
|