diff --git a/api/src/controllers/series.ts b/api/src/controllers/series.ts deleted file mode 100644 index 6c6f65b6..00000000 --- a/api/src/controllers/series.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Elysia, t } from "elysia"; -import { Serie } from "~/models/serie"; - -export const series = new Elysia({ prefix: "/series" }) - .model({ - serie: Serie, - error: t.Object({}), - }) - .get("/:id", () => "hello" as unknown as Serie, { - response: { 200: "serie" }, - }); diff --git a/api/src/controllers/shows/collections.ts b/api/src/controllers/shows/collections.ts index bee34a2d..5ebdd915 100644 --- a/api/src/controllers/shows/collections.ts +++ b/api/src/controllers/shows/collections.ts @@ -10,6 +10,8 @@ import { import { KError } from "~/models/error"; import { duneCollection } from "~/models/examples"; import { Movie } from "~/models/movie"; +import { Serie } from "~/models/serie"; +import { Show } from "~/models/show"; import { AcceptLanguage, Filter, @@ -324,7 +326,7 @@ export const collections = new Elysia({ "accept-language": AcceptLanguage({ autoFallback: true }), }), response: { - 200: Page(Movie), + 200: Page(Serie), 404: { ...KError, description: "No collection found with the given id or slug.", @@ -401,7 +403,7 @@ export const collections = new Elysia({ "accept-language": AcceptLanguage({ autoFallback: true }), }), response: { - 200: Page(Movie), + 200: Page(Show), 404: { ...KError, description: "No collection found with the given id or slug.", diff --git a/api/src/controllers/shows/shows.ts b/api/src/controllers/shows/shows.ts index ee0a598f..49b837dd 100644 --- a/api/src/controllers/shows/shows.ts +++ b/api/src/controllers/shows/shows.ts @@ -2,10 +2,8 @@ import { and, isNull, sql } from "drizzle-orm"; import { Elysia, t } from "elysia"; import { db } from "~/db"; import { shows } from "~/db/schema"; -import { Collection } from "~/models/collections"; import { KError } from "~/models/error"; -import { Movie } from "~/models/movie"; -import { Serie } from "~/models/serie"; +import { Show } from "~/models/show"; import { AcceptLanguage, Filter, @@ -16,8 +14,6 @@ import { import { desc } from "~/models/utils/descriptions"; import { getShows, showFilters, showSort } from "./logic"; -const Show = t.Union([Movie, Serie, Collection]); - export const showsH = new Elysia({ prefix: "/shows", tags: ["shows"] }) .model({ show: Show, diff --git a/api/src/controllers/studios.ts b/api/src/controllers/studios.ts new file mode 100644 index 00000000..2eeb5e8e --- /dev/null +++ b/api/src/controllers/studios.ts @@ -0,0 +1,108 @@ +import { and, eq, exists } from "drizzle-orm"; +import Elysia, { t } from "elysia"; +import { db } from "~/db"; +import { showStudioJoin, shows, studios } from "~/db/schema"; +import { KError } from "~/models/error"; +import { Show } from "~/models/show"; +import { Studio, StudioTranslation } from "~/models/studio"; +import { + AcceptLanguage, + Filter, + Page, + createPage, + isUuid, + processLanguages, +} from "~/models/utils"; +import { desc } from "~/models/utils/descriptions"; +import { getShows, showFilters, showSort } from "./shows/logic"; + +export const studiosH = new Elysia({ tags: ["studios"] }) + .model({ + studio: Studio, + "studio-translation": StudioTranslation, + }) + .get( + "/studios/:id/shows", + async ({ + params: { id }, + query: { limit, after, query, sort, filter, preferOriginal }, + headers: { "accept-language": languages }, + request: { url }, + error, + }) => { + const [studio] = await db + .select({ pk: studios.pk }) + .from(studios) + .where(isUuid(id) ? eq(studios.id, id) : eq(studios.slug, id)) + .limit(1); + + if (!studios) { + return error(404, { + status: 404, + message: `No studios with the id or slug: '${id}'.`, + }); + } + + const langs = processLanguages(languages); + const items = await getShows({ + limit, + after, + query, + sort, + filter: and( + exists( + db + .select() + .from(showStudioJoin) + .where( + and( + eq(showStudioJoin.studio, studio.pk), + eq(showStudioJoin.show, shows.pk), + ), + ), + ), + filter, + ), + languages: langs, + preferOriginal, + }); + return createPage(items, { url, sort, limit }); + }, + { + detail: { description: "Get all series & movies made by a studio." }, + params: t.Object({ + id: t.String({ + description: "The id or slug of the studio.", + example: "mappa", + }), + }), + query: t.Object({ + sort: showSort, + filter: t.Optional(Filter({ def: showFilters })), + query: t.Optional(t.String({ description: desc.query })), + limit: t.Integer({ + minimum: 1, + maximum: 250, + default: 50, + description: "Max page size.", + }), + after: t.Optional(t.String({ description: desc.after })), + preferOriginal: t.Optional( + t.Boolean({ + description: desc.preferOriginal, + }), + ), + }), + headers: t.Object({ + "accept-language": AcceptLanguage({ autoFallback: true }), + }), + response: { + 200: Page(Show), + 404: { + ...KError, + description: "No collection found with the given id or slug.", + }, + 422: KError, + }, + }, + ); diff --git a/api/src/elysia.ts b/api/src/elysia.ts index 3dd80ac0..1df911cf 100644 --- a/api/src/elysia.ts +++ b/api/src/elysia.ts @@ -6,6 +6,7 @@ import { collections } from "./controllers/shows/collections"; import { movies } from "./controllers/shows/movies"; import { series } from "./controllers/shows/series"; import { showsH } from "./controllers/shows/shows"; +import { studiosH } from "./controllers/studios"; import { videosH } from "./controllers/videos"; import type { KError } from "./models/error"; @@ -48,4 +49,5 @@ export const app = new Elysia() .use(entriesH) .use(seasonsH) .use(videosH) + .use(studiosH) .use(seed); diff --git a/api/src/index.ts b/api/src/index.ts index 9a38beea..65e74f53 100644 --- a/api/src/index.ts +++ b/api/src/index.ts @@ -63,6 +63,7 @@ app Can be used for administration or third party apps. `, }, + { name: "studios", description: "Routes about studios" }, ], }, }), diff --git a/api/src/models/show.ts b/api/src/models/show.ts new file mode 100644 index 00000000..ccaaf35a --- /dev/null +++ b/api/src/models/show.ts @@ -0,0 +1,6 @@ +import { t } from "elysia"; +import { Collection } from "./collections"; +import { Movie } from "./movie"; +import { Serie } from "./serie"; + +export const Show = t.Union([Movie, Serie, Collection]);