import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi"; import { fetchFromMultipleSources } from "~/libs/fetchFromMultipleSources"; import { readEnvVariable } from "~/libs/readEnvVariable"; import type { Env } from "~/types/env"; import { AniListIdQuerySchema, ErrorResponse, ErrorResponseSchema, SuccessResponseSchema, } from "~/types/schema"; import { getEpisodesFromAnify } from "./anify"; import { EpisodesResponse } from "./episode"; const EpisodesResponseSchema = SuccessResponseSchema(EpisodesResponse); const route = createRoute({ tags: ["aniplay", "episodes"], summary: "Fetch episodes for a title", operationId: "fetchEpisodes", method: "get", path: "/{aniListId}", request: { params: z.object({ aniListId: AniListIdQuerySchema }), }, responses: { 200: { content: { "application/json": { schema: EpisodesResponseSchema, }, }, description: "Returns a list of episodes", }, 404: { content: { "application/json": { schema: ErrorResponseSchema, }, }, description: "Returns an empty list because episodes not found", }, }, }); const app = new OpenAPIHono(); app.openapi(route, async (c) => { const aniListId = Number(c.req.param("aniListId")); const episodes = await fetchFromMultipleSources([ () => { const isAnifyEnabled = readEnvVariable(c.env, "ENABLE_ANIFY"); return getEpisodesFromAnify(isAnifyEnabled, aniListId); }, () => import("./consumet").then(({ getEpisodesFromConsumet }) => getEpisodesFromConsumet(aniListId), ), () => import("./amvstrm").then(({ getEpisodesFromAmvstrm }) => getEpisodesFromAmvstrm(aniListId), ), ]); if (!episodes) { return c.json(ErrorResponse, { status: 404 }); } return c.json({ success: true, result: episodes, }); }); export default app;