diff options
Diffstat (limited to 'app/graphql/types/base_field.rb')
-rw-r--r-- | app/graphql/types/base_field.rb | 55 |
1 files changed, 20 insertions, 35 deletions
diff --git a/app/graphql/types/base_field.rb b/app/graphql/types/base_field.rb index f145b9d45c3..78ab6890923 100644 --- a/app/graphql/types/base_field.rb +++ b/app/graphql/types/base_field.rb @@ -9,48 +9,29 @@ module Types DEFAULT_COMPLEXITY = 1 - def initialize(*args, **kwargs, &block) + def initialize(**kwargs, &block) @calls_gitaly = !!kwargs.delete(:calls_gitaly) - @constant_complexity = !!kwargs[:complexity] + @constant_complexity = kwargs[:complexity].is_a?(Integer) && kwargs[:complexity] > 0 @requires_argument = !!kwargs.delete(:requires_argument) kwargs[:complexity] = field_complexity(kwargs[:resolver_class], kwargs[:complexity]) @feature_flag = kwargs[:feature_flag] kwargs = check_feature_flag(kwargs) kwargs = gitlab_deprecation(kwargs) - super(*args, **kwargs, &block) + super(**kwargs, &block) + + # We want to avoid the overhead of this in prod + extension ::Gitlab::Graphql::CallsGitaly::FieldExtension if Gitlab.dev_or_test_env? + + extension ::Gitlab::Graphql::Present::FieldExtension end - def requires_argument? - @requires_argument || arguments.values.any? { |argument| argument.type.non_null? } + def may_call_gitaly? + @constant_complexity || @calls_gitaly end - # Based on https://github.com/rmosolgo/graphql-ruby/blob/v1.11.4/lib/graphql/schema/field.rb#L538-L563 - # Modified to fix https://github.com/rmosolgo/graphql-ruby/issues/3113 - def resolve_field(obj, args, ctx) - ctx.schema.after_lazy(obj) do |after_obj| - query_ctx = ctx.query.context - inner_obj = after_obj&.object - - ctx.schema.after_lazy(to_ruby_args(after_obj, args, ctx)) do |ruby_args| - if authorized?(inner_obj, ruby_args, query_ctx) - if @resolve_proc - # We pass `after_obj` here instead of `inner_obj` because extensions expect a GraphQL::Schema::Object - with_extensions(after_obj, ruby_args, query_ctx) do |extended_obj, extended_args| - # Since `extended_obj` is now a GraphQL::Schema::Object, we need to get the inner object and pass that to `@resolve_proc` - extended_obj = extended_obj.object if extended_obj.is_a?(GraphQL::Schema::Object) - - @resolve_proc.call(extended_obj, args, ctx) - end - else - public_send_field(after_obj, ruby_args, query_ctx) - end - else - err = GraphQL::UnauthorizedFieldError.new(object: inner_obj, type: obj.class, context: ctx, field: self) - query_ctx.schema.unauthorized_field(err) - end - end - end + def requires_argument? + @requires_argument || arguments.values.any? { |argument| argument.type.non_null? } end def base_complexity @@ -82,8 +63,10 @@ module Types end def check_feature_flag(args) - args[:description] = feature_documentation_message(args[:feature_flag], args[:description]) if args[:feature_flag].present? - args.delete(:feature_flag) + ff = args.delete(:feature_flag) + return args unless ff.present? + + args[:description] = feature_documentation_message(ff, args[:description]) args end @@ -106,7 +89,9 @@ module Types # items which can be loaded. proc do |ctx, args, child_complexity| # Resolvers may add extra complexity depending on used arguments - complexity = child_complexity + self.resolver&.try(:resolver_complexity, args, child_complexity: child_complexity).to_i + complexity = child_complexity + resolver&.try( + :resolver_complexity, args, child_complexity: child_complexity + ).to_i complexity += 1 if calls_gitaly? complexity += complexity * connection_complexity_multiplier(ctx, args) @@ -121,7 +106,7 @@ module Types page_size = field_defn.connection_max_page_size || ctx.schema.default_max_page_size limit_value = [args[:first], args[:last], page_size].compact.min - multiplier = self.resolver&.try(:complexity_multiplier, args).to_f + multiplier = resolver&.try(:complexity_multiplier, args).to_f limit_value * multiplier end end |