mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Move sort parsing to typebox
This commit is contained in:
parent
0499be4194
commit
482ad0dda2
@ -7,13 +7,14 @@ import {
|
|||||||
isUuid,
|
isUuid,
|
||||||
processLanguages,
|
processLanguages,
|
||||||
} from "~/models/utils";
|
} from "~/models/utils";
|
||||||
import { comment, type RemovePrefix } from "~/utils";
|
import { comment } from "~/utils";
|
||||||
import { db } from "../db";
|
import { db } from "../db";
|
||||||
import { shows, showTranslations } from "../db/schema/shows";
|
import { shows, showTranslations } from "../db/schema/shows";
|
||||||
import { getColumns } from "../db/schema/utils";
|
import { getColumns } from "../db/schema/utils";
|
||||||
import { bubble } from "../models/examples";
|
import { bubble } from "../models/examples";
|
||||||
import { Movie, MovieStatus, MovieTranslation } from "../models/movie";
|
import { Movie, MovieStatus, MovieTranslation } from "../models/movie";
|
||||||
import { Filter, type Page } from "~/models/utils";
|
import { Filter, type Page } from "~/models/utils";
|
||||||
|
import { Sort } from "~/models/utils/sort";
|
||||||
|
|
||||||
// drizzle is bugged and doesn't allow js arrays to be used in raw sql.
|
// drizzle is bugged and doesn't allow js arrays to be used in raw sql.
|
||||||
export function sqlarr(array: unknown[]) {
|
export function sqlarr(array: unknown[]) {
|
||||||
@ -158,15 +159,8 @@ export const movies = new Elysia({ prefix: "/movies", tags: ["movies"] })
|
|||||||
}) => {
|
}) => {
|
||||||
const langs = processLanguages(languages);
|
const langs = processLanguages(languages);
|
||||||
const [transQ, transCol] = getTranslationQuery(langs);
|
const [transQ, transCol] = getTranslationQuery(langs);
|
||||||
// TODO: move this to typebox transform
|
|
||||||
const order = sort.map((x) => {
|
|
||||||
const desc = x[0] === "-";
|
|
||||||
const key = (desc ? x.substring(1) : x) as RemovePrefix<typeof x, "-">;
|
|
||||||
if (key === "airDate") return { key: "startAir" as const, desc };
|
|
||||||
return { key, desc };
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO: Add sql indexes on order keys
|
// TODO: Add sql indexes on sort keys
|
||||||
|
|
||||||
const items = await db
|
const items = await db
|
||||||
.select({
|
.select({
|
||||||
@ -179,7 +173,7 @@ export const movies = new Elysia({ prefix: "/movies", tags: ["movies"] })
|
|||||||
.innerJoin(transQ, eq(shows.pk, transQ.pk))
|
.innerJoin(transQ, eq(shows.pk, transQ.pk))
|
||||||
.where(filter)
|
.where(filter)
|
||||||
.orderBy(
|
.orderBy(
|
||||||
...order.map((x) => (x.desc ? desc(shows[x.key]) : shows[x.key])),
|
...sort.map((x) => (x.desc ? desc(shows[x.key]) : shows[x.key])),
|
||||||
shows.pk,
|
shows.pk,
|
||||||
)
|
)
|
||||||
.limit(limit);
|
.limit(limit);
|
||||||
@ -189,23 +183,17 @@ export const movies = new Elysia({ prefix: "/movies", tags: ["movies"] })
|
|||||||
{
|
{
|
||||||
detail: { description: "Get all movies" },
|
detail: { description: "Get all movies" },
|
||||||
query: t.Object({
|
query: t.Object({
|
||||||
sort: t.Array(
|
sort: Sort(
|
||||||
// TODO: Add random
|
[
|
||||||
t.UnionEnum([
|
|
||||||
"slug",
|
"slug",
|
||||||
"-slug",
|
|
||||||
"rating",
|
"rating",
|
||||||
"-rating",
|
|
||||||
"airDate",
|
"airDate",
|
||||||
"-airDate",
|
|
||||||
"createdAt",
|
"createdAt",
|
||||||
"-createdAt",
|
|
||||||
"nextRefresh",
|
"nextRefresh",
|
||||||
"-nextRefresh",
|
],
|
||||||
]),
|
|
||||||
// TODO: support explode: true (allow sort=slug,-createdAt). needs a pr to elysia
|
|
||||||
{
|
{
|
||||||
explode: false,
|
// TODO: Add random
|
||||||
|
remap: { airDate: "startAir" },
|
||||||
default: ["slug"],
|
default: ["slug"],
|
||||||
description: "How to sort the query",
|
description: "How to sort the query",
|
||||||
},
|
},
|
||||||
|
53
api/src/models/utils/sort.ts
Normal file
53
api/src/models/utils/sort.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import { t } from "elysia";
|
||||||
|
|
||||||
|
type Sort<
|
||||||
|
T extends string[],
|
||||||
|
Remap extends Partial<Record<T[number], string>>,
|
||||||
|
> = {
|
||||||
|
key: Exclude<T[number], keyof Remap> | Remap[keyof Remap];
|
||||||
|
desc: boolean;
|
||||||
|
}[];
|
||||||
|
|
||||||
|
type NonEmptyArray<T> = [T, ...T[]];
|
||||||
|
|
||||||
|
export const Sort = <
|
||||||
|
const T extends NonEmptyArray<string>,
|
||||||
|
const Remap extends Partial<Record<T[number], string>>,
|
||||||
|
>(
|
||||||
|
values: T,
|
||||||
|
{
|
||||||
|
description = "How to sort the query",
|
||||||
|
default: def,
|
||||||
|
remap,
|
||||||
|
}: {
|
||||||
|
default?: T[number][];
|
||||||
|
description: string;
|
||||||
|
remap: Remap;
|
||||||
|
},
|
||||||
|
) =>
|
||||||
|
t
|
||||||
|
.Transform(
|
||||||
|
t.Array(
|
||||||
|
t.UnionEnum([
|
||||||
|
...values,
|
||||||
|
...values.map((x: T[number]) => `-${x}` as const),
|
||||||
|
]),
|
||||||
|
{
|
||||||
|
// TODO: support explode: true (allow sort=slug,-createdAt). needs a pr to elysia
|
||||||
|
explode: false,
|
||||||
|
default: def,
|
||||||
|
description: description,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.Decode((sort): Sort<T, Remap> => {
|
||||||
|
return sort.map((x) => {
|
||||||
|
const desc = x[0] === "-";
|
||||||
|
const key = (desc ? x.substring(1) : x) as T[number];
|
||||||
|
if (key in remap) return { key: remap[key], desc };
|
||||||
|
return { key: key as Exclude<typeof key, keyof Remap>, desc };
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.Encode(() => {
|
||||||
|
throw new Error("Encode not supported for sort");
|
||||||
|
});
|
@ -6,8 +6,3 @@ export const comment = (str: TemplateStringsArray, ...values: any[]) =>
|
|||||||
.replace(/^[ \t]+/gm, "") // leading spaces
|
.replace(/^[ \t]+/gm, "") // leading spaces
|
||||||
.replace(/([^\n])\n([^\n])/g, "$1 $2") // two lines to space separated line
|
.replace(/([^\n])\n([^\n])/g, "$1 $2") // two lines to space separated line
|
||||||
.replace(/\n{2}/g, "\n"); // keep newline if there's an empty line
|
.replace(/\n{2}/g, "\n"); // keep newline if there's an empty line
|
||||||
|
|
||||||
export type RemovePrefix<
|
|
||||||
T extends string,
|
|
||||||
Prefix extends string,
|
|
||||||
> = T extends `${Prefix}${infer Ret}` ? Ret : T;
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user