import type { APIRoute } from "astro"; import { getEmDashCollection, getSiteSettings } from "emdash"; export const GET: APIRoute = async ({ site, url }) => { const siteUrl = site?.toString() || url.origin; const settings = await getSiteSettings(); const siteTitle = settings?.title || "Studio"; const siteDescription = settings?.tagline || "Design & Development"; const { entries: projects } = await getEmDashCollection("projects", { orderBy: { published_at: "desc" }, limit: 20, }); const items = projects .map((project) => { if (!project.data.publishedAt) return null; const pubDate = project.data.publishedAt.toUTCString(); const projectUrl = `${siteUrl}/work/${project.id}`; const title = escapeXml(project.data.title || "Untitled"); const description = escapeXml(project.data.summary || ""); return ` ${title} ${projectUrl} ${projectUrl} ${pubDate} ${description} `; }) .filter(Boolean) .join("\n"); const rss = ` ${escapeXml(siteTitle)} ${escapeXml(siteDescription)} ${siteUrl} en-us ${new Date().toUTCString()} ${items} `; return new Response(rss, { headers: { "Content-Type": "application/rss+xml; charset=utf-8", "Cache-Control": "public, max-age=3600", }, }); }; const XML_ESCAPE_PATTERNS = [ [/&/g, "&"], [//g, ">"], [/"/g, """], [/'/g, "'"], ] as const; function escapeXml(str: string): string { let result = str; for (const [pattern, replacement] of XML_ESCAPE_PATTERNS) { result = result.replace(pattern, replacement); } return result; }