diff --git a/api/src/controllers/entries.ts b/api/src/controllers/entries.ts index 9dcada78..dbdd42bd 100644 --- a/api/src/controllers/entries.ts +++ b/api/src/controllers/entries.ts @@ -250,10 +250,10 @@ export const entriesH = new Elysia({ tags: ["series"] }) }, { detail: { description: "Get extras of a serie" }, - path: t.Object({ + params: t.Object({ id: t.String({ description: "The id or slug of the serie.", - examples: [madeInAbyss.slug], + example: madeInAbyss.slug, }), }), query: t.Object({ diff --git a/api/src/models/entry/episode.ts b/api/src/models/entry/episode.ts index 3b46fd4e..7ce353c6 100644 --- a/api/src/models/entry/episode.ts +++ b/api/src/models/entry/episode.ts @@ -1,10 +1,10 @@ import { t } from "elysia"; import type { Prettify } from "~/utils"; +import { bubbleImages, madeInAbyss, registerExamples } from "../examples"; import { EpisodeId, Resource, SeedImage, TranslationRecord } from "../utils"; import { BaseEntry, EntryTranslation } from "./base-entry"; export const BaseEpisode = t.Intersect([ - BaseEntry, t.Object({ kind: t.Literal("episode"), order: t.Number({ minimum: 1, description: "Absolute playback order." }), @@ -12,9 +12,10 @@ export const BaseEpisode = t.Intersect([ episodeNumber: t.Number(), externalId: EpisodeId, }), + BaseEntry, ]); -export const Episode = t.Intersect([Resource(), BaseEpisode, EntryTranslation]); +export const Episode = t.Intersect([Resource(), EntryTranslation, BaseEpisode]); export type Episode = Prettify; export const SeedEpisode = t.Intersect([ @@ -26,3 +27,11 @@ export const SeedEpisode = t.Intersect([ }), ]); export type SeedEpisode = Prettify; + +const ep = madeInAbyss.entries.find((x) => x.kind === "episode")!; +registerExamples(Episode, { + ...ep, + ...ep.translations.en, + ...bubbleImages, + slug: `${madeInAbyss.slug}-s${ep.seasonNumber}-e${ep.episodeNumber}`, +}); diff --git a/api/src/models/entry/extra.ts b/api/src/models/entry/extra.ts index 94ab4cc7..462955c0 100644 --- a/api/src/models/entry/extra.ts +++ b/api/src/models/entry/extra.ts @@ -1,5 +1,6 @@ import { t } from "elysia"; import { type Prettify, comment } from "~/utils"; +import { madeInAbyss, registerExamples } from "../examples"; import { SeedImage } from "../utils"; import { Resource } from "../utils/resource"; import { BaseEntry } from "./base-entry"; @@ -16,11 +17,11 @@ export type ExtraType = typeof ExtraType.static; export const BaseExtra = t.Intersect( [ - t.Omit(BaseEntry, ["nextRefresh", "airDate"]), t.Object({ kind: ExtraType, name: t.String(), }), + t.Omit(BaseEntry, ["nextRefresh", "airDate"]), ], { description: comment` @@ -42,3 +43,5 @@ export const SeedExtra = t.Intersect([ }), ]); export type SeedExtra = Prettify; + +registerExamples(Extra, madeInAbyss.extras[0]); diff --git a/api/src/models/entry/movie-entry.ts b/api/src/models/entry/movie-entry.ts index 67b50b7b..75757f42 100644 --- a/api/src/models/entry/movie-entry.ts +++ b/api/src/models/entry/movie-entry.ts @@ -1,5 +1,6 @@ import { t } from "elysia"; import { type Prettify, comment } from "~/utils"; +import { bubbleImages, madeInAbyss, registerExamples } from "../examples"; import { ExternalId, Image, @@ -11,7 +12,6 @@ import { BaseEntry, EntryTranslation } from "./base-entry"; export const BaseMovieEntry = t.Intersect( [ - BaseEntry, t.Object({ kind: t.Literal("movie"), order: t.Number({ @@ -20,6 +20,7 @@ export const BaseMovieEntry = t.Intersect( }), externalId: ExternalId, }), + BaseEntry, ], { description: comment` @@ -39,8 +40,8 @@ export const MovieEntryTranslation = t.Intersect([ export const MovieEntry = t.Intersect([ Resource(), - BaseMovieEntry, MovieEntryTranslation, + BaseMovieEntry, ]); export type MovieEntry = Prettify; @@ -59,3 +60,10 @@ export const SeedMovieEntry = t.Intersect([ }), ]); export type SeedMovieEntry = Prettify; + +const ep = madeInAbyss.entries.find((x) => x.kind === "movie")!; +registerExamples(MovieEntry, { + ...ep, + ...ep.translations.en, + ...bubbleImages, +}); diff --git a/api/src/models/entry/special.ts b/api/src/models/entry/special.ts index ea53f8c9..f9f459f1 100644 --- a/api/src/models/entry/special.ts +++ b/api/src/models/entry/special.ts @@ -2,10 +2,10 @@ import { t } from "elysia"; import { type Prettify, comment } from "~/utils"; import { EpisodeId, Resource, SeedImage, TranslationRecord } from "../utils"; import { BaseEntry, EntryTranslation } from "./base-entry"; +import { bubbleImages, madeInAbyss, registerExamples } from "../examples"; export const BaseSpecial = t.Intersect( [ - BaseEntry, t.Object({ kind: t.Literal("special"), order: t.Number({ @@ -15,6 +15,7 @@ export const BaseSpecial = t.Intersect( number: t.Number({ minimum: 1 }), externalId: EpisodeId, }), + BaseEntry, ], { description: comment` @@ -24,7 +25,7 @@ export const BaseSpecial = t.Intersect( }, ); -export const Special = t.Intersect([Resource(), BaseSpecial, EntryTranslation]); +export const Special = t.Intersect([Resource(), EntryTranslation, BaseSpecial]); export type Special = Prettify; export const SeedSpecial = t.Intersect([ @@ -36,3 +37,11 @@ export const SeedSpecial = t.Intersect([ }), ]); export type SeedSpecial = Prettify; + +const ep = madeInAbyss.entries.find((x) => x.kind === "special")!; +registerExamples(Special, { + ...ep, + ...ep.translations.en, + ...bubbleImages, + slug: `${madeInAbyss.slug}-sp3` +}); diff --git a/api/src/models/examples/made-in-abyss.ts b/api/src/models/examples/made-in-abyss.ts index 37e679d9..58be76c4 100644 --- a/api/src/models/examples/made-in-abyss.ts +++ b/api/src/models/examples/made-in-abyss.ts @@ -84,7 +84,6 @@ export const madeInAbyss = { }, seasons: [ { - slug: "made-in-abyss-s1", seasonNumber: 1, translations: { en: { @@ -108,7 +107,6 @@ export const madeInAbyss = { }, }, { - slug: "made-in-abyss-s2", seasonNumber: 2, translations: { en: { diff --git a/api/src/models/season.ts b/api/src/models/season.ts index d5c032eb..bcdaec04 100644 --- a/api/src/models/season.ts +++ b/api/src/models/season.ts @@ -1,4 +1,5 @@ import { t } from "elysia"; +import type { Prettify } from "~/utils"; import { bubbleImages, madeInAbyss, registerExamples } from "./examples"; import { SeasonId } from "./utils/external-id"; import { Image, SeedImage } from "./utils/image"; @@ -26,13 +27,12 @@ export const SeasonTranslation = t.Object({ }); export type SeasonTranslation = typeof SeasonTranslation.static; -export const Season = t.Intersect([Resource(), BaseSeason, SeasonTranslation]); +export const Season = t.Intersect([Resource(), SeasonTranslation, BaseSeason]); export type Season = typeof Season.static; export const SeedSeason = t.Intersect([ t.Omit(BaseSeason, ["createdAt", "nextRefresh"]), t.Object({ - slug: t.String({ format: "slug", examples: ["made-in-abyss-s1"] }), translations: TranslationRecord( t.Intersect([ t.Omit(SeasonTranslation, ["poster", "thumbnail", "banner"]), @@ -45,10 +45,11 @@ export const SeedSeason = t.Intersect([ ), }), ]); -export type SeedSeason = typeof SeedSeason.static; +export type SeedSeason = Prettify; registerExamples(Season, { ...madeInAbyss.seasons[0], ...madeInAbyss.seasons[0].translations.en, ...bubbleImages, + slug: `${madeInAbyss.slug}-s1`, }); diff --git a/api/src/models/utils/language.ts b/api/src/models/utils/language.ts index 88085e57..76f141e3 100644 --- a/api/src/models/utils/language.ts +++ b/api/src/models/utils/language.ts @@ -22,6 +22,7 @@ export const Language = (props?: NonNullable[0]>) => BCP 47 is also known as RFC 5646. It subsumes ISO 639 and is backward compatible with it. `, error: "Expected a valid (and NORMALIZED) bcp-47 language code.", + examples: ["en-US"], ...props, }), ) @@ -39,9 +40,15 @@ export const TranslationRecord = ( props?: Parameters>[2], ) => t - .Transform(t.Record(t.String(), values, { minPropreties: 1, ...props })) - // @ts-expect-error idk why the translations type can't get resolved so it's a pain to work - // with without casting it + .Transform( + t.Record( + t.String({ + examples: ["en-US"], + }), + values, + { minPropreties: 1, ...props }, + ), + ) .Decode((translations: Record>) => { for (const lang of Object.keys(translations)) { try { @@ -91,10 +98,11 @@ export const AcceptLanguage = ({ comment` List of languages you want the data in. This follows the [Accept-Language offical specification](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language). - ` + autoFallback + ` + + (autoFallback ? comment` In this request, * is always implied (if no language could satisfy the request, kyoo will use any language available.) ` - : "", + : ""), });