File size: 1,075 Bytes
8da2481
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
defmodule Plausible.Pagination do
  @moduledoc """
  Cursor-based pagination.
  """

  @limit 10
  @maximum_limit 100

  @spec paginate(Ecto.Queryable.t(), map(), Keyword.t(), Keyword.t()) :: Paginator.Page.t()
  def paginate(queryable, params, opts, repo_opts \\ []) do
    opts = Keyword.merge([limit: @limit, maximum_limit: @maximum_limit], opts)

    Paginator.paginate(
      queryable,
      Keyword.merge(opts, to_pagination_opts(params)),
      Plausible.Repo,
      repo_opts
    )
  end

  defp to_pagination_opts(params) do
    Enum.reduce(params, Keyword.new(), fn
      {"after", cursor}, acc ->
        Keyword.put(acc, :after, cursor)

      {"before", cursor}, acc ->
        Keyword.put(acc, :before, cursor)

      {"limit", limit}, acc ->
        limit = to_int(limit)

        if limit > 0 and limit <= @maximum_limit do
          Keyword.put(acc, :limit, limit)
        else
          acc
        end

      _, acc ->
        acc
    end)
  end

  defp to_int(x) when is_binary(x), do: String.to_integer(x)
  defp to_int(x) when is_integer(x), do: x
end