From 9eedd7a5638c147304767eb45af51c11fd57f79e Mon Sep 17 00:00:00 2001 From: Mohtasim Alam Sohom <94981761+codeblitz97@users.noreply.github.com> Date: Tue, 16 Jul 2024 18:52:10 +0600 Subject: [PATCH] Fix episode not loading --- bun.lockb | Bin 467707 -> 468050 bytes package.json | 1 + src/app/api/episodes/[id]/route.ts | 635 ++++++++++++----------- src/app/info/[id]/page.tsx | 2 +- src/components/shared/EpisodeList.tsx | 7 +- src/lib/anime.ts | 22 +- src/types/episodes.ts | 702 ++++++++++++++++++++++++++ 7 files changed, 1024 insertions(+), 345 deletions(-) create mode 100644 src/types/episodes.ts diff --git a/bun.lockb b/bun.lockb index b2e8791307f598edfed195abcebafef0ab42b931..200491c33db01020e7edd660f7a032ebd459f731 100644 GIT binary patch delta 78740 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 wlh1=u@$X{6t)+itaNb^rhX delta 78154 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 z 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 e8OF*4RE=K_ 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 JFs;+^e*nNg3^f1% diff --git a/package.json b/package.json index 642d1e3..f615464 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "file-saver": "^2.0.5", "framer-motion": "^11.2.6", "ioredis": "^5.4.1", + "ky": "^1.4.0", "lodash": "^4.17.21", "lucide-react": "^0.407.0", "marked": "^13.0.0", diff --git a/src/app/api/episodes/[id]/route.ts b/src/app/api/episodes/[id]/route.ts index 9ceeb51..83201ce 100644 --- a/src/app/api/episodes/[id]/route.ts +++ b/src/app/api/episodes/[id]/route.ts @@ -1,388 +1,371 @@ -import axios from 'axios'; -import { cache } from '@/lib/cache'; +import ky from 'ky'; +import _ from 'lodash'; import { NextRequest, NextResponse } from 'next/server'; -import { mergeEpisodeMetadata } from '@/lib/episode'; -import { ConsumetAnimeEpisode } from '@/types/consumet'; -import { AnifyEpisodesResponse } from '@/types/anify'; -import { MalSyncAnime, MalSyncSiteDetails } from '@/types/malSync'; -import { GogoAnimeAnime } from '@/types/gogo'; -import { HiAnimeSeries } from '@/types/hianime'; -import { AniZipData } from '@/types/anizip'; - -axios.interceptors.request.use((config) => { - config.timeout = 9000; - return config; + +import { Anime } from '@/types/episodes'; + +export const dynamic = 'force-dynamic'; +export const revalidate = 3600; + +const bky = ky.extend({ + timeout: 11000, }); -const fetchCData = async (id: string, dub: boolean) => { - const res = await axios.get( - `${process.env.CONSUMET_API}/meta/anilist/episodes/${id}${ - dub ? '?dub=true' : '' - }` - ); - const data = res.data as ConsumetAnimeEpisode[] | { message: string }; +export interface HiAnimeEpisode { + title: string; + episodeId: string; + number: number; + isFiller: boolean; +} - if ( - (data as { message: string })?.message === 'Anime not found' && - (data as ConsumetAnimeEpisode[])?.length < 1 - ) { - return []; - } - return data as ConsumetAnimeEpisode[]; -}; +export interface HiAnimeEpisodesData { + totalEpisodes: number; + episodes: HiAnimeEpisode[]; +} + +interface EpisodeTitle { + ja: string; + en: string; + 'x-jat': string; +} + +interface Episode { + tvdbShowId: number; + tvdbId: number; + seasonNumber: number; + episodeNumber: number; + absoluteEpisodeNumber: number; + title: EpisodeTitle; + airDate: string; + airDateUtc: string; + runtime: number; + overview: string; + image: string; + episode: string; + anidbEid: number; + length: number; + airdate: string; + rating: string; + summary: string; + finaleType?: string; +} + +interface Episodes { + [key: string]: Episode; +} + +interface GogoAnimeInfo { + id: string; + title: string; + url: string; + genres: string[]; + totalEpisodes: number; + image: string; + releaseDate: string; + description: string; + subOrDub: string; + type: string; + status: string; + otherName: string; + episodes: GogoEpisode[]; +} + +interface GogoEpisode { + id: string; + number: number; + url: string; +} + +interface ConsumetEpisode { + id: string; + title: string | null; + image: string | null; + imageHash: string; + number: number; + createdAt: string | null; + description: null; + url: string; +} + +interface ProviderEpisodes { + sub: Omit[]; + dub: Omit[]; +} + +export interface ProviderData { + providerId: string; + episodes: ProviderEpisodes; +} + +const getConsumet = async (id: string): Promise => { + const fetchGogoData = async (i: string, dub = false) => { + try { + const res = await bky.get( + `${process.env.CONSUMET_API}/meta/anilist/episodes/${i}${ + dub ? '?dub=true' : '' + }` + ); + const data = await res.json(); + + if (data.length < 1) return []; + + return data.map((d) => + _.omit(d, ['image', 'imageHash', 'description', 'createdAt']) + ); + } catch (error) { + return []; + } + }; -async function fetchConsumet(id: string) { try { - const [subData, dubData] = await Promise.all([ - fetchCData(id, false), - fetchCData(id, true), + const [dub, sub] = await Promise.all([ + fetchGogoData(id, true), + fetchGogoData(id), ]); - const array = [ + return [ { - consumet: true, providerId: 'gogoanime', episodes: { - ...(subData && subData.length > 0 && { sub: subData }), - ...(dubData && dubData.length > 0 && { dub: dubData }), + sub: (sub ?? []) as _.Omit[], + dub: (dub ?? []) as _.Omit[], }, }, ]; - - return array; } catch (error) { - console.error('Error fetching consumet:', error); - return []; + return [ + { + providerId: 'gogoanime', + episodes: { + sub: [], + dub: [], + }, + }, + { + providerId: 'hianime', + episodes: { + sub: [], + dub: [], + }, + }, + ]; } -} +}; -async function fetchAnify(id: string) { +const getMadaraMappings = async (id: string) => { try { - const res = await axios.get( - `https://api.anify.tv/info/${id}?fields=[episodes]` + const res = await bky.get( + process.env.MADARA_MAPPINGS_API_KEY + ? `https://api-mappings.madara.live/anime/${id}?api_key=${process.env.MADARA_MAPPINGS_API_KEY}` + : `https://api-mappings.madara.live/anime/${id}` ); - const data = res.data as AnifyEpisodesResponse; + const data = await res.json(); - if (!data || !data?.episodes?.data) { - return []; - } - const epData = data?.episodes?.data; + const malSync = data.mappings.malSync; - const filteredData = epData?.filter( - (episodes) => episodes.providerId !== '9anime' - ); - const mappedData = filteredData?.map((i) => { - if (i?.providerId === 'gogoanime') { - return { - episodes: i.episodes, - providerId: 'gogobackup', - }; - } - return i; - }); - return mappedData; - } catch (error) { - console.error('Error fetching anify:', error); - return []; - } -} + let subUrl = ''; + let dubUrl = ''; + let hianimeUrl = ''; -async function malSync(id: string) { - try { - const response = await axios.get(`${process.env.MALSYNC_URI}${id}`); - - const data = response?.data as MalSyncAnime; - const sites = Object.keys(data.Sites).map((providerId) => ({ - providerId: providerId.toLowerCase(), - data: Object.values(data.Sites[providerId]), - })) as { - providerId: string; - data: MalSyncSiteDetails[]; - }[]; - const newData = sites.filter( - (site) => site.providerId === 'gogoanime' || site.providerId === 'zoro' - ); - const finalData: any = []; - console.log(newData); - newData.forEach((item) => { - const { providerId, data } = item; - if (providerId === 'gogoanime') { - const remove1 = 'https://anitaku.so/category/'; - const remove2 = 'https://anitaku.to/category/'; - - const dub = data.find((item: any) => - item.title.toLowerCase().endsWith(' (dub)') - ); - const dubUrl = dub?.url?.replace( - dub.url.includes('https://anitaku.to/') ? remove2 : remove1, + if (malSync.Sites?.Gogoanime) { + for (const key in malSync.Sites.Gogoanime) { + const siteDetail = + malSync.Sites.Gogoanime[key as keyof typeof malSync.Sites.Gogoanime]; + const cleanedUrl = siteDetail.url.replace( + /https?:\/\/[^/]+\/category\//, '' ); - const subItem = data.find((item: any) => - item.title.toLowerCase().includes(' (uncensored)') - ); - const subUrl = subItem - ? subItem.url.replace( - subItem.url.includes('https://anitaku.to/') ? remove2 : remove1, - '' - ) - : null; - - const nonDubNonUncensoredItem = data.find( - (item: any) => - !item.title.toLowerCase().includes(')') && item.url !== dub?.url - ); - const nonDubNonUncensoredUrl = nonDubNonUncensoredItem - ? nonDubNonUncensoredItem.url.replace( - nonDubNonUncensoredItem.url.includes('https://anitaku.to/') - ? remove2 - : remove1, - '' - ) - : null; - - const sub = - subUrl ?? - data - .find((item: any) => item.url === dub?.url?.replace(/-dub$/, '')) - ?.url.replace( - dub?.url?.includes('https://anitaku.to/') ? remove2 : remove1, - '' - ) ?? - nonDubNonUncensoredUrl; - - finalData.push({ providerId, sub: sub || '', dub: dubUrl || '' }); - } else { - const remove = 'https://hianime.to/'; - const sub = data[0]?.url?.replace(remove, ''); - finalData.push({ providerId, sub: sub || '' }); + if (!siteDetail.title.includes('Dub') && !key.includes('dub')) { + subUrl = cleanedUrl; + } + + if (siteDetail.title.includes('(Dub)') || key.includes('dub')) { + dubUrl = cleanedUrl; + } } - }); - return finalData as { providerId?: string; sub?: string; dub?: string }[]; - } catch (error) { - console.error('Error fetching data from Malsync:', error); - return null; - } -} + } -const fetchDData = async (id: string) => { - const res = await axios.get( - `${process.env.CONSUMET_API}/anime/gogoanime/info/${id}` - ); - const data = res.data as GogoAnimeAnime | { message: string }; + if (malSync.Sites?.Zoro) { + for (const key in malSync.Sites?.Zoro) { + const siteDetail = + malSync.Sites.Zoro[key as keyof typeof malSync.Sites.Zoro]; - if ( - (data as { message: string })?.message === 'Anime not found' && - (data as GogoAnimeAnime)?.episodes?.length < 1 - ) { - return []; - } - return (data as GogoAnimeAnime)?.episodes; -}; + const cleanedUrl = siteDetail.url.replace(/https?:\/\/[^/]+\//, ''); -async function fetchGogoanime(sub: string, dub: string) { - try { - const [subData, dubData] = await Promise.all([ - sub !== '' ? fetchDData(sub) : Promise.resolve([]), - dub !== '' ? fetchDData(dub) : Promise.resolve([]), - ]); + hianimeUrl = cleanedUrl; + } + } - const array = [ - { - consumet: true, - providerId: 'gogoanime', - episodes: { - ...(subData && subData.length > 0 && { sub: subData }), - ...(dubData && dubData.length > 0 && { dub: dubData }), - }, - }, - ]; + const malsync = { sub: subUrl, dub: dubUrl, hianime: hianimeUrl }; + + const aniZip = data.mappings.anizip; + let anizip = {}; + + if (!aniZip || !aniZip.episodes) anizip = {}; + anizip = aniZip.episodes; - return array; + return { + malsync, + anizip, + }; } catch (error) { - console.error('Error fetching consumet gogoanime:', error); - return []; + return { + malsync: { + sub: '', + dub: '', + hianime: '', + }, + anizip: {}, + }; } -} +}; -async function fetchHIAnime(id: string) { +const getGogoAnime = async (id: string) => { try { - const res = await axios.get( - `${process.env.HIANIME_API}/anime/episodes/${id}` + const res = await bky.get( + `${process.env.CONSUMET_API}/anime/gogoanime/info/${id}` ); + const data = await res.json(); - const data = res.data as HiAnimeSeries; - if (!data?.episodes) return []; - - const array = [ - { - providerId: 'zoro', - episodes: data?.episodes, - }, - ]; + if (!data || !data.episodes) return []; - return array; + return data.episodes; } catch (error) { - console.error('Error fetching hianime:', error); return []; } -} +}; -async function fetchEpisodeMeta(id: string, available = false) { +const getHiAnime = async (id: string) => { try { - if (available) { - return null; - } - const data = await axios.get( - `https://api.ani.zip/mappings?anilist_id=${id}` + const res = await bky.get( + `${process.env.HIANIME_API}/anime/episodes/${id}` ); - const episodesArray = Object.values((data?.data as AniZipData)?.episodes); - if (!episodesArray) { - return []; - } - return episodesArray; - } catch (error) { - console.error('Error fetching and processing meta:', error); + const data = await res.json(); + + return data.episodes; + } catch { return []; } -} +}; -/** - * Asynchronously fetches and caches data based on the provided parameters. - * - * @param {string} id - The ID used to fetch the data. - * @param {any} meta - The metadata associated with the data. - * @param {any} cacheTime - The time to cache the data. - * @param {any} refresh - Flag indicating whether to refresh the cache. - * @return {Promise} The combined and processed data after caching and merging. - */ -const fetchAndCacheData = async ( - id: string, - meta: any, - cacheTime: any, - refresh: any -): Promise => { - let malsync; - if (id) { - malsync = await malSync(id); +const combineMetadataAndEpisodes = ( + consumetResponse: ProviderData[], + metadataResponse: Episodes, + combinedSubAndDub: ProviderData[] +): ProviderData[] => { + if (consumetResponse.length < 1) { + return []; } - const promises = []; - if (malsync) { - const gogoAnimeProvider = malsync.find((i) => i.providerId === 'gogoanime'); - const hiAnimeProvider = malsync.find((i) => i.providerId === 'zoro'); - - if (gogoAnimeProvider) { - promises.push( - fetchGogoanime(gogoAnimeProvider.sub!, gogoAnimeProvider.dub!) - ); - } else { - promises.push(Promise.resolve([])); - } + const gogoAnimeIndex = consumetResponse.findIndex( + (provider) => provider.providerId === 'gogoanime' + ); - if (hiAnimeProvider) { - promises.push(fetchHIAnime(hiAnimeProvider.sub!)); - } else { - promises.push(Promise.resolve([])); - } - promises.push(fetchEpisodeMeta(id, !refresh)); - } else { - promises.push(fetchConsumet(id)); - promises.push(fetchAnify(id)); - promises.push(fetchEpisodeMeta(id, !refresh)); + if (gogoAnimeIndex !== -1) { + consumetResponse[gogoAnimeIndex] = combinedSubAndDub[0]; } - const [consumet, anify, cover] = await Promise.all(promises); - - // Check if cache is available - if (cache) { - if (consumet?.length! > 0 || anify?.length! > 0) { - await cache.set( - `episode:data:${id}`, - JSON.stringify(consumet && anify ? [...consumet, ...anify] : []), - cacheTime - ); - } - const combinedData = [...(consumet ?? []), ...(anify ?? [])]; - let data = combinedData; - if (refresh) { - if (cover && cover?.length > 0) { - try { - await cache.set(`meta:data:${id}`, JSON.stringify(cover), cacheTime); - data = await mergeEpisodeMetadata(combinedData, cover); - } catch (error) { - console.error('Error serializing cover:', error); + _.forEach(consumetResponse, (provider) => { + _.forEach(['sub', 'dub'], (type) => { + // @ts-ignore + provider.episodes[type as 'sub' | 'dub'] = _.map( + provider.episodes[type as 'sub' | 'dub'], + (episode: _.Omit) => { + const metadataEpisode = metadataResponse[episode.number]; + + if (metadataEpisode) { + const title = + metadataEpisode.title.en || + metadataEpisode.title['x-jat'] || + metadataEpisode.title.ja; + + return { + ...episode, + id: + episode.id || (episode as unknown as HiAnimeEpisode).episodeId, + title: title, + image: metadataEpisode.image, + description: metadataEpisode.overview ?? null, + rating: Number(metadataEpisode.rating), + season: metadataEpisode.seasonNumber, + createdAt: metadataEpisode.airDateUtc, + }; + } else { + return { + ...episode, + title: null, + image: null, + description: null, + rating: null, + }; + } } - } else if (meta) { - data = await mergeEpisodeMetadata(combinedData, JSON.parse(meta)); - } - } else if (meta) { - data = await mergeEpisodeMetadata(combinedData, JSON.parse(meta)); - } + ) as { + title: string; + image: string | null; + description: string | null; + rating: string; + createdAt: string; + number: number; + id: string; + url: string; + }[]; + }); + }); - return data; - } else { - console.error('cache URL not provided. Caching not possible.'); - return [...(consumet ?? []), ...(anify ?? [])]; - } + return consumetResponse; +}; + +const getEpisodes = async (id: string) => { + const [consumet, madara] = await Promise.all([ + getConsumet(id), + getMadaraMappings(id), + ]); + + const malsync = madara.malsync; + const meta = madara.anizip; + + const [sub, dub, hianime] = await Promise.all([ + malsync.sub !== '' ? getGogoAnime(malsync.sub) : Promise.resolve([]), + malsync.dub !== '' ? getGogoAnime(malsync.dub) : Promise.resolve([]), + malsync.hianime !== '' ? getHiAnime(malsync.hianime) : Promise.resolve([]), + ]); + + const combinedSubAndDub: ProviderData[] = [ + { + providerId: 'gogoanime', + episodes: { + sub: [...sub] as _.Omit[], + dub: [...dub] as _.Omit[], + }, + }, + ]; + + const combinedHiAnime: ProviderData = { + providerId: 'hianime', + episodes: { + sub: [...hianime] as unknown as _.Omit[], + dub: + dub.length > 0 + ? ([...hianime] as unknown as _.Omit[]) + : ([] as _.Omit[]), + }, + }; + + return combineMetadataAndEpisodes( + [...consumet, combinedHiAnime], + meta, + combinedSubAndDub + ); }; export const GET = async ( - req: NextRequest, + request: NextRequest, { params }: { params: { id: string } } ) => { - const url = new URL(req.url); - const id = params.id; - const releasing = url.searchParams.get('releasing') || false; - const refresh = url.searchParams.get('refresh') === 'true' || false; - - let cacheTime = null; - if (releasing === 'true') { - cacheTime = 60 * 60 * 3; - } else if (releasing === 'false') { - cacheTime = 60 * 60 * 3; - } - - let meta: any = null; - let cached: string | null = null; + const res = await getEpisodes(params.id); - if (cache) { - try { - meta = await cache.get(`meta:data:${id}`); - if (JSON.parse(meta)?.length === 0) { - await cache.del(`meta:data:${id}`); - meta = null; - } - cached = await cache.get(`episode:data:${id}`); - if (JSON.parse(cached!)?.length === 0) { - await cache.del(`episode:data:${id}`); - cached = null; - } - let data: any[] | any = null; - if (refresh) { - data = await fetchAndCacheData(id, meta, cacheTime, refresh); - } - if (data?.length > 0) { - return NextResponse.json(data); - } - } catch (error) { - console.error('Error checking cache cache:', error); - } - } - - if (cached) { - try { - let cachedData = JSON.parse(cached); - if (meta) { - cachedData = await mergeEpisodeMetadata(cachedData, JSON.parse(meta)); - } - return NextResponse.json(cachedData); - } catch (error) { - console.error('Error parsing cached data:', error); - } - } else { - const fetchedData = await fetchAndCacheData(id, meta, cacheTime, !refresh); - return NextResponse.json(fetchedData); - } + return NextResponse.json(res); }; diff --git a/src/app/info/[id]/page.tsx b/src/app/info/[id]/page.tsx index 80d73ee..a99cf51 100644 --- a/src/app/info/[id]/page.tsx +++ b/src/app/info/[id]/page.tsx @@ -78,7 +78,7 @@ export default function Information({ const [info, episodes, characters] = use( Promise.all([infoPromise, episodesPromise, charactersPromise]) ); - console.log(characters); + console.log(episodes); return ( <> diff --git a/src/components/shared/EpisodeList.tsx b/src/components/shared/EpisodeList.tsx index 7bd7da7..cf8b0f3 100644 --- a/src/components/shared/EpisodeList.tsx +++ b/src/components/shared/EpisodeList.tsx @@ -23,9 +23,10 @@ import { TooltipTrigger, } from '../ui/tooltip'; import { Button, Image } from '@nextui-org/react'; +import { ProviderData } from '@/app/api/episodes/[id]/route'; interface Props { - animeData: Provider[]; + animeData: ProviderData[]; id: string; info: AnilistInfo; } @@ -33,7 +34,7 @@ interface Props { const AnimeViewer: React.FC = ({ animeData, info, id }) => { const [selectedProvider, setSelectedProvider] = useState< Provider | undefined - >(animeData.find((p) => p.providerId === 'zoro') || animeData[0]); + >(animeData.find((p) => p.providerId === 'hianime') || animeData[0]); const [language, setLanguage] = useState<'sub' | 'dub'>('sub'); const [episodePage, setEpisodePage] = useState(0); const [searchQuery, setSearchQuery] = useState(''); @@ -63,7 +64,7 @@ const AnimeViewer: React.FC = ({ animeData, info, id }) => { }, [selectedProvider, language]); const filteredEpisodes = useMemo(() => { - return (episodes as Episode[]).filter( + return (episodes as Episode[])?.[language].filter( (episode) => (episode.title ?? `Episode ${episode.number}`) .toLowerCase() diff --git a/src/lib/anime.ts b/src/lib/anime.ts index a6762fd..f38cb29 100644 --- a/src/lib/anime.ts +++ b/src/lib/anime.ts @@ -26,7 +26,7 @@ const FetchDataAndCache = async ( method: method ? method : 'GET', headers: headers ? new Headers(headers) : undefined, body: body ? body : undefined, - cache: 'no-store' + cache: 'no-store', }; data = await (await fetch(url, options)).json(); @@ -1122,20 +1122,12 @@ export async function getEpisodes( `episode-${id}` ); - if (response && typeof response === 'object' && !Array.isArray(response)) { - return Object.keys(response) - .filter((key) => key !== 'isCached') - .map((key) => { - const provider = response[key]; - return { - consumet: provider.consumet, - providerId: provider.providerId, - episodes: provider.episodes, - } as Provider; - }); - } else { - throw new Error('Invalid response format'); - } + // Check if the response is an object with numeric keys and convert it to an array + const episodesArray = Object.keys(response) + .filter((key) => !isNaN(Number(key))) // Filter out non-numeric keys + .map((key) => response[key]); // Map numeric keys to array elements + + return episodesArray; } catch (error) { throw error; } diff --git a/src/types/episodes.ts b/src/types/episodes.ts new file mode 100644 index 0000000..c01ab1b --- /dev/null +++ b/src/types/episodes.ts @@ -0,0 +1,702 @@ +export interface AnifyTitle { + native: string; + romaji: string; + english: string; +} + +export interface AnifyMapping { + id: string; + providerId: string; + similarity: number; + providerType: string; +} + +export interface AnifyRating { + tmdb?: number; + kitsu?: number; + anilist?: number; +} + +export interface AnifyPopularity { + tmdb?: number; + anilist?: number; +} + +export interface AnifyRelationTitle { + native: string; + romaji: string; + english: string; +} + +export interface AnifyRelation { + id: string; + type: string; + title: AnifyRelationTitle; + format: string; + relationType: string; +} + +export interface AnifyEpisode { + id: string; + img: string | null; + title: string; + hasDub: boolean; + number: number; + rating: number | null; + isFiller: boolean; + updatedAt: number; + description: string | null; +} + +export interface AnifyEpisodesProvider { + episodes: AnifyEpisode[]; + providerId: string; +} + +export interface AnifyEpisodesData { + data: AnifyEpisodesProvider[]; + latest: { + updatedAt: number; + latestTitle: string; + latestEpisode: number; + }; +} + +export interface AnifyArtwork { + img: string; + type: string; + providerId: string; +} + +export interface AnifyVoiceActor { + name: string; + image: string; +} + +export interface AnifyCharacter { + name: string; + image: string; + voiceActor: AnifyVoiceActor; +} + +export interface AnifyAnime { + id: string; + slug: string; + coverImage: string; + bannerImage: string; + trailer: string; + status: string; + season: string; + title: AnifyTitle; + currentEpisode: number; + mappings: AnifyMapping[]; + synonyms: string[]; + countryOfOrigin: string; + description: string; + duration: number; + color: string; + year: number; + rating: AnifyRating; + popularity: AnifyPopularity; + type: string; + format: string; + relations: AnifyRelation[]; + totalEpisodes: number; + genres: string[]; + tags: string[]; + episodes: AnifyEpisodesData; + averageRating: number; + averagePopularity: number; + artwork: AnifyArtwork[]; + characters: AnifyCharacter[]; +} + +interface MediaCoverImage { + extraLarge: string; + large: string; + medium: string; + color: string; + _id: string; +} + +interface MediaEndDate { + year: number | null; + month: number | null; + day: number | null; + _id: string; +} + +interface MediaMappings { + anilistId: string; + fribb: { + livechart_id: number; + thetvdb_id: number; + anime_planet_id: string; + imdb_id: string; + anisearch_id: number; + themoviedb_id: number; + anidb_id: number; + kitsu_id: number; + mal_id: number; + type: string; + notify_moe_id: string; + anilist_id: string; + }; + thetvdb: { + seriesId: string; + status: string; + firstAired: string; + recent: string; + airs: string; + studio: string; + network: string[]; + averageRuntime: string; + genres: string[]; + originalCountry: string; + originalLanguage: string; + geographicLocation: string[]; + subGenre: string[]; + supernaturalBeings: string[]; + imdbLink: string; + officialWebsite: string | null; + redditLink: string; + tvMazeLink: string | null; + theMovieDBLink: string; + twitterLink: string; + wikidataLink: string; + wikipediaLink: string; + trailerLink: string; + favoritedCount: number; + created: { + date: { + day: number; + month: string; + year: number; + monthNum: number; + }; + by: string; + }; + modified: { + date: { + day: number; + month: string; + year: number; + monthNum: number; + }; + by: string; + }; + artworks: { + backgrounds: string[]; + banners: string[]; + clearArt: string[]; + clearLogo: string[]; + icons: string[]; + posters: string[]; + }; + }; +} + +interface MediaStudioNode { + id: number; + isAnimationStudio: boolean; + favourites: number; + name: string; + siteUrl: string; + _id: string; +} + +interface MediaStudioEdge { + id: number; + isMain: boolean; + node: MediaStudioNode; + _id: string; +} + +interface MediaTitle { + romaji: string; + english: string; + native: string; + userPreferred: string; + _id: string; +} + +interface MediaTrailer { + id: string; + site: string; + thumbnail: string; + _id: string; +} + +interface MediaNextAiringEpisode { + id: number; + airingAt: number; + timeUntilAiring: number; + episode: number; + mediaId: number; + _id: string; +} + +export interface Media { + _id: string; + id: number; + __v: number; + averageScore: number; + bannerImage: string; + countryOfOrigin: string; + coverImage: MediaCoverImage; + description: string; + duration: number; + endDate: MediaEndDate; + episodes: number; + favourites: number; + format: string; + genres: string[]; + idMal: number; + mappings: MediaMappings; + meanScore: number; + nextAiringEpisode: MediaNextAiringEpisode; + season: string; + seasonYear: number; + status: string; + studios: { + edges: MediaStudioEdge[]; + _id: string; + }; + synonyms: string[]; + title: MediaTitle; + trailer: MediaTrailer; + type: string; +} + +interface Response { + media: Media[]; +} + +interface Image { + extraLarge: string; + large: string; + medium: string; + color: string; +} + +interface Title { + romaji: string; + english: string; + native: string; + userPreferred: string; +} + +interface StudioNode { + favourites: number; + id: number; + isAnimationStudio: boolean; + isFavourite: boolean; + name: string; + siteUrl: string; +} + +interface StudioEdge { + isMain: boolean; + id: number; + node: StudioNode; +} + +interface Studios { + edges: StudioEdge[]; +} + +interface Trailer { + id: string; + site: string; + thumbnail: string; +} + +interface Date { + year: number; + month: number; + day: number; + _id: string; +} + +interface EpisodeTitle { + ja: string; + en: string; + x_jat: string; +} + +interface Episode { + tvdbShowId: number; + tvdbId: number; + seasonNumber: number; + episodeNumber: number; + absoluteEpisodeNumber: number; + title: EpisodeTitle; + airDate: string; + airDateUtc: string; + runtime: number; + overview: string; + image: string; + episode: string; + anidbEid: number; + length: number; + airdate: string; + rating: string; + summary: string; +} + +interface Anizip { + titles: { + x_jat: string; + ja: string; + en: string; + }; + episodes: { + [key: number]: Episode; + }; + episodeCount: number; + specialCount: number; + images: { + coverType: string; + url: string; + }[]; + mappings: { + animeplanet_id: string; + kitsu_id: number; + mal_id: number; + type: string; + anilist_id: number; + anisearch_id: number; + anidb_id: number; + notifymoe_id: string; + livechart_id: number; + thetvdb_id: number; + imdb_id: string; + themoviedb_id: number; + }; +} + +export interface SiteDetail { + identifier: string | number; + image: string; + malId: number; + aniId: number; + page: string; + title: string; + type: string; + url: string; + external?: boolean; +} + +export interface Sites { + [key: string]: { + [key: string]: SiteDetail; + }; +} + +interface Mappings { + anilistId: string; + anizip: Anizip; + fribb: { + livechart_id: number; + thetvdb_id: number; + anime_planet_id: string; + imdb_id: string; + anisearch_id: number; + themoviedb_id: number; + anidb_id: number; + kitsu_id: number; + mal_id: number; + type: string; + notify_moe_id: string; + anilist_id: number; + }; + gogoanime: { + id: string; + title: string; + url: string; + image: string; + releaseDate: string; + subOrDub: string; + }; + thetvdb: { + seriesId: string; + status: string; + firstAired: string; + recent: string; + airs: string; + studio: string; + network: string[]; + averageRuntime: string; + genres: string[]; + originalCountry: string; + originalLanguage: string; + geographicLocation: string[]; + subGenre: string[]; + supernaturalBeings: string[]; + imdbLink: string; + officialWebsite: string | null; + redditLink: string; + tvMazeLink: string | null; + theMovieDBLink: string; + twitterLink: string; + wikidataLink: string; + wikipediaLink: string; + trailerLink: string; + favoritedCount: number; + created: { + date: { + day: number; + month: string; + year: number; + monthNum: number; + }; + by: string; + }; + modified: { + date: { + day: number; + month: string; + year: number; + monthNum: number; + }; + by: string; + }; + artworks: { + backgrounds: string[]; + banners: string[]; + clearArt: string[]; + clearLogo: string[]; + icons: string[]; + posters: string[]; + }; + }; + kitsu: { + id: string; + type: string; + links: { + self: string; + }; + attributes: { + createdAt: string; + updatedAt: string; + slug: string; + synopsis: string; + description: string; + coverImageTopOffset: number; + titles: { + en: string; + en_jp: string; + ja_jp: string; + th_th: string; + }; + canonicalTitle: string; + abbreviatedTitles: string[]; + averageRating: string; + ratingFrequencies: { + [key: string]: string; + }; + userCount: number; + favoritesCount: number; + startDate: string; + endDate: string; + nextRelease: string | null; + popularityRank: number; + ratingRank: number; + ageRating: string; + ageRatingGuide: string; + subtype: string; + status: string; + tba: string | null; + posterImage: { + tiny: string; + large: string; + small: string; + medium: string; + original: string; + meta: { + dimensions: { + tiny: { + width: number; + height: number; + }; + large: { + width: number; + height: number; + }; + small: { + width: number; + height: number; + }; + medium: { + width: number; + height: number; + }; + }; + }; + }; + coverImage: { + tiny: string; + large: string; + small: string; + original: string; + meta: { + dimensions: { + tiny: { + width: number; + height: number; + }; + large: { + width: number; + height: number; + }; + small: { + width: number; + height: number; + }; + }; + }; + }; + episodeCount: number; + episodeLength: number; + totalLength: number | null; + youtubeVideoId: string; + showType: string; + nsfw: boolean; + }; + relationships: { + genres: { + links: { + self: string; + related: string; + }; + }; + categories: { + links: { + self: string; + related: string; + }; + }; + castings: { + links: { + self: string; + related: string; + }; + }; + installments: { + links: { + self: string; + related: string; + }; + }; + mappings: { + links: { + self: string; + related: string; + }; + }; + reviews: { + links: { + self: string; + related: string; + }; + }; + mediaRelationships: { + links: { + self: string; + related: string; + }; + }; + characters: { + links: { + self: string; + related: string; + }; + }; + staff: { + links: { + self: string; + related: string; + }; + }; + productions: { + links: { + self: string; + related: string; + }; + }; + quotes: { + links: { + self: string; + related: string; + }; + }; + episodes: { + links: { + self: string; + related: string; + }; + }; + streamingLinks: { + links: { + self: string; + related: string; + }; + }; + animeProductions: { + links: { + self: string; + related: string; + }; + }; + animeCharacters: { + links: { + self: string; + related: string; + }; + }; + animeStaff: { + links: { + self: string; + related: string; + }; + }; + }; + }; + malSync: { + id: number; + type: string; + title: string; + url: string; + total: number; + image: string; + malId: number; + Sites: Sites; + }; +} + +export interface Anime { + _id: string; + bannerImage: string; + averageScore: number; + coverImage: Image; + title: Title; + format: string; + type: string; + season: string; + seasonYear: number; + id: number; + idMal: number; + color: string; + status: string; + episodes: number; + duration: number; + description: string; + studios: Studios; + trailer: Trailer; + startDate: Date; + endDate: Date; + synonyms: string[]; + countryOfOrigin: string; + isAdult: boolean; + mappings: Mappings; +}