mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-06-04 22:24:14 -04:00
Define schema for all entries type
This commit is contained in:
parent
eb2d2009f7
commit
7071e07ef4
@ -29,7 +29,7 @@ export const entries = schema.table(
|
|||||||
id: uuid().notNull().unique().defaultRandom(),
|
id: uuid().notNull().unique().defaultRandom(),
|
||||||
slug: varchar({ length: 255 }).notNull().unique(),
|
slug: varchar({ length: 255 }).notNull().unique(),
|
||||||
showPk: integer().references(() => shows.pk, { onDelete: "cascade" }),
|
showPk: integer().references(() => shows.pk, { onDelete: "cascade" }),
|
||||||
order: integer().notNull(),
|
order: integer(),
|
||||||
seasonNumber: integer(),
|
seasonNumber: integer(),
|
||||||
episodeNumber: integer(),
|
episodeNumber: integer(),
|
||||||
type: entryType().notNull(),
|
type: entryType().notNull(),
|
||||||
|
111
api/src/models/entry.ts
Normal file
111
api/src/models/entry.ts
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
import { t } from "elysia";
|
||||||
|
import { Image } from "./utils/image";
|
||||||
|
import { ExternalId, EpisodeId } from "./utils/external-id";
|
||||||
|
import { comment } from "../utils";
|
||||||
|
|
||||||
|
export const Entry = t.Object({
|
||||||
|
id: t.String({ format: "uuid" }),
|
||||||
|
slug: t.String(),
|
||||||
|
serieId: t.String({ format: "uuid" }),
|
||||||
|
name: t.Nullable(t.String()),
|
||||||
|
description: t.Nullable(t.String()),
|
||||||
|
airDate: t.Nullable(t.String({ format: "data" })),
|
||||||
|
runtime: t.Nullable(
|
||||||
|
t.Number({ minimum: 0, description: "Runtime of the episode in minutes" }),
|
||||||
|
),
|
||||||
|
thumbnail: t.Nullable(Image),
|
||||||
|
|
||||||
|
createtAt: t.String({ format: "date-time" }),
|
||||||
|
nextRefresh: t.String({ format: "date-time" }),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const Episode = t.Union([
|
||||||
|
Entry,
|
||||||
|
t.Object({
|
||||||
|
kind: t.Literal("episode"),
|
||||||
|
seasonId: t.String({ format: "uuid" }),
|
||||||
|
order: t.Number({ minimum: 1, description: "Absolute playback order." }),
|
||||||
|
seasonNumber: t.Number(),
|
||||||
|
episodeNumber: t.Number(),
|
||||||
|
externalId: EpisodeId,
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
export type Episode = typeof Episode.static;
|
||||||
|
|
||||||
|
export const MovieEntry = t.Union(
|
||||||
|
[
|
||||||
|
Entry,
|
||||||
|
t.Object({
|
||||||
|
kind: t.Literal("movie"),
|
||||||
|
order: t.Number({
|
||||||
|
minimum: 1,
|
||||||
|
description: "Absolute playback order. Can be mixed with episodes.",
|
||||||
|
}),
|
||||||
|
externalId: ExternalId,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
{
|
||||||
|
description: comment`
|
||||||
|
If a movie is part of a serie (watching the movie require context from the serie &
|
||||||
|
the next episode of the serie require you to have seen the movie to understand it.)
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
export type MovieEntry = typeof MovieEntry.static;
|
||||||
|
|
||||||
|
export const Special = t.Union(
|
||||||
|
[
|
||||||
|
Entry,
|
||||||
|
t.Object({
|
||||||
|
kind: t.Literal("special"),
|
||||||
|
order: t.Number({
|
||||||
|
minimum: 1,
|
||||||
|
description: "Absolute playback order. Can be mixed with episodes.",
|
||||||
|
}),
|
||||||
|
number: t.Number({ minimum: 1 }),
|
||||||
|
externalId: EpisodeId,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
{
|
||||||
|
description: comment`
|
||||||
|
A special is either an OAV episode (side story & co) or an important episode that was released standalone
|
||||||
|
(outside of a season.)
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
export type Special = typeof Special.static;
|
||||||
|
|
||||||
|
export const Extra = t.Union(
|
||||||
|
[
|
||||||
|
Entry,
|
||||||
|
t.Object({
|
||||||
|
kind: t.Literal("extra"),
|
||||||
|
number: t.Number({ minimum: 1 }),
|
||||||
|
// not sure about this id type
|
||||||
|
externalId: EpisodeId,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
{
|
||||||
|
description: comment`
|
||||||
|
An extra can be a beyond-the-scene, short-episodes or anything that is in a different format & not required
|
||||||
|
in the main story plot.
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
export type Extra = typeof Extra.static;
|
||||||
|
|
||||||
|
export const Video = t.Union(
|
||||||
|
[
|
||||||
|
t.Omit(Entry, ["serieId", "airDate"]),
|
||||||
|
t.Object({
|
||||||
|
kind: t.Literal("unknown"),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
{
|
||||||
|
description: comment`
|
||||||
|
A video not releated to any series or movie. This can be due to a matching error but it can be a youtube
|
||||||
|
video or any other video content.
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
export type Video = typeof Video.static;
|
@ -1,4 +1,5 @@
|
|||||||
import { t } from "elysia";
|
import { t } from "elysia";
|
||||||
|
import { comment } from "../../utils";
|
||||||
|
|
||||||
export const ExternalId = t.Record(
|
export const ExternalId = t.Record(
|
||||||
t.String(),
|
t.String(),
|
||||||
@ -9,3 +10,22 @@ export const ExternalId = t.Record(
|
|||||||
);
|
);
|
||||||
|
|
||||||
export type ExternalId = typeof ExternalId.static;
|
export type ExternalId = typeof ExternalId.static;
|
||||||
|
|
||||||
|
export const EpisodeId = t.Record(
|
||||||
|
t.String(),
|
||||||
|
t.Object({
|
||||||
|
serieId: t.String({
|
||||||
|
descrpition: comment`
|
||||||
|
Id on the external website.
|
||||||
|
We store the serie's id because episode id are rarely stable.
|
||||||
|
`,
|
||||||
|
}),
|
||||||
|
season: t.Nullable(
|
||||||
|
t.Number({
|
||||||
|
description: "Null if the external website uses absolute numbering.",
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
episode: t.Number(),
|
||||||
|
link: t.Nullable(t.String({ format: "uri" })),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user