2023-01-22 19:26:08 +01:00
|
|
|
import { MWMediaMeta, MWMediaType, MWSeasonMeta } from "./types";
|
2023-01-14 00:12:56 +01:00
|
|
|
|
|
|
|
export const JW_API_BASE = "https://apis.justwatch.com";
|
2023-01-15 16:01:07 +01:00
|
|
|
export const JW_IMAGE_BASE = "https://images.justwatch.com";
|
2023-01-14 00:12:56 +01:00
|
|
|
|
|
|
|
export type JWContentTypes = "movie" | "show";
|
|
|
|
|
2023-01-22 19:26:08 +01:00
|
|
|
export type JWSeasonShort = {
|
|
|
|
title: string;
|
|
|
|
id: number;
|
|
|
|
season_number: number;
|
|
|
|
};
|
|
|
|
|
|
|
|
export type JWEpisodeShort = {
|
|
|
|
title: string;
|
|
|
|
id: number;
|
|
|
|
episode_number: number;
|
|
|
|
};
|
|
|
|
|
2023-01-14 00:12:56 +01:00
|
|
|
export type JWMediaResult = {
|
|
|
|
title: string;
|
|
|
|
poster?: string;
|
|
|
|
id: number;
|
2023-03-22 22:31:23 +01:00
|
|
|
original_release_year?: number;
|
2023-01-14 00:12:56 +01:00
|
|
|
jw_entity_id: string;
|
|
|
|
object_type: JWContentTypes;
|
2023-01-22 19:26:08 +01:00
|
|
|
seasons?: JWSeasonShort[];
|
|
|
|
};
|
|
|
|
|
|
|
|
export type JWSeasonMetaResult = {
|
|
|
|
title: string;
|
|
|
|
id: string;
|
|
|
|
season_number: number;
|
|
|
|
episodes: JWEpisodeShort[];
|
2023-01-14 00:12:56 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
export function mediaTypeToJW(type: MWMediaType): JWContentTypes {
|
|
|
|
if (type === MWMediaType.MOVIE) return "movie";
|
|
|
|
if (type === MWMediaType.SERIES) return "show";
|
|
|
|
throw new Error("unsupported type");
|
|
|
|
}
|
|
|
|
|
|
|
|
export function JWMediaToMediaType(type: string): MWMediaType {
|
|
|
|
if (type === "movie") return MWMediaType.MOVIE;
|
|
|
|
if (type === "show") return MWMediaType.SERIES;
|
|
|
|
throw new Error("unsupported type");
|
|
|
|
}
|
|
|
|
|
2023-01-22 19:26:08 +01:00
|
|
|
export function formatJWMeta(
|
|
|
|
media: JWMediaResult,
|
|
|
|
season?: JWSeasonMetaResult
|
|
|
|
): MWMediaMeta {
|
2023-01-14 00:12:56 +01:00
|
|
|
const type = JWMediaToMediaType(media.object_type);
|
2023-01-22 19:26:08 +01:00
|
|
|
let seasons: undefined | MWSeasonMeta[];
|
|
|
|
if (type === MWMediaType.SERIES) {
|
|
|
|
seasons = media.seasons
|
|
|
|
?.sort((a, b) => a.season_number - b.season_number)
|
|
|
|
.map(
|
|
|
|
(v): MWSeasonMeta => ({
|
|
|
|
id: v.id.toString(),
|
|
|
|
number: v.season_number,
|
|
|
|
title: v.title,
|
|
|
|
})
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2023-01-14 00:12:56 +01:00
|
|
|
return {
|
|
|
|
title: media.title,
|
|
|
|
id: media.id.toString(),
|
2023-03-22 22:31:23 +01:00
|
|
|
year: media.original_release_year?.toString(),
|
2023-01-14 00:12:56 +01:00
|
|
|
poster: media.poster
|
2023-01-15 16:01:07 +01:00
|
|
|
? `${JW_IMAGE_BASE}${media.poster.replace("{profile}", "s166")}`
|
2023-01-14 00:12:56 +01:00
|
|
|
: undefined,
|
|
|
|
type,
|
2023-01-22 19:26:08 +01:00
|
|
|
seasons: seasons as any,
|
|
|
|
seasonData: season
|
|
|
|
? ({
|
|
|
|
id: season.id.toString(),
|
|
|
|
number: season.season_number,
|
|
|
|
title: season.title,
|
|
|
|
episodes: season.episodes
|
|
|
|
.sort((a, b) => a.episode_number - b.episode_number)
|
|
|
|
.map((v) => ({
|
|
|
|
id: v.id.toString(),
|
|
|
|
number: v.episode_number,
|
|
|
|
title: v.title,
|
|
|
|
})),
|
|
|
|
} as any)
|
|
|
|
: (undefined as any),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
export function JWMediaToId(media: MWMediaMeta): string {
|
|
|
|
return ["JW", mediaTypeToJW(media.type), media.id].join("-");
|
|
|
|
}
|
|
|
|
|
|
|
|
export function decodeJWId(
|
|
|
|
paramId: string
|
|
|
|
): { id: string; type: MWMediaType } | null {
|
|
|
|
const [prefix, type, id] = paramId.split("-", 3);
|
|
|
|
if (prefix !== "JW") return null;
|
|
|
|
let mediaType;
|
|
|
|
try {
|
|
|
|
mediaType = JWMediaToMediaType(type);
|
|
|
|
} catch {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
type: mediaType,
|
|
|
|
id,
|
2023-01-14 00:12:56 +01:00
|
|
|
};
|
|
|
|
}
|