import rss from '@astrojs/rss'; import { getCollection } from 'astro:content'; import { existsSync, statSync } from 'node:fs'; import { join } from 'node:path'; const PUBLIC_DIR = join(process.cwd(), 'public'); const DEFAULT_AUTHOR = 'Elie Habib'; function escapeXml(value: string): string { return value .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"'); } function getPublicAssetPath(pathOrUrl: string | undefined): string | undefined { if (!pathOrUrl || /^https?:\/\//.test(pathOrUrl)) return undefined; const withoutBlogBase = pathOrUrl.startsWith('/blog/') ? pathOrUrl.slice('/blog/'.length) : pathOrUrl.replace(/^\//, ''); return join(PUBLIC_DIR, withoutBlogBase); } function getEnclosure(heroImage: string | undefined) { if (!heroImage) return undefined; const url = /^https?:\/\//.test(heroImage) ? heroImage : `https://www.worldmonitor.app${heroImage}`; const localPath = getPublicAssetPath(heroImage); const length = localPath && existsSync(localPath) ? statSync(localPath).size : 1; return { url, length, type: heroImage.endsWith('.png') ? 'image/png' : 'image/jpeg', }; } export async function GET(context: { site: URL }) { const posts = await getCollection('blog'); return rss({ title: 'World Monitor Blog', description: 'Real-time global intelligence, OSINT, geopolitics, and markets.', site: context.site, xmlns: { atom: 'http://www.w3.org/2005/Atom', dc: 'http://purl.org/dc/elements/1.1/', media: 'http://search.yahoo.com/mrss/', }, customData: [ 'en-us', ``, ].join(''), items: posts .sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf()) .map((post) => { const enclosure = getEnclosure(post.data.heroImage); return { title: post.data.title, pubDate: post.data.pubDate, description: post.data.description, link: `/blog/posts/${post.id}/`, categories: post.data.keywords?.split(',').map((k: string) => k.trim()), ...(enclosure ? { enclosure } : {}), customData: [ `${escapeXml(post.data.author || DEFAULT_AUTHOR)}`, post.data.modifiedDate ? `${post.data.modifiedDate.toISOString()}` : '', enclosure ? `` : '', ].filter(Boolean).join(''), }; }), }); }