diff --git a/api/src/models/movie.ts b/api/src/models/movie.ts index b7eef38a..c19ee5be 100644 --- a/api/src/models/movie.ts +++ b/api/src/models/movie.ts @@ -5,13 +5,15 @@ import { Image, Language, Resource, + SeedImage, } from "./utils"; -import { Video } from "./video"; +import { SeedVideo } from "./video"; +import { bubble, registerExamples } from "./examples"; export const MovieStatus = t.UnionEnum(["unknown", "finished", "planned"]); export type MovieStatus = typeof MovieStatus.static; -export const BaseMovie = t.Object({ +const BaseMovie = t.Object({ genres: t.Array(Genre), rating: t.Nullable(t.Number({ minimum: 0, maximum: 100 })), status: MovieStatus, @@ -31,8 +33,6 @@ export const BaseMovie = t.Object({ externalId: ExternalId, }); -export type BaseMovie = typeof BaseMovie.static; - export const MovieTranslation = t.Object({ name: t.String(), description: t.Nullable(t.String()), @@ -48,23 +48,31 @@ export const MovieTranslation = t.Object({ }); export type MovieTranslation = typeof MovieTranslation.static; -export const Movie = t.Intersect([ - Resource, - BaseMovie, - t.Ref(MovieTranslation), -]); +export const Movie = t.Intersect([Resource, MovieTranslation, BaseMovie]); export type Movie = typeof Movie.static; export const SeedMovie = t.Intersect([ - BaseMovie, + t.Omit(BaseMovie, ["createdAt", "nextRefresh"]), t.Object({ slug: t.String({ format: "slug" }), - image: t.Ref("image"), - toto: t.Ref("mt"), - translations: t.Record(t.String(), t.Ref("mt"), { - minProperties: 1, - }), - videos: t.Optional(t.Array(t.Ref(Video))), + translations: t.Record( + Language(), + t.Intersect([ + t.Omit(MovieTranslation, ["poster", "thumbnail", "banner", "logo"]), + t.Object({ + poster: t.Nullable(SeedImage), + thumbnail: t.Nullable(SeedImage), + banner: t.Nullable(SeedImage), + logo: t.Nullable(SeedImage), + }), + ]), + { + minProperties: 1, + }, + ), + videos: t.Optional(t.Array(SeedVideo)), }), ]); export type SeedMovie = typeof SeedMovie.static; + +registerExamples(SeedMovie, bubble); diff --git a/api/src/models/utils/image.ts b/api/src/models/utils/image.ts index 407de425..c1883d60 100644 --- a/api/src/models/utils/image.ts +++ b/api/src/models/utils/image.ts @@ -6,3 +6,5 @@ export const Image = t.Object({ blurhash: t.String(), }); export type Image = typeof Image.static; + +export const SeedImage = t.String({ format: "uri" }); diff --git a/api/src/models/utils/resource.ts b/api/src/models/utils/resource.ts index 0de06436..4c47cf48 100644 --- a/api/src/models/utils/resource.ts +++ b/api/src/models/utils/resource.ts @@ -1,6 +1,8 @@ import { FormatRegistry } from "@sinclair/typebox"; import { t } from "elysia"; +export const slugPattern = "^[a-z0-9-]+$"; + FormatRegistry.Set("slug", (slug) => { return /^[a-z0-9-]+$/g.test(slug); }); diff --git a/api/src/models/video.ts b/api/src/models/video.ts index bb6f9cb6..12346e50 100644 --- a/api/src/models/video.ts +++ b/api/src/models/video.ts @@ -1,11 +1,9 @@ import { t } from "elysia"; import { comment } from "../utils"; -import { bubble, registerExamples } from "./examples"; -import { Movie } from "./movie"; export const Video = t.Object({ id: t.String({ format: "uuid" }), - slug: t.String(), + slug: t.String({ format: "slug" }), path: t.String(), rendering: t.String({ description: comment` @@ -36,4 +34,7 @@ export const Video = t.Object({ export type Video = typeof Video.static; -registerExamples(Video, ...bubble.videos); +export const SeedVideo = t.Union([ + t.Omit(Video, ["id", "slug", "createdAt"]), + t.String({ format: "uuid" }), +]);