Files
joelhooks__joelclaw/apps/web/app/feed.xml/route.ts

73 lines
2.2 KiB
TypeScript

import { getAdrRouteSlug, getAllAdrs } from "@/lib/adrs";
import { AUTHOR, SITE_DESCRIPTION, SITE_NAME, SITE_URL } from "@/lib/constants";
import { formatRssPubDate } from "@/lib/date";
import { getAllDiscoveries } from "@/lib/discoveries";
import { getAllPosts } from "@/lib/posts";
export async function GET() {
const posts = await getAllPosts();
const adrs = await getAllAdrs();
const discoveries = await getAllDiscoveries();
const postItems = posts.map((post) => ({
title: post.title,
link: `${SITE_URL}/${post.slug}`,
description: post.description,
date: post.updated ?? post.date,
category: "post",
}));
const adrItems = adrs.map((adr) => ({
title: `ADR-${adr.number}: ${adr.title}`,
link: `${SITE_URL}/adrs/${getAdrRouteSlug(adr.number)}`,
description: `[${adr.status}] ${adr.description ?? adr.title}`,
date: adr.date,
category: "adr",
}));
const discoveryItems = discoveries.map((d) => ({
title: d.title,
link: `${SITE_URL}/cool/${d.slug}`,
description: `[${d.tags.join(", ")}] ${d.relevance ?? d.title}`,
date: d.discovered,
category: "discovery",
}));
const allItems = [...postItems, ...adrItems, ...discoveryItems]
.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
const items = allItems
.map(
(item) => `
<item>
<title><![CDATA[${item.title}]]></title>
<link>${item.link}</link>
<guid isPermaLink="true">${item.link}</guid>
<description><![CDATA[${item.description}]]></description>
<pubDate>${formatRssPubDate(item.date)}</pubDate>
<category>${item.category}</category>
</item>`,
)
.join("\n");
const feed = `<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>${SITE_NAME}</title>
<link>${SITE_URL}</link>
<description>${SITE_DESCRIPTION}</description>
<language>en-us</language>
<managingEditor>${AUTHOR.name}</managingEditor>
<atom:link href="${SITE_URL}/feed.xml" rel="self" type="application/rss+xml" />
${items}
</channel>
</rss>`;
return new Response(feed, {
headers: {
"Content-Type": "application/xml",
"Cache-Control": "s-maxage=3600, stale-while-revalidate",
},
});
}