gallery.badmanners.xyz/src/pages/feed.xml.ts
2024-12-05 21:43:04 -03:00

58 lines
2.1 KiB
TypeScript

import rss from "@astrojs/rss";
import type { APIRoute } from "astro";
import { getCollection, render } from "astro:content";
import { blogFeedItem, gameFeedItem, storyFeedItem, type EntryWithPubDate } from "@utils/feed";
const MAX_ITEMS = 8;
export const GET: APIRoute = async ({ site }) => {
if (!site) {
throw new Error("site is required.");
}
const stories = (
(await getCollection(
"stories",
(story) => !story.data.isDraft && story.data.pubDate,
)) as EntryWithPubDate<"stories">[]
)
.sort((a, b) => b.data.pubDate.getTime() - a.data.pubDate.getTime())
.slice(0, MAX_ITEMS);
const games = (
(await getCollection("games", (game) => !game.data.isDraft && game.data.pubDate)) as EntryWithPubDate<"games">[]
)
.sort((a, b) => b.data.pubDate.getTime() - a.data.pubDate.getTime())
.slice(0, MAX_ITEMS);
const posts = (
(await getCollection("blog", (post) => !post.data.isDraft && post.data.pubDate)) as EntryWithPubDate<"blog">[]
)
.sort((a, b) => b.data.pubDate.getTime() - a.data.pubDate.getTime())
.slice(0, MAX_ITEMS);
return rss({
title: "Gallery | Bad Manners",
description: "Stories, games, and more by Bad Manners.",
site,
xmlns: { atom: "http://www.w3.org/2005/Atom" },
customData: `<link href="${site}" rel="alternate" type="text/html" /><atom:link href="${new URL("feed.xml", site)}" rel="self" type="application/rss+xml" />`,
items: await Promise.all(
[
stories.map((story) => ({
date: story.data.pubDate,
fn: async () => storyFeedItem(site, story.data, story.id, (await render(story)).Content),
})),
games.map((game) => ({
date: game.data.pubDate,
fn: async () => gameFeedItem(site, game.data, game.id, (await render(game)).Content),
})),
posts.map((post) => ({
date: post.data.pubDate,
fn: async () => blogFeedItem(site, post.data, post.id, (await render(post)).Content),
})),
]
.flat()
.sort((a, b) => b.date.getTime() - a.date.getTime())
.slice(0, MAX_ITEMS)
.map((value) => value.fn()),
),
});
};