mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Add serie model, dummy controller & example
This commit is contained in:
parent
89952185a9
commit
c5a502ec32
11
api/src/controllers/series.ts
Normal file
11
api/src/controllers/series.ts
Normal file
@ -0,0 +1,11 @@
|
||||
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" },
|
||||
});
|
@ -3,6 +3,7 @@ import { swagger } from "@elysiajs/swagger";
|
||||
import { migrate } from "drizzle-orm/node-postgres/migrator";
|
||||
import { Elysia } from "elysia";
|
||||
import { movies } from "./controllers/movies";
|
||||
import { series } from "./controllers/series";
|
||||
import { videos } from "./controllers/videos";
|
||||
import { db } from "./db";
|
||||
|
||||
@ -33,6 +34,7 @@ const app = new Elysia()
|
||||
.use(swagger())
|
||||
.get("/", () => "Hello Elysia")
|
||||
.use(movies)
|
||||
.use(series)
|
||||
.use(videos)
|
||||
.listen(3000);
|
||||
|
||||
|
@ -1,22 +1,4 @@
|
||||
import type { TSchema } from "elysia";
|
||||
import type { CompleteVideo } from "./video";
|
||||
|
||||
export const registerExamples = <T extends TSchema>(
|
||||
schema: T,
|
||||
...examples: (T["static"] | undefined)[]
|
||||
) => {
|
||||
for (const example of examples) {
|
||||
if (!example) continue;
|
||||
for (const [key, val] of Object.entries(example)) {
|
||||
const prop = schema.properties[
|
||||
key as keyof typeof schema.properties
|
||||
] as TSchema;
|
||||
if (!prop) continue;
|
||||
prop.examples ??= [];
|
||||
prop.examples.push(val);
|
||||
}
|
||||
}
|
||||
};
|
||||
import type { CompleteVideo } from "../video";
|
||||
|
||||
export const bubble: CompleteVideo = {
|
||||
id: "0934da28-4a49-404e-920b-a150404a3b6d",
|
27
api/src/models/examples/index.ts
Normal file
27
api/src/models/examples/index.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import type { TSchema } from "elysia";
|
||||
|
||||
export const registerExamples = <T extends TSchema>(
|
||||
schema: T,
|
||||
...examples: (T["static"] | undefined)[]
|
||||
) => {
|
||||
if ("anyOf" in schema) {
|
||||
for (const union of schema.anyOf) {
|
||||
registerExamples(union, examples);
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (const example of examples) {
|
||||
if (!example) continue;
|
||||
for (const [key, val] of Object.entries(example)) {
|
||||
const prop = schema.properties[
|
||||
key as keyof typeof schema.properties
|
||||
] as TSchema;
|
||||
if (!prop) continue;
|
||||
prop.examples ??= [];
|
||||
prop.examples.push(val);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export { bubble } from "./bubble";
|
||||
export { madeInAbyss } from "./made-in-abyss";
|
79
api/src/models/examples/made-in-abyss.ts
Normal file
79
api/src/models/examples/made-in-abyss.ts
Normal file
@ -0,0 +1,79 @@
|
||||
import type { Serie } from "../serie";
|
||||
|
||||
export const madeInAbyss: Serie = {
|
||||
id: "04bcf2ac-3c09-42f6-8357-b003798f9562",
|
||||
slug: "made-in-abyss",
|
||||
name: "Made in Abyss",
|
||||
tagline: "How far would you go… for the ones you love?",
|
||||
aliases: [
|
||||
"Made in Abyss: The Golden City of the Scorching Sun",
|
||||
"Meidoinabisu",
|
||||
"Meidoinabisu: Retsujitsu no ôgonkyô",
|
||||
],
|
||||
description:
|
||||
"Located in the center of a remote island, the Abyss is the last unexplored region, a huge and treacherous fathomless hole inhabited by strange creatures where only the bravest adventurers descend in search of ancient relics. In the upper levels of the Abyss, Riko, a girl who dreams of becoming an explorer, stumbles upon a mysterious little boy.",
|
||||
tags: [
|
||||
"android",
|
||||
"amnesia",
|
||||
"post-apocalyptic future",
|
||||
"exploration",
|
||||
"friendship",
|
||||
"mecha",
|
||||
"survival",
|
||||
"curse",
|
||||
"tragedy",
|
||||
"orphan",
|
||||
"based on manga",
|
||||
"robot",
|
||||
"dark fantasy",
|
||||
"seinen",
|
||||
"anime",
|
||||
"drastic change of life",
|
||||
"fantasy",
|
||||
"adventure",
|
||||
],
|
||||
genres: [
|
||||
"animation",
|
||||
"drama",
|
||||
"action",
|
||||
"adventure",
|
||||
"science-fiction",
|
||||
"fantasy",
|
||||
],
|
||||
status: "finished",
|
||||
rating: 84,
|
||||
runtime: 24,
|
||||
originalLanguage: "ja",
|
||||
startAir: "2017-07-07",
|
||||
endAir: "2022-09-28",
|
||||
poster: {
|
||||
id: "8205a20e-d91f-804c-3a84-4e4dc6202d66",
|
||||
source:
|
||||
"https://image.tmdb.org/t/p/original/4Bh9qzB1Kau4RDaVQXVFdoJ0HcE.jpg",
|
||||
blurhash: "LZGlS3XTD%jE~Wf,SeV@%2o|WERj",
|
||||
},
|
||||
thumbnail: {
|
||||
id: "819d816c-88f6-9f3a-b5e7-ce3daaffbac4",
|
||||
source:
|
||||
"https://image.tmdb.org/t/p/original/Df9XrvZFIeQfLKfu8evRmzvRsd.jpg",
|
||||
blurhash: "LmJtk{kq~q%2bbWCxaV@.8RixuNG",
|
||||
},
|
||||
logo: {
|
||||
id: "23cb7b06-8406-2288-8e40-08bfc16180b5",
|
||||
source:
|
||||
"https://image.tmdb.org/t/p/original/7hY3Q4GhkiYPBfn4UoVg0AO4Zgk.png",
|
||||
blurhash: "LKGaa%M{0zbI#7$%bbofGGw^wcw{",
|
||||
},
|
||||
banner: null,
|
||||
trailerUrl: "https://www.youtube.com/watch?v=ePOyy6Wlk4s",
|
||||
externalId: {
|
||||
themoviedatabase: {
|
||||
dataId: "72636",
|
||||
link: "https://www.themoviedb.org/tv/72636",
|
||||
},
|
||||
imdb: { dataId: "tt7222086", link: "https://www.imdb.com/title/tt7222086" },
|
||||
tvdb: { dataId: "326109", link: null },
|
||||
},
|
||||
createdAt: "2023-11-29T11:12:11.949503Z",
|
||||
nextRefresh: "2025-01-07T11:42:50.948248Z",
|
||||
};
|
@ -1,10 +1,13 @@
|
||||
import { t } from "elysia";
|
||||
import { Genre, ShowStatus } from "./show";
|
||||
import { Genre } from "./show";
|
||||
import { Image } from "./image";
|
||||
import { ExternalId } from "./external-id";
|
||||
import { bubble, registerExamples } from "./examples";
|
||||
import { comment } from "../utils";
|
||||
|
||||
export const MovieStatus = t.UnionEnum(["unknown", "finished", "planned"]);
|
||||
export type MovieStatus = typeof MovieStatus.static;
|
||||
|
||||
export const Movie = t.Object({
|
||||
id: t.String({ format: "uuid" }),
|
||||
slug: t.String(),
|
||||
@ -16,8 +19,10 @@ export const Movie = t.Object({
|
||||
|
||||
genres: t.Array(Genre),
|
||||
rating: t.Nullable(t.Number({ minimum: 0, maximum: 100 })),
|
||||
status: ShowStatus,
|
||||
runtime: t.Nullable(t.Number({ minimum: 0 })),
|
||||
status: MovieStatus,
|
||||
runtime: t.Nullable(
|
||||
t.Number({ minimum: 0, description: "Runtime of the movie in minutes." }),
|
||||
),
|
||||
|
||||
airDate: t.Nullable(t.String({ format: "date" })),
|
||||
originalLanguage: t.Nullable(
|
||||
|
61
api/src/models/serie.ts
Normal file
61
api/src/models/serie.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import { t } from "elysia";
|
||||
import { Genre } from "./show";
|
||||
import { Image } from "./image";
|
||||
import { ExternalId } from "./external-id";
|
||||
import { madeInAbyss , registerExamples } from "./examples";
|
||||
import { comment } from "../utils";
|
||||
|
||||
export const SerieStatus = t.UnionEnum([
|
||||
"unknown",
|
||||
"finished",
|
||||
"airing",
|
||||
"planned",
|
||||
]);
|
||||
export type SerieStatus = typeof SerieStatus.static;
|
||||
|
||||
export const Serie = t.Object({
|
||||
id: t.String({ format: "uuid" }),
|
||||
slug: t.String(),
|
||||
name: t.String(),
|
||||
description: t.Nullable(t.String()),
|
||||
tagline: t.Nullable(t.String()),
|
||||
aliases: t.Array(t.String()),
|
||||
tags: t.Array(t.String()),
|
||||
|
||||
genres: t.Array(Genre),
|
||||
rating: t.Nullable(t.Number({ minimum: 0, maximum: 100 })),
|
||||
status: SerieStatus,
|
||||
runtime: t.Nullable(
|
||||
t.Number({
|
||||
minimum: 0,
|
||||
description: "Average runtime of all episodes (in minutes.)",
|
||||
}),
|
||||
),
|
||||
|
||||
startAir: t.Nullable(t.String({ format: "date" })),
|
||||
endAir: t.Nullable(t.String({ format: "date" })),
|
||||
originalLanguage: t.Nullable(
|
||||
t.String({
|
||||
description: comment`
|
||||
The language code this movie was made in.
|
||||
This is a BCP 47 language code (the IETF Best Current Practices on Tags for Identifying Languages).
|
||||
BCP 47 is also known as RFC 5646. It subsumes ISO 639 and is backward compatible with it.
|
||||
`,
|
||||
}),
|
||||
),
|
||||
|
||||
poster: t.Nullable(Image),
|
||||
thumbnail: t.Nullable(Image),
|
||||
banner: t.Nullable(Image),
|
||||
logo: t.Nullable(Image),
|
||||
trailerUrl: t.Nullable(t.String()),
|
||||
|
||||
createdAt: t.String({ format: "date-time" }),
|
||||
nextRefresh: t.String({ format: "date-time" }),
|
||||
|
||||
externalId: ExternalId,
|
||||
});
|
||||
|
||||
export type Serie = typeof Serie.static;
|
||||
|
||||
registerExamples(Serie, madeInAbyss);
|
@ -1,13 +1,5 @@
|
||||
import { t } from "elysia";
|
||||
|
||||
export const ShowStatus = t.UnionEnum([
|
||||
"unknown",
|
||||
"finished",
|
||||
"airing",
|
||||
"planned",
|
||||
]);
|
||||
export type ShowStatus = typeof ShowStatus.static;
|
||||
|
||||
export const Genre = t.UnionEnum([
|
||||
"action",
|
||||
"adventure",
|
||||
|
7
api/src/seed.ts
Normal file
7
api/src/seed.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { db } from "./db";
|
||||
import { videos } from "./db/schema/videos";
|
||||
import { Video } from "./models/video";
|
||||
|
||||
const seed = async () =>{
|
||||
db.insert(videos).values(Video.examples)
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user