Files
aniplay-api/src/index.ts

123 lines
3.3 KiB
TypeScript

import { swaggerUI } from "@hono/swagger-ui";
import { OpenAPIHono } from "@hono/zod-openapi";
import { maybeUpdateLastConnectedAt } from "~/controllers/maybeUpdateLastConnectedAt";
import type { QueueName } from "~/libs/tasks/queueName.ts";
import { onNewEpisode } from "./controllers/internal/new-episode";
import { AnilistUpdateType } from "./libs/anilist/updateType";
import type { QueueBody } from "./libs/tasks/queueTask";
export const app = new OpenAPIHono<{ Bindings: Env }>();
app.use(maybeUpdateLastConnectedAt);
app.route(
"/",
await import("~/controllers/health-check").then(
(controller) => controller.default,
),
);
app.route(
"/title",
await import("~/controllers/title").then((controller) => controller.default),
);
app.route(
"/episodes",
await import("~/controllers/episodes").then(
(controller) => controller.default,
),
);
app.route(
"/search",
await import("~/controllers/search").then((controller) => controller.default),
);
app.route(
"/watch-status",
await import("~/controllers/watch-status").then(
(controller) => controller.default,
),
);
app.route(
"/token",
await import("~/controllers/token").then((controller) => controller.default),
);
app.route(
"/auth",
await import("~/controllers/auth").then((controller) => controller.default),
);
app.route(
"/popular",
await import("~/controllers/popular").then(
(controller) => controller.default,
),
);
app.route(
"/internal",
await import("~/controllers/internal").then(
(controller) => controller.default,
),
);
// The OpenAPI documentation will be available at /doc
app.doc("/openapi.json", {
openapi: "3.0.0",
info: {
version: "1.0.0",
title: "Aniplay API",
},
});
app.get("/docs", swaggerUI({ url: "/openapi.json" }));
export default {
fetch: app.fetch,
async queue(batch) {
switch (batch.queue as QueueName) {
case "ANILIST_UPDATES":
for (const message of (
batch as MessageBatch<QueueBody["ANILIST_UPDATES"]>
).messages) {
switch (message.body.updateType) {
case AnilistUpdateType.UpdateWatchStatus:
if (!message.body[AnilistUpdateType.UpdateWatchStatus]) {
throw new Error(
`Discarding update, unknown body ${JSON.stringify(message.body)}`,
);
}
const { updateWatchStatusOnAnilist } =
await import("~/controllers/watch-status/anilist");
const payload = message.body[AnilistUpdateType.UpdateWatchStatus];
await updateWatchStatusOnAnilist(
payload.titleId,
payload.watchStatus,
payload.aniListToken,
);
break;
}
message.ack();
}
break;
case "NEW_EPISODE":
for (const message of (batch as MessageBatch<QueueBody["NEW_EPISODE"]>)
.messages) {
await onNewEpisode(
message.body.aniListId,
message.body.episodeNumber,
);
message.ack();
}
break;
}
},
async scheduled(event, env, ctx) {
const { processDelayedTasks } =
await import("~/libs/tasks/processDelayedTasks");
await processDelayedTasks(env, ctx);
},
} satisfies ExportedHandler<Env>;
export { AnilistDurableObject as AnilistDo } from "~/libs/anilist/anilist-do.ts";