diff --git a/front/src/models/collection.ts b/front/src/models/collection.ts new file mode 100644 index 00000000..86eacd74 --- /dev/null +++ b/front/src/models/collection.ts @@ -0,0 +1,40 @@ +import { z } from "zod"; +import { Genre } from "./utils/genre"; +import { Image } from "./utils/images"; +import { Metadata } from "./utils/metadata"; +import { zdate } from "./utils/utils"; + +export const Collection = z + .object({ + id: z.string(), + slug: z.string(), + name: z.string(), + original: z.object({ + name: z.string(), + latinName: z.string().nullable(), + language: z.string(), + }), + tagline: z.string().nullable(), + aliases: z.array(z.string()), + tags: z.array(z.string()), + description: z.string().nullable(), + rating: z.number().int().gte(0).lte(100).nullable(), + startAir: zdate().nullable(), + endAir: zdate().nullable(), + genres: z.array(Genre), + externalId: Metadata, + + poster: Image.nullable(), + thumbnail: Image.nullable(), + banner: Image.nullable(), + logo: Image.nullable(), + + createdAt: zdate(), + updatedAt: zdate(), + }) + .transform((x) => ({ + ...x, + href: `/collections/${x.slug}`, + })); + +export type Collection = z.infer; diff --git a/front/src/models/index.ts b/front/src/models/index.ts index 60822ce5..3b6e3bd5 100644 --- a/front/src/models/index.ts +++ b/front/src/models/index.ts @@ -1,4 +1,9 @@ export * from "./utils/page"; export * from "./kyoo-error"; -export * from "./resources"; -export * from "./traits"; + +export * from "./movie"; +export * from "./serie"; +export * from "./collection"; +export * from "./entry"; +export * from "./studio"; +export * from "./video"; diff --git a/front/src/models/movie.ts b/front/src/models/movie.ts new file mode 100644 index 00000000..3ed821eb --- /dev/null +++ b/front/src/models/movie.ts @@ -0,0 +1,56 @@ +import { z } from "zod"; +import { Studio } from "./studio"; +import { Genre } from "./utils/genre"; +import { Image } from "./utils/images"; +import { Metadata } from "./utils/metadata"; +import { zdate } from "./utils/utils"; +import { EmbeddedVideo } from "./video"; + +export const Movie = z + .object({ + id: z.string(), + slug: z.string(), + name: z.string(), + original: z.object({ + name: z.string(), + latinName: z.string().nullable(), + language: z.string(), + }), + tagline: z.string().nullable(), + aliases: z.array(z.string()), + tags: z.array(z.string()), + description: z.string().nullable(), + status: z.enum(["unknown", "finished", "planned"]), + rating: z.number().int().gte(0).lte(100), + runtime: z.number().int().nullable(), + airDate: zdate().nullable(), + genres: z.array(Genre), + externalId: Metadata, + + poster: Image.nullable(), + thumbnail: Image.nullable(), + banner: Image.nullable(), + logo: Image.nullable(), + trailerUrl: z.string().optional().nullable(), + + isAvailable: z.boolean(), + + createdAt: zdate(), + updatedAt: zdate(), + + studios: z.array(Studio).optional(), + videos: z.array(EmbeddedVideo).optional(), + watchStatus: z + .object({ + status: z.enum(["completed", "watching", "rewatching", "dropped", "planned"]), + score: z.number().int().gte(0).lte(100).nullable(), + completedAt: zdate().nullable(), + percent: z.number().int().gte(0).lte(100), + }) + .nullable(), + }) + .transform((x) => ({ + ...x, + href: `/movies/${x.slug}`, + })); +export type Movie = z.infer; diff --git a/front/src/models/resources/collection.ts b/front/src/models/resources/collection.ts deleted file mode 100644 index 1442db15..00000000 --- a/front/src/models/resources/collection.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { z } from "zod"; -import { ImagesP, ResourceP } from "../traits"; - -export const CollectionP = ResourceP("collection") - .merge(ImagesP) - .extend({ - /** - * The title of this collection. - */ - name: z.string(), - /** - * The summary of this show. - */ - overview: z.string().nullable(), - }) - .transform((x) => ({ - ...x, - href: `/collection/${x.slug}`, - })); - -/** - * A class representing collections of show or movies. - */ -export type Collection = z.infer; diff --git a/front/src/models/resources/movie.ts b/front/src/models/resources/movie.ts deleted file mode 100644 index c0c186a5..00000000 --- a/front/src/models/resources/movie.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { z } from "zod"; -import { ImagesP, ResourceP } from "../traits"; -import { zdate } from "../utils"; -import { CollectionP } from "./collection"; -import { Genre } from "./genre"; -import { MetadataP } from "./metadata"; -import { Status } from "./show"; -import { StudioP } from "./studio"; -import { WatchStatusP } from "./watch-status"; - -export const MovieP = ResourceP("movie") - .merge(ImagesP) - .extend({ - /** - * The title of this movie. - */ - name: z.string(), - /** - * A catchphrase for this show. - */ - tagline: z.string().nullable(), - /** - * The list of alternative titles of this movie. - */ - aliases: z.array(z.string()), - /** - * The summary of this movie. - */ - overview: z.string().nullable(), - /** - * A list of tags that match this movie. - */ - tags: z.array(z.string()), - /** - * /** Is this movie not aired yet or finished? - */ - status: z.nativeEnum(Status), - /** - * How well this item is rated? (from 0 to 100). - */ - rating: z.number().int().gte(0).lte(100), - /** - * How long is this movie? (in minutes). - */ - runtime: z.number().int().nullable(), - /** - * The date this movie aired. It can also be null if this is unknown. - */ - airDate: zdate().nullable(), - /** - * A youtube url for the trailer. - */ - trailer: z.string().optional().nullable(), - /** - * The list of genres (themes) this movie has. - */ - genres: z.array(z.nativeEnum(Genre)), - /** - * The studio that made this movie. - */ - studio: StudioP.optional().nullable(), - /** - * The collection this movie is part of. - */ - collections: z.array(CollectionP).optional(), - /** - * The links to see a movie or an episode. - */ - links: z.object({ - /** - * The direct link to the unprocessed video (pristine quality). - */ - direct: z.string(), - - /** - * The link to an HLS master playlist containing all qualities available for this video. - */ - hls: z.string().nullable(), - }), - /** - * The link to metadata providers that this show has. - */ - externalId: MetadataP, - /** - * Metadata of what an user as started/planned to watch. - */ - watchStatus: WatchStatusP.optional().nullable(), - }) - .transform((x) => ({ - ...x, - runtime: x.runtime === 0 ? null : x.runtime, - })) - .transform((x) => { - if (!x.thumbnail && x.poster) { - x.thumbnail = { ...x.poster }; - if (x.thumbnail) { - x.thumbnail.low = x.thumbnail.high; - x.thumbnail.medium = x.thumbnail.high; - } - } - return x; - }) - .transform((x) => ({ - ...x, - href: `/movie/${x.slug}`, - playHref: `/movie/${x.slug}/watch`, - })); - -/** - * A Movie type - */ -export type Movie = z.infer; diff --git a/front/src/models/serie.ts b/front/src/models/serie.ts index 3cffee78..7bca6f0d 100644 --- a/front/src/models/serie.ts +++ b/front/src/models/serie.ts @@ -28,15 +28,15 @@ export const Serie = z runtime: z.number().nullable(), externalId: Metadata, - entriesCount: z.number().int(), - availableCount: z.number().int(), - poster: Image.nullable(), thumbnail: Image.nullable(), banner: Image.nullable(), logo: Image.nullable(), trailerUrl: z.string().optional().nullable(), + entriesCount: z.number().int(), + availableCount: z.number().int(), + createdAt: zdate(), updatedAt: zdate(), @@ -55,7 +55,7 @@ export const Serie = z }) .transform((x) => ({ ...x, - href: `/serie/${x.slug}`, + href: `/series/${x.slug}`, playHref: x.firstEntry ? `/watch/${x.firstEntry.slug}` : null, })); diff --git a/front/src/models/video.ts b/front/src/models/video.ts new file mode 100644 index 00000000..1cf02250 --- /dev/null +++ b/front/src/models/video.ts @@ -0,0 +1,11 @@ +import { z } from "zod"; + +export const EmbeddedVideo = z.object({ + id: z.string(), + slug: z.string(), + path: z.string(), + rendering: z.string(), + part: z.number().int().gt(0).nullable(), + version: z.number().gt(0), +}); +export type EmbeddedVideo = z.infer;