graphql 0.15.3 → 0.16.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/graphql.rb +4 -1
- data/lib/graphql/analysis.rb +5 -0
- data/lib/graphql/analysis/analyze_query.rb +73 -0
- data/lib/graphql/analysis/max_query_complexity.rb +25 -0
- data/lib/graphql/analysis/max_query_depth.rb +25 -0
- data/lib/graphql/analysis/query_complexity.rb +122 -0
- data/lib/graphql/analysis/query_depth.rb +54 -0
- data/lib/graphql/analysis_error.rb +4 -0
- data/lib/graphql/base_type.rb +7 -0
- data/lib/graphql/define/assign_object_field.rb +2 -1
- data/lib/graphql/field.rb +25 -3
- data/lib/graphql/input_object_type.rb +1 -1
- data/lib/graphql/internal_representation.rb +2 -0
- data/lib/graphql/internal_representation/node.rb +81 -0
- data/lib/graphql/internal_representation/rewrite.rb +177 -0
- data/lib/graphql/language/visitor.rb +15 -9
- data/lib/graphql/object_type.rb +1 -1
- data/lib/graphql/query.rb +66 -7
- data/lib/graphql/query/context.rb +10 -3
- data/lib/graphql/query/directive_resolution.rb +5 -5
- data/lib/graphql/query/serial_execution.rb +5 -3
- data/lib/graphql/query/serial_execution/field_resolution.rb +22 -15
- data/lib/graphql/query/serial_execution/operation_resolution.rb +7 -5
- data/lib/graphql/query/serial_execution/selection_resolution.rb +20 -105
- data/lib/graphql/query/serial_execution/value_resolution.rb +15 -12
- data/lib/graphql/schema.rb +7 -2
- data/lib/graphql/schema/timeout_middleware.rb +67 -0
- data/lib/graphql/static_validation/all_rules.rb +0 -1
- data/lib/graphql/static_validation/type_stack.rb +7 -11
- data/lib/graphql/static_validation/validation_context.rb +11 -1
- data/lib/graphql/static_validation/validator.rb +14 -4
- data/lib/graphql/version.rb +1 -1
- data/readme.md +10 -9
- data/spec/graphql/analysis/analyze_query_spec.rb +50 -0
- data/spec/graphql/analysis/max_query_complexity_spec.rb +62 -0
- data/spec/graphql/{static_validation/rules/document_does_not_exceed_max_depth_spec.rb → analysis/max_query_depth_spec.rb} +20 -21
- data/spec/graphql/analysis/query_complexity_spec.rb +235 -0
- data/spec/graphql/analysis/query_depth_spec.rb +80 -0
- data/spec/graphql/directive_spec.rb +1 -0
- data/spec/graphql/internal_representation/rewrite_spec.rb +120 -0
- data/spec/graphql/introspection/schema_type_spec.rb +1 -0
- data/spec/graphql/language/visitor_spec.rb +14 -4
- data/spec/graphql/non_null_type_spec.rb +31 -0
- data/spec/graphql/query/context_spec.rb +24 -1
- data/spec/graphql/query_spec.rb +6 -2
- data/spec/graphql/schema/timeout_middleware_spec.rb +180 -0
- data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +1 -1
- data/spec/graphql/static_validation/rules/arguments_are_defined_spec.rb +1 -1
- data/spec/graphql/static_validation/rules/directives_are_defined_spec.rb +1 -1
- data/spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb +1 -1
- data/spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb +1 -1
- data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +1 -1
- data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +1 -1
- data/spec/graphql/static_validation/rules/fragment_spreads_are_possible_spec.rb +1 -1
- data/spec/graphql/static_validation/rules/fragment_types_exist_spec.rb +1 -1
- data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +1 -1
- data/spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb +1 -1
- data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +1 -1
- data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +1 -1
- data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +1 -1
- data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +1 -1
- data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +1 -1
- data/spec/graphql/static_validation/rules/variables_are_used_and_defined_spec.rb +1 -1
- data/spec/graphql/static_validation/validator_spec.rb +1 -1
- data/spec/support/dairy_app.rb +22 -1
- metadata +29 -5
- data/lib/graphql/static_validation/rules/document_does_not_exceed_max_depth.rb +0 -79
@@ -19,7 +19,7 @@ describe GraphQL::StaticValidation::ArgumentLiteralsAreCompatible do
|
|
19
19
|
|
20
20
|
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::ArgumentLiteralsAreCompatible]) }
|
21
21
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
22
|
-
let(:errors) { validator.validate(query) }
|
22
|
+
let(:errors) { validator.validate(query)[:errors] }
|
23
23
|
|
24
24
|
it "finds undefined or missing-required arguments to fields and directives" do
|
25
25
|
assert_equal(6, errors.length)
|
@@ -16,7 +16,7 @@ describe GraphQL::StaticValidation::ArgumentsAreDefined do
|
|
16
16
|
|
17
17
|
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::ArgumentsAreDefined]) }
|
18
18
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
19
|
-
let(:errors) { validator.validate(query) }
|
19
|
+
let(:errors) { validator.validate(query)[:errors] }
|
20
20
|
|
21
21
|
it "finds undefined arguments to fields and directives" do
|
22
22
|
assert_equal(4, errors.length)
|
@@ -15,7 +15,7 @@ describe GraphQL::StaticValidation::DirectivesAreDefined do
|
|
15
15
|
|
16
16
|
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::DirectivesAreDefined]) }
|
17
17
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
18
|
-
let(:errors) { validator.validate(query) }
|
18
|
+
let(:errors) { validator.validate(query)[:errors] }
|
19
19
|
|
20
20
|
describe "non-existent directives" do
|
21
21
|
it "makes errors for them" do
|
@@ -19,7 +19,7 @@ describe GraphQL::StaticValidation::DirectivesAreInValidLocations do
|
|
19
19
|
|
20
20
|
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::DirectivesAreInValidLocations]) }
|
21
21
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
22
|
-
let(:errors) { validator.validate(query) }
|
22
|
+
let(:errors) { validator.validate(query)[:errors] }
|
23
23
|
|
24
24
|
describe "invalid directive locations" do
|
25
25
|
it "makes errors for them" do
|
@@ -13,7 +13,7 @@ describe GraphQL::StaticValidation::FieldsAreDefinedOnType do
|
|
13
13
|
|
14
14
|
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FieldsAreDefinedOnType]) }
|
15
15
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
16
|
-
let(:errors) { validator.validate(query) }
|
16
|
+
let(:errors) { validator.validate(query)[:errors] }
|
17
17
|
let(:error_messages) { errors.map { |e| e["message"] } }
|
18
18
|
|
19
19
|
it "finds fields that are requested on types that don't have that field" do
|
@@ -11,7 +11,7 @@ describe GraphQL::StaticValidation::FieldsHaveAppropriateSelections do
|
|
11
11
|
|
12
12
|
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FieldsHaveAppropriateSelections]) }
|
13
13
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
14
|
-
let(:errors) { validator.validate(query) }
|
14
|
+
let(:errors) { validator.validate(query)[:errors] }
|
15
15
|
|
16
16
|
it "adds errors for selections on scalars" do
|
17
17
|
assert_equal(2, errors.length)
|
@@ -31,7 +31,7 @@ describe GraphQL::StaticValidation::FieldsWillMerge do
|
|
31
31
|
|
32
32
|
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FieldsWillMerge]) }
|
33
33
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
34
|
-
let(:errors) { validator.validate(query) }
|
34
|
+
let(:errors) { validator.validate(query)[:errors] }
|
35
35
|
let(:error_messages) { errors.map { |e| e["message" ] }}
|
36
36
|
|
37
37
|
it "finds field naming conflicts" do
|
@@ -24,7 +24,7 @@ describe GraphQL::StaticValidation::FragmentSpreadsArePossible do
|
|
24
24
|
|
25
25
|
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FragmentSpreadsArePossible]) }
|
26
26
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
27
|
-
let(:errors) { validator.validate(query) }
|
27
|
+
let(:errors) { validator.validate(query)[:errors] }
|
28
28
|
|
29
29
|
it "doesnt allow spreads where they'll never apply" do
|
30
30
|
# TODO: more negative, abstract examples here, add stuff to the schema
|
@@ -21,7 +21,7 @@ describe GraphQL::StaticValidation::FragmentTypesExist do
|
|
21
21
|
|
22
22
|
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FragmentTypesExist]) }
|
23
23
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
24
|
-
let(:errors) { validator.validate(query) }
|
24
|
+
let(:errors) { validator.validate(query)[:errors] }
|
25
25
|
|
26
26
|
it "finds non-existent types on fragments" do
|
27
27
|
assert_equal(2, errors.length)
|
@@ -26,7 +26,7 @@ describe GraphQL::StaticValidation::FragmentsAreFinite do
|
|
26
26
|
|
27
27
|
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FragmentsAreFinite]) }
|
28
28
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
29
|
-
let(:errors) { validator.validate(query) }
|
29
|
+
let(:errors) { validator.validate(query)[:errors] }
|
30
30
|
|
31
31
|
it "doesnt allow infinite loops" do
|
32
32
|
expected = [
|
@@ -27,7 +27,7 @@ describe GraphQL::StaticValidation::FragmentsAreOnCompositeTypes do
|
|
27
27
|
|
28
28
|
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FragmentsAreOnCompositeTypes]) }
|
29
29
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
30
|
-
let(:errors) { validator.validate(query) }
|
30
|
+
let(:errors) { validator.validate(query)[:errors] }
|
31
31
|
|
32
32
|
it "requires Object/Union/Interface fragment types" do
|
33
33
|
expected = [
|
@@ -13,7 +13,7 @@ describe GraphQL::StaticValidation::FragmentsAreUsed do
|
|
13
13
|
|
14
14
|
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FragmentsAreUsed]) }
|
15
15
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
16
|
-
let(:errors) { validator.validate(query) }
|
16
|
+
let(:errors) { validator.validate(query)[:errors] }
|
17
17
|
|
18
18
|
it "adds errors for unused fragment definitions" do
|
19
19
|
assert_includes(errors, {"message"=>"Fragment unusedFields was defined, but not used", "locations"=>[{"line"=>8, "column"=>5}]})
|
@@ -16,7 +16,7 @@ describe GraphQL::StaticValidation::RequiredArgumentsArePresent do
|
|
16
16
|
|
17
17
|
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::RequiredArgumentsArePresent]) }
|
18
18
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
19
|
-
let(:errors) { validator.validate(query) }
|
19
|
+
let(:errors) { validator.validate(query)[:errors] }
|
20
20
|
|
21
21
|
it "finds undefined arguments to fields and directives" do
|
22
22
|
assert_equal(3, errors.length)
|
data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb
CHANGED
@@ -18,7 +18,7 @@ describe GraphQL::StaticValidation::VariableDefaultValuesAreCorrectlyTyped do
|
|
18
18
|
|
19
19
|
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::VariableDefaultValuesAreCorrectlyTyped]) }
|
20
20
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
21
|
-
let(:errors) { validator.validate(query) }
|
21
|
+
let(:errors) { validator.validate(query)[:errors] }
|
22
22
|
|
23
23
|
it "finds default values that don't match their types" do
|
24
24
|
expected = [
|
@@ -36,7 +36,7 @@ describe GraphQL::StaticValidation::VariableUsagesAreAllowed do
|
|
36
36
|
|
37
37
|
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::VariableUsagesAreAllowed]) }
|
38
38
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
39
|
-
let(:errors) { validator.validate(query) }
|
39
|
+
let(:errors) { validator.validate(query)[:errors] }
|
40
40
|
|
41
41
|
it "finds variables used as arguments but don't match the argument's type" do
|
42
42
|
assert_equal(4, errors.length)
|
@@ -15,7 +15,7 @@ describe GraphQL::StaticValidation::VariablesAreInputTypes do
|
|
15
15
|
|
16
16
|
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::VariablesAreInputTypes]) }
|
17
17
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
18
|
-
let(:errors) { validator.validate(query) }
|
18
|
+
let(:errors) { validator.validate(query)[:errors] }
|
19
19
|
|
20
20
|
it "finds variables whose types are invalid" do
|
21
21
|
expected = [
|
@@ -31,7 +31,7 @@ describe GraphQL::StaticValidation::VariablesAreUsedAndDefined do
|
|
31
31
|
|
32
32
|
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::VariablesAreUsedAndDefined]) }
|
33
33
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
34
|
-
let(:errors) { validator.validate(query) }
|
34
|
+
let(:errors) { validator.validate(query)[:errors] }
|
35
35
|
|
36
36
|
it "finds variables which are used-but-not-defined or defined-but-not-used" do
|
37
37
|
expected = [
|
@@ -3,7 +3,7 @@ require "spec_helper"
|
|
3
3
|
describe GraphQL::StaticValidation::Validator do
|
4
4
|
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema) }
|
5
5
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
6
|
-
let(:errors) { validator.validate(query) }
|
6
|
+
let(:errors) { validator.validate(query)[:errors] }
|
7
7
|
|
8
8
|
|
9
9
|
describe "validation order" do
|
data/spec/support/dairy_app.rb
CHANGED
@@ -83,11 +83,17 @@ MilkType = GraphQL::ObjectType.define do
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
+
SweetenerInterface = GraphQL::InterfaceType.define do
|
87
|
+
name "Sweetener"
|
88
|
+
field :sweetness, types.Int
|
89
|
+
end
|
90
|
+
|
86
91
|
# No actual data; This type is an "orphan", only accessible through Interfaces
|
87
92
|
HoneyType = GraphQL::ObjectType.define do
|
88
93
|
name "Honey"
|
89
94
|
description "Sweet, dehydrated bee barf"
|
90
|
-
|
95
|
+
field :flowerType, types.String, "What flower this honey came from"
|
96
|
+
interfaces [EdibleInterface, AnimalProductInterface, SweetenerInterface]
|
91
97
|
end
|
92
98
|
|
93
99
|
DairyType = GraphQL::ObjectType.define do
|
@@ -150,6 +156,17 @@ DairyProductInputType = GraphQL::InputObjectType.define {
|
|
150
156
|
input_field :organic, types.Boolean, default_value: false
|
151
157
|
}
|
152
158
|
|
159
|
+
DeepNonNullType = GraphQL::ObjectType.define do
|
160
|
+
name "DeepNonNull"
|
161
|
+
field :nonNullInt, !types.Int do
|
162
|
+
argument :returning, types.Int
|
163
|
+
resolve -> (obj, args, ctx) { args[:returning] }
|
164
|
+
end
|
165
|
+
|
166
|
+
field :deepNonNull, -> { DeepNonNullType.to_non_null_type } do
|
167
|
+
resolve -> (obj, args, ctx) { :deepNonNull }
|
168
|
+
end
|
169
|
+
end
|
153
170
|
|
154
171
|
class FetchField
|
155
172
|
def self.create(type:, data:, id_type: !GraphQL::INT_TYPE)
|
@@ -239,6 +256,10 @@ QueryType = GraphQL::ObjectType.define do
|
|
239
256
|
field :maybeNull, MaybeNullType do
|
240
257
|
resolve -> (t, a, c) { OpenStruct.new(cheese: nil) }
|
241
258
|
end
|
259
|
+
|
260
|
+
field :deepNonNull, !DeepNonNullType do
|
261
|
+
resolve -> (o, a, c) { :deepNonNull }
|
262
|
+
end
|
242
263
|
end
|
243
264
|
|
244
265
|
GLOBAL_VALUES = []
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.16.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Mosolgo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-07-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: codeclimate-test-reporter
|
@@ -188,6 +188,13 @@ extra_rdoc_files: []
|
|
188
188
|
files:
|
189
189
|
- MIT-LICENSE
|
190
190
|
- lib/graphql.rb
|
191
|
+
- lib/graphql/analysis.rb
|
192
|
+
- lib/graphql/analysis/analyze_query.rb
|
193
|
+
- lib/graphql/analysis/max_query_complexity.rb
|
194
|
+
- lib/graphql/analysis/max_query_depth.rb
|
195
|
+
- lib/graphql/analysis/query_complexity.rb
|
196
|
+
- lib/graphql/analysis/query_depth.rb
|
197
|
+
- lib/graphql/analysis_error.rb
|
191
198
|
- lib/graphql/argument.rb
|
192
199
|
- lib/graphql/base_type.rb
|
193
200
|
- lib/graphql/boolean_type.rb
|
@@ -211,6 +218,9 @@ files:
|
|
211
218
|
- lib/graphql/input_object_type.rb
|
212
219
|
- lib/graphql/int_type.rb
|
213
220
|
- lib/graphql/interface_type.rb
|
221
|
+
- lib/graphql/internal_representation.rb
|
222
|
+
- lib/graphql/internal_representation/node.rb
|
223
|
+
- lib/graphql/internal_representation/rewrite.rb
|
214
224
|
- lib/graphql/introspection.rb
|
215
225
|
- lib/graphql/introspection/arguments_field.rb
|
216
226
|
- lib/graphql/introspection/directive_location_enum.rb
|
@@ -269,6 +279,7 @@ files:
|
|
269
279
|
- lib/graphql/schema/printer.rb
|
270
280
|
- lib/graphql/schema/reduce_types.rb
|
271
281
|
- lib/graphql/schema/rescue_middleware.rb
|
282
|
+
- lib/graphql/schema/timeout_middleware.rb
|
272
283
|
- lib/graphql/schema/type_expression.rb
|
273
284
|
- lib/graphql/schema/type_map.rb
|
274
285
|
- lib/graphql/schema/validation.rb
|
@@ -281,7 +292,6 @@ files:
|
|
281
292
|
- lib/graphql/static_validation/rules/arguments_are_defined.rb
|
282
293
|
- lib/graphql/static_validation/rules/directives_are_defined.rb
|
283
294
|
- lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb
|
284
|
-
- lib/graphql/static_validation/rules/document_does_not_exceed_max_depth.rb
|
285
295
|
- lib/graphql/static_validation/rules/fields_are_defined_on_type.rb
|
286
296
|
- lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb
|
287
297
|
- lib/graphql/static_validation/rules/fields_will_merge.rb
|
@@ -303,6 +313,11 @@ files:
|
|
303
313
|
- lib/graphql/union_type.rb
|
304
314
|
- lib/graphql/version.rb
|
305
315
|
- readme.md
|
316
|
+
- spec/graphql/analysis/analyze_query_spec.rb
|
317
|
+
- spec/graphql/analysis/max_query_complexity_spec.rb
|
318
|
+
- spec/graphql/analysis/max_query_depth_spec.rb
|
319
|
+
- spec/graphql/analysis/query_complexity_spec.rb
|
320
|
+
- spec/graphql/analysis/query_depth_spec.rb
|
306
321
|
- spec/graphql/argument_spec.rb
|
307
322
|
- spec/graphql/base_type_spec.rb
|
308
323
|
- spec/graphql/boolean_type_spec.rb
|
@@ -316,6 +331,7 @@ files:
|
|
316
331
|
- spec/graphql/input_object_type_spec.rb
|
317
332
|
- spec/graphql/int_type_spec.rb
|
318
333
|
- spec/graphql/interface_type_spec.rb
|
334
|
+
- spec/graphql/internal_representation/rewrite_spec.rb
|
319
335
|
- spec/graphql/introspection/directive_type_spec.rb
|
320
336
|
- spec/graphql/introspection/input_value_type_spec.rb
|
321
337
|
- spec/graphql/introspection/introspection_query_spec.rb
|
@@ -325,6 +341,7 @@ files:
|
|
325
341
|
- spec/graphql/language/parser_spec.rb
|
326
342
|
- spec/graphql/language/visitor_spec.rb
|
327
343
|
- spec/graphql/list_type_spec.rb
|
344
|
+
- spec/graphql/non_null_type_spec.rb
|
328
345
|
- spec/graphql/object_type_spec.rb
|
329
346
|
- spec/graphql/query/arguments_spec.rb
|
330
347
|
- spec/graphql/query/context_spec.rb
|
@@ -340,6 +357,7 @@ files:
|
|
340
357
|
- spec/graphql/schema/printer_spec.rb
|
341
358
|
- spec/graphql/schema/reduce_types_spec.rb
|
342
359
|
- spec/graphql/schema/rescue_middleware_spec.rb
|
360
|
+
- spec/graphql/schema/timeout_middleware_spec.rb
|
343
361
|
- spec/graphql/schema/type_expression_spec.rb
|
344
362
|
- spec/graphql/schema/validation_spec.rb
|
345
363
|
- spec/graphql/schema_spec.rb
|
@@ -347,7 +365,6 @@ files:
|
|
347
365
|
- spec/graphql/static_validation/rules/arguments_are_defined_spec.rb
|
348
366
|
- spec/graphql/static_validation/rules/directives_are_defined_spec.rb
|
349
367
|
- spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb
|
350
|
-
- spec/graphql/static_validation/rules/document_does_not_exceed_max_depth_spec.rb
|
351
368
|
- spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb
|
352
369
|
- spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb
|
353
370
|
- spec/graphql/static_validation/rules/fields_will_merge_spec.rb
|
@@ -396,6 +413,11 @@ signing_key:
|
|
396
413
|
specification_version: 4
|
397
414
|
summary: A GraphQL server implementation for Ruby
|
398
415
|
test_files:
|
416
|
+
- spec/graphql/analysis/analyze_query_spec.rb
|
417
|
+
- spec/graphql/analysis/max_query_complexity_spec.rb
|
418
|
+
- spec/graphql/analysis/max_query_depth_spec.rb
|
419
|
+
- spec/graphql/analysis/query_complexity_spec.rb
|
420
|
+
- spec/graphql/analysis/query_depth_spec.rb
|
399
421
|
- spec/graphql/argument_spec.rb
|
400
422
|
- spec/graphql/base_type_spec.rb
|
401
423
|
- spec/graphql/boolean_type_spec.rb
|
@@ -409,6 +431,7 @@ test_files:
|
|
409
431
|
- spec/graphql/input_object_type_spec.rb
|
410
432
|
- spec/graphql/int_type_spec.rb
|
411
433
|
- spec/graphql/interface_type_spec.rb
|
434
|
+
- spec/graphql/internal_representation/rewrite_spec.rb
|
412
435
|
- spec/graphql/introspection/directive_type_spec.rb
|
413
436
|
- spec/graphql/introspection/input_value_type_spec.rb
|
414
437
|
- spec/graphql/introspection/introspection_query_spec.rb
|
@@ -418,6 +441,7 @@ test_files:
|
|
418
441
|
- spec/graphql/language/parser_spec.rb
|
419
442
|
- spec/graphql/language/visitor_spec.rb
|
420
443
|
- spec/graphql/list_type_spec.rb
|
444
|
+
- spec/graphql/non_null_type_spec.rb
|
421
445
|
- spec/graphql/object_type_spec.rb
|
422
446
|
- spec/graphql/query/arguments_spec.rb
|
423
447
|
- spec/graphql/query/context_spec.rb
|
@@ -433,6 +457,7 @@ test_files:
|
|
433
457
|
- spec/graphql/schema/printer_spec.rb
|
434
458
|
- spec/graphql/schema/reduce_types_spec.rb
|
435
459
|
- spec/graphql/schema/rescue_middleware_spec.rb
|
460
|
+
- spec/graphql/schema/timeout_middleware_spec.rb
|
436
461
|
- spec/graphql/schema/type_expression_spec.rb
|
437
462
|
- spec/graphql/schema/validation_spec.rb
|
438
463
|
- spec/graphql/schema_spec.rb
|
@@ -440,7 +465,6 @@ test_files:
|
|
440
465
|
- spec/graphql/static_validation/rules/arguments_are_defined_spec.rb
|
441
466
|
- spec/graphql/static_validation/rules/directives_are_defined_spec.rb
|
442
467
|
- spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb
|
443
|
-
- spec/graphql/static_validation/rules/document_does_not_exceed_max_depth_spec.rb
|
444
468
|
- spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb
|
445
469
|
- spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb
|
446
470
|
- spec/graphql/static_validation/rules/fields_will_merge_spec.rb
|
@@ -1,79 +0,0 @@
|
|
1
|
-
module GraphQL
|
2
|
-
module StaticValidation
|
3
|
-
class DocumentDoesNotExceedMaxDepth
|
4
|
-
include GraphQL::StaticValidation::Message::MessageHelper
|
5
|
-
|
6
|
-
def validate(context)
|
7
|
-
max_allowed_depth = context.query.max_depth
|
8
|
-
return if max_allowed_depth.nil?
|
9
|
-
|
10
|
-
visitor = context.visitor
|
11
|
-
|
12
|
-
# operation or fragment name
|
13
|
-
current_field_scope = nil
|
14
|
-
current_depth = 0
|
15
|
-
skip_current_scope = false
|
16
|
-
|
17
|
-
# {name => depth} pairs for operations and fragments
|
18
|
-
depths = Hash.new { |h, k| h[k] = 0 }
|
19
|
-
|
20
|
-
# {name => [fragmentName...]} pairs
|
21
|
-
fragments = Hash.new { |h, k| h[k] = []}
|
22
|
-
|
23
|
-
visitor[GraphQL::Language::Nodes::Document].leave << -> (node, parent) {
|
24
|
-
context.errors.none? && assert_under_max_depth(context, max_allowed_depth, depths, fragments)
|
25
|
-
}
|
26
|
-
|
27
|
-
visitor[GraphQL::Language::Nodes::OperationDefinition] << -> (node, parent) {
|
28
|
-
current_field_scope = node.name
|
29
|
-
}
|
30
|
-
|
31
|
-
visitor[GraphQL::Language::Nodes::FragmentDefinition] << -> (node, parent) {
|
32
|
-
current_field_scope = node.name
|
33
|
-
}
|
34
|
-
|
35
|
-
visitor[GraphQL::Language::Nodes::Field] << -> (node, parent) {
|
36
|
-
# Don't validate queries on __schema, __type
|
37
|
-
skip_current_scope ||= context.skip_field?(node.name)
|
38
|
-
|
39
|
-
if node.selections.any? && !skip_current_scope
|
40
|
-
current_depth += 1
|
41
|
-
if current_depth > depths[current_field_scope]
|
42
|
-
depths[current_field_scope] = current_depth
|
43
|
-
end
|
44
|
-
end
|
45
|
-
}
|
46
|
-
|
47
|
-
visitor[GraphQL::Language::Nodes::Field].leave << -> (node, parent) {
|
48
|
-
if skip_current_scope && context.skip_field?(node.name)
|
49
|
-
skip_current_scope = false
|
50
|
-
elsif node.selections.any?
|
51
|
-
current_depth -= 1
|
52
|
-
end
|
53
|
-
}
|
54
|
-
|
55
|
-
visitor [GraphQL::Language::Nodes::FragmentSpread] << -> (node, parent) {
|
56
|
-
fragments[current_field_scope] << node.name
|
57
|
-
}
|
58
|
-
end
|
59
|
-
|
60
|
-
private
|
61
|
-
|
62
|
-
def assert_under_max_depth(context, max_allowed_depth, depths, fragments)
|
63
|
-
context.operations.each do |op_name, operation|
|
64
|
-
op_depth = get_total_depth(op_name, depths, fragments)
|
65
|
-
if op_depth > max_allowed_depth
|
66
|
-
op_name ||= "operation"
|
67
|
-
context.errors << message("#{op_name} has depth of #{op_depth}, which exceeds max depth of #{max_allowed_depth}", operation)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
# Get the total depth of a given fragment or operation
|
73
|
-
def get_total_depth(scope_name, depths, fragments)
|
74
|
-
own_fragments = fragments[scope_name]
|
75
|
-
depths[scope_name] + own_fragments.reduce(0) { |memo, frag_name| memo + get_total_depth(frag_name, depths, fragments) }
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|