graphql 1.8.0.pre2 → 1.8.0.pre3
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 +1 -1
- data/lib/graphql/deprecated_dsl.rb +2 -0
- data/lib/graphql/enum_type.rb +1 -1
- data/lib/graphql/field.rb +10 -1
- data/lib/graphql/input_object_type.rb +3 -1
- data/lib/graphql/introspection.rb +3 -10
- data/lib/graphql/introspection/base_object.rb +15 -0
- data/lib/graphql/introspection/directive_location_enum.rb +11 -7
- data/lib/graphql/introspection/directive_type.rb +23 -16
- data/lib/graphql/introspection/dynamic_fields.rb +11 -0
- data/lib/graphql/introspection/entry_points.rb +29 -0
- data/lib/graphql/introspection/enum_value_type.rb +16 -11
- data/lib/graphql/introspection/field_type.rb +21 -12
- data/lib/graphql/introspection/input_value_type.rb +26 -23
- data/lib/graphql/introspection/schema_field.rb +7 -2
- data/lib/graphql/introspection/schema_type.rb +36 -22
- data/lib/graphql/introspection/type_by_name_field.rb +10 -2
- data/lib/graphql/introspection/type_kind_enum.rb +10 -6
- data/lib/graphql/introspection/type_type.rb +85 -23
- data/lib/graphql/introspection/typename_field.rb +1 -0
- data/lib/graphql/language.rb +1 -0
- data/lib/graphql/language/document_from_schema_definition.rb +129 -37
- data/lib/graphql/language/generation.rb +3 -182
- data/lib/graphql/language/nodes.rb +12 -2
- data/lib/graphql/language/parser.rb +63 -55
- data/lib/graphql/language/parser.y +2 -1
- data/lib/graphql/language/printer.rb +351 -0
- data/lib/graphql/object_type.rb +1 -1
- data/lib/graphql/query.rb +1 -1
- data/lib/graphql/query/arguments.rb +24 -8
- data/lib/graphql/query/context.rb +3 -0
- data/lib/graphql/query/literal_input.rb +4 -1
- data/lib/graphql/railtie.rb +28 -6
- data/lib/graphql/schema.rb +42 -7
- data/lib/graphql/schema/enum.rb +1 -0
- data/lib/graphql/schema/field.rb +26 -5
- data/lib/graphql/schema/field/dynamic_resolve.rb +18 -9
- data/lib/graphql/schema/input_object.rb +2 -2
- data/lib/graphql/schema/introspection_system.rb +93 -0
- data/lib/graphql/schema/late_bound_type.rb +32 -0
- data/lib/graphql/schema/member.rb +21 -1
- data/lib/graphql/schema/member/build_type.rb +8 -6
- data/lib/graphql/schema/member/has_fields.rb +1 -1
- data/lib/graphql/schema/member/instrumentation.rb +3 -1
- data/lib/graphql/schema/member/list_type_proxy.rb +4 -0
- data/lib/graphql/schema/member/non_null_type_proxy.rb +4 -0
- data/lib/graphql/schema/object.rb +2 -1
- data/lib/graphql/schema/printer.rb +33 -266
- data/lib/graphql/schema/traversal.rb +74 -6
- data/lib/graphql/schema/validation.rb +3 -2
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +6 -6
- data/lib/graphql/tracing/scout_tracing.rb +2 -2
- data/lib/graphql/upgrader/member.rb +463 -63
- data/lib/graphql/version.rb +1 -1
- data/spec/fixtures/upgrader/blame_range.original.rb +43 -0
- data/spec/fixtures/upgrader/blame_range.transformed.rb +31 -0
- data/spec/fixtures/upgrader/subscribable.original.rb +51 -0
- data/spec/fixtures/upgrader/subscribable.transformed.rb +46 -0
- data/spec/fixtures/upgrader/type_x.original.rb +35 -0
- data/spec/fixtures/upgrader/type_x.transformed.rb +35 -0
- data/spec/graphql/language/document_from_schema_definition_spec.rb +729 -296
- data/spec/graphql/language/generation_spec.rb +21 -186
- data/spec/graphql/language/nodes_spec.rb +21 -0
- data/spec/graphql/language/printer_spec.rb +203 -0
- data/spec/graphql/query/arguments_spec.rb +14 -4
- data/spec/graphql/query/context_spec.rb +17 -0
- data/spec/graphql/schema/build_from_definition_spec.rb +13 -4
- data/spec/graphql/schema/field_spec.rb +14 -0
- data/spec/graphql/schema/introspection_system_spec.rb +39 -0
- data/spec/graphql/schema/object_spec.rb +12 -1
- data/spec/graphql/schema/printer_spec.rb +14 -14
- data/spec/graphql/tracing/platform_tracing_spec.rb +2 -2
- data/spec/graphql/upgrader/member_spec.rb +274 -62
- data/spec/support/jazz.rb +75 -3
- metadata +38 -9
- data/lib/graphql/introspection/arguments_field.rb +0 -7
- data/lib/graphql/introspection/enum_values_field.rb +0 -18
- data/lib/graphql/introspection/fields_field.rb +0 -13
- data/lib/graphql/introspection/input_fields_field.rb +0 -12
- data/lib/graphql/introspection/interfaces_field.rb +0 -11
- data/lib/graphql/introspection/of_type_field.rb +0 -6
- data/lib/graphql/introspection/possible_types_field.rb +0 -11
data/lib/graphql/object_type.rb
CHANGED
@@ -32,7 +32,7 @@ module GraphQL
|
|
32
32
|
# @return [Hash<String => GraphQL::Field>] Map String fieldnames to their {GraphQL::Field} implementations
|
33
33
|
|
34
34
|
# @!attribute mutation
|
35
|
-
# @return [GraphQL::Relay::Mutation, nil] The mutation this
|
35
|
+
# @return [GraphQL::Relay::Mutation, nil] The mutation this object type was derived from, if it is an auto-generated payload type.
|
36
36
|
|
37
37
|
def initialize
|
38
38
|
super
|
data/lib/graphql/query.rb
CHANGED
@@ -79,7 +79,7 @@ module GraphQL
|
|
79
79
|
def initialize(schema, query_string = nil, query: nil, document: nil, context: nil, variables: {}, validate: true, subscription_topic: nil, operation_name: nil, root_value: nil, max_depth: nil, max_complexity: nil, except: nil, only: nil)
|
80
80
|
@schema = schema
|
81
81
|
@filter = schema.default_filter.merge(except: except, only: only)
|
82
|
-
@context =
|
82
|
+
@context = schema.context_class.new(query: self, object: root_value, values: context)
|
83
83
|
@subscription_topic = subscription_topic
|
84
84
|
@root_value = root_value
|
85
85
|
@fragments = nil
|
@@ -35,13 +35,14 @@ module GraphQL
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
def initialize(values, context:)
|
38
|
+
def initialize(values, context:, defaults_used:)
|
39
39
|
@argument_values = values.inject({}) do |memo, (inner_key, inner_value)|
|
40
|
-
|
41
|
-
|
40
|
+
arg_name = inner_key.to_s
|
41
|
+
arg_defn = self.class.argument_definitions[arg_name]
|
42
|
+
arg_default_used = defaults_used.include?(arg_name)
|
42
43
|
arg_value = wrap_value(inner_value, arg_defn.type, context)
|
43
44
|
string_key = arg_defn.expose_as
|
44
|
-
memo[string_key] = ArgumentValue.new(string_key, arg_value, arg_defn)
|
45
|
+
memo[string_key] = ArgumentValue.new(string_key, arg_value, arg_defn, arg_default_used)
|
45
46
|
memo
|
46
47
|
end
|
47
48
|
end
|
@@ -60,6 +61,13 @@ module GraphQL
|
|
60
61
|
@argument_values.key?(key_s)
|
61
62
|
end
|
62
63
|
|
64
|
+
# @param key [String, Symbol] name of value to access
|
65
|
+
# @return [Boolean] true if the argument default was passed as the argument value to the resolver
|
66
|
+
def default_used?(key)
|
67
|
+
key_s = key.is_a?(String) ? key : key.to_s
|
68
|
+
@argument_values.fetch(key_s, NULL_ARGUMENT_VALUE).default_used?
|
69
|
+
end
|
70
|
+
|
63
71
|
# Get the hash of all values, with stringified keys
|
64
72
|
# @return [Hash] the stringified hash
|
65
73
|
def to_h
|
@@ -92,20 +100,28 @@ module GraphQL
|
|
92
100
|
self.argument_definitions = []
|
93
101
|
end
|
94
102
|
|
95
|
-
NO_ARGS = NoArguments.new({}, context: nil)
|
103
|
+
NO_ARGS = NoArguments.new({}, context: nil, defaults_used: Set.new)
|
96
104
|
|
97
105
|
private
|
98
106
|
|
99
107
|
class ArgumentValue
|
100
108
|
attr_reader :key, :value, :definition
|
101
|
-
|
109
|
+
attr_writer :default_used
|
110
|
+
|
111
|
+
def initialize(key, value, definition, default_used)
|
102
112
|
@key = key
|
103
113
|
@value = value
|
104
114
|
@definition = definition
|
115
|
+
@default_used = default_used
|
116
|
+
end
|
117
|
+
|
118
|
+
# @return [Boolean] true if the argument default was passed as the argument value to the resolver
|
119
|
+
def default_used?
|
120
|
+
@default_used
|
105
121
|
end
|
106
122
|
end
|
107
123
|
|
108
|
-
NULL_ARGUMENT_VALUE = ArgumentValue.new(nil, nil, nil)
|
124
|
+
NULL_ARGUMENT_VALUE = ArgumentValue.new(nil, nil, nil, nil)
|
109
125
|
|
110
126
|
def wrap_value(value, arg_defn_type, context)
|
111
127
|
if value.nil?
|
@@ -118,7 +134,7 @@ module GraphQL
|
|
118
134
|
wrap_value(value, arg_defn_type.of_type, context)
|
119
135
|
when GraphQL::InputObjectType
|
120
136
|
if value.is_a?(Hash)
|
121
|
-
arg_defn_type.arguments_class.new(value, context: context)
|
137
|
+
arg_defn_type.arguments_class.new(value, context: context, defaults_used: Set.new)
|
122
138
|
else
|
123
139
|
value
|
124
140
|
end
|
@@ -49,6 +49,8 @@ module GraphQL
|
|
49
49
|
def self.from_arguments(ast_arguments, argument_owner, variables)
|
50
50
|
context = variables ? variables.context : nil
|
51
51
|
values_hash = {}
|
52
|
+
defaults_used = Set.new
|
53
|
+
|
52
54
|
indexed_arguments = case ast_arguments
|
53
55
|
when Hash
|
54
56
|
ast_arguments
|
@@ -93,6 +95,7 @@ module GraphQL
|
|
93
95
|
# then add the default value.
|
94
96
|
if arg_defn.default_value? && !values_hash.key?(arg_name)
|
95
97
|
value = arg_defn.default_value
|
98
|
+
defaults_used << arg_name
|
96
99
|
# `context` isn't present when pre-calculating defaults
|
97
100
|
if context
|
98
101
|
value = arg_defn.prepare(value, context)
|
@@ -105,7 +108,7 @@ module GraphQL
|
|
105
108
|
end
|
106
109
|
end
|
107
110
|
|
108
|
-
argument_owner.arguments_class.new(values_hash, context: context)
|
111
|
+
argument_owner.arguments_class.new(values_hash, context: context, defaults_used: defaults_used)
|
109
112
|
end
|
110
113
|
end
|
111
114
|
end
|
data/lib/graphql/railtie.rb
CHANGED
@@ -19,17 +19,40 @@ module GraphQL
|
|
19
19
|
Rake::Task["graphql:upgrade:member"].execute(Struct.new(:member_file).new(file))
|
20
20
|
end
|
21
21
|
end
|
22
|
+
|
23
|
+
puts "Upgrade complete! Note that this is a best-effort approach, and may very well contain some bugs."
|
24
|
+
puts "Don't forget to create the base objects. For example, you could run:"
|
25
|
+
puts "\tbin/rake graphql:upgrade:create_base_objects[app/graphql]"
|
22
26
|
end
|
23
27
|
|
24
28
|
namespace :upgrade do
|
25
29
|
task :create_base_objects, [:base_dir] do |t, args|
|
26
|
-
base_dir = args
|
30
|
+
unless (base_dir = args[:base_dir])
|
31
|
+
fail 'You have to give me a directory where your GraphQL types live. ' \
|
32
|
+
'For example: `bin/rake graphql:upgrade:create_base_objects[app/graphql]`'
|
33
|
+
end
|
34
|
+
|
35
|
+
destination_file = File.join(base_dir, "types", "base_scalar.rb")
|
36
|
+
unless File.exists?(destination_file)
|
37
|
+
FileUtils.mkdir_p(File.dirname(destination_file))
|
38
|
+
File.open(destination_file, 'w') do |f|
|
39
|
+
f.write "class Types::BaseScalar < GraphQL::Schema::Scalar\nend"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
destination_file = File.join(base_dir, "types", "base_input_object.rb")
|
44
|
+
unless File.exists?(destination_file)
|
45
|
+
FileUtils.mkdir_p(File.dirname(destination_file))
|
46
|
+
File.open(destination_file, 'w') do |f|
|
47
|
+
f.write "class Types::BaseInputObject < GraphQL::Schema::InputObject\nend"
|
48
|
+
end
|
49
|
+
end
|
27
50
|
|
28
51
|
destination_file = File.join(base_dir, "types", "base_enum.rb")
|
29
52
|
unless File.exists?(destination_file)
|
30
53
|
FileUtils.mkdir_p(File.dirname(destination_file))
|
31
54
|
File.open(destination_file, 'w') do |f|
|
32
|
-
f.write "class Types::BaseEnum < GraphQL::Schema::Enum
|
55
|
+
f.write "class Types::BaseEnum < GraphQL::Schema::Enum\nend"
|
33
56
|
end
|
34
57
|
end
|
35
58
|
|
@@ -37,7 +60,7 @@ module GraphQL
|
|
37
60
|
unless File.exists?(destination_file)
|
38
61
|
FileUtils.mkdir_p(File.dirname(destination_file))
|
39
62
|
File.open(destination_file, 'w') do |f|
|
40
|
-
f.write "class Types::BaseUnion < GraphQL::Schema::Union
|
63
|
+
f.write "class Types::BaseUnion < GraphQL::Schema::Union\nend"
|
41
64
|
end
|
42
65
|
end
|
43
66
|
|
@@ -45,14 +68,14 @@ module GraphQL
|
|
45
68
|
unless File.exists?(destination_file)
|
46
69
|
FileUtils.mkdir_p(File.dirname(destination_file))
|
47
70
|
File.open(destination_file, 'w') do |f|
|
48
|
-
f.write "class Types::BaseInterface < GraphQL::Schema::Interface
|
71
|
+
f.write "class Types::BaseInterface < GraphQL::Schema::Interface\nend"
|
49
72
|
end
|
50
73
|
end
|
51
74
|
|
52
75
|
destination_file = File.join(base_dir, "types", "base_object.rb")
|
53
76
|
unless File.exists?(destination_file)
|
54
77
|
File.open(destination_file, 'w') do |f|
|
55
|
-
f.write "class Types::BaseObject < GraphQL::Schema::Object
|
78
|
+
f.write "class Types::BaseObject < GraphQL::Schema::Object\nend"
|
56
79
|
end
|
57
80
|
end
|
58
81
|
end
|
@@ -80,4 +103,3 @@ module GraphQL
|
|
80
103
|
end
|
81
104
|
end
|
82
105
|
end
|
83
|
-
|
data/lib/graphql/schema.rb
CHANGED
@@ -4,6 +4,8 @@ require "graphql/schema/catchall_middleware"
|
|
4
4
|
require "graphql/schema/default_parse_error"
|
5
5
|
require "graphql/schema/default_type_error"
|
6
6
|
require "graphql/schema/invalid_type_error"
|
7
|
+
require "graphql/schema/introspection_system"
|
8
|
+
require "graphql/schema/late_bound_type"
|
7
9
|
require "graphql/schema/middleware_chain"
|
8
10
|
require "graphql/schema/null_mask"
|
9
11
|
require "graphql/schema/possible_types"
|
@@ -91,7 +93,7 @@ module GraphQL
|
|
91
93
|
:orphan_types, :directives,
|
92
94
|
:query_analyzers, :multiplex_analyzers, :instrumenters, :lazy_methods,
|
93
95
|
:cursor_encoder,
|
94
|
-
:raise_definition_error
|
96
|
+
:raise_definition_error, :introspection_namespace
|
95
97
|
|
96
98
|
# Single, long-lived instance of the provided subscriptions class, if there is one.
|
97
99
|
# @return [GraphQL::Subscriptions]
|
@@ -104,6 +106,10 @@ module GraphQL
|
|
104
106
|
# @see {Query.new} for query-specific filters with `except:`
|
105
107
|
attr_accessor :default_mask
|
106
108
|
|
109
|
+
# @see {GraphQL::Query::Context} The parent class of these classes
|
110
|
+
# @return [Class] Instantiated for each query
|
111
|
+
attr_accessor :context_class
|
112
|
+
|
107
113
|
class << self
|
108
114
|
attr_accessor :default_execution_strategy
|
109
115
|
end
|
@@ -148,6 +154,9 @@ module GraphQL
|
|
148
154
|
@subscription_execution_strategy = self.class.default_execution_strategy
|
149
155
|
@default_mask = GraphQL::Schema::NullMask
|
150
156
|
@rebuilding_artifacts = false
|
157
|
+
@context_class = GraphQL::Query::Context
|
158
|
+
@introspection_namespace = nil
|
159
|
+
@introspection_system = nil
|
151
160
|
end
|
152
161
|
|
153
162
|
def initialize_copy(other)
|
@@ -175,6 +184,7 @@ module GraphQL
|
|
175
184
|
# This will be rebuilt when it's requested
|
176
185
|
# or during a later `define` call
|
177
186
|
@types = nil
|
187
|
+
@introspection_system = nil
|
178
188
|
end
|
179
189
|
|
180
190
|
def rescue_from(*args, &block)
|
@@ -250,6 +260,14 @@ module GraphQL
|
|
250
260
|
end
|
251
261
|
end
|
252
262
|
|
263
|
+
# @api private
|
264
|
+
def introspection_system
|
265
|
+
@introspection_system ||= begin
|
266
|
+
rebuild_artifacts
|
267
|
+
@introspection_system
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
253
271
|
# Returns a list of Arguments and Fields referencing a certain type
|
254
272
|
# @param type_name [String]
|
255
273
|
# @return [Hash]
|
@@ -331,12 +349,10 @@ module GraphQL
|
|
331
349
|
defined_field = @instrumented_field_map[parent_type_name][field_name]
|
332
350
|
if defined_field
|
333
351
|
defined_field
|
334
|
-
elsif
|
335
|
-
|
336
|
-
elsif
|
337
|
-
|
338
|
-
elsif field_name == "__type" && parent_type == query
|
339
|
-
GraphQL::Introspection::TypeByNameField
|
352
|
+
elsif parent_type == query && (entry_point_field = introspection_system.entry_point(name: field_name))
|
353
|
+
entry_point_field
|
354
|
+
elsif (dynamic_field = introspection_system.dynamic_field(name: field_name))
|
355
|
+
dynamic_field
|
340
356
|
else
|
341
357
|
nil
|
342
358
|
end
|
@@ -632,9 +648,11 @@ module GraphQL
|
|
632
648
|
directives(DIRECTIVES)
|
633
649
|
end
|
634
650
|
schema_defn.directives = directives
|
651
|
+
schema_defn.introspection_namespace = introspection
|
635
652
|
schema_defn.resolve_type = method(:resolve_type)
|
636
653
|
schema_defn.object_from_id = method(:object_from_id)
|
637
654
|
schema_defn.id_from_object = method(:id_from_object)
|
655
|
+
schema_defn.context_class = context_class
|
638
656
|
instrumenters.each do |step, insts|
|
639
657
|
insts.each do |inst|
|
640
658
|
schema_defn.instrumenters[step] << inst
|
@@ -686,6 +704,14 @@ module GraphQL
|
|
686
704
|
end
|
687
705
|
end
|
688
706
|
|
707
|
+
def introspection(new_introspection_namespace = nil)
|
708
|
+
if new_introspection_namespace
|
709
|
+
@introspection = new_introspection_namespace
|
710
|
+
else
|
711
|
+
@introspection
|
712
|
+
end
|
713
|
+
end
|
714
|
+
|
689
715
|
def default_max_page_size(new_default_max_page_size = nil)
|
690
716
|
if new_default_max_page_size
|
691
717
|
@default_max_page_size = new_default_max_page_size
|
@@ -718,6 +744,14 @@ module GraphQL
|
|
718
744
|
end
|
719
745
|
end
|
720
746
|
|
747
|
+
def context_class(new_context_class = nil)
|
748
|
+
if new_context_class
|
749
|
+
@context_class = new_context_class
|
750
|
+
else
|
751
|
+
@context_class || GraphQL::Query::Context
|
752
|
+
end
|
753
|
+
end
|
754
|
+
|
721
755
|
def resolve_type(type, obj, ctx)
|
722
756
|
raise NotImplementedError, "#{self.name}.resolve_type(type, obj, ctx) must be implemented to use Union types or Interface types (tried to resolve: #{type.name})"
|
723
757
|
end
|
@@ -805,6 +839,7 @@ module GraphQL
|
|
805
839
|
raise CyclicalDefinitionError, "Part of the schema build process re-triggered the schema build process, causing an infinite loop. Avoid using Schema#types, Schema#possible_types, and Schema#get_field during schema build."
|
806
840
|
else
|
807
841
|
@rebuilding_artifacts = true
|
842
|
+
@introspection_system = Schema::IntrospectionSystem.new(self)
|
808
843
|
traversal = Traversal.new(self)
|
809
844
|
@types = traversal.type_map
|
810
845
|
@root_types = [query, mutation, subscription]
|
data/lib/graphql/schema/enum.rb
CHANGED
@@ -54,6 +54,7 @@ module GraphQL
|
|
54
54
|
enum_type = GraphQL::EnumType.new
|
55
55
|
enum_type.name = graphql_name
|
56
56
|
enum_type.description = description
|
57
|
+
enum_type.introspection = introspection
|
57
58
|
values.each do |val|
|
58
59
|
enum_value = GraphQL::EnumType::EnumValue.new
|
59
60
|
enum_value.name = val.name
|
data/lib/graphql/schema/field.rb
CHANGED
@@ -13,7 +13,7 @@ module GraphQL
|
|
13
13
|
# @return [String]
|
14
14
|
attr_reader :description
|
15
15
|
|
16
|
-
def initialize(name, return_type_expr = nil, desc = nil, null: nil, field: nil, function: nil, deprecation_reason: nil, method: nil, connection: nil, max_page_size: nil, resolve: nil, &args_block)
|
16
|
+
def initialize(name, return_type_expr = nil, desc = nil, null: nil, field: nil, function: nil, description: nil, deprecation_reason: nil, method: nil, connection: nil, max_page_size: nil, resolve: nil, introspection: false, extras: [], &args_block)
|
17
17
|
if !(field || function)
|
18
18
|
if return_type_expr.nil?
|
19
19
|
raise ArgumentError, "missing positional argument `type`"
|
@@ -22,8 +22,14 @@ module GraphQL
|
|
22
22
|
raise ArgumentError, "missing keyword argument null:"
|
23
23
|
end
|
24
24
|
end
|
25
|
+
if (field || function || resolve) && extras.any?
|
26
|
+
raise ArgumentError, "keyword `extras:` may only be used with method-based resolve, please remove `field:`, `function:`, or `resolve:`"
|
27
|
+
end
|
25
28
|
@name = name.to_s
|
26
|
-
|
29
|
+
if description && desc
|
30
|
+
raise ArgumentError, "Provide description as a positional argument or `description:` keyword, but not both (#{desc.inspect}, #{description.inspect})"
|
31
|
+
end
|
32
|
+
@description = description || desc
|
27
33
|
@field = field
|
28
34
|
@function = function
|
29
35
|
@resolve = resolve
|
@@ -34,6 +40,8 @@ module GraphQL
|
|
34
40
|
@args_block = args_block
|
35
41
|
@connection = connection
|
36
42
|
@max_page_size = max_page_size
|
43
|
+
@introspection = introspection
|
44
|
+
@extras = extras
|
37
45
|
end
|
38
46
|
|
39
47
|
# @return [GraphQL::Field]
|
@@ -49,7 +57,6 @@ module GraphQL
|
|
49
57
|
end
|
50
58
|
|
51
59
|
field_defn.name = Member::BuildType.camelize(name)
|
52
|
-
|
53
60
|
if @return_type_expr
|
54
61
|
return_type_name = Member::BuildType.to_type_name(@return_type_expr)
|
55
62
|
connection = @connection.nil? ? return_type_name.end_with?("Connection") : @connection
|
@@ -75,11 +82,16 @@ module GraphQL
|
|
75
82
|
prev_resolve = @resolve || field_defn.resolve_proc
|
76
83
|
UnwrappedResolve.new(inner_resolve: prev_resolve)
|
77
84
|
else
|
78
|
-
DynamicResolve.new(
|
85
|
+
DynamicResolve.new(
|
86
|
+
method_name: method_name,
|
87
|
+
connection: connection,
|
88
|
+
extras: @extras
|
89
|
+
)
|
79
90
|
end
|
80
91
|
|
81
92
|
field_defn.connection = connection
|
82
93
|
field_defn.connection_max_page_size = @max_page_size
|
94
|
+
field_defn.introspection = @introspection
|
83
95
|
|
84
96
|
field_proxy = FieldProxy.new(field_defn, argument_class: self.class.argument_class)
|
85
97
|
# apply this first, so it can be overriden below
|
@@ -122,7 +134,16 @@ module GraphQL
|
|
122
134
|
# This is the `argument(...)` DSL for class-based field definitons
|
123
135
|
def argument(*args)
|
124
136
|
arg = @argument_class.new(*args)
|
125
|
-
|
137
|
+
graphql_arg = arg.graphql_definition
|
138
|
+
@field.arguments[graphql_arg.name] = graphql_arg
|
139
|
+
end
|
140
|
+
|
141
|
+
def description(text)
|
142
|
+
if @field.description
|
143
|
+
fail "You're overriding the description of #{@field.name} in the provided block!"
|
144
|
+
else
|
145
|
+
@field.description = text
|
146
|
+
end
|
126
147
|
end
|
127
148
|
end
|
128
149
|
end
|
@@ -4,16 +4,17 @@ module GraphQL
|
|
4
4
|
class Schema
|
5
5
|
class Field
|
6
6
|
class DynamicResolve
|
7
|
-
def initialize(method_name:, connection:)
|
7
|
+
def initialize(method_name:, connection:, extras:)
|
8
8
|
@method_name = method_name
|
9
9
|
@connection = connection
|
10
|
+
@extras = extras
|
10
11
|
end
|
11
12
|
|
12
13
|
def call(obj, args, ctx)
|
13
14
|
if obj.respond_to?(@method_name)
|
14
|
-
public_send_field(obj, @method_name, args)
|
15
|
+
public_send_field(obj, @method_name, args, ctx)
|
15
16
|
elsif obj.object.respond_to?(@method_name)
|
16
|
-
public_send_field(obj.object, @method_name, args)
|
17
|
+
public_send_field(obj.object, @method_name, args, ctx)
|
17
18
|
elsif obj.is_a?(Hash)
|
18
19
|
obj[@method_name]
|
19
20
|
else
|
@@ -31,8 +32,10 @@ ERR
|
|
31
32
|
|
32
33
|
private
|
33
34
|
|
34
|
-
|
35
|
-
|
35
|
+
NO_ARGS = {}.freeze
|
36
|
+
|
37
|
+
def public_send_field(obj, method_name, graphql_args, field_ctx)
|
38
|
+
if graphql_args.any? || @extras.any?
|
36
39
|
# Splat the GraphQL::Arguments to Ruby keyword arguments
|
37
40
|
ruby_kwargs = {}
|
38
41
|
|
@@ -48,11 +51,17 @@ ERR
|
|
48
51
|
ruby_kwargs.delete(:after)
|
49
52
|
end
|
50
53
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
obj.public_send(method_name)
|
54
|
+
@extras.each do |extra_arg|
|
55
|
+
# TODO: provide proper tests for `:ast_node`, `:irep_node`, `:parent`, others?
|
56
|
+
ruby_kwargs[extra_arg] = field_ctx.public_send(extra_arg)
|
55
57
|
end
|
58
|
+
else
|
59
|
+
ruby_kwargs = NO_ARGS
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
if ruby_kwargs.any?
|
64
|
+
obj.public_send(method_name, ruby_kwargs)
|
56
65
|
else
|
57
66
|
obj.public_send(method_name)
|
58
67
|
end
|