diff options
Diffstat (limited to 'packages/trpc')
| -rw-r--r-- | packages/trpc/models/highlights.ts | 48 | ||||
| -rw-r--r-- | packages/trpc/routers/highlights.ts | 22 |
2 files changed, 69 insertions, 1 deletions
diff --git a/packages/trpc/models/highlights.ts b/packages/trpc/models/highlights.ts index 49791467..48f0672a 100644 --- a/packages/trpc/models/highlights.ts +++ b/packages/trpc/models/highlights.ts @@ -1,5 +1,5 @@ import { TRPCError } from "@trpc/server"; -import { and, desc, eq, lt, lte, or } from "drizzle-orm"; +import { and, desc, eq, like, lt, lte, or } from "drizzle-orm"; import { z } from "zod"; import { highlights } from "@karakeep/db/schema"; @@ -114,6 +114,52 @@ export class Highlight { }; } + static async search( + ctx: AuthedContext, + searchText: string, + cursor?: z.infer<typeof zCursorV2> | null, + limit = 50, + ): Promise<{ + highlights: Highlight[]; + nextCursor: z.infer<typeof zCursorV2> | null; + }> { + const searchPattern = `%${searchText}%`; + const results = await ctx.db.query.highlights.findMany({ + where: and( + eq(highlights.userId, ctx.user.id), + or( + like(highlights.text, searchPattern), + like(highlights.note, searchPattern), + ), + cursor + ? or( + lt(highlights.createdAt, cursor.createdAt), + and( + eq(highlights.createdAt, cursor.createdAt), + lte(highlights.id, cursor.id), + ), + ) + : undefined, + ), + limit: limit + 1, + orderBy: [desc(highlights.createdAt), desc(highlights.id)], + }); + + let nextCursor: z.infer<typeof zCursorV2> | null = null; + if (results.length > limit) { + const nextItem = results.pop()!; + nextCursor = { + id: nextItem.id, + createdAt: nextItem.createdAt, + }; + } + + return { + highlights: results.map((h) => new Highlight(ctx, h)), + nextCursor, + }; + } + async delete(): Promise<z.infer<typeof zHighlightSchema>> { const result = await this.ctx.db .delete(highlights) diff --git a/packages/trpc/routers/highlights.ts b/packages/trpc/routers/highlights.ts index 65d99880..7338077a 100644 --- a/packages/trpc/routers/highlights.ts +++ b/packages/trpc/routers/highlights.ts @@ -7,6 +7,7 @@ import { zNewHighlightSchema, zUpdateHighlightSchema, } from "@karakeep/shared/types/highlights"; +import { zCursorV2 } from "@karakeep/shared/types/pagination"; import { authedProcedure, router } from "../index"; import { Highlight } from "../models/highlights"; @@ -51,6 +52,27 @@ export const highlightsAppRouter = router({ nextCursor: result.nextCursor, }; }), + search: authedProcedure + .input( + z.object({ + text: z.string(), + cursor: zCursorV2.nullish(), + limit: z.number().optional().default(DEFAULT_NUM_HIGHLIGHTS_PER_PAGE), + }), + ) + .output(zGetAllHighlightsResponseSchema) + .query(async ({ input, ctx }) => { + const result = await Highlight.search( + ctx, + input.text, + input.cursor, + input.limit, + ); + return { + highlights: result.highlights.map((h) => h.asPublicHighlight()), + nextCursor: result.nextCursor, + }; + }), delete: authedProcedure .input(z.object({ highlightId: z.string() })) .output(zHighlightSchema) |
