summaryrefslogtreecommitdiff
path: root/packages/astro-rss/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/astro-rss/src')
-rw-r--r--packages/astro-rss/src/index.ts37
-rw-r--r--packages/astro-rss/src/schema.ts11
2 files changed, 47 insertions, 1 deletions
diff --git a/packages/astro-rss/src/index.ts b/packages/astro-rss/src/index.ts
index 9c5908b93..2a35bd573 100644
--- a/packages/astro-rss/src/index.ts
+++ b/packages/astro-rss/src/index.ts
@@ -47,6 +47,16 @@ type RSSFeedItem = {
customData?: z.infer<typeof rssSchema>['customData'];
/** Whether draft or not */
draft?: z.infer<typeof rssSchema>['draft'];
+ /** Categories or tags related to the item */
+ categories?: z.infer<typeof rssSchema>['categories'];
+ /** The item author's email address */
+ author?: z.infer<typeof rssSchema>['author'];
+ /** A URL of a page for comments related to the item */
+ commentsUrl?: z.infer<typeof rssSchema>['commentsUrl'];
+ /** The RSS channel that the item came from */
+ source?: z.infer<typeof rssSchema>['source'];
+ /** A media object that belongs to the item */
+ enclosure?: z.infer<typeof rssSchema>['enclosure'];
};
type ValidatedRSSFeedItem = z.infer<typeof rssFeedItemValidator>;
@@ -148,6 +158,7 @@ async function generateRSS(rssOptions: ValidatedRSSOptions): Promise<string> {
// when using `customData`
// https://github.com/withastro/astro/issues/5794
suppressEmptyNode: true,
+ suppressBooleanAttributes: false,
};
const parser = new XMLParser(xmlOptions);
const root: any = { '?xml': { '@_version': '1.0', '@_encoding': 'UTF-8' } };
@@ -196,7 +207,7 @@ async function generateRSS(rssOptions: ValidatedRSSOptions): Promise<string> {
const item: any = {
title: result.title,
link: itemLink,
- guid: itemLink,
+ guid: { '#text': itemLink, '@_isPermaLink': 'true' },
};
if (result.description) {
item.description = result.description;
@@ -211,6 +222,30 @@ async function generateRSS(rssOptions: ValidatedRSSOptions): Promise<string> {
if (typeof result.customData === 'string') {
Object.assign(item, parser.parse(`<item>${result.customData}</item>`).item);
}
+ if (Array.isArray(result.categories)) {
+ item.category = result.categories;
+ }
+ if (typeof result.author === 'string') {
+ item.author = result.author;
+ }
+ if (typeof result.commentsUrl === 'string') {
+ item.comments = isValidURL(result.commentsUrl)
+ ? result.commentsUrl
+ : createCanonicalURL(result.commentsUrl, rssOptions.trailingSlash, site).href;
+ }
+ if (result.source) {
+ item.source = parser.parse(
+ `<source url="${result.source.url}">${result.source.title}</source>`
+ ).source;
+ }
+ if (result.enclosure) {
+ const enclosureURL = isValidURL(result.enclosure.url)
+ ? result.enclosure.url
+ : createCanonicalURL(result.enclosure.url, rssOptions.trailingSlash, site).href;
+ item.enclosure = parser.parse(
+ `<enclosure url="${enclosureURL}" length="${result.enclosure.length}" type="${result.enclosure.type}"/>`
+ ).enclosure;
+ }
return item;
});
diff --git a/packages/astro-rss/src/schema.ts b/packages/astro-rss/src/schema.ts
index b24a1441f..829a4da1e 100644
--- a/packages/astro-rss/src/schema.ts
+++ b/packages/astro-rss/src/schema.ts
@@ -6,4 +6,15 @@ export const rssSchema = z.object({
description: z.string().optional(),
customData: z.string().optional(),
draft: z.boolean().optional(),
+ categories: z.array(z.string()).optional(),
+ author: z.string().optional(),
+ commentsUrl: z.string().optional(),
+ source: z.object({ url: z.string().url(), title: z.string() }).optional(),
+ enclosure: z
+ .object({
+ url: z.string(),
+ length: z.number().positive().int().finite(),
+ type: z.string(),
+ })
+ .optional(),
});