server/packages/api/routes/api/v1/accounts/[id]/feed.atom.ts
2025-06-15 23:43:27 +02:00

62 lines
1.9 KiB
TypeScript

import { RolePermission } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { apiRoute, auth, handleZodError, withUserParam } from "@versia/kit/api";
import { describeRoute } from "hono-openapi";
import { resolver, validator } from "hono-openapi/zod";
import { z } from "zod";
import { getFeed } from "@/rss";
export default apiRoute((app) =>
app.get(
"/api/v1/accounts/:id/feed.atom",
describeRoute({
summary: "Get account's Atom feed",
description:
"Statuses posted to the given account, in Atom 1.0 format.",
tags: ["Accounts"],
responses: {
200: {
description: "Statuses posted to the given account.",
content: {
"application/atom+xml": {
schema: resolver(z.any()),
},
},
},
404: ApiError.accountNotFound().schema,
422: ApiError.validationFailed().schema,
},
}),
withUserParam,
auth({
auth: false,
permissions: [
RolePermission.ViewNotes,
RolePermission.ViewAccounts,
],
scopes: ["read:statuses"],
}),
validator(
"query",
z.object({
page: z.coerce.number().default(0).openapi({
description: "Page number to fetch. Defaults to 0.",
example: 2,
}),
}),
handleZodError,
),
async (context) => {
const otherUser = context.get("user");
const { page } = context.req.valid("query");
const feed = await getFeed(otherUser, page);
context.header("Content-Type", "application/atom+xml");
return context.body(feed.atom1(), 200);
},
),
);