From 50dd88bc6611243e3f1b2df643af6d0b551fe140 Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Mon, 7 Oct 2024 17:42:19 +0200 Subject: [PATCH] fix(@astrojs/rss): prevent an error when `pubDate` is missing (#12137) * fix(rss): prevent error when `pubDate` is missing * docs(rss): switch some RSS items to optional --- .changeset/ninety-dolls-reply.md | 5 +++++ .changeset/plenty-kings-swim.md | 5 +++++ packages/astro-rss/README.md | 10 +++++----- packages/astro-rss/src/schema.ts | 6 +++--- packages/astro-rss/test/rss.test.js | 14 ++++++++++++++ packages/astro-rss/test/test-utils.js | 7 +++++-- 6 files changed, 37 insertions(+), 10 deletions(-) create mode 100644 .changeset/ninety-dolls-reply.md create mode 100644 .changeset/plenty-kings-swim.md diff --git a/.changeset/ninety-dolls-reply.md b/.changeset/ninety-dolls-reply.md new file mode 100644 index 000000000000..ae7990b56569 --- /dev/null +++ b/.changeset/ninety-dolls-reply.md @@ -0,0 +1,5 @@ +--- +'@astrojs/rss': patch +--- + +Fixes an error that occurred when the optional `pubDate` property was missing in an item. diff --git a/.changeset/plenty-kings-swim.md b/.changeset/plenty-kings-swim.md new file mode 100644 index 000000000000..3a4c896aa007 --- /dev/null +++ b/.changeset/plenty-kings-swim.md @@ -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. diff --git a/packages/astro-rss/README.md b/packages/astro-rss/README.md index 2a5d6a7954f2..d24c5dabc0d6 100644 --- a/packages/astro-rss/README.md +++ b/packages/astro-rss/README.md @@ -198,19 +198,19 @@ 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. @@ -218,7 +218,7 @@ Indicates when the item was published. 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` diff --git a/packages/astro-rss/src/schema.ts b/packages/astro-rss/src/schema.ts index 1c2db762dcad..c4a0fec3f093 100644 --- a/packages/astro-rss/src/schema.ts +++ b/packages/astro-rss/src/schema.ts @@ -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(), diff --git a/packages/astro-rss/test/rss.test.js b/packages/astro-rss/test/rss.test.js index 5a0fd1fd0b00..8014f87fe928 100644 --- a/packages/astro-rss/test/rss.test.js +++ b/packages/astro-rss/test/rss.test.js @@ -10,6 +10,7 @@ import { phpFeedItem, phpFeedItemWithContent, phpFeedItemWithCustomData, + phpFeedItemWithoutDate, site, title, web1FeedItem, @@ -25,6 +26,8 @@ const validXmlResult = `<![CDATA[${title}]]>${site}/<![CDATA[${phpFeedItemWithContent.title}]]>${site}${phpFeedItemWithContent.link}/${site}${phpFeedItemWithContent.link}/${new Date(phpFeedItemWithContent.pubDate).toUTCString()}<![CDATA[${web1FeedItemWithContent.title}]]>${site}${web1FeedItemWithContent.link}/${site}${web1FeedItemWithContent.link}/${new Date(web1FeedItemWithContent.pubDate).toUTCString()}`; // biome-ignore format: keep in one line +const validXmlResultWithMissingDate = `<![CDATA[${title}]]>${site}/<![CDATA[${phpFeedItemWithoutDate.title}]]>${site}${phpFeedItemWithoutDate.link}/${site}${phpFeedItemWithoutDate.link}/<![CDATA[${phpFeedItem.title}]]>${site}${phpFeedItem.link}/${site}${phpFeedItem.link}/${new Date(phpFeedItem.pubDate).toUTCString()}`; +// biome-ignore format: keep in one line const validXmlResultWithAllData = `<![CDATA[${title}]]>${site}/<![CDATA[${phpFeedItem.title}]]>${site}${phpFeedItem.link}/${site}${phpFeedItem.link}/${new Date(phpFeedItem.pubDate).toUTCString()}<![CDATA[${web1FeedItemWithAllData.title}]]>${site}${web1FeedItemWithAllData.link}/${site}${web1FeedItemWithAllData.link}/${new Date(web1FeedItemWithAllData.pubDate).toUTCString()}${web1FeedItemWithAllData.categories[0]}${web1FeedItemWithAllData.categories[1]}${web1FeedItemWithAllData.author}${web1FeedItemWithAllData.commentsUrl}${web1FeedItemWithAllData.source.title}`; // biome-ignore format: keep in one line const validXmlWithCustomDataResult = `<![CDATA[${title}]]>${site}/<![CDATA[${phpFeedItemWithCustomData.title}]]>${site}${phpFeedItemWithCustomData.link}/${site}${phpFeedItemWithCustomData.link}/${new Date(phpFeedItemWithCustomData.pubDate).toUTCString()}${phpFeedItemWithCustomData.customData}<![CDATA[${web1FeedItemWithContent.title}]]>${site}${web1FeedItemWithContent.link}/${site}${web1FeedItemWithContent.link}/${new Date(web1FeedItemWithContent.pubDate).toUTCString()}`; @@ -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, diff --git a/packages/astro-rss/test/test-utils.js b/packages/astro-rss/test/test-utils.js index dcc57df21f4e..d3ee8ca336c7 100644 --- a/packages/astro-rss/test/test-utils.js +++ b/packages/astro-rss/test/test-utils.js @@ -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: `

${phpFeedItem.title}

${phpFeedItem.description}

`,