graphql 1.3.0 → 1.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/graphql/base_type.rb +33 -5
- data/lib/graphql/boolean_type.rb +1 -0
- data/lib/graphql/compatibility/execution_specification.rb +1 -1
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +1 -0
- data/lib/graphql/directive.rb +10 -2
- data/lib/graphql/directive/deprecated_directive.rb +1 -0
- data/lib/graphql/directive/include_directive.rb +1 -0
- data/lib/graphql/directive/skip_directive.rb +1 -0
- data/lib/graphql/enum_type.rb +1 -0
- data/lib/graphql/execution/execute.rb +1 -13
- data/lib/graphql/float_type.rb +1 -0
- data/lib/graphql/id_type.rb +1 -0
- data/lib/graphql/input_object_type.rb +12 -2
- data/lib/graphql/int_type.rb +1 -0
- data/lib/graphql/interface_type.rb +1 -0
- data/lib/graphql/introspection/directive_location_enum.rb +1 -0
- data/lib/graphql/introspection/directive_type.rb +1 -0
- data/lib/graphql/introspection/enum_value_type.rb +1 -0
- data/lib/graphql/introspection/field_type.rb +1 -0
- data/lib/graphql/introspection/input_fields_field.rb +1 -1
- data/lib/graphql/introspection/input_value_type.rb +1 -0
- data/lib/graphql/introspection/schema_type.rb +2 -0
- data/lib/graphql/introspection/type_kind_enum.rb +1 -0
- data/lib/graphql/introspection/type_type.rb +1 -0
- data/lib/graphql/list_type.rb +1 -0
- data/lib/graphql/non_null_type.rb +1 -0
- data/lib/graphql/object_type.rb +1 -0
- data/lib/graphql/query.rb +50 -13
- data/lib/graphql/query/context.rb +5 -4
- data/lib/graphql/query/serial_execution/field_resolution.rb +1 -22
- data/lib/graphql/relay/array_connection.rb +3 -1
- data/lib/graphql/relay/connection_type.rb +15 -1
- data/lib/graphql/relay/node.rb +1 -0
- data/lib/graphql/relay/page_info.rb +1 -0
- data/lib/graphql/relay/relation_connection.rb +2 -0
- data/lib/graphql/schema.rb +21 -13
- data/lib/graphql/schema/catchall_middleware.rb +2 -2
- data/lib/graphql/schema/middleware_chain.rb +71 -13
- data/lib/graphql/schema/null_mask.rb +10 -0
- data/lib/graphql/schema/printer.rb +85 -59
- data/lib/graphql/schema/rescue_middleware.rb +2 -2
- data/lib/graphql/schema/timeout_middleware.rb +2 -2
- data/lib/graphql/schema/validation.rb +1 -12
- data/lib/graphql/schema/warden.rb +48 -24
- data/lib/graphql/static_validation/literal_validator.rb +2 -2
- data/lib/graphql/string_type.rb +1 -0
- data/lib/graphql/union_type.rb +7 -1
- data/lib/graphql/version.rb +1 -1
- data/readme.md +0 -19
- data/spec/graphql/directive/skip_directive_spec.rb +8 -0
- data/spec/graphql/directive_spec.rb +9 -3
- data/spec/graphql/input_object_type_spec.rb +67 -0
- data/spec/graphql/query/variables_spec.rb +1 -1
- data/spec/graphql/relay/array_connection_spec.rb +9 -0
- data/spec/graphql/relay/connection_type_spec.rb +20 -0
- data/spec/graphql/relay/node_spec.rb +6 -0
- data/spec/graphql/relay/page_info_spec.rb +4 -0
- data/spec/graphql/relay/relation_connection_spec.rb +8 -0
- data/spec/graphql/scalar_type_spec.rb +4 -0
- data/spec/graphql/schema/middleware_chain_spec.rb +27 -13
- data/spec/graphql/schema/printer_spec.rb +121 -6
- data/spec/graphql/schema/rescue_middleware_spec.rb +4 -4
- data/spec/graphql/schema/warden_spec.rb +16 -12
- data/spec/graphql/schema_spec.rb +9 -0
- data/spec/graphql/string_type_spec.rb +10 -4
- data/spec/spec_helper.rb +2 -1
- data/spec/support/star_wars_schema.rb +2 -2
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54eddb1e7e7ebdbe1ada0ab8286bda07a4141ebc
|
4
|
+
data.tar.gz: d9cc5078d078b0d9d8eded46a17ae224d33b738c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f918ba8ec64d8e3157d454ef76002b4087644fcb1f92a50821f5fd189f40806b4daec24d27049c022a59c27dc9a698742ad099546ce53b20645a7e0f6ebd8c28
|
7
|
+
data.tar.gz: 21140eaea9b18fd8405cb195f67d8f380d08dbf7d537e191c4672bd65240b1f589074927e0a62951f6506eaf0762efcd351e35b0e7951c4012b3552d70b747e0
|
data/lib/graphql/base_type.rb
CHANGED
@@ -4,12 +4,22 @@ module GraphQL
|
|
4
4
|
class BaseType
|
5
5
|
include GraphQL::Define::NonNullWithBang
|
6
6
|
include GraphQL::Define::InstanceDefinable
|
7
|
-
accepts_definitions :name, :description,
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
accepts_definitions :name, :description,
|
8
|
+
:introspection,
|
9
|
+
:default_scalar,
|
10
|
+
:default_relay,
|
11
|
+
{
|
12
|
+
connection: GraphQL::Define::AssignConnection,
|
13
|
+
global_id_field: GraphQL::Define::AssignGlobalIdField,
|
14
|
+
}
|
11
15
|
|
12
|
-
ensure_defined(:name, :description)
|
16
|
+
ensure_defined(:name, :description, :introspection?, :default_scalar?)
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
@introspection = false
|
20
|
+
@default_scalar = false
|
21
|
+
@default_relay = false
|
22
|
+
end
|
13
23
|
|
14
24
|
def initialize_copy(other)
|
15
25
|
super
|
@@ -24,6 +34,24 @@ module GraphQL
|
|
24
34
|
# @return [String, nil] a description for this type
|
25
35
|
attr_accessor :description
|
26
36
|
|
37
|
+
# @return [Boolean] Is this type a predefined introspection type?
|
38
|
+
def introspection?
|
39
|
+
@introspection
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [Boolean] Is this type a built-in scalar type? (eg, `String`, `Int`)
|
43
|
+
def default_scalar?
|
44
|
+
@default_scalar
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [Boolean] Is this type a built-in Relay type? (`Node`, `PageInfo`)
|
48
|
+
def default_relay?
|
49
|
+
@default_relay
|
50
|
+
end
|
51
|
+
|
52
|
+
# @api private
|
53
|
+
attr_writer :introspection, :default_scalar, :default_relay
|
54
|
+
|
27
55
|
# @param other [GraphQL::BaseType] compare to this object
|
28
56
|
# @return [Boolean] are these types equivalent? (incl. non-null, list)
|
29
57
|
def ==(other)
|
data/lib/graphql/boolean_type.rb
CHANGED
@@ -49,6 +49,7 @@ module GraphQL
|
|
49
49
|
end
|
50
50
|
|
51
51
|
module TestMiddleware
|
52
|
+
# TODO: Once deprecated `next_middleware` argument becomes unsupported, add `&` to the argument
|
52
53
|
def self.call(parent_type, parent_object, field_definition, field_args, query_context, next_middleware)
|
53
54
|
query_context[:middleware_log] && query_context[:middleware_log] << field_definition.name
|
54
55
|
next_middleware.call
|
data/lib/graphql/directive.rb
CHANGED
@@ -8,10 +8,12 @@ module GraphQL
|
|
8
8
|
#
|
9
9
|
class Directive
|
10
10
|
include GraphQL::Define::InstanceDefinable
|
11
|
-
accepts_definitions :locations, :name, :description, :arguments, argument: GraphQL::Define::AssignArgument
|
11
|
+
accepts_definitions :locations, :name, :description, :arguments, :default_directive, argument: GraphQL::Define::AssignArgument
|
12
12
|
|
13
13
|
attr_accessor :locations, :arguments, :name, :description
|
14
|
-
|
14
|
+
# @api private
|
15
|
+
attr_writer :default_directive
|
16
|
+
ensure_defined(:locations, :arguments, :name, :description, :default_directive?)
|
15
17
|
|
16
18
|
LOCATIONS = [
|
17
19
|
QUERY = :QUERY,
|
@@ -58,6 +60,7 @@ module GraphQL
|
|
58
60
|
|
59
61
|
def initialize
|
60
62
|
@arguments = {}
|
63
|
+
@default_directive = false
|
61
64
|
end
|
62
65
|
|
63
66
|
def to_s
|
@@ -75,6 +78,11 @@ module GraphQL
|
|
75
78
|
def on_operation?
|
76
79
|
locations.include?(QUERY) && locations.include?(MUTATION) && locations.include?(SUBSCRIPTION)
|
77
80
|
end
|
81
|
+
|
82
|
+
# @return [Boolean] Is this directive supplied by default? (eg `@skip`)
|
83
|
+
def default_directive?
|
84
|
+
@default_directive
|
85
|
+
end
|
78
86
|
end
|
79
87
|
end
|
80
88
|
|
@@ -9,4 +9,5 @@ GraphQL::Directive::DeprecatedDirective = GraphQL::Directive.define do
|
|
9
9
|
"in [Markdown](https://daringfireball.net/projects/markdown/)."
|
10
10
|
|
11
11
|
argument :reason, GraphQL::STRING_TYPE, reason_description, default_value: GraphQL::Directive::DEFAULT_DEPRECATION_REASON
|
12
|
+
default_directive true
|
12
13
|
end
|
@@ -4,4 +4,5 @@ GraphQL::Directive::IncludeDirective = GraphQL::Directive.define do
|
|
4
4
|
description "Directs the executor to include this field or fragment only when the `if` argument is true."
|
5
5
|
locations([GraphQL::Directive::FIELD, GraphQL::Directive::FRAGMENT_SPREAD, GraphQL::Directive::INLINE_FRAGMENT])
|
6
6
|
argument :if, !GraphQL::BOOLEAN_TYPE, 'Included when true.'
|
7
|
+
default_directive true
|
7
8
|
end
|
data/lib/graphql/enum_type.rb
CHANGED
@@ -57,20 +57,8 @@ module GraphQL
|
|
57
57
|
)
|
58
58
|
|
59
59
|
arguments = query.arguments_for(selection.irep_node, field)
|
60
|
-
middlewares = query.schema.middleware
|
61
|
-
resolve_arguments = [parent_type, object, field, arguments, field_ctx]
|
62
|
-
|
63
60
|
raw_value = begin
|
64
|
-
|
65
|
-
if middlewares.any?
|
66
|
-
chain = GraphQL::Schema::MiddlewareChain.new(
|
67
|
-
steps: middlewares + [FieldResolveStep],
|
68
|
-
arguments: resolve_arguments
|
69
|
-
)
|
70
|
-
chain.call
|
71
|
-
else
|
72
|
-
FieldResolveStep.call(*resolve_arguments)
|
73
|
-
end
|
61
|
+
query_ctx.schema.middleware.invoke([parent_type, object, field, arguments, field_ctx])
|
74
62
|
rescue GraphQL::ExecutionError => err
|
75
63
|
err
|
76
64
|
end
|
data/lib/graphql/float_type.rb
CHANGED
data/lib/graphql/id_type.rb
CHANGED
@@ -42,6 +42,7 @@ module GraphQL
|
|
42
42
|
|
43
43
|
|
44
44
|
def initialize
|
45
|
+
super
|
45
46
|
@arguments = {}
|
46
47
|
end
|
47
48
|
|
@@ -57,7 +58,16 @@ module GraphQL
|
|
57
58
|
def validate_non_null_input(input, warden)
|
58
59
|
result = GraphQL::Query::InputValidationResult.new
|
59
60
|
|
60
|
-
|
61
|
+
if (input.to_h rescue nil).nil?
|
62
|
+
result.add_problem(
|
63
|
+
"Expected #{JSON.generate(input, quirks_mode: true)} to be a key, value object " \
|
64
|
+
" responding to `to_h`."
|
65
|
+
)
|
66
|
+
return result
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
visible_arguments_map = warden.arguments(self).reduce({}) { |m, f| m[f.name] = f; m}
|
61
71
|
|
62
72
|
# Items in the input that are unexpected
|
63
73
|
input.each do |name, value|
|
@@ -67,7 +77,7 @@ module GraphQL
|
|
67
77
|
end
|
68
78
|
|
69
79
|
# Items in the input that are expected, but have invalid values
|
70
|
-
|
80
|
+
visible_arguments_map.map do |name, field|
|
71
81
|
field_result = field.type.validate_input(input[name], warden)
|
72
82
|
if !field_result.valid?
|
73
83
|
result.merge_result!(name, field_result)
|
data/lib/graphql/int_type.rb
CHANGED
@@ -14,4 +14,5 @@ GraphQL::Introspection::DirectiveType = GraphQL::ObjectType.define do
|
|
14
14
|
field :onOperation, !types.Boolean, deprecation_reason: "Use `locations`.", property: :on_operation?
|
15
15
|
field :onFragment, !types.Boolean, deprecation_reason: "Use `locations`.", property: :on_fragment?
|
16
16
|
field :onField, !types.Boolean, deprecation_reason: "Use `locations`.", property: :on_field?
|
17
|
+
introspection true
|
17
18
|
end
|
@@ -4,7 +4,7 @@ GraphQL::Introspection::InputFieldsField = GraphQL::Field.define do
|
|
4
4
|
type types[!GraphQL::Introspection::InputValueType]
|
5
5
|
resolve ->(target, a, ctx) {
|
6
6
|
if target.kind.input_object?
|
7
|
-
ctx.warden.
|
7
|
+
ctx.warden.arguments(target)
|
8
8
|
else
|
9
9
|
nil
|
10
10
|
end
|
@@ -24,4 +24,6 @@ GraphQL::Introspection::SchemaType = GraphQL::ObjectType.define do
|
|
24
24
|
field :directives, !types[!GraphQL::Introspection::DirectiveType], "A list of all directives supported by this server." do
|
25
25
|
resolve ->(obj, arg, ctx) { obj.directives.values }
|
26
26
|
end
|
27
|
+
|
28
|
+
introspection true
|
27
29
|
end
|
@@ -22,4 +22,5 @@ GraphQL::Introspection::TypeType = GraphQL::ObjectType.define do
|
|
22
22
|
field :enumValues, GraphQL::Introspection::EnumValuesField
|
23
23
|
field :inputFields, GraphQL::Introspection::InputFieldsField
|
24
24
|
field :ofType, GraphQL::Introspection::OfTypeField
|
25
|
+
introspection true
|
25
26
|
end
|
data/lib/graphql/list_type.rb
CHANGED
data/lib/graphql/object_type.rb
CHANGED
data/lib/graphql/query.rb
CHANGED
@@ -18,14 +18,6 @@ module GraphQL
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
module NullExcept
|
22
|
-
module_function
|
23
|
-
|
24
|
-
def call(member)
|
25
|
-
false
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
21
|
attr_reader :schema, :document, :context, :fragments, :operations, :root_value, :max_depth, :query_string, :warden, :provided_variables
|
30
22
|
|
31
23
|
# Prepare query `query_string` on `schema`
|
@@ -38,11 +30,19 @@ module GraphQL
|
|
38
30
|
# @param max_depth [Numeric] the maximum number of nested selections allowed for this query (falls back to schema-level value)
|
39
31
|
# @param max_complexity [Numeric] the maximum field complexity for this query (falls back to schema-level value)
|
40
32
|
# @param except [<#call(schema_member)>] If provided, objects will be hidden from the schema when `.call(schema_member)` returns truthy
|
41
|
-
def initialize(schema, query_string = nil, document: nil, context: nil, variables: {}, validate: true, operation_name: nil, root_value: nil, max_depth: nil, max_complexity: nil, except:
|
33
|
+
def initialize(schema, query_string = nil, document: nil, context: nil, variables: {}, validate: true, operation_name: nil, root_value: nil, max_depth: nil, max_complexity: nil, except: nil, only: nil)
|
42
34
|
fail ArgumentError, "a query string or document is required" unless query_string || document
|
43
35
|
|
44
36
|
@schema = schema
|
45
|
-
|
37
|
+
mask = if except
|
38
|
+
wrap_if_legacy_mask(except)
|
39
|
+
elsif only
|
40
|
+
InvertedMask.new(wrap_if_legacy_mask(only))
|
41
|
+
else
|
42
|
+
schema.default_mask
|
43
|
+
end
|
44
|
+
@context = Context.new(query: self, values: context)
|
45
|
+
@warden = GraphQL::Schema::Warden.new(mask, schema: @schema, context: @context)
|
46
46
|
@max_depth = max_depth || schema.max_depth
|
47
47
|
@max_complexity = max_complexity || schema.max_complexity
|
48
48
|
@query_analyzers = schema.query_analyzers.dup
|
@@ -52,7 +52,6 @@ module GraphQL
|
|
52
52
|
if @max_complexity
|
53
53
|
@query_analyzers << GraphQL::Analysis::MaxQueryComplexity.new(@max_complexity)
|
54
54
|
end
|
55
|
-
@context = Context.new(query: self, values: context)
|
56
55
|
@root_value = root_value
|
57
56
|
@operation_name = operation_name
|
58
57
|
@fragments = {}
|
@@ -74,6 +73,8 @@ module GraphQL
|
|
74
73
|
end
|
75
74
|
end
|
76
75
|
|
76
|
+
@resolved_types_cache = Hash.new { |h, k| h[k] = @schema.resolve_type(k, @context) }
|
77
|
+
|
77
78
|
@arguments_cache = Hash.new { |h, k| h[k] = {} }
|
78
79
|
@validation_errors = []
|
79
80
|
@analysis_errors = []
|
@@ -214,8 +215,11 @@ module GraphQL
|
|
214
215
|
@warden.possible_types(type)
|
215
216
|
end
|
216
217
|
|
217
|
-
|
218
|
-
|
218
|
+
# @param value [Object] Any runtime value
|
219
|
+
# @return [GraphQL::ObjectType, nil] The runtime type of `value` from {Schema#resolve_type}
|
220
|
+
# @see {#possible_types} to apply filtering from `only` / `except`
|
221
|
+
def resolve_type(value)
|
222
|
+
@resolved_types_cache[value]
|
219
223
|
end
|
220
224
|
|
221
225
|
def mutation?
|
@@ -257,5 +261,38 @@ module GraphQL
|
|
257
261
|
operations[operation_name]
|
258
262
|
end
|
259
263
|
end
|
264
|
+
|
265
|
+
def wrap_if_legacy_mask(mask)
|
266
|
+
if (mask.is_a?(Proc) && mask.arity == 1) || mask.method(:call).arity == 1
|
267
|
+
warn("Schema.execute(..., except:) filters now accept two arguments, `(member, ctx)`. One-argument filters are deprecated.")
|
268
|
+
LegacyMaskWrap.new(mask)
|
269
|
+
else
|
270
|
+
mask
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
# @api private
|
275
|
+
class InvertedMask
|
276
|
+
def initialize(inner_mask)
|
277
|
+
@inner_mask = inner_mask
|
278
|
+
end
|
279
|
+
|
280
|
+
# Returns true when the inner mask returned false
|
281
|
+
# Returns false when the inner mask returned true
|
282
|
+
def call(member, ctx)
|
283
|
+
!@inner_mask.call(member, ctx)
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
# @api private
|
288
|
+
class LegacyMaskWrap
|
289
|
+
def initialize(inner_mask)
|
290
|
+
@inner_mask = inner_mask
|
291
|
+
end
|
292
|
+
|
293
|
+
def call(member, ctx)
|
294
|
+
@inner_mask.call(member)
|
295
|
+
end
|
296
|
+
end
|
260
297
|
end
|
261
298
|
end
|
@@ -32,9 +32,6 @@ module GraphQL
|
|
32
32
|
# @return [GraphQL::Schema]
|
33
33
|
attr_reader :schema
|
34
34
|
|
35
|
-
# @return [GraphQL::Schema::Mask::Warden]
|
36
|
-
attr_reader :warden
|
37
|
-
|
38
35
|
# @return [Array<String, Integer>] The current position in the result
|
39
36
|
attr_reader :path
|
40
37
|
|
@@ -46,7 +43,6 @@ module GraphQL
|
|
46
43
|
@schema = query.schema
|
47
44
|
@values = values || {}
|
48
45
|
@errors = []
|
49
|
-
@warden = query.warden
|
50
46
|
@path = []
|
51
47
|
end
|
52
48
|
|
@@ -55,6 +51,11 @@ module GraphQL
|
|
55
51
|
@values[key]
|
56
52
|
end
|
57
53
|
|
54
|
+
# @return [GraphQL::Schema::Warden]
|
55
|
+
def warden
|
56
|
+
@warden ||= @query.warden
|
57
|
+
end
|
58
|
+
|
58
59
|
# Reassign `key` to the hash passed to {Schema#execute} as `context:`
|
59
60
|
def []=(key, value)
|
60
61
|
@values[key] = value
|