graphql 1.4.5 → 1.5.3
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/enum_generator.rb +33 -0
- data/lib/generators/graphql/function_generator.rb +15 -0
- data/lib/generators/graphql/install_generator.rb +118 -0
- data/lib/generators/graphql/interface_generator.rb +27 -0
- data/lib/generators/graphql/loader_generator.rb +17 -0
- data/lib/generators/graphql/mutation_generator.rb +19 -0
- data/lib/generators/graphql/object_generator.rb +34 -0
- data/lib/generators/graphql/templates/enum.erb +4 -0
- data/lib/generators/graphql/templates/function.erb +17 -0
- data/lib/generators/graphql/templates/graphql_controller.erb +32 -0
- data/lib/generators/graphql/templates/interface.erb +4 -0
- data/lib/generators/graphql/templates/loader.erb +15 -0
- data/lib/generators/graphql/templates/mutation.erb +12 -0
- data/lib/generators/graphql/templates/object.erb +5 -0
- data/lib/generators/graphql/templates/query_type.erb +15 -0
- data/lib/generators/graphql/templates/schema.erb +34 -0
- data/lib/generators/graphql/templates/union.erb +4 -0
- data/lib/generators/graphql/type_generator.rb +78 -0
- data/lib/generators/graphql/union_generator.rb +33 -0
- data/lib/graphql.rb +10 -0
- data/lib/graphql/analysis/analyze_query.rb +1 -1
- data/lib/graphql/analysis/query_complexity.rb +6 -50
- data/lib/graphql/analysis/query_depth.rb +1 -1
- data/lib/graphql/argument.rb +21 -0
- data/lib/graphql/compatibility/execution_specification/counter_schema.rb +3 -3
- data/lib/graphql/define.rb +1 -0
- data/lib/graphql/define/assign_argument.rb +3 -19
- data/lib/graphql/define/assign_mutation_function.rb +34 -0
- data/lib/graphql/define/assign_object_field.rb +26 -14
- data/lib/graphql/define/defined_object_proxy.rb +21 -0
- data/lib/graphql/define/instance_definable.rb +61 -11
- data/lib/graphql/directive.rb +6 -1
- data/lib/graphql/execution/directive_checks.rb +1 -0
- data/lib/graphql/execution/execute.rb +14 -9
- data/lib/graphql/execution/field_result.rb +1 -0
- data/lib/graphql/execution/lazy.rb +8 -17
- data/lib/graphql/execution/lazy/lazy_method_map.rb +2 -0
- data/lib/graphql/execution/lazy/resolve.rb +1 -0
- data/lib/graphql/execution/selection_result.rb +1 -0
- data/lib/graphql/execution/typecast.rb +39 -26
- data/lib/graphql/field.rb +15 -3
- data/lib/graphql/field/resolve.rb +3 -3
- data/lib/graphql/function.rb +134 -0
- data/lib/graphql/id_type.rb +1 -1
- data/lib/graphql/input_object_type.rb +1 -1
- data/lib/graphql/internal_representation.rb +1 -1
- data/lib/graphql/internal_representation/node.rb +35 -107
- data/lib/graphql/internal_representation/rewrite.rb +189 -183
- data/lib/graphql/internal_representation/visit.rb +38 -0
- data/lib/graphql/introspection/input_value_type.rb +10 -1
- data/lib/graphql/introspection/schema_type.rb +1 -1
- data/lib/graphql/language/lexer.rb +6 -3
- data/lib/graphql/language/lexer.rl +6 -3
- data/lib/graphql/object_type.rb +53 -13
- data/lib/graphql/query.rb +30 -14
- data/lib/graphql/query/arguments.rb +2 -0
- data/lib/graphql/query/context.rb +2 -2
- data/lib/graphql/query/literal_input.rb +9 -0
- data/lib/graphql/query/serial_execution/field_resolution.rb +2 -2
- data/lib/graphql/query/serial_execution/selection_resolution.rb +1 -1
- data/lib/graphql/relay.rb +1 -0
- data/lib/graphql/relay/array_connection.rb +1 -1
- data/lib/graphql/relay/base_connection.rb +34 -15
- data/lib/graphql/relay/connection_resolve.rb +7 -2
- data/lib/graphql/relay/mutation.rb +45 -4
- data/lib/graphql/relay/node.rb +18 -6
- data/lib/graphql/relay/range_add.rb +45 -0
- data/lib/graphql/relay/relation_connection.rb +17 -2
- data/lib/graphql/runtime_type_error.rb +1 -0
- data/lib/graphql/schema.rb +40 -5
- data/lib/graphql/schema/base_64_encoder.rb +1 -0
- data/lib/graphql/schema/build_from_definition.rb +56 -21
- data/lib/graphql/schema/default_parse_error.rb +10 -0
- data/lib/graphql/schema/loader.rb +8 -1
- data/lib/graphql/schema/null_mask.rb +1 -0
- data/lib/graphql/schema/validation.rb +35 -0
- data/lib/graphql/static_validation.rb +1 -0
- data/lib/graphql/static_validation/all_rules.rb +1 -0
- data/lib/graphql/static_validation/arguments_validator.rb +7 -4
- data/lib/graphql/static_validation/definition_dependencies.rb +183 -0
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +28 -96
- data/lib/graphql/static_validation/rules/fragment_names_are_unique.rb +23 -0
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +8 -5
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +6 -31
- data/lib/graphql/static_validation/rules/fragments_are_used.rb +11 -41
- data/lib/graphql/static_validation/rules/operation_names_are_valid.rb +2 -2
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +19 -7
- data/lib/graphql/static_validation/validation_context.rb +22 -1
- data/lib/graphql/static_validation/validator.rb +4 -1
- data/lib/graphql/string_type.rb +5 -1
- data/lib/graphql/version.rb +1 -1
- data/readme.md +12 -3
- data/spec/generators/graphql/enum_generator_spec.rb +29 -0
- data/spec/generators/graphql/function_generator_spec.rb +33 -0
- data/spec/generators/graphql/install_generator_spec.rb +185 -0
- data/spec/generators/graphql/interface_generator_spec.rb +32 -0
- data/spec/generators/graphql/loader_generator_spec.rb +31 -0
- data/spec/generators/graphql/mutation_generator_spec.rb +28 -0
- data/spec/generators/graphql/object_generator_spec.rb +42 -0
- data/spec/generators/graphql/union_generator_spec.rb +50 -0
- data/spec/graphql/analysis/query_complexity_spec.rb +2 -1
- data/spec/graphql/define/instance_definable_spec.rb +38 -0
- data/spec/graphql/directive/skip_directive_spec.rb +1 -0
- data/spec/graphql/directive_spec.rb +18 -0
- data/spec/graphql/execution/typecast_spec.rb +41 -46
- data/spec/graphql/field_spec.rb +1 -1
- data/spec/graphql/function_spec.rb +128 -0
- data/spec/graphql/internal_representation/rewrite_spec.rb +166 -129
- data/spec/graphql/introspection/type_type_spec.rb +1 -1
- data/spec/graphql/language/lexer_spec.rb +6 -0
- data/spec/graphql/object_type_spec.rb +73 -2
- data/spec/graphql/query/arguments_spec.rb +28 -0
- data/spec/graphql/query/variables_spec.rb +7 -1
- data/spec/graphql/query_spec.rb +30 -0
- data/spec/graphql/relay/base_connection_spec.rb +26 -8
- data/spec/graphql/relay/connection_resolve_spec.rb +45 -0
- data/spec/graphql/relay/connection_type_spec.rb +21 -0
- data/spec/graphql/relay/node_spec.rb +30 -2
- data/spec/graphql/relay/range_add_spec.rb +113 -0
- data/spec/graphql/schema/build_from_definition_spec.rb +114 -0
- data/spec/graphql/schema/loader_spec.rb +1 -0
- data/spec/graphql/schema/printer_spec.rb +2 -2
- data/spec/graphql/schema/validation_spec.rb +80 -11
- data/spec/graphql/schema/warden_spec.rb +10 -10
- data/spec/graphql/schema_spec.rb +18 -1
- data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +16 -0
- data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +50 -3
- data/spec/graphql/static_validation/rules/fragment_names_are_unique_spec.rb +27 -0
- data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +57 -0
- data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +1 -1
- data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +14 -0
- data/spec/graphql/string_type_spec.rb +7 -0
- data/spec/spec_helper.rb +3 -3
- data/spec/support/base_generator_test.rb +7 -0
- data/spec/support/dummy/schema.rb +32 -30
- data/spec/support/star_wars/schema.rb +81 -23
- metadata +98 -20
- data/lib/graphql/internal_representation/selection.rb +0 -85
data/lib/graphql/directive.rb
CHANGED
@@ -13,7 +13,7 @@ module GraphQL
|
|
13
13
|
attr_accessor :locations, :arguments, :name, :description
|
14
14
|
# @api private
|
15
15
|
attr_writer :default_directive
|
16
|
-
ensure_defined(:locations, :arguments, :name, :description, :default_directive
|
16
|
+
ensure_defined(:locations, :arguments, :name, :description, :default_directive?, :default_arguments)
|
17
17
|
|
18
18
|
LOCATIONS = [
|
19
19
|
QUERY = :QUERY,
|
@@ -83,6 +83,11 @@ module GraphQL
|
|
83
83
|
def default_directive?
|
84
84
|
@default_directive
|
85
85
|
end
|
86
|
+
|
87
|
+
# @return [GraphQL::Query::Arguments] Arguments to use when no args are provided in the query
|
88
|
+
def default_arguments
|
89
|
+
@default_arguments ||= GraphQL::Query::LiteralInput.defaults_for(self.arguments)
|
90
|
+
end
|
86
91
|
end
|
87
92
|
end
|
88
93
|
|
@@ -2,6 +2,7 @@
|
|
2
2
|
module GraphQL
|
3
3
|
module Execution
|
4
4
|
# A valid execution strategy
|
5
|
+
# @api private
|
5
6
|
class Execute
|
6
7
|
PROPAGATE_NULL = :__graphql_propagate_null__
|
7
8
|
|
@@ -26,13 +27,12 @@ module GraphQL
|
|
26
27
|
|
27
28
|
selection_result = SelectionResult.new
|
28
29
|
|
29
|
-
selection.
|
30
|
-
field = query.get_field(current_type, subselection.definition_name)
|
30
|
+
selection.typed_children[current_type].each do |name, subselection|
|
31
31
|
field_result = resolve_field(
|
32
32
|
selection_result,
|
33
33
|
subselection,
|
34
34
|
current_type,
|
35
|
-
|
35
|
+
subselection.definition,
|
36
36
|
object,
|
37
37
|
query_ctx
|
38
38
|
)
|
@@ -63,7 +63,7 @@ module GraphQL
|
|
63
63
|
selection: selection,
|
64
64
|
)
|
65
65
|
|
66
|
-
arguments = query.arguments_for(selection
|
66
|
+
arguments = query.arguments_for(selection, field)
|
67
67
|
raw_value = begin
|
68
68
|
query_ctx.schema.middleware.invoke([parent_type, object, field, arguments, field_ctx])
|
69
69
|
rescue GraphQL::ExecutionError => err
|
@@ -83,11 +83,16 @@ module GraphQL
|
|
83
83
|
continue_resolve_field(selection, parent_type, field, raw_value, field_ctx)
|
84
84
|
end
|
85
85
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
86
|
+
case result
|
87
|
+
when PROPAGATE_NULL, GraphQL::Execution::Lazy, SelectionResult
|
88
|
+
FieldResult.new(
|
89
|
+
owner: owner,
|
90
|
+
field: field,
|
91
|
+
value: result,
|
92
|
+
)
|
93
|
+
else
|
94
|
+
result
|
95
|
+
end
|
91
96
|
end
|
92
97
|
|
93
98
|
def continue_resolve_field(selection, parent_type, field, raw_value, field_ctx)
|
@@ -10,6 +10,7 @@ module GraphQL
|
|
10
10
|
# This is an itty-bitty promise-like object, with key differences:
|
11
11
|
# - It has only two states, not-resolved and resolved
|
12
12
|
# - It has no error-catching functionality
|
13
|
+
# @api private
|
13
14
|
class Lazy
|
14
15
|
# Traverse `val`, lazily resolving any values along the way
|
15
16
|
# @param val [Object] A data structure containing mixed plain values and `Lazy` instances
|
@@ -19,16 +20,9 @@ module GraphQL
|
|
19
20
|
end
|
20
21
|
|
21
22
|
# Create a {Lazy} which will get its inner value by calling the block
|
22
|
-
# @param target [Object]
|
23
|
-
# @param method_name [Symbol]
|
24
23
|
# @param get_value_func [Proc] a block to get the inner value (later)
|
25
|
-
def initialize(
|
26
|
-
|
27
|
-
@get_value_func = get_value_func
|
28
|
-
else
|
29
|
-
@target = target
|
30
|
-
@method_name = method_name
|
31
|
-
end
|
24
|
+
def initialize(&get_value_func)
|
25
|
+
@get_value_func = get_value_func
|
32
26
|
@resolved = false
|
33
27
|
end
|
34
28
|
|
@@ -36,22 +30,19 @@ module GraphQL
|
|
36
30
|
def value
|
37
31
|
if !@resolved
|
38
32
|
@resolved = true
|
39
|
-
|
40
|
-
@
|
41
|
-
|
42
|
-
|
33
|
+
@value = begin
|
34
|
+
@get_value_func.call
|
35
|
+
rescue GraphQL::ExecutionError => err
|
36
|
+
err
|
43
37
|
end
|
44
38
|
end
|
45
39
|
@value
|
46
|
-
rescue GraphQL::ExecutionError => err
|
47
|
-
@resolved = true
|
48
|
-
@value = err
|
49
40
|
end
|
50
41
|
|
51
42
|
# @return [Lazy] A {Lazy} whose value depends on another {Lazy}, plus any transformations in `block`
|
52
43
|
def then(&block)
|
53
44
|
self.class.new {
|
54
|
-
|
45
|
+
block.call(value)
|
55
46
|
}
|
56
47
|
end
|
57
48
|
end
|
@@ -5,6 +5,8 @@ module GraphQL
|
|
5
5
|
# {GraphQL::Schema} uses this to match returned values to lazy resolution methods.
|
6
6
|
# Methods may be registered for classes, they apply to its subclasses also.
|
7
7
|
# The result of this lookup is cached for future resolutions.
|
8
|
+
# @api private
|
9
|
+
# @see {Schema#lazy?} looks up values from this map
|
8
10
|
class LazyMethodMap
|
9
11
|
def initialize
|
10
12
|
@storage = Hash.new do |h, value_class|
|
@@ -1,35 +1,48 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module GraphQL
|
3
3
|
module Execution
|
4
|
-
#
|
5
|
-
# - `current_type == potential_type`
|
6
|
-
# - `current_type` is a union and it contains `potential_type`
|
7
|
-
# - `potential_type` is a union and it contains `current_type`
|
8
|
-
# - `current_type` is an interface and `potential_type` implements it
|
9
|
-
# - `potential_type` is an interface and `current_type` implements it
|
4
|
+
# @api private
|
10
5
|
module Typecast
|
11
|
-
#
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
#
|
16
|
-
# @param current_type [GraphQL::BaseType] the type which GraphQL is using now
|
17
|
-
# @param potential_type [GraphQL::BaseType] can this type be used from here?
|
18
|
-
# @param query_ctx [GraphQL::Query::Context] the context for the current query
|
19
|
-
# @return [Boolean] true if `value` be evaluated as a `potential_type`
|
20
|
-
def self.compatible?(current_type, potential_type, query_ctx)
|
21
|
-
if current_type == potential_type
|
6
|
+
# @return [Boolean]
|
7
|
+
def self.subtype?(parent_type, child_type)
|
8
|
+
if parent_type == child_type
|
9
|
+
# Equivalent types are subtypes
|
22
10
|
true
|
23
|
-
elsif
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
11
|
+
elsif child_type.is_a?(GraphQL::NonNullType)
|
12
|
+
# A non-null type is a subtype of a nullable type
|
13
|
+
# if its inner type is a subtype of that type
|
14
|
+
if parent_type.is_a?(GraphQL::NonNullType)
|
15
|
+
subtype?(parent_type.of_type, child_type.of_type)
|
16
|
+
else
|
17
|
+
subtype?(parent_type, child_type.of_type)
|
18
|
+
end
|
31
19
|
else
|
32
|
-
|
20
|
+
case parent_type
|
21
|
+
when GraphQL::InterfaceType
|
22
|
+
# A type is a subtype of an interface
|
23
|
+
# if it implements that interface
|
24
|
+
case child_type
|
25
|
+
when GraphQL::ObjectType
|
26
|
+
child_type.interfaces.include?(parent_type)
|
27
|
+
else
|
28
|
+
false
|
29
|
+
end
|
30
|
+
when GraphQL::UnionType
|
31
|
+
# A type is a subtype of that interface
|
32
|
+
# if the union includes that interface
|
33
|
+
parent_type.possible_types.include?(child_type)
|
34
|
+
when GraphQL::ListType
|
35
|
+
# A list type is a subtype of another list type
|
36
|
+
# if its inner type is a subtype of the other inner type
|
37
|
+
case child_type
|
38
|
+
when GraphQL::ListType
|
39
|
+
subtype?(parent_type.of_type, child_type.of_type)
|
40
|
+
else
|
41
|
+
false
|
42
|
+
end
|
43
|
+
else
|
44
|
+
false
|
45
|
+
end
|
33
46
|
end
|
34
47
|
end
|
35
48
|
end
|
data/lib/graphql/field.rb
CHANGED
@@ -124,16 +124,18 @@ module GraphQL
|
|
124
124
|
accepts_definitions :name, :description, :deprecation_reason,
|
125
125
|
:resolve, :lazy_resolve,
|
126
126
|
:type, :arguments,
|
127
|
-
:property, :hash_key, :complexity,
|
127
|
+
:property, :hash_key, :complexity,
|
128
|
+
:mutation, :function,
|
128
129
|
:relay_node_field,
|
129
130
|
:relay_nodes_field,
|
130
131
|
argument: GraphQL::Define::AssignArgument
|
131
132
|
|
132
133
|
ensure_defined(
|
133
|
-
:name, :deprecation_reason, :description, :description=, :property, :hash_key,
|
134
|
+
:name, :deprecation_reason, :description, :description=, :property, :hash_key,
|
135
|
+
:mutation, :arguments, :complexity, :function,
|
134
136
|
:resolve, :resolve=, :lazy_resolve, :lazy_resolve=, :lazy_resolve_proc, :resolve_proc,
|
135
137
|
:type, :type=, :name=, :property=, :hash_key=,
|
136
|
-
:relay_node_field, :relay_nodes_field,
|
138
|
+
:relay_node_field, :relay_nodes_field, :default_arguments
|
137
139
|
)
|
138
140
|
|
139
141
|
# @return [Boolean] True if this is the Relay find-by-id field
|
@@ -172,17 +174,22 @@ module GraphQL
|
|
172
174
|
# @return [Object, nil] The key to access with `obj.[]` to resolve this field (overrides {#name} if present)
|
173
175
|
attr_accessor :hash_key
|
174
176
|
|
177
|
+
# @return [Object, GraphQL::Function] The function used to derive this field
|
178
|
+
attr_accessor :function
|
179
|
+
|
175
180
|
def initialize
|
176
181
|
@complexity = 1
|
177
182
|
@arguments = {}
|
178
183
|
@resolve_proc = build_default_resolver
|
179
184
|
@lazy_resolve_proc = DefaultLazyResolve
|
180
185
|
@relay_node_field = false
|
186
|
+
@default_arguments = nil
|
181
187
|
end
|
182
188
|
|
183
189
|
def initialize_copy(other)
|
184
190
|
super
|
185
191
|
@arguments = other.arguments.dup
|
192
|
+
@default_arguments = nil
|
186
193
|
end
|
187
194
|
|
188
195
|
# Get a value for this field
|
@@ -263,6 +270,11 @@ module GraphQL
|
|
263
270
|
}
|
264
271
|
end
|
265
272
|
|
273
|
+
# @return [GraphQL::Query::Arguments] Arguments to use when no args are provided in the query
|
274
|
+
def default_arguments
|
275
|
+
@default_arguments ||= GraphQL::Query::LiteralInput.defaults_for(self.arguments)
|
276
|
+
end
|
277
|
+
|
266
278
|
private
|
267
279
|
|
268
280
|
def build_default_resolver
|
@@ -9,7 +9,7 @@ module GraphQL
|
|
9
9
|
# @return [Proc] A resolver for this field, based on its config
|
10
10
|
def create_proc(field)
|
11
11
|
if field.property
|
12
|
-
MethodResolve.new(field
|
12
|
+
MethodResolve.new(field)
|
13
13
|
elsif !field.hash_key.nil?
|
14
14
|
HashKeyResolve.new(field.hash_key)
|
15
15
|
else
|
@@ -23,8 +23,8 @@ module GraphQL
|
|
23
23
|
|
24
24
|
# Resolve the field by `public_send`ing `@method_name`
|
25
25
|
class MethodResolve < BuiltInResolve
|
26
|
-
def initialize(
|
27
|
-
@method_name =
|
26
|
+
def initialize(field)
|
27
|
+
@method_name = field.property.to_sym
|
28
28
|
end
|
29
29
|
|
30
30
|
def call(obj, args, ctx)
|
@@ -0,0 +1,134 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
# A reusable container for field logic, including arguments, resolve, return type, and documentation.
|
4
|
+
#
|
5
|
+
# Class-level values defined with the DSL will be inherited,
|
6
|
+
# so {GraphQL::Function}s can extend one another.
|
7
|
+
#
|
8
|
+
# It's OK to override the instance methods here in order to customize behavior of instances.
|
9
|
+
#
|
10
|
+
# @example A reusable GraphQL::Function attached as a field
|
11
|
+
# class FindRecord < GraphQL::Function
|
12
|
+
# attr_reader :type
|
13
|
+
#
|
14
|
+
# def initialize(model:, type:)
|
15
|
+
# @model = model
|
16
|
+
# @type = type
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# argument :id, GraphQL::ID_TYPE
|
20
|
+
#
|
21
|
+
# def resolve(obj, args, ctx)
|
22
|
+
# @model.find(args.id)
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# QueryType = GraphQL::ObjectType.define do
|
27
|
+
# name "Query"
|
28
|
+
# field :post, function: FindRecord.new(model: Post, type: PostType)
|
29
|
+
# field :comment, function: FindRecord.new(model: Comment, type: CommentType)
|
30
|
+
# end
|
31
|
+
class Function
|
32
|
+
# @return [Hash<String => GraphQL::Argument>] Arguments, keyed by name
|
33
|
+
def arguments
|
34
|
+
self.class.arguments
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [GraphQL::BaseType] Return type
|
38
|
+
def type
|
39
|
+
self.class.type
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [Object] This function's resolver
|
43
|
+
def call(obj, args, ctx)
|
44
|
+
raise NotImplementedError
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [String, nil]
|
48
|
+
def description
|
49
|
+
self.class.description
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [String, nil]
|
53
|
+
def deprecation_reason
|
54
|
+
self.class.deprecation_reason
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return [Integer, Proc]
|
58
|
+
def complexity
|
59
|
+
self.class.complexity || 1
|
60
|
+
end
|
61
|
+
|
62
|
+
class << self
|
63
|
+
# Define an argument for this function & its subclasses
|
64
|
+
# @see {GraphQL::Field} same arguments as the `argument` definition helper
|
65
|
+
# @return [void]
|
66
|
+
def argument(*args, **kwargs, &block)
|
67
|
+
argument = GraphQL::Argument.from_dsl(*args, **kwargs, &block)
|
68
|
+
own_arguments[argument.name] = argument
|
69
|
+
nil
|
70
|
+
end
|
71
|
+
|
72
|
+
# @return [Hash<String => GraphQL::Argument>] Arguments for this function class, including inherited arguments
|
73
|
+
def arguments
|
74
|
+
if parent_function?
|
75
|
+
own_arguments.merge(superclass.arguments)
|
76
|
+
else
|
77
|
+
own_arguments.dup
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Get or set the return type for this function class & descendants
|
82
|
+
# @return [GraphQL::BaseType]
|
83
|
+
def type(premade_type = nil, &block)
|
84
|
+
if block_given?
|
85
|
+
@type = GraphQL::ObjectType.define(&block)
|
86
|
+
elsif premade_type
|
87
|
+
@type = premade_type
|
88
|
+
elsif parent_function?
|
89
|
+
@type || superclass.type
|
90
|
+
else
|
91
|
+
@type
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Class-level reader/writer which is inherited
|
96
|
+
# @api private
|
97
|
+
def self.inherited_value(name)
|
98
|
+
self.class_eval <<-RUBY
|
99
|
+
def #{name}(new_value = nil)
|
100
|
+
if new_value
|
101
|
+
@#{name} = new_value
|
102
|
+
elsif parent_function?
|
103
|
+
@#{name} || superclass.#{name}
|
104
|
+
else
|
105
|
+
@#{name}
|
106
|
+
end
|
107
|
+
end
|
108
|
+
RUBY
|
109
|
+
end
|
110
|
+
|
111
|
+
# @!method description(new_value = nil)
|
112
|
+
# Get or set this class's description
|
113
|
+
inherited_value(:description)
|
114
|
+
# @!method deprecation_reason(new_value = nil)
|
115
|
+
# Get or set this class's deprecation_reason
|
116
|
+
inherited_value(:deprecation_reason)
|
117
|
+
# @!method complexity(new_value = nil)
|
118
|
+
# Get or set this class's complexity
|
119
|
+
inherited_value(:complexity)
|
120
|
+
|
121
|
+
private
|
122
|
+
|
123
|
+
# Does this function inherit from another function?
|
124
|
+
def parent_function?
|
125
|
+
superclass <= GraphQL::Function
|
126
|
+
end
|
127
|
+
|
128
|
+
# Arguments defined on this class (not superclasses)
|
129
|
+
def own_arguments
|
130
|
+
@own_arguments ||= {}
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|