57 lines
2.0 KiB
TypeScript
57 lines
2.0 KiB
TypeScript
/**
|
|
* Serves the chat's history to the chatbox (`ChatModal`). Messages are sent,
|
|
* edited and deleted over the socket instead (`routes/ws.ts`).
|
|
*
|
|
* - `GET /api/chat?limit=&before=&beforeId=&after=&afterId=`, signed in.
|
|
* Returns messages oldest first, at most `limit` (50 by default, 100 at
|
|
* most). With no cursor, it returns the latest. With `before`, it returns
|
|
* the page just older than that cursor, for "load older". With `after`, it
|
|
* returns what follows it, for the resync after a reconnect. A cursor is a
|
|
* message's ISO `created_at`, and its id breaks ties. Without `afterId`,
|
|
* messages at the `after` timestamp itself are included.
|
|
*
|
|
* @module
|
|
*/
|
|
|
|
import { Router } from "@oak/oak";
|
|
import type { APIResponse } from "../../shared/api.ts";
|
|
import type { ChatMessage } from "../../shared/chat.ts";
|
|
import { authMiddleware } from "../middleware/auth.ts";
|
|
import {
|
|
getChatMessagesAfter,
|
|
getRecentChatMessages,
|
|
} from "../services/chat-service.ts";
|
|
|
|
/**
|
|
* Mounted by `api/main.ts` behind the error, Open Graph and CORS middleware.
|
|
* An `APIException` thrown by a handler becomes the JSON error response there.
|
|
*/
|
|
const router: Router = new Router({ prefix: "/api/chat" });
|
|
|
|
router.get("/", authMiddleware, (ctx) => {
|
|
const params = ctx.request.url.searchParams;
|
|
const limitParam = params.get("limit");
|
|
const limit = limitParam ? Number(limitParam) : NaN;
|
|
const cappedLimit = Number.isFinite(limit) ? limit : undefined;
|
|
const before = params.get("before");
|
|
const after = params.get("after");
|
|
const messages = after
|
|
? getChatMessagesAfter(
|
|
{ createdAt: after, id: params.get("afterId") ?? undefined },
|
|
cappedLimit,
|
|
)
|
|
: getRecentChatMessages(
|
|
cappedLimit,
|
|
before
|
|
? { createdAt: before, id: params.get("beforeId") ?? undefined }
|
|
: undefined,
|
|
);
|
|
const responseBody: APIResponse<ChatMessage[]> = {
|
|
success: true,
|
|
data: messages,
|
|
};
|
|
ctx.response.body = responseBody;
|
|
});
|
|
|
|
export default router;
|