0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-02-17 22:44:24 -05:00

fix(rss): apply refinement at the point of parsing (#9797)

This commit is contained in:
William Killerud 2024-01-24 06:37:06 +01:00 committed by GitHub
parent c1e02688e7
commit 457e8b6422
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 47 additions and 29 deletions

View file

@ -0,0 +1,5 @@
---
"@astrojs/rss": patch
---
Restores `rssSchema` to a zod object

View file

@ -137,7 +137,12 @@ export function pagesGlobToRssItems(items: GlobResult): Promise<ValidatedRSSFeed
`[RSS] You can only glob entries within 'src/pages/' when passing import.meta.glob() directly. Consider mapping the result to an array of RSSFeedItems. See the RSS docs for usage examples: https://docs.astro.build/en/guides/rss/#2-list-of-rss-feed-objects` `[RSS] You can only glob entries within 'src/pages/' when passing import.meta.glob() directly. Consider mapping the result to an array of RSSFeedItems. See the RSS docs for usage examples: https://docs.astro.build/en/guides/rss/#2-list-of-rss-feed-objects`
); );
} }
const parsedResult = rssSchema.safeParse({ ...frontmatter, link: url }, { errorMap }); const parsedResult = rssSchema
.refine((val) => val.title || val.description, {
message: 'At least title or description must be provided.',
path: ['title', 'description'],
})
.safeParse({ ...frontmatter, link: url }, { errorMap });
if (parsedResult.success) { if (parsedResult.success) {
return parsedResult.data; return parsedResult.data;

View file

@ -1,30 +1,25 @@
import { z } from 'astro/zod'; import { z } from 'astro/zod';
export const rssSchema = z export const rssSchema = z.object({
.object({ title: z.string().optional(),
title: z.string().optional(), description: z.string().optional(),
description: z.string().optional(), pubDate: z
pubDate: z .union([z.string(), z.number(), z.date()])
.union([z.string(), z.number(), z.date()]) .optional()
.optional() .transform((value) => (value === undefined ? value : new Date(value)))
.transform((value) => (value === undefined ? value : new Date(value))) .refine((value) => (value === undefined ? value : !isNaN(value.getTime()))),
.refine((value) => (value === undefined ? value : !isNaN(value.getTime()))), customData: z.string().optional(),
customData: z.string().optional(), categories: z.array(z.string()).optional(),
categories: z.array(z.string()).optional(), author: z.string().optional(),
author: z.string().optional(), commentsUrl: z.string().optional(),
commentsUrl: z.string().optional(), source: z.object({ url: z.string().url(), title: z.string() }).optional(),
source: z.object({ url: z.string().url(), title: z.string() }).optional(), enclosure: z
enclosure: z .object({
.object({ url: z.string(),
url: z.string(), length: z.number().positive().int().finite(),
length: z.number().positive().int().finite(), type: z.string(),
type: z.string(), })
}) .optional(),
.optional(), link: z.string().optional(),
link: z.string().optional(), content: z.string().optional(),
content: z.string().optional(), });
})
.refine((val) => val.title || val.description, {
message: 'At least title or description must be provided.',
path: ['title', 'description'],
});

View file

@ -1,6 +1,7 @@
import chai from 'chai'; import chai from 'chai';
import chaiPromises from 'chai-as-promised'; import chaiPromises from 'chai-as-promised';
import chaiXml from 'chai-xml'; import chaiXml from 'chai-xml';
import { z } from 'astro/zod';
import rss, { getRssString } from '../dist/index.js'; import rss, { getRssString } from '../dist/index.js';
import { rssSchema } from '../dist/schema.js'; import { rssSchema } from '../dist/schema.js';
import { import {
@ -214,4 +215,16 @@ describe('getRssString', () => {
chai.expect(res.success).to.be.false; chai.expect(res.success).to.be.false;
chai.expect(res.error.issues[0].path[0]).to.equal('pubDate'); chai.expect(res.error.issues[0].path[0]).to.equal('pubDate');
}); });
it('should be extendable', () => {
let error = null;
try {
rssSchema.extend({
category: z.string().optional(),
});
} catch (e) {
error = e.message;
}
chai.expect(error).to.be.null;
});
}); });