feat: add Amvstrm as source for /episodes

Summary:

Test Plan:
This commit is contained in:
2024-05-26 13:22:03 -04:00
parent e91f92354c
commit b661b59078
7 changed files with 125 additions and 2 deletions

View File

@@ -0,0 +1,60 @@
import { Episode, type EpisodesResponse } from "./episode";
export async function getEpisodesFromAmvstrm(
aniListId: number,
): Promise<EpisodesResponse | null> {
try {
const episodes: Episode[] | null = await fetch(
`https://api-amvstrm.nyt92.eu.org/api/v2/episode/${aniListId}`,
)
.then((res) => res.json<AmvstrmEpisodesResponse>())
.then(({ code, message, episodes }) => {
if (code >= 400) {
console.error(
`Error trying to load episodes from amvstrm; aniListId: ${aniListId}, code: ${code}, message: ${message}`,
);
return null;
}
return episodes.map<Episode>(
({ id, description, image, title, episode, airDate }) => ({
id,
number: episode,
description,
img: image,
title,
updatedAt: airDate ?? 0,
}),
);
});
if (!episodes || episodes.length === 0) {
return null;
}
return { providerId: "amvstrm", episodes };
} catch (error) {
console.error(
new Error(
`Error trying to load episodes from amvstrm; aniListId: ${aniListId}`,
{ cause: error },
),
);
}
return null;
}
interface AmvstrmEpisodesResponse {
code: number;
message: string;
episodes: AmvstrmEpisode[];
}
interface AmvstrmEpisode {
id: string;
title: string;
description: string | null;
episode: number;
image: string;
airDate: null;
}

View File

@@ -10,7 +10,7 @@ export async function getEpisodesFromConsumet(
const aniList = new META.Anilist(gogoAnime, undefined, fetchAdapter);
try {
const episodes = await aniList
const episodes: Episode[] = await aniList
.fetchEpisodesListById(aniListId.toString())
.then((episodes) =>
episodes.map(

View File

@@ -186,6 +186,32 @@ describe('requests the "/episodes" route', () => {
});
});
it("with list of episodes from Amvstrm", async () => {
const response = await app.request(
"/episodes/4",
{},
{
ENABLE_ANIFY: "true",
},
);
expect(response.json()).resolves.toEqual({
success: true,
result: {
providerId: "amvstrm",
episodes: [
{
id: "amvstrm-1",
number: 1,
title: "EP 1",
updatedAt: 0,
img: null,
},
],
},
});
});
it("with no episodes from all sources", async () => {
const response = await app.request("/episodes/-1");

View File

@@ -57,6 +57,10 @@ app.openapi(route, async (c) => {
import("./consumet").then(({ getEpisodesFromConsumet }) =>
getEpisodesFromConsumet(aniListId),
),
() =>
import("./amvstrm").then(({ getEpisodesFromAmvstrm }) =>
getEpisodesFromAmvstrm(aniListId),
),
]);
if (!episodes) {

View File

@@ -0,0 +1,31 @@
import { HttpResponse, http } from "msw";
export function getAmvstrmEpisodes() {
return http.get(
"https://api-amvstrm.nyt92.eu.org/api/v2/episode/:aniListId",
({ params }) => {
const aniListId = Number(params["aniListId"]);
if (aniListId === 4) {
return HttpResponse.json({
code: 200,
message: "success",
episodes: [
{
id: "amvstrm-1",
episode: 1,
title: "EP 1",
isFiller: false,
isDub: false,
image: null,
},
],
});
}
return HttpResponse.json(
{ code: 500, message: "Server error", episodes: [] },
{ status: 500 },
);
},
);
}

View File

@@ -3,7 +3,7 @@ import { HttpResponse, http } from "msw";
export function getAnifyEpisodes() {
return http.get("https://api.anify.tv/episodes/:aniListId", ({ params }) => {
const aniListId = Number(params["aniListId"]);
if (aniListId === 3 || aniListId < 0) {
if (aniListId === 3 || aniListId === 4 || aniListId < 0) {
return HttpResponse.json([]);
}

View File

@@ -1,3 +1,4 @@
import { getAmvstrmEpisodes } from "./amvstrm/episodes";
import { getAmvstrmSearchResults } from "./amvstrm/search";
import { getAmvstrmTitle } from "./amvstrm/title";
import { getAnifyEpisodes } from "./anify/episodes";
@@ -8,6 +9,7 @@ import { getAnilistTitle } from "./anilist/title";
export const handlers = [
getAnilistSearchResults(),
getAnilistTitle(),
getAmvstrmEpisodes(),
getAmvstrmSearchResults(),
getAmvstrmTitle(),
getAnifyEpisodes(),