diff options
| author | MohamedBassem <me@mbassem.com> | 2024-10-05 14:42:22 +0000 |
|---|---|---|
| committer | MohamedBassem <me@mbassem.com> | 2024-10-05 14:42:22 +0000 |
| commit | c8a3c1ee02e917b2e553d403b7bf94cbc736f51d (patch) | |
| tree | ef1135578055968e761fd14a7dabb505544e95f1 /apps/web/app/api/bookmarks | |
| parent | 463d041f0b321348593087047a14a0d9a433d60f (diff) | |
| download | karakeep-c8a3c1ee02e917b2e553d403b7bf94cbc736f51d.tar.zst | |
feature(web): Allow users to export their links and notes
Diffstat (limited to 'apps/web/app/api/bookmarks')
| -rw-r--r-- | apps/web/app/api/bookmarks/export/route.tsx | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/apps/web/app/api/bookmarks/export/route.tsx b/apps/web/app/api/bookmarks/export/route.tsx new file mode 100644 index 00000000..3b12b878 --- /dev/null +++ b/apps/web/app/api/bookmarks/export/route.tsx @@ -0,0 +1,66 @@ +import { api, createContextFromRequest } from "@/server/api/client"; + +import type { ZBookmark } from "@hoarder/shared/types/bookmarks"; +import { + BookmarkTypes, + MAX_NUM_BOOKMARKS_PER_PAGE, +} from "@hoarder/shared/types/bookmarks"; + +function toExportFormat(bookmark: ZBookmark) { + return { + createdAt: bookmark.createdAt.toISOString(), + title: + bookmark.title ?? + (bookmark.content.type === BookmarkTypes.LINK + ? bookmark.content.title + : null), + tags: bookmark.tags.map((t) => t.name), + type: bookmark.content.type, + url: + bookmark.content.type === BookmarkTypes.LINK + ? bookmark.content.url + : undefined, + text: + bookmark.content.type === BookmarkTypes.TEXT + ? bookmark.content.text + : undefined, + note: bookmark.note, + }; +} + +export const dynamic = "force-dynamic"; +export async function GET(request: Request) { + const ctx = await createContextFromRequest(request); + if (!ctx.user) { + return Response.json({ error: "Unauthorized" }, { status: 401 }); + } + const req = { + limit: MAX_NUM_BOOKMARKS_PER_PAGE, + useCursorV2: true, + }; + + let resp = await api.bookmarks.getBookmarks(req); + let results = resp.bookmarks.map(toExportFormat); + + while (resp.nextCursor) { + resp = await api.bookmarks.getBookmarks({ + ...request, + cursor: resp.nextCursor, + }); + results = [...results, ...resp.bookmarks.map(toExportFormat)]; + } + + return new Response( + JSON.stringify({ + // Exclude asset types for now + bookmarks: results.filter((b) => b.type !== BookmarkTypes.ASSET), + }), + { + status: 200, + headers: { + "Content-type": "application/json", + "Content-disposition": `attachment; filename="hoarder-export-${new Date().toISOString()}.json"`, + }, + }, + ); +} |
