1# frozen_string_literal: true
2
3module Resolvers
4  class PaginatedTreeResolver < BaseResolver
5    type Types::Tree::TreeType.connection_type, null: true
6    extension Gitlab::Graphql::Extensions::ExternallyPaginatedArrayExtension
7
8    calls_gitaly!
9
10    argument :path, GraphQL::Types::String,
11              required: false,
12              default_value: '', # root of the repository
13              description: 'Path to get the tree for. Default value is the root of the repository.'
14    argument :ref, GraphQL::Types::String,
15              required: false,
16              default_value: :head,
17              description: 'Commit ref to get the tree for. Default value is HEAD.'
18    argument :recursive, GraphQL::Types::Boolean,
19              required: false,
20              default_value: false,
21              description: 'Used to get a recursive tree. Default is false.'
22
23    alias_method :repository, :object
24
25    def resolve(**args)
26      return unless repository.exists?
27
28      cursor = args.delete(:after)
29
30      pagination_params = {
31        limit: @field.max_page_size || 100,
32        page_token: cursor
33      }
34
35      tree = repository.tree(args[:ref], args[:path], recursive: args[:recursive], pagination_params: pagination_params)
36
37      next_cursor = tree.cursor&.next_cursor
38      Gitlab::Graphql::ExternallyPaginatedArray.new(cursor, next_cursor, *tree)
39    rescue Gitlab::Git::CommandError => e
40      raise Gitlab::Graphql::Errors::ArgumentError, e
41    end
42
43    def self.field_options
44      super.merge(connection: false) # we manage the pagination manually, so opt out of the connection field extension
45    end
46  end
47end
48