#

# RBS Signatures


Pagy provides a centralized RBS file for the public API. It should give your type checker and linter the info to work in your IDE.

pagy.rbs
# sig/pagy.rbs

module ActiveRecord
  class Base[T]
  end
  class Relation[T]
  end
end

module ActiveSupport
  class TimeWithZone
  end
end

module Sequel
  class Dataset[T]
  end
  class Model[T]
  end
end

class Pagy
  VERSION: String
  ROOT:    Pathname
  OPTIONS: options

  def self.options: () -> options

  # Class methods
  def self.sync_javascript: (String destination, *String targets) -> void
  def self.dev_tools: (?wand_scale: Integer) -> String
  def self.translate_with_the_slower_i18n_gem!: () -> void

  class Offset < Pagy
    attr_reader offset:   Integer
    attr_reader count:    Integer
    attr_reader from:     Integer
    attr_reader to:       Integer
    attr_reader previous: Integer?
    attr_reader next:     Integer?
    attr_reader last:     Integer

    alias pages last
  end

  class Countish < Offset
  end
  class Countless < Offset
    attr_reader last: Integer?
  end
  class Keyset < Pagy
    class ActiveRecord < Keyset
    end
    class Sequel < Keyset
    end
    class Keynav < Keyset
      class ActiveRecord < Keyset
      end
      class Sequel < Keyset
      end
    end

    attr_reader records: Array[untyped]
  end

  class Calendar < ::Hash[Symbol, Calendar::Unit]
    def self.localize_with_rails_i18n_gem: (*Symbol locales) -> void

    def showtime: () -> ActiveSupport::TimeWithZone
    def url_at: (ActiveSupport::TimeWithZone time, **url_opts) -> String

    class Unit < Pagy
      attr_reader order: Symbol
      attr_reader from: ActiveSupport::TimeWithZone
      attr_reader to: ActiveSupport::TimeWithZone
      attr_reader previous: Integer?
      attr_reader last: Integer
      alias pages last
    end

    class Year < Unit
    end
    class Quarter < Unit
    end
    class Month < Unit
    end
    class Week < Unit
    end
    class Day < Unit
    end
  end

  class SearchBase < Offset
  end

  class ElasticsearchRails < SearchBase
  end

  class Meilisearch < SearchBase
  end

  class Searchkick < SearchBase
  end

  class TypesenseRails < SearchBase
  end

  module Search
    class Arguments < Array[untyped]
    end

    def pagy_search: (*untyped arguments, untyped) -> Search::Arguments
  end

  class Method
    interface _Collection
      def offset: (Integer offset) -> _Collection
      def limit:  (Integer limit)  -> _Collection
    end


    type collection = _Collection | Array[untyped]

    def pagy: (:offset,    collection collection, **offset_opts options)    -> [Offset,    collection]
            | (:countless, collection collection, **countless_opts options) -> [Countless, collection]
            | (:countish,  collection collection, **countish_opts options)  -> [Countish,  collection]

            | (:keyset,    ::ActiveRecord::Relation[untyped] set, **keyset_opts options) -> [Keyset::ActiveRecord, Array[::ActiveRecord::Base[untyped]]]
            | (:keyset,    ::Sequel::Dataset[untyped] set,        **keyset_opts options) -> [Keyset::Sequel, Array[::Sequel::Model[untyped]]]

            | (:keynav_js, ::ActiveRecord::Relation[untyped] set, **keyset_opts options) -> [Keyset::Keynav::ActiveRecord, Array[::ActiveRecord::Base[untyped]]]
            | (:keynav_js, ::Sequel::Dataset[untyped] set,        **keyset_opts options) -> [Keyset::Keynav::Sequel, Array[::Sequel::Model[untyped]]]

            | (:calendar, _Collection collection, **calendar_config) -> [Calendar, Offset, _Collection]

            | (:elasticsearch_rails, Search::Arguments, **search_opts options) -> [ElasticsearchRails, untyped]
            | (:elasticsearch_rails, untyped search, **search_opts options)    -> ElasticsearchRails

            | (:meilisearch, Search::Arguments, **search_opts options) -> [Meilisearch, untyped]
            | (:meilisearch, untyped search, **search_opts options)    -> Meilisearch

            | (:searchkick, Search::Arguments, **search_opts options) -> [Searchkick, untyped]
            | (:searchkick, untyped search, **search_opts options)    -> Searchkick

            | (:typesense_rails, Search::Arguments, **search_opts options) -> [TypesenseRails, untyped]
            | (:typesense_rails, untyped search, **search_opts options)    -> TypesenseRails
  end

  # Helper methods
  def data_hash: (**data_opts) -> pagy_data_hash
  def headers_hash: (**headers_opts) -> Hash[String, String]
  def urls_hash: (**url_opts) -> Hash[Symbol, String]

  def page_url: (:first | :current | :page | :previous | :next | :last | Integer page, **url_opts) -> String
  def next_tag: (String? text, **anchor_tags_opts) -> String

  module NumericHelpers
    def series_nav:    (?Symbol? style, **series_nav_opts) -> String
    def series_nav_js: (?Symbol? style, **series_nav_js_opts) -> String
    def input_nav_js:  (?Symbol? style, **nav_opts) -> String

    def previous_tag: (String? text, **anchor_tags_opts) -> String
    def limit_tag_js: (?id: String?, ?item_name: String?, **url_opts) -> String
    def info_tag:     (?id: String?, ?item_name: String?) -> String
  end

  ##### OPTIONS #####

  type url_opts = {
    ?fragment:  String,
    ?absolute:  bool,
    ?path:      String,
    ?querify:   Proc,
    ?jsonapi:   bool,
    ?root_key:  String,
    ?page_key:  String,
    ?limit_key: String,
  }

  ##### Paginator Options #####

  type paginator_opts = url_opts & {
    ?page:             Integer,
    ?limit:            Integer,
    ?max_pages:        Integer,
    ?client_max_limit: Integer,
    ?request:          _RackRequest | request_hash
  }

  type offset_opts = paginator_opts & {
    ?count:             Integer,
    ?count_over:        bool,
    ?raise_range_error: bool
  }

  type countish_opts = offset_opts & {
    ?ttl:   Integer,
    ?epoch: Integer
  }

  type countless_opts = offset_opts & {
    ?headless: bool
  }

  type unit_opts = paginator_opts & {
    ?slots:    Integer,
    ?compact:  bool,
    ?format:   String,
    ?order:    Symbol
  }

  type calendar_config = {
    ?year:     unit_opts,
    ?quarter:  unit_opts,
    ?month:    unit_opts,
    ?week:     unit_opts,
    ?day:      unit_opts,
    ?offset:   offset_opts,
    ?disabled: bool
  }

  type keyset_opts = paginator_opts & {
    ?keyset:           Hash[untyped, untyped],
    ?tuple_comparison: bool,
    ?pre_serialize:    Proc
  }

  type search_opts = {
    ?search_method: Symbol
  }

  ##### Helper Options #####

  ### data_hash ###
  type pagy_data_key = :url_template | :first_url | :previous_url | :current_url
                     | :page_url | :next_url | :last_url | :count | :page
                     | :limit | :last | :in | :from | :to | :previous
                     | :next | :options | Symbol

  # The return structure with optional keys (marked with ?)
  type pagy_data_hash = {
    ?url_template: String,
    ?first_url:    String,
    ?previous_url: String,
    ?current_url:  String,
    ?page_url:     String,
    ?next_url:     String,
    ?last_url:     String,
    ?count:        Integer,
    ?page:         Integer,
    ?limit:        Integer,
    ?last:         Integer,
    ?in:           Integer,
    ?from:         Integer,
    ?to:           Integer,
    ?previous:     Integer,
    ?next:         Integer,
    ?options:      options
  } & Hash[Symbol, untyped] # Intersection allows for 'send' method results

  type data_opts = url_opts & {
    ?data_keys: Array[pagy_data_key]
  }

  type headers_opts = url_opts & {
    ?headers_map: Hash[Symbol, String]
  }

  ##### NumericUI Options #####
  type anchor_tags_opts = url_opts & {
    ?text:       String,
    ?aria_label: String
  }

  type nav_opts = url_opts & {
    ?id:            String,
    ?aria_label:    String,
    ?item_name:     String,
    ?style:         :pagy | :bootstrap | :bulma,
    ?anchor_string: String
  }

  type series_nav_opts = nav_opts & {
    ?slots:   Integer,
    ?compact: bool,
  }

  type series_nav_js_opts = series_nav_opts & {
    ?steps: Hash[Integer, Integer]
  }

  type options = url_opts & paginator_opts & offset_opts & countish_opts & countless_opts &
                 unit_opts & keyset_opts & search_opts &
                 anchor_tags_opts & nav_opts & data_opts & headers_opts & nav_opts & series_nav_opts & series_nav_js_opts

  ##### REQUEST #####

  interface _RackRequest
    def base_url: () -> String
    def path:     () -> String
    def GET:      () -> Hash[String, untyped]
    def POST:     () -> Hash[String, untyped]
    def cookies:  () -> Hash[String, String]
  end

  type request_hash = {
    base_url: String,
    path:     String,
    params:   Hash[String, untyped],
    ?cookie:  String
  }
end