aboutsummaryrefslogtreecommitdiffstats
path: root/apps/web/app/api/v1/utils/pagination.ts
diff options
context:
space:
mode:
authorMohamed Bassem <me@mbassem.com>2024-10-20 13:54:05 +0000
committerMohamed Bassem <me@mbassem.com>2024-10-20 14:08:24 +0000
commitfb297eaadee9b741ddb6731a91eb4648020dcb3b (patch)
tree42b5c779dab4ef4d6afbd3a41cbcd6c4d5c86f07 /apps/web/app/api/v1/utils/pagination.ts
parenta822ff26ce83db867d4589181d21da20592fbf7c (diff)
downloadkarakeep-fb297eaadee9b741ddb6731a91eb4648020dcb3b.tar.zst
featue: Add infra for REST APIs and implement GET /bookmarks
Diffstat (limited to 'apps/web/app/api/v1/utils/pagination.ts')
-rw-r--r--apps/web/app/api/v1/utils/pagination.ts32
1 files changed, 32 insertions, 0 deletions
diff --git a/apps/web/app/api/v1/utils/pagination.ts b/apps/web/app/api/v1/utils/pagination.ts
new file mode 100644
index 00000000..5ce9ac8f
--- /dev/null
+++ b/apps/web/app/api/v1/utils/pagination.ts
@@ -0,0 +1,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()}`,
+ };
+}