aboutsummaryrefslogtreecommitdiffstats
path: root/apps/web/app/api/v1/utils/pagination.ts
blob: 5ce9ac8f1dbd4e032cda670045d35bdad0c6cab5 (plain) (blame)
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
import { z } from "zod";

import {
  MAX_NUM_BOOKMARKS_PER_PAGE,
  zCursorV2,
} from "@hoarder/shared/types/bookmarks";

export const zPagination = z.object({
  limit: z.coerce.number().max(MAX_NUM_BOOKMARKS_PER_PAGE).optional(),
  cursor: z
    .string()
    .refine((val) => val.includes("_"), "Must be a valid cursor")
    .transform((val) => {
      const [id, createdAt] = val.split("_");
      return { id, createdAt };
    })
    .pipe(z.object({ id: z.string(), createdAt: z.coerce.date() }))
    .optional(),
});

export function adaptPagination<
  T extends { nextCursor: z.infer<typeof zCursorV2> | null },
>(input: T) {
  const { nextCursor, ...rest } = input;
  if (!nextCursor) {
    return input;
  }
  return {
    ...rest,
    nextCursor: `${nextCursor.id}_${nextCursor.createdAt.toISOString()}`,
  };
}