Some checks failed
Docker Deploy / build-and-push (push) Has been cancelled
78 lines
2.2 KiB
JavaScript
78 lines
2.2 KiB
JavaScript
import { getCollection } from "astro:content";
|
|
|
|
function formatPubDate(date) {
|
|
const timezone = process.env.PUBLIC_RSS_TIMEZONE
|
|
? process.env.PUBLIC_RSS_TIMEZONE
|
|
: import.meta.env.PUBLIC_RSS_TIMEZONE;
|
|
|
|
if (!timezone) {
|
|
return date;
|
|
}
|
|
|
|
try {
|
|
const year = date.getUTCFullYear();
|
|
const month = String(date.getUTCMonth() + 1).padStart(2, "0");
|
|
const day = String(date.getUTCDate()).padStart(2, "0");
|
|
|
|
const formatter = new Intl.DateTimeFormat("en-US", {
|
|
timeZone: timezone,
|
|
timeZoneName: "longOffset",
|
|
});
|
|
|
|
const parts = formatter.formatToParts(date);
|
|
const offsetPart = parts.find((p) => p.type === "timeZoneName");
|
|
const offset = offsetPart ? offsetPart.value.replace("GMT", "") : "+00:00";
|
|
|
|
const dateStr = `${year}-${month}-${day}T00:00:00${offset}`;
|
|
|
|
return new Date(dateStr);
|
|
} catch (e) {
|
|
console.warn(`Invalid timezone "${timezone}":`, e.message);
|
|
return date;
|
|
}
|
|
}
|
|
|
|
export async function GET(context) {
|
|
const posts = await getCollection("posts");
|
|
|
|
// Sort posts by date, newest first
|
|
posts.sort((a, b) => new Date(b.data.pubDate) - new Date(a.data.pubDate));
|
|
|
|
const siteUrl = context.site?.toString().replace(/\/$/, "") || "";
|
|
|
|
const items = posts
|
|
.map((post) => {
|
|
const title = post.data.title;
|
|
const description = post.data.description || "";
|
|
const link = `${siteUrl}/post/${post.id}/`;
|
|
const pubDate = formatPubDate(post.data.pubDate).toUTCString();
|
|
|
|
return ` <item>
|
|
<title><![CDATA[${title}]]></title>
|
|
<link>${link}</link>
|
|
<guid isPermaLink="true">${link}</guid>
|
|
<description><![CDATA[${description}]]></description>
|
|
<pubDate>${pubDate}</pubDate>
|
|
</item>`;
|
|
})
|
|
.join("\n");
|
|
|
|
const rssXml = `<?xml version="1.0" encoding="UTF-8"?>
|
|
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
|
<channel>
|
|
<title>Atridad Lahiji</title>
|
|
<description>Recent posts from Atridad Lahiji</description>
|
|
<link>${siteUrl}/</link>
|
|
<language>en-us</language>
|
|
<atom:link href="${siteUrl}/rss.xml" rel="self" type="application/rss+xml" />
|
|
${items}
|
|
</channel>
|
|
</rss>`;
|
|
|
|
return new Response(rssXml, {
|
|
headers: {
|
|
"Content-Type": "application/xml",
|
|
},
|
|
});
|
|
}
|