From ff968983fff055e8a4cbf08ca35c458709991d6b Mon Sep 17 00:00:00 2001 From: Berry de Vos Date: Fri, 12 May 2023 15:36:13 +0200 Subject: [PATCH] Create a generic solution for parsing links --- src/email/GenericFeed.tsx | 23 ++++++++++++++--------- src/email/daringfireball/Feed.tsx | 7 +++---- src/email/parseLinks.ts | 20 ++++++++++++++++++++ 3 files changed, 37 insertions(+), 13 deletions(-) create mode 100644 src/email/parseLinks.ts diff --git a/src/email/GenericFeed.tsx b/src/email/GenericFeed.tsx index 65b30b1..26682a8 100644 --- a/src/email/GenericFeed.tsx +++ b/src/email/GenericFeed.tsx @@ -7,6 +7,7 @@ import { Output } from 'rss-parser' import { CustomItem } from '../parseFeeds' import { formatDate } from '../utils/formatter' import Summary from './Summary' +import { parseLinks } from './parseLinks' interface Props { feed: Output @@ -21,15 +22,19 @@ export default ({ feed, hasBottomSeparator }: Props) => { {feed.title} - {feed.items.map((item) => ( - - - {item.title} - - {item.pubDate && {formatDate(item.pubDate)}} - {item.content && } - - ))} + {feed.items.map((item) => { + const href = parseLinks(item.links) + + return ( + + + {item.title} + + {item.pubDate && {formatDate(item.pubDate)}} + {item.content && } + + ) + })} {hasBottomSeparator && (

diff --git a/src/email/daringfireball/Feed.tsx b/src/email/daringfireball/Feed.tsx index 533328a..2cabbbb 100644 --- a/src/email/daringfireball/Feed.tsx +++ b/src/email/daringfireball/Feed.tsx @@ -3,15 +3,14 @@ import { Img } from '@react-email/img' import { Link } from '@react-email/link' import { Text } from '@react-email/text' import { Output } from 'rss-parser' -import { CustomItem, ItemLink } from '../../parseFeeds' +import { CustomItem } from '../../parseFeeds' import Summary from './Summary' +import { parseLinks } from '../parseLinks' interface Props { feed: Output } -const findRelatedLink = (links: ItemLink[]) => links.map(({ $: link }) => link).find(({ rel }) => rel === 'related')?.href - export default ({ feed }: Props) => { return ( @@ -19,7 +18,7 @@ export default ({ feed }: Props) => { {feed.items.map((item) => { - const href = findRelatedLink(item.links) ?? item.link + const href = parseLinks(item.links) return ( diff --git a/src/email/parseLinks.ts b/src/email/parseLinks.ts new file mode 100644 index 0000000..f64afeb --- /dev/null +++ b/src/email/parseLinks.ts @@ -0,0 +1,20 @@ +import { ItemLink } from '../parseFeeds' + +type Rel = 'alternate' | 'related' + +const hrefByRel = (links: ItemLink[], rel: Rel) => links.map(({ $: link }) => link).find((link) => link.rel === rel)?.href + +export const parseLinks = (links: ItemLink[]) => { + if (links.length === 0) { + throw new Error('Empty links array cannot be parsed') + } + + const validLinks = links.filter((link) => link.$) + + if (validLinks.length === 0) { + // The RSS parsers result is weird, when the links are just a string we can use the first without parsing + return `${links[0]}` + } + + return hrefByRel(links, 'related') ?? hrefByRel(links, 'alternate') ?? links[0].$.href +}