graphql 2.3.5 → 2.3.11
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.
Potentially problematic release.
This version of graphql might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/generators/graphql/install_generator.rb +46 -0
- data/lib/graphql/analysis/analyzer.rb +89 -0
- data/lib/graphql/analysis/field_usage.rb +82 -0
- data/lib/graphql/analysis/max_query_complexity.rb +20 -0
- data/lib/graphql/analysis/max_query_depth.rb +20 -0
- data/lib/graphql/analysis/query_complexity.rb +183 -0
- data/lib/graphql/analysis/{ast/query_depth.rb → query_depth.rb} +23 -25
- data/lib/graphql/analysis/visitor.rb +283 -0
- data/lib/graphql/analysis.rb +92 -1
- data/lib/graphql/current.rb +52 -0
- data/lib/graphql/dataloader/async_dataloader.rb +2 -0
- data/lib/graphql/dataloader/source.rb +5 -2
- data/lib/graphql/dataloader.rb +4 -1
- data/lib/graphql/execution/interpreter/arguments_cache.rb +5 -10
- data/lib/graphql/execution/interpreter/runtime.rb +8 -14
- data/lib/graphql/execution/interpreter.rb +3 -1
- data/lib/graphql/execution/lookahead.rb +10 -10
- data/lib/graphql/introspection/directive_type.rb +1 -1
- data/lib/graphql/introspection/entry_points.rb +2 -2
- data/lib/graphql/introspection/field_type.rb +1 -1
- data/lib/graphql/introspection/schema_type.rb +6 -11
- data/lib/graphql/introspection/type_type.rb +5 -5
- data/lib/graphql/language/document_from_schema_definition.rb +19 -26
- data/lib/graphql/language/lexer.rb +0 -3
- data/lib/graphql/language/nodes.rb +2 -2
- data/lib/graphql/language/parser.rb +9 -1
- data/lib/graphql/language/sanitized_printer.rb +1 -1
- data/lib/graphql/language.rb +0 -1
- data/lib/graphql/query/context.rb +7 -1
- data/lib/graphql/query/null_context.rb +2 -2
- data/lib/graphql/query/validation_pipeline.rb +2 -2
- data/lib/graphql/query.rb +26 -7
- data/lib/graphql/schema/always_visible.rb +1 -0
- data/lib/graphql/schema/argument.rb +19 -5
- data/lib/graphql/schema/build_from_definition.rb +8 -1
- data/lib/graphql/schema/directive/flagged.rb +1 -1
- data/lib/graphql/schema/directive.rb +2 -0
- data/lib/graphql/schema/enum.rb +9 -5
- data/lib/graphql/schema/field/connection_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +13 -1
- data/lib/graphql/schema/has_single_input_argument.rb +2 -1
- data/lib/graphql/schema/input_object.rb +8 -7
- data/lib/graphql/schema/interface.rb +20 -4
- data/lib/graphql/schema/introspection_system.rb +5 -16
- data/lib/graphql/schema/member/has_arguments.rb +14 -9
- data/lib/graphql/schema/member/has_fields.rb +6 -4
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +5 -1
- data/lib/graphql/schema/resolver.rb +5 -5
- data/lib/graphql/schema/subset.rb +510 -0
- data/lib/graphql/schema/type_expression.rb +2 -2
- data/lib/graphql/schema/types_migration.rb +185 -0
- data/lib/graphql/schema/validator/all_validator.rb +60 -0
- data/lib/graphql/schema/validator.rb +2 -0
- data/lib/graphql/schema/warden.rb +89 -5
- data/lib/graphql/schema.rb +74 -37
- data/lib/graphql/static_validation/base_visitor.rb +6 -5
- data/lib/graphql/static_validation/literal_validator.rb +4 -4
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +1 -1
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -2
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +7 -7
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +1 -1
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
- data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/query_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +3 -3
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +3 -3
- data/lib/graphql/static_validation/rules/subscription_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +18 -27
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +1 -1
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
- data/lib/graphql/static_validation/validation_context.rb +2 -2
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +11 -5
- data/lib/graphql/subscriptions/event.rb +1 -1
- data/lib/graphql/subscriptions.rb +3 -3
- data/lib/graphql/testing/helpers.rb +8 -5
- data/lib/graphql/types/relay/connection_behaviors.rb +10 -0
- data/lib/graphql/types/relay/edge_behaviors.rb +10 -0
- data/lib/graphql/types/relay/page_info_behaviors.rb +4 -0
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +1 -0
- metadata +14 -13
- data/lib/graphql/analysis/ast/analyzer.rb +0 -91
- data/lib/graphql/analysis/ast/field_usage.rb +0 -84
- data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -22
- data/lib/graphql/analysis/ast/max_query_depth.rb +0 -22
- data/lib/graphql/analysis/ast/query_complexity.rb +0 -185
- data/lib/graphql/analysis/ast/visitor.rb +0 -284
- data/lib/graphql/analysis/ast.rb +0 -94
- data/lib/graphql/language/token.rb +0 -34
- data/lib/graphql/schema/invalid_type_error.rb +0 -7
@@ -82,13 +82,29 @@ module GraphQL
|
|
82
82
|
super
|
83
83
|
end
|
84
84
|
|
85
|
+
# Register other Interface or Object types as implementers of this Interface.
|
86
|
+
#
|
87
|
+
# When those Interfaces or Objects aren't used as the return values of fields,
|
88
|
+
# they may have to be registered using this method so that GraphQL-Ruby can find them.
|
89
|
+
# @param types [Class, Module]
|
90
|
+
# @return [Array<Module, Class>] Implementers of this interface, if they're registered
|
85
91
|
def orphan_types(*types)
|
86
92
|
if types.any?
|
87
|
-
@orphan_types
|
93
|
+
@orphan_types ||= []
|
94
|
+
@orphan_types.concat(types)
|
88
95
|
else
|
89
|
-
|
90
|
-
|
91
|
-
|
96
|
+
if defined?(@orphan_types)
|
97
|
+
all_orphan_types = @orphan_types.dup
|
98
|
+
if defined?(super)
|
99
|
+
all_orphan_types += super
|
100
|
+
all_orphan_types.uniq!
|
101
|
+
end
|
102
|
+
all_orphan_types
|
103
|
+
elsif defined?(super)
|
104
|
+
super
|
105
|
+
else
|
106
|
+
EmptyObjects::EMPTY_ARRAY
|
107
|
+
end
|
92
108
|
end
|
93
109
|
end
|
94
110
|
|
@@ -25,7 +25,7 @@ module GraphQL
|
|
25
25
|
load_constant(:DirectiveLocationEnum)
|
26
26
|
]
|
27
27
|
@types = {}
|
28
|
-
@possible_types = {}.
|
28
|
+
@possible_types = {}.compare_by_identity
|
29
29
|
type_defns.each do |t|
|
30
30
|
@types[t.graphql_name] = t
|
31
31
|
@possible_types[t] = [t]
|
@@ -69,7 +69,7 @@ module GraphQL
|
|
69
69
|
def resolve_late_bindings
|
70
70
|
@types.each do |name, t|
|
71
71
|
if t.kind.fields?
|
72
|
-
t.
|
72
|
+
t.all_field_definitions.each do |field_defn|
|
73
73
|
field_defn.type = resolve_late_binding(field_defn.type)
|
74
74
|
end
|
75
75
|
end
|
@@ -90,7 +90,8 @@ module GraphQL
|
|
90
90
|
def resolve_late_binding(late_bound_type)
|
91
91
|
case late_bound_type
|
92
92
|
when GraphQL::Schema::LateBoundType
|
93
|
-
|
93
|
+
type_name = late_bound_type.name
|
94
|
+
@types[type_name] || @schema.get_type(type_name)
|
94
95
|
when GraphQL::Schema::List
|
95
96
|
resolve_late_binding(late_bound_type.of_type).to_list_type
|
96
97
|
when GraphQL::Schema::NonNull
|
@@ -113,19 +114,7 @@ module GraphQL
|
|
113
114
|
|
114
115
|
def get_fields_from_class(class_sym:)
|
115
116
|
object_type_defn = load_constant(class_sym)
|
116
|
-
|
117
|
-
if object_type_defn.is_a?(Module)
|
118
|
-
object_type_defn.fields
|
119
|
-
else
|
120
|
-
extracted_field_defns = {}
|
121
|
-
object_class = object_type_defn.metadata[:type_class]
|
122
|
-
object_type_defn.all_fields.each do |field_defn|
|
123
|
-
inner_resolve = field_defn.resolve_proc
|
124
|
-
resolve_with_instantiate = PerFieldProxyResolve.new(object_class: object_class, inner_resolve: inner_resolve)
|
125
|
-
extracted_field_defns[field_defn.name] = field_defn.redefine(resolve: resolve_with_instantiate)
|
126
|
-
end
|
127
|
-
extracted_field_defns
|
128
|
-
end
|
117
|
+
object_type_defn.fields
|
129
118
|
end
|
130
119
|
|
131
120
|
# This is probably not 100% robust -- but it has to be good enough to avoid modifying the built-in introspection types
|
@@ -135,10 +135,11 @@ module GraphQL
|
|
135
135
|
|
136
136
|
def get_argument(argument_name, context = GraphQL::Query::NullContext.instance)
|
137
137
|
warden = Warden.from_context(context)
|
138
|
+
skip_visible = context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::Subset)
|
138
139
|
for ancestor in ancestors
|
139
140
|
if ancestor.respond_to?(:own_arguments) &&
|
140
141
|
(a = ancestor.own_arguments[argument_name]) &&
|
141
|
-
(a = Warden.visible_entry?(:visible_argument?, a, context, warden))
|
142
|
+
(skip_visible || (a = Warden.visible_entry?(:visible_argument?, a, context, warden)))
|
142
143
|
return a
|
143
144
|
end
|
144
145
|
end
|
@@ -197,16 +198,20 @@ module GraphQL
|
|
197
198
|
end
|
198
199
|
|
199
200
|
def all_argument_definitions
|
200
|
-
|
201
|
-
|
202
|
-
|
201
|
+
if own_arguments.any?
|
202
|
+
all_defns = own_arguments.values
|
203
|
+
all_defns.flatten!
|
204
|
+
all_defns
|
205
|
+
else
|
206
|
+
EmptyObjects::EMPTY_ARRAY
|
207
|
+
end
|
203
208
|
end
|
204
209
|
|
205
210
|
# @return [GraphQL::Schema::Argument, nil] Argument defined on this thing, fetched by name.
|
206
211
|
def get_argument(argument_name, context = GraphQL::Query::NullContext.instance)
|
207
212
|
warden = Warden.from_context(context)
|
208
|
-
if (arg_config = own_arguments[argument_name]) && (visible_arg = Warden.visible_entry?(:visible_argument?, arg_config, context, warden))
|
209
|
-
visible_arg
|
213
|
+
if (arg_config = own_arguments[argument_name]) && ((context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::Subset)) || (visible_arg = Warden.visible_entry?(:visible_argument?, arg_config, context, warden)))
|
214
|
+
visible_arg || arg_config
|
210
215
|
elsif defined?(@resolver_class) && @resolver_class
|
211
216
|
@resolver_class.get_field_argument(argument_name, context)
|
212
217
|
else
|
@@ -230,7 +235,7 @@ module GraphQL
|
|
230
235
|
# @return [Interpreter::Arguments, Execution::Lazy<Interpreter::Arguments>]
|
231
236
|
def coerce_arguments(parent_object, values, context, &block)
|
232
237
|
# Cache this hash to avoid re-merging it
|
233
|
-
arg_defns = context.
|
238
|
+
arg_defns = context.types.arguments(self)
|
234
239
|
total_args_count = arg_defns.size
|
235
240
|
|
236
241
|
finished_args = nil
|
@@ -364,8 +369,8 @@ module GraphQL
|
|
364
369
|
end
|
365
370
|
|
366
371
|
if !(
|
367
|
-
context.
|
368
|
-
context.
|
372
|
+
context.types.possible_types(argument.loads).include?(application_object_type) ||
|
373
|
+
context.types.loadable?(argument.loads, context)
|
369
374
|
)
|
370
375
|
err = GraphQL::LoadApplicationObjectFailedError.new(context: context, argument: argument, id: id, object: application_object)
|
371
376
|
application_object = load_application_object_failed(err)
|
@@ -99,11 +99,12 @@ module GraphQL
|
|
99
99
|
module InterfaceMethods
|
100
100
|
def get_field(field_name, context = GraphQL::Query::NullContext.instance)
|
101
101
|
warden = Warden.from_context(context)
|
102
|
+
skip_visible = context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::Subset)
|
102
103
|
for ancestor in ancestors
|
103
104
|
if ancestor.respond_to?(:own_fields) &&
|
104
105
|
(f_entry = ancestor.own_fields[field_name]) &&
|
105
|
-
(
|
106
|
-
return
|
106
|
+
(skip_visible || (f_entry = Warden.visible_entry?(:visible_field?, f_entry, context, warden)))
|
107
|
+
return f_entry
|
107
108
|
end
|
108
109
|
end
|
109
110
|
nil
|
@@ -134,13 +135,14 @@ module GraphQL
|
|
134
135
|
# Objects need to check that the interface implementation is visible, too
|
135
136
|
warden = Warden.from_context(context)
|
136
137
|
ancs = ancestors
|
138
|
+
skip_visible = context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::Subset)
|
137
139
|
i = 0
|
138
140
|
while (ancestor = ancs[i])
|
139
141
|
if ancestor.respond_to?(:own_fields) &&
|
140
142
|
visible_interface_implementation?(ancestor, context, warden) &&
|
141
143
|
(f_entry = ancestor.own_fields[field_name]) &&
|
142
|
-
(
|
143
|
-
return
|
144
|
+
(skip_visible || (f_entry = Warden.visible_entry?(:visible_field?, f_entry, context, warden)))
|
145
|
+
return f_entry
|
144
146
|
end
|
145
147
|
i += 1
|
146
148
|
end
|
@@ -7,7 +7,11 @@ module GraphQL
|
|
7
7
|
module HasUnresolvedTypeError
|
8
8
|
private
|
9
9
|
def add_unresolved_type_error(child_class)
|
10
|
-
child_class.
|
10
|
+
if child_class.name # Don't set this for anonymous classes
|
11
|
+
child_class.const_set(:UnresolvedTypeError, Class.new(GraphQL::UnresolvedTypeError))
|
12
|
+
else
|
13
|
+
child_class.const_set(:UnresolvedTypeError, UnresolvedTypeError)
|
14
|
+
end
|
11
15
|
end
|
12
16
|
end
|
13
17
|
end
|
@@ -25,6 +25,7 @@ module GraphQL
|
|
25
25
|
extend GraphQL::Schema::Member::HasValidators
|
26
26
|
include Schema::Member::HasPath
|
27
27
|
extend Schema::Member::HasPath
|
28
|
+
extend Schema::Member::HasDirectives
|
28
29
|
|
29
30
|
# @param object [Object] The application object that this field is being resolved on
|
30
31
|
# @param context [GraphQL::Query::Context]
|
@@ -35,7 +36,7 @@ module GraphQL
|
|
35
36
|
@field = field
|
36
37
|
# Since this hash is constantly rebuilt, cache it for this call
|
37
38
|
@arguments_by_keyword = {}
|
38
|
-
|
39
|
+
context.types.arguments(self.class).each do |arg|
|
39
40
|
@arguments_by_keyword[arg.keyword] = arg
|
40
41
|
end
|
41
42
|
@prepared_arguments = nil
|
@@ -151,7 +152,7 @@ module GraphQL
|
|
151
152
|
# @return [Boolean, early_return_data] If `false`, execution will stop (and `early_return_data` will be returned instead, if present.)
|
152
153
|
def authorized?(**inputs)
|
153
154
|
arg_owner = @field # || self.class
|
154
|
-
args =
|
155
|
+
args = context.types.arguments(arg_owner)
|
155
156
|
authorize_arguments(args, inputs)
|
156
157
|
end
|
157
158
|
|
@@ -168,7 +169,7 @@ module GraphQL
|
|
168
169
|
private
|
169
170
|
|
170
171
|
def authorize_arguments(args, inputs)
|
171
|
-
args.
|
172
|
+
args.each do |argument|
|
172
173
|
arg_keyword = argument.keyword
|
173
174
|
if inputs.key?(arg_keyword) && !(arg_value = inputs[arg_keyword]).nil? && (arg_value != argument.default_value)
|
174
175
|
auth_result = argument.authorized?(self, arg_value, context)
|
@@ -181,10 +182,9 @@ module GraphQL
|
|
181
182
|
elsif auth_result == false
|
182
183
|
return auth_result
|
183
184
|
end
|
184
|
-
else
|
185
|
-
true
|
186
185
|
end
|
187
186
|
end
|
187
|
+
true
|
188
188
|
end
|
189
189
|
|
190
190
|
def load_arguments(args)
|