spb/wp-spboucher-ai
Public
1import { listPapers } from "@/lib/papers/queries";2import { APP_URL, SITE_NAME, SITE_SECONDARY } from "@/lib/env";3export const revalidate = 600;4const esc = (s: string) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);5export async function GET() {6 const { items } = await listPapers({ sort: "revised", perPage: 30 });7 const xml = `<?xml version="1.0" encoding="UTF-8"?>8<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">9<channel><title>${esc(SITE_NAME)} — ${esc(SITE_SECONDARY)}</title><link>${APP_URL}</link><description>Latest research working papers and revisions.</description><language>en-ca</language><atom:link href="${APP_URL}/feed.xml" rel="self" type="application/rss+xml"/>10${items.map((p) => `<item><title>${esc(`${p.identifier} · ${p.title}`)}</title><link>${APP_URL}/papers/${p.slug}</link><guid isPermaLink="true">${APP_URL}/papers/${p.slug}</guid>${p.last_revised_on ? `<pubDate>${new Date(p.last_revised_on + "T12:00:00Z").toUTCString()}</pubDate>` : ""}${p.authors.map((a) => `<dc:creator>${esc(a.display_name)}</dc:creator>`).join("")}<description>${esc((p.abstract[0] ?? "").slice(0, 600))}</description></item>`).join("\n")}11</channel></rss>`;12 return new Response(xml, { headers: { "Content-Type": "application/rss+xml; charset=utf-8", "Cache-Control": "public, max-age=600" } });13}14