Skip to content

Commit

Permalink
fix(@astrojs/rss): prevent an error when pubDate is missing (#12137)
Browse files Browse the repository at this point in the history
* fix(rss): prevent error when `pubDate` is missing

* docs(rss): switch some RSS items to optional
  • Loading branch information
ArmandPhilippot authored Oct 7, 2024
1 parent 2385d58 commit 50dd88b
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/ninety-dolls-reply.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/rss': patch
---

Fixes an error that occurred when the optional `pubDate` property was missing in an item.
5 changes: 5 additions & 0 deletions .changeset/plenty-kings-swim.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/rss': patch
---

Fixes an error where docs incorrectly stated the `title`, `link` and `pubDate` properties of RSS items was required.
10 changes: 5 additions & 5 deletions packages/astro-rss/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,27 +198,27 @@ const item = {
### `title`
Type: `string (required)`
Type: `string (optional)`
The title of the item in the feed.
The title of the item in the feed. Optional only if a description is set. Otherwise, required.
### `link`
Type: `string (required)`
Type: `string (optional)`
The URL of the item on the web.
### `pubDate`
Type: `Date (required)`
Type: `Date (optional)`
Indicates when the item was published.
### `description`
Type: `string (optional)`
A synopsis of your item when you are publishing the full content of the item in the `content` field. The `description` may alternatively be the full content of the item in the feed if you are not using the `content` field (entity-coded HTML is permitted).
A synopsis of your item when you are publishing the full content of the item in the `content` field. The `description` may alternatively be the full content of the item in the feed if you are not using the `content` field (entity-coded HTML is permitted). Optional only if a title is set. Otherwise, required.
### `content`
Expand Down
6 changes: 3 additions & 3 deletions packages/astro-rss/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ export const rssSchema = z.object({
description: z.string().optional(),
pubDate: z
.union([z.string(), z.number(), z.date()])
.optional()
.transform((value) => (value === undefined ? value : new Date(value)))
.refine((value) => (value === undefined ? value : !isNaN(value.getTime()))),
.transform((value) => new Date(value))
.refine((value) => !isNaN(value.getTime()))
.optional(),
customData: z.string().optional(),
categories: z.array(z.string()).optional(),
author: z.string().optional(),
Expand Down
14 changes: 14 additions & 0 deletions packages/astro-rss/test/rss.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
phpFeedItem,
phpFeedItemWithContent,
phpFeedItemWithCustomData,
phpFeedItemWithoutDate,
site,
title,
web1FeedItem,
Expand All @@ -25,6 +26,8 @@ const validXmlResult = `<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
// biome-ignore format: keep in one line
const validXmlWithContentResult = `<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title><![CDATA[${title}]]></title><description><![CDATA[${description}]]></description><link>${site}/</link><item><title><![CDATA[${phpFeedItemWithContent.title}]]></title><link>${site}${phpFeedItemWithContent.link}/</link><guid isPermaLink="true">${site}${phpFeedItemWithContent.link}/</guid><description><![CDATA[${phpFeedItemWithContent.description}]]></description><pubDate>${new Date(phpFeedItemWithContent.pubDate).toUTCString()}</pubDate><content:encoded><![CDATA[${phpFeedItemWithContent.content}]]></content:encoded></item><item><title><![CDATA[${web1FeedItemWithContent.title}]]></title><link>${site}${web1FeedItemWithContent.link}/</link><guid isPermaLink="true">${site}${web1FeedItemWithContent.link}/</guid><description><![CDATA[${web1FeedItemWithContent.description}]]></description><pubDate>${new Date(web1FeedItemWithContent.pubDate).toUTCString()}</pubDate><content:encoded><![CDATA[${web1FeedItemWithContent.content}]]></content:encoded></item></channel></rss>`;
// biome-ignore format: keep in one line
const validXmlResultWithMissingDate = `<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title><![CDATA[${title}]]></title><description><![CDATA[${description}]]></description><link>${site}/</link><item><title><![CDATA[${phpFeedItemWithoutDate.title}]]></title><link>${site}${phpFeedItemWithoutDate.link}/</link><guid isPermaLink="true">${site}${phpFeedItemWithoutDate.link}/</guid><description><![CDATA[${phpFeedItemWithoutDate.description}]]></description></item><item><title><![CDATA[${phpFeedItem.title}]]></title><link>${site}${phpFeedItem.link}/</link><guid isPermaLink="true">${site}${phpFeedItem.link}/</guid><description><![CDATA[${phpFeedItem.description}]]></description><pubDate>${new Date(phpFeedItem.pubDate).toUTCString()}</pubDate></item></channel></rss>`;
// biome-ignore format: keep in one line
const validXmlResultWithAllData = `<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title><![CDATA[${title}]]></title><description><![CDATA[${description}]]></description><link>${site}/</link><item><title><![CDATA[${phpFeedItem.title}]]></title><link>${site}${phpFeedItem.link}/</link><guid isPermaLink="true">${site}${phpFeedItem.link}/</guid><description><![CDATA[${phpFeedItem.description}]]></description><pubDate>${new Date(phpFeedItem.pubDate).toUTCString()}</pubDate></item><item><title><![CDATA[${web1FeedItemWithAllData.title}]]></title><link>${site}${web1FeedItemWithAllData.link}/</link><guid isPermaLink="true">${site}${web1FeedItemWithAllData.link}/</guid><description><![CDATA[${web1FeedItemWithAllData.description}]]></description><pubDate>${new Date(web1FeedItemWithAllData.pubDate).toUTCString()}</pubDate><category>${web1FeedItemWithAllData.categories[0]}</category><category>${web1FeedItemWithAllData.categories[1]}</category><author>${web1FeedItemWithAllData.author}</author><comments>${web1FeedItemWithAllData.commentsUrl}</comments><source url="${web1FeedItemWithAllData.source.url}">${web1FeedItemWithAllData.source.title}</source><enclosure url="${site}${web1FeedItemWithAllData.enclosure.url}" length="${web1FeedItemWithAllData.enclosure.length}" type="${web1FeedItemWithAllData.enclosure.type}"/></item></channel></rss>`;
// biome-ignore format: keep in one line
const validXmlWithCustomDataResult = `<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title><![CDATA[${title}]]></title><description><![CDATA[${description}]]></description><link>${site}/</link><item><title><![CDATA[${phpFeedItemWithCustomData.title}]]></title><link>${site}${phpFeedItemWithCustomData.link}/</link><guid isPermaLink="true">${site}${phpFeedItemWithCustomData.link}/</guid><description><![CDATA[${phpFeedItemWithCustomData.description}]]></description><pubDate>${new Date(phpFeedItemWithCustomData.pubDate).toUTCString()}</pubDate>${phpFeedItemWithCustomData.customData}</item><item><title><![CDATA[${web1FeedItemWithContent.title}]]></title><link>${site}${web1FeedItemWithContent.link}/</link><guid isPermaLink="true">${site}${web1FeedItemWithContent.link}/</guid><description><![CDATA[${web1FeedItemWithContent.description}]]></description><pubDate>${new Date(web1FeedItemWithContent.pubDate).toUTCString()}</pubDate><content:encoded><![CDATA[${web1FeedItemWithContent.content}]]></content:encoded></item></channel></rss>`;
Expand Down Expand Up @@ -101,6 +104,17 @@ describe('getRssString', () => {
assertXmlDeepEqual(str, validXmlWithContentResult);
});

it('should generate on valid RSSFeedItem array with missing date', async () => {
const str = await getRssString({
title,
description,
items: [phpFeedItemWithoutDate, phpFeedItem],
site,
});

assertXmlDeepEqual(str, validXmlResultWithMissingDate);
});

it('should generate on valid RSSFeedItem array with all RSS content included', async () => {
const str = await getRssString({
title,
Expand Down
7 changes: 5 additions & 2 deletions packages/astro-rss/test/test-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ export const title = 'My RSS feed';
export const description = 'This sure is a nice RSS feed';
export const site = 'https://example.com';

export const phpFeedItem = {
export const phpFeedItemWithoutDate = {
link: '/php',
title: 'Remember PHP?',
pubDate: '1994-05-03',
description:
'PHP is a general-purpose scripting language geared toward web development. It was originally created by Danish-Canadian programmer Rasmus Lerdorf in 1994.',
};
export const phpFeedItem = {
...phpFeedItemWithoutDate,
pubDate: '1994-05-03',
};
export const phpFeedItemWithContent = {
...phpFeedItem,
content: `<h1>${phpFeedItem.title}</h1><p>${phpFeedItem.description}</p>`,
Expand Down

0 comments on commit 50dd88b

Please sign in to comment.