mirror of
https://github.com/zoriya/Kyoo.git
synced 2026-06-07 23:05:15 -04:00
Fix pagination with search
This commit is contained in:
@@ -298,6 +298,12 @@ export async function getEntries({
|
||||
episodeNumber: sql<number>`${episodeNumber}`,
|
||||
name: sql<string>`${transQ.name}`,
|
||||
|
||||
__similarity: query
|
||||
? sql`word_similarity(${query}::text, concat(${entries.episodeNumber}, ' ', ${transQ.name}))`.as(
|
||||
"__similarity",
|
||||
)
|
||||
: sql`false`,
|
||||
|
||||
...buildRelations(relations, entryRelations, {
|
||||
languages,
|
||||
preferOriginal,
|
||||
@@ -313,15 +319,11 @@ export async function getEntries({
|
||||
query
|
||||
? sql`concat(${entries.episodeNumber}, ' ', ${transQ.name}) %> ${query}::text`
|
||||
: undefined,
|
||||
keysetPaginate({ after, sort }),
|
||||
keysetPaginate({ after, sort, query }),
|
||||
),
|
||||
)
|
||||
.orderBy(
|
||||
...(query
|
||||
? [
|
||||
sql`word_similarity(${query}::text, concat(${entries.episodeNumber}, ' ', ${transQ.name})) desc`,
|
||||
]
|
||||
: sortToSql(sort)),
|
||||
...(query ? [desc(sql`__similarity`)] : sortToSql(sort)),
|
||||
entries.pk,
|
||||
)
|
||||
.limit(limit)
|
||||
@@ -405,7 +407,7 @@ export const entriesH = new Elysia({ tags: ["series"] })
|
||||
});
|
||||
}
|
||||
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: { description: "Get entries of a serie" },
|
||||
@@ -501,7 +503,7 @@ export const entriesH = new Elysia({ tags: ["series"] })
|
||||
userId: sub,
|
||||
})) as Extra[];
|
||||
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: { description: "Get extras of a serie" },
|
||||
@@ -559,7 +561,7 @@ export const entriesH = new Elysia({ tags: ["series"] })
|
||||
preferOriginal: settings.preferOriginal,
|
||||
})) as (Entry & { show: Show })[];
|
||||
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: { description: "Get new movies/episodes added recently." },
|
||||
|
||||
@@ -391,7 +391,7 @@ export const historyH = new Elysia({ tags: ["profiles"] })
|
||||
relations: ["show"],
|
||||
})) as (Entry & { show: Show })[];
|
||||
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: {
|
||||
@@ -438,7 +438,7 @@ export const historyH = new Elysia({ tags: ["profiles"] })
|
||||
progressQ: historyProgressQ,
|
||||
})) as Entry[];
|
||||
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { and, eq, isNotNull, lt, or, sql } from "drizzle-orm";
|
||||
import { and, eq, isNotNull, lt, or, sql, desc as sqlDesc } from "drizzle-orm";
|
||||
import Elysia, { t } from "elysia";
|
||||
import { auth } from "~/auth";
|
||||
import { db } from "~/db";
|
||||
@@ -93,6 +93,11 @@ export const nextup = new Elysia({ tags: ["profiles"] })
|
||||
.select({
|
||||
...entryCol,
|
||||
...getColumns(transQ),
|
||||
__similarity: query
|
||||
? sql`word_similarity(${query}::text, ${transQ.name})`.as(
|
||||
"__similarity",
|
||||
)
|
||||
: sql`false`,
|
||||
videos: entryVideosQ.videos,
|
||||
progress: mapProgress({ aliased: true }),
|
||||
// specials don't have an `episodeNumber` but a `number` field.
|
||||
@@ -126,19 +131,17 @@ export const nextup = new Elysia({ tags: ["profiles"] })
|
||||
),
|
||||
filter,
|
||||
query ? sql`${transQ.name} %> ${query}::text` : undefined,
|
||||
keysetPaginate({ after, sort }),
|
||||
keysetPaginate({ after, sort, query }),
|
||||
),
|
||||
)
|
||||
.orderBy(
|
||||
...(query
|
||||
? [sql`word_similarity(${query}::text, ${transQ.name}) desc`]
|
||||
: sortToSql(sort)),
|
||||
...(query ? [sqlDesc(sql`__similarity`)] : sortToSql(sort)),
|
||||
entries.pk,
|
||||
)
|
||||
.limit(limit)
|
||||
.execute({ userId: sub });
|
||||
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: {
|
||||
|
||||
@@ -157,7 +157,7 @@ export const watchlistH = new Elysia({ tags: ["profiles"] })
|
||||
relations: ["nextEntry"],
|
||||
userId: sub,
|
||||
});
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: { description: "Get all movies/series in your watchlist" },
|
||||
@@ -210,7 +210,7 @@ export const watchlistH = new Elysia({ tags: ["profiles"] })
|
||||
relations: ["nextEntry"],
|
||||
userId: uInfo.id,
|
||||
});
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { and, eq, type SQL, sql } from "drizzle-orm";
|
||||
import { and, eq, type SQL, sql, desc as sqlDesc } from "drizzle-orm";
|
||||
import { Elysia, t } from "elysia";
|
||||
import { db } from "~/db";
|
||||
import { seasons, seasonTranslations, shows } from "~/db/schema";
|
||||
@@ -83,6 +83,11 @@ export async function getSeasons({
|
||||
.select({
|
||||
...getColumns(seasons),
|
||||
...transCol,
|
||||
__similarity: query
|
||||
? sql`word_similarity(${query}::text, ${transQ.name})`.as(
|
||||
"__similarity",
|
||||
)
|
||||
: sql`false`,
|
||||
})
|
||||
.from(seasons)
|
||||
.leftJoin(transQ, eq(seasons.pk, transQ.pk))
|
||||
@@ -90,13 +95,11 @@ export async function getSeasons({
|
||||
and(
|
||||
filter,
|
||||
query ? sql`${transQ.name} %> ${query}::text` : undefined,
|
||||
keysetPaginate({ after, sort }),
|
||||
keysetPaginate({ after, sort, query }),
|
||||
),
|
||||
)
|
||||
.orderBy(
|
||||
...(query
|
||||
? [sql`word_similarity(${query}::text, ${transQ.name}) desc`]
|
||||
: sortToSql(sort)),
|
||||
...(query ? [sqlDesc(sql`__similarity`)] : sortToSql(sort)),
|
||||
seasons.pk,
|
||||
)
|
||||
.limit(limit);
|
||||
@@ -144,7 +147,7 @@ export const seasonsH = new Elysia({ tags: ["series"] })
|
||||
languages: langs,
|
||||
});
|
||||
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: { description: "Get seasons of a serie" },
|
||||
|
||||
@@ -167,7 +167,7 @@ export const collections = new Elysia({
|
||||
preferOriginal: preferOriginal ?? settings.preferOriginal,
|
||||
userId: sub,
|
||||
});
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: { description: "Get all collections" },
|
||||
@@ -268,7 +268,7 @@ export const collections = new Elysia({
|
||||
preferOriginal: preferOriginal ?? settings.preferOriginal,
|
||||
userId: sub,
|
||||
});
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: { description: "Get all movies in a collection" },
|
||||
@@ -325,7 +325,7 @@ export const collections = new Elysia({
|
||||
preferOriginal: preferOriginal ?? settings.preferOriginal,
|
||||
userId: sub,
|
||||
});
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: { description: "Get all series in a collection" },
|
||||
@@ -378,7 +378,7 @@ export const collections = new Elysia({
|
||||
preferOriginal: preferOriginal ?? settings.preferOriginal,
|
||||
userId: sub,
|
||||
});
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: { description: "Get all series & movies in a collection" },
|
||||
|
||||
@@ -340,7 +340,7 @@ export async function getShows({
|
||||
pk: showTranslations.pk,
|
||||
similarity:
|
||||
sql<number>`max(word_similarity(${query ?? ""}::text, ${showTranslations.name}))`.as(
|
||||
"similarity",
|
||||
"__similarity",
|
||||
),
|
||||
})
|
||||
.from(showTranslations)
|
||||
@@ -397,6 +397,8 @@ export async function getShows({
|
||||
|
||||
watchStatus: getColumns(watchStatusQ),
|
||||
|
||||
__similarity: searchQ.similarity,
|
||||
|
||||
...buildRelations(relations, showRelations, {
|
||||
languages,
|
||||
preferOriginal,
|
||||
@@ -413,13 +415,11 @@ export async function getShows({
|
||||
and(
|
||||
filter,
|
||||
query ? sql`${searchQ.pk} is not null` : undefined,
|
||||
keysetPaginate({ after, sort }),
|
||||
keysetPaginate({ after, sort, query }),
|
||||
),
|
||||
)
|
||||
.orderBy(
|
||||
...(query
|
||||
? [desc(searchQ.similarity)]
|
||||
: sortToSql(sort)),
|
||||
...(query ? [desc(searchQ.similarity)] : sortToSql(sort)),
|
||||
shows.pk,
|
||||
)
|
||||
.limit(limit)
|
||||
|
||||
@@ -161,7 +161,7 @@ export const movies = new Elysia({ prefix: "/movies", tags: ["movies"] })
|
||||
preferOriginal: preferOriginal ?? settings.preferOriginal,
|
||||
userId: sub,
|
||||
});
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: { description: "Get all movies" },
|
||||
|
||||
@@ -173,7 +173,7 @@ export const series = new Elysia({ prefix: "/series", tags: ["series"] })
|
||||
preferOriginal: preferOriginal ?? settings.preferOriginal,
|
||||
userId: sub,
|
||||
});
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: { description: "Get all series" },
|
||||
|
||||
@@ -122,7 +122,7 @@ export const showsH = new Elysia({ prefix: "/shows", tags: ["shows"] })
|
||||
preferOriginal: preferOriginal ?? settings.preferOriginal,
|
||||
userId: sub,
|
||||
});
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: { description: "Get all movies/series/collections" },
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { and, eq, type SQL, sql } from "drizzle-orm";
|
||||
import { and, eq, type SQL, sql, desc as sqlDesc } from "drizzle-orm";
|
||||
import Elysia, { t } from "elysia";
|
||||
import { auth } from "~/auth";
|
||||
import { prefix } from "~/base";
|
||||
@@ -93,6 +93,9 @@ async function getStaffRoles({
|
||||
.select({
|
||||
...getColumns(roles),
|
||||
staff: getColumns(staff),
|
||||
__similarity: query
|
||||
? sql`word_similarity(${query}::text, ${staff.name})`.as("__similarity")
|
||||
: sql`false`,
|
||||
})
|
||||
.from(roles)
|
||||
.innerJoin(staff, eq(roles.staffPk, staff.pk))
|
||||
@@ -100,13 +103,11 @@ async function getStaffRoles({
|
||||
and(
|
||||
filter,
|
||||
query ? sql`${staff.name} %> ${query}::text` : undefined,
|
||||
keysetPaginate({ sort, after }),
|
||||
keysetPaginate({ sort, after, query }),
|
||||
),
|
||||
)
|
||||
.orderBy(
|
||||
...(query
|
||||
? [sql`word_similarity(${query}::text, ${staff.name}) desc`]
|
||||
: sortToSql(sort)),
|
||||
...(query ? [sqlDesc(sql`__similarity`)] : sortToSql(sort)),
|
||||
staff.pk,
|
||||
)
|
||||
.limit(limit);
|
||||
@@ -232,6 +233,11 @@ export const staffH = new Elysia({ tags: ["staff"] })
|
||||
const items = await db
|
||||
.select({
|
||||
...getColumns(roles),
|
||||
__similarity: query
|
||||
? sql`word_similarity(${query}::text, ${transQ.name})`.as(
|
||||
"__similarity",
|
||||
)
|
||||
: sql`false`,
|
||||
show: {
|
||||
...getColumns(shows),
|
||||
...getColumns(transQ),
|
||||
@@ -259,17 +265,15 @@ export const staffH = new Elysia({ tags: ["staff"] })
|
||||
eq(roles.staffPk, member.pk),
|
||||
filter,
|
||||
query ? sql`${transQ.name} %> ${query}::text` : undefined,
|
||||
keysetPaginate({ after, sort }),
|
||||
keysetPaginate({ after, sort, query }),
|
||||
),
|
||||
)
|
||||
.orderBy(
|
||||
...(query
|
||||
? [sql`word_similarity(${query}::text, ${transQ.name}) desc`]
|
||||
: sortToSql(sort)),
|
||||
...(query ? [sqlDesc(sql`__similarity`)] : sortToSql(sort)),
|
||||
roles.showPk,
|
||||
)
|
||||
.limit(limit);
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: {
|
||||
@@ -319,22 +323,27 @@ export const staffH = new Elysia({ tags: ["staff"] })
|
||||
headers,
|
||||
}) => {
|
||||
const items = await db
|
||||
.select()
|
||||
.select({
|
||||
...getColumns(staff),
|
||||
__similarity: query
|
||||
? sql`word_similarity(${query}::text, ${staff.name})`.as(
|
||||
"__similarity",
|
||||
)
|
||||
: sql`false`,
|
||||
})
|
||||
.from(staff)
|
||||
.where(
|
||||
and(
|
||||
query ? sql`${staff.name} %> ${query}::text` : undefined,
|
||||
keysetPaginate({ after, sort }),
|
||||
keysetPaginate({ after, sort, query }),
|
||||
),
|
||||
)
|
||||
.orderBy(
|
||||
...(query
|
||||
? [sql`word_similarity(${query}::text, ${staff.name}) desc`]
|
||||
: sortToSql(sort)),
|
||||
...(query ? [sqlDesc(sql`__similarity`)] : sortToSql(sort)),
|
||||
staff.pk,
|
||||
)
|
||||
.limit(limit);
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: {
|
||||
@@ -391,7 +400,7 @@ export const staffH = new Elysia({ tags: ["staff"] })
|
||||
sort,
|
||||
filter: and(eq(roles.showPk, movie.pk), filter),
|
||||
});
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: {
|
||||
@@ -459,7 +468,7 @@ export const staffH = new Elysia({ tags: ["staff"] })
|
||||
sort,
|
||||
filter: and(eq(roles.showPk, serie.pk), filter),
|
||||
});
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { and, eq, exists, type SQL, sql } from "drizzle-orm";
|
||||
import { and, eq, exists, type SQL, sql, desc as sqlDesc } from "drizzle-orm";
|
||||
import Elysia, { t } from "elysia";
|
||||
import { auth } from "~/auth";
|
||||
import { prefix } from "~/base";
|
||||
@@ -101,6 +101,11 @@ export async function getStudios({
|
||||
.select({
|
||||
...getColumns(studios),
|
||||
...getColumns(transQ),
|
||||
__similarity: query
|
||||
? sql`word_similarity(${query}::text, ${transQ.name})`.as(
|
||||
"__similarity",
|
||||
)
|
||||
: sql`false`,
|
||||
...buildRelations(relations, studioRelations),
|
||||
})
|
||||
.from(studios)
|
||||
@@ -112,13 +117,11 @@ export async function getStudios({
|
||||
and(
|
||||
filter,
|
||||
query ? sql`${transQ.name} %> ${query}::text` : undefined,
|
||||
keysetPaginate({ after, sort }),
|
||||
keysetPaginate({ after, sort, query }),
|
||||
),
|
||||
)
|
||||
.orderBy(
|
||||
...(query
|
||||
? [sql`word_similarity(${query}::text, ${transQ.name}) desc`]
|
||||
: sortToSql(sort)),
|
||||
...(query ? [sqlDesc(sql`__similarity`)] : sortToSql(sort)),
|
||||
studios.pk,
|
||||
)
|
||||
.limit(limit);
|
||||
@@ -243,7 +246,7 @@ export const studiosH = new Elysia({ prefix: "/studios", tags: ["studios"] })
|
||||
sort,
|
||||
languages: langs,
|
||||
});
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: { description: "Get all studios" },
|
||||
@@ -342,7 +345,7 @@ export const studiosH = new Elysia({ prefix: "/studios", tags: ["studios"] })
|
||||
preferOriginal: preferOriginal ?? settings.preferOriginal,
|
||||
userId: sub,
|
||||
});
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: { description: "Get all series & movies made by a studio." },
|
||||
@@ -404,7 +407,7 @@ export const studiosH = new Elysia({ prefix: "/studios", tags: ["studios"] })
|
||||
preferOriginal: preferOriginal ?? settings.preferOriginal,
|
||||
userId: sub,
|
||||
});
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: { description: "Get all movies made by a studio." },
|
||||
@@ -466,7 +469,7 @@ export const studiosH = new Elysia({ prefix: "/studios", tags: ["studios"] })
|
||||
preferOriginal: preferOriginal ?? settings.preferOriginal,
|
||||
userId: sub,
|
||||
});
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: { description: "Get all series made by a studio." },
|
||||
|
||||
@@ -326,6 +326,11 @@ export async function getVideos({
|
||||
.with(...cte)
|
||||
.select({
|
||||
...getColumns(videos),
|
||||
__similarity: query
|
||||
? sql`word_similarity(${query}::text, ${videos.path})`.as(
|
||||
"__similarity",
|
||||
)
|
||||
: sql`false`,
|
||||
...buildRelations(["slugs", "progress", ...relations], videoRelations, {
|
||||
languages,
|
||||
preferOriginal,
|
||||
@@ -336,13 +341,11 @@ export async function getVideos({
|
||||
and(
|
||||
filter,
|
||||
query ? sql`${videos.path} %> ${query}::text` : undefined,
|
||||
keysetPaginate({ after, sort }),
|
||||
keysetPaginate({ after, sort, query }),
|
||||
),
|
||||
)
|
||||
.orderBy(
|
||||
...(query
|
||||
? [sql`word_similarity(${query}::text, ${videos.path}) desc`]
|
||||
: sortToSql(sort)),
|
||||
...(query ? [desc(sql`__similarity`)] : sortToSql(sort)),
|
||||
videos.pk,
|
||||
)
|
||||
.limit(limit)
|
||||
@@ -482,7 +485,7 @@ export const videosReadH = new Elysia({ tags: ["videos"] })
|
||||
preferOriginal: preferOriginal ?? settings.preferOriginal,
|
||||
userId: sub,
|
||||
});
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: {
|
||||
@@ -596,7 +599,14 @@ export const videosReadH = new Elysia({ tags: ["videos"] })
|
||||
request: { url },
|
||||
}) => {
|
||||
const ret = await db
|
||||
.select()
|
||||
.select({
|
||||
...getColumns(videos),
|
||||
__similarity: query
|
||||
? sql`greatest(word_similarity(${query}::text, ${videos.path}), word_similarity(${query}::text, ${videos.guess}->>'title'))`.as(
|
||||
"__similarity",
|
||||
)
|
||||
: sql`false`,
|
||||
})
|
||||
.from(videos)
|
||||
.where(
|
||||
and(
|
||||
@@ -612,12 +622,15 @@ export const videosReadH = new Elysia({ tags: ["videos"] })
|
||||
sql`${videos.guess}->>'title' %> ${query}::text`,
|
||||
)
|
||||
: undefined,
|
||||
keysetPaginate({ after, sort }),
|
||||
keysetPaginate({ after, sort, query }),
|
||||
),
|
||||
)
|
||||
.orderBy(...(query ? [] : sortToSql(sort)), videos.pk)
|
||||
.orderBy(
|
||||
...(query ? [desc(sql`__similarity`)] : sortToSql(sort)),
|
||||
videos.pk,
|
||||
)
|
||||
.limit(limit);
|
||||
return createPage(ret, { url, sort, limit, headers });
|
||||
return createPage(ret, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: { description: "Get unknown/unmatched videos." },
|
||||
@@ -719,7 +732,7 @@ export const videosReadH = new Elysia({ tags: ["videos"] })
|
||||
(x) =>
|
||||
(x as unknown as typeof entries.$inferSelect).showPk === serie.pk,
|
||||
);
|
||||
return createPage(items, { url, sort, limit, headers });
|
||||
return createPage(items, { url, sort, limit, headers, query });
|
||||
},
|
||||
{
|
||||
detail: { description: "List videos of a serie" },
|
||||
|
||||
@@ -19,9 +19,11 @@ type After = (string | number | boolean | Date | undefined)[];
|
||||
export const keysetPaginate = ({
|
||||
sort,
|
||||
after,
|
||||
query,
|
||||
}: {
|
||||
sort: Sort | undefined;
|
||||
after: string | undefined;
|
||||
query?: string;
|
||||
}) => {
|
||||
if (!after || !sort) return undefined;
|
||||
const cursor: After = JSON.parse(
|
||||
@@ -35,6 +37,13 @@ export const keysetPaginate = ({
|
||||
desc: false,
|
||||
};
|
||||
|
||||
if (query) {
|
||||
return or(
|
||||
lt(sql`__similarity`, cursor[0]),
|
||||
and(eq(sql`__similarity`, cursor[0]), gt(sort.tablePk, cursor[1])),
|
||||
);
|
||||
}
|
||||
|
||||
if (sort.random) {
|
||||
return or(
|
||||
gt(
|
||||
@@ -76,7 +85,9 @@ export const keysetPaginate = ({
|
||||
return where;
|
||||
};
|
||||
|
||||
export const generateAfter = (cursor: any, sort: Sort) => {
|
||||
const ret = [...sort.sort.map((by) => by.accessor(cursor)), cursor.pk];
|
||||
export const generateAfter = (cursor: any, sort: Sort, query?: string) => {
|
||||
const ret = query
|
||||
? [cursor.__similarity, cursor.pk]
|
||||
: [...sort.sort.map((by) => by.accessor(cursor)), cursor.pk];
|
||||
return Buffer.from(JSON.stringify(ret), "utf-8").toString("base64url");
|
||||
};
|
||||
|
||||
@@ -21,6 +21,7 @@ export const createPage = <T>(
|
||||
{
|
||||
url,
|
||||
sort,
|
||||
query,
|
||||
limit,
|
||||
headers,
|
||||
}: {
|
||||
@@ -28,6 +29,7 @@ export const createPage = <T>(
|
||||
sort: Sort;
|
||||
limit: number;
|
||||
headers?: Record<string, string | undefined>;
|
||||
query?: string;
|
||||
},
|
||||
) => {
|
||||
const uri = new URL(url);
|
||||
@@ -52,7 +54,10 @@ export const createPage = <T>(
|
||||
// maybe the next page is empty, this is a bit weird but it allows us to handle pages
|
||||
// without making a new request to the db so it's fine.
|
||||
if (items.length >= limit && limit > 0) {
|
||||
uri.searchParams.set("after", generateAfter(items[items.length - 1], sort));
|
||||
uri.searchParams.set(
|
||||
"after",
|
||||
generateAfter(items[items.length - 1], sort, query),
|
||||
);
|
||||
next = uri.toString();
|
||||
}
|
||||
return { items, this: current, next };
|
||||
|
||||
Reference in New Issue
Block a user