diff options
| author | Mohamed Bassem <me@mbassem.com> | 2025-06-01 20:46:41 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-01 20:46:41 +0100 |
| commit | ea1d0023bfee55358ebb1a96f3d06e783a219c0d (patch) | |
| tree | 5bddd451728cb7dd377574a9ea1ea591bca069c4 /packages/trpc/models/lists.ts | |
| parent | 3afe1e21df6dcc0483e74e0db02d9d82af32ecea (diff) | |
| download | karakeep-ea1d0023bfee55358ebb1a96f3d06e783a219c0d.tar.zst | |
feat: Add support for public lists (#1511)
* WIP: public lists
* Drop viewing modes
* Add the public endpoint for assets
* regen the openapi spec
* proper handling for different asset types
* Add num bookmarks and a no bookmark banner
* Correctly set page title
* Add a not-found page
* merge the RSS and public list endpoints
* Add e2e tests for the public endpoints
* Redesign the share list modal
* Make NEXTAUTH_SECRET not required
* propery render text bookmarks
* rebase migration
* fix public token tests
* Add more tests
Diffstat (limited to 'packages/trpc/models/lists.ts')
| -rw-r--r-- | packages/trpc/models/lists.ts | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/packages/trpc/models/lists.ts b/packages/trpc/models/lists.ts index 4413a8cd..2631ca7e 100644 --- a/packages/trpc/models/lists.ts +++ b/packages/trpc/models/lists.ts @@ -1,6 +1,6 @@ import crypto from "node:crypto"; import { TRPCError } from "@trpc/server"; -import { and, count, eq } from "drizzle-orm"; +import { and, count, eq, or } from "drizzle-orm"; import invariant from "tiny-invariant"; import { z } from "zod"; @@ -8,11 +8,13 @@ import { SqliteError } from "@karakeep/db"; import { bookmarkLists, bookmarksInLists } from "@karakeep/db/schema"; import { triggerRuleEngineOnEvent } from "@karakeep/shared/queues"; import { parseSearchQuery } from "@karakeep/shared/searchQueryParser"; +import { ZSortOrder } from "@karakeep/shared/types/bookmarks"; import { ZBookmarkList, zEditBookmarkListSchemaWithValidation, zNewBookmarkListSchema, } from "@karakeep/shared/types/lists"; +import { ZCursor } from "@karakeep/shared/types/pagination"; import { AuthedContext, Context } from ".."; import { buildImpersonatingAuthedContext } from "../lib/impersonate"; @@ -61,18 +63,23 @@ export abstract class List implements PrivacyAware { } } - static async getForRss( + static async getPublicListContents( ctx: Context, listId: string, - token: string, + token: string | null, pagination: { limit: number; + order: Exclude<ZSortOrder, "relevance">; + cursor: ZCursor | null | undefined; }, ) { const listdb = await ctx.db.query.bookmarkLists.findFirst({ where: and( eq(bookmarkLists.id, listId), - eq(bookmarkLists.rssToken, token), + or( + eq(bookmarkLists.public, true), + token !== null ? eq(bookmarkLists.rssToken, token) : undefined, + ), ), }); if (!listdb) { @@ -85,7 +92,6 @@ export abstract class List implements PrivacyAware { // The token here acts as an authed context, so we can create // an impersonating context for the list owner as long as // we don't leak the context. - const authedCtx = await buildImpersonatingAuthedContext(listdb.userId); const list = List.fromData(authedCtx, listdb); const bookmarkIds = await list.getBookmarkIds(); @@ -94,7 +100,8 @@ export abstract class List implements PrivacyAware { ids: bookmarkIds, includeContent: false, limit: pagination.limit, - sortOrder: "desc", + sortOrder: pagination.order, + cursor: pagination.cursor, }); return { @@ -102,8 +109,10 @@ export abstract class List implements PrivacyAware { icon: list.list.icon, name: list.list.name, description: list.list.description, + numItems: bookmarkIds.length, }, bookmarks: bookmarks.bookmarks.map((b) => b.asPublicBookmark()), + nextCursor: bookmarks.nextCursor, }; } @@ -185,6 +194,7 @@ export abstract class List implements PrivacyAware { icon: input.icon, parentId: input.parentId, query: input.query, + public: input.public, }) .where( and( |
