From 0fa72f6328c9f5cf83c7a61fc24b45a5c5351235 Mon Sep 17 00:00:00 2001 From: Henry Orozco Date: Fri, 20 Dec 2024 13:28:13 -0600 Subject: [PATCH 1/3] feat: add playlist RSS --- package-lock.json | 16 +++--- .../library/playlist/detail.graphql | 13 +++++ src/containers/library/playlist/detail.tsx | 6 ++- src/lib/routes/playlists.ts | 1 + .../playlists/[playlist]/feed.xml/index.ts | 50 +++++++++++++++++++ 5 files changed, 78 insertions(+), 8 deletions(-) create mode 100644 src/pages/[language]/playlists/[playlist]/feed.xml/index.ts diff --git a/package-lock.json b/package-lock.json index 0920ccfef..cc17004d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4782,10 +4782,11 @@ "dev": true }, "node_modules/@graphql-tools/utils": { - "version": "10.6.2", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.6.2.tgz", - "integrity": "sha512-ABZHTpwiVR8oE2//NI/nnU3nNhbBpqMlMYyCF5cnqjLfhlyOdFfoRuhYEATEsmMfDg0ijGreULywK/SmepVGfw==", + "version": "10.6.4", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.6.4.tgz", + "integrity": "sha512-itCgjwVxbO+3uI/K73G9heedG8KelNFzgn368rUhPjTrkJX6NyLQwT5EMq/A8tvazMXyJYdtnN5nD+tT4DUpbQ==", "dev": true, + "license": "MIT", "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "cross-inspect": "1.0.1", @@ -11204,9 +11205,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001686", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001686.tgz", - "integrity": "sha512-Y7deg0Aergpa24M3qLC5xjNklnKnhsmSyR/V89dLZ1n0ucJIFNs7PgR2Yfa/Zf6W79SbBicgtGxZr2juHkEUIA==", + "version": "1.0.30001690", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz", + "integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==", "funding": [ { "type": "opencollective", @@ -11220,7 +11221,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/capital-case": { "version": "1.0.4", diff --git a/src/containers/library/playlist/detail.graphql b/src/containers/library/playlist/detail.graphql index edb154868..06964c4a9 100644 --- a/src/containers/library/playlist/detail.graphql +++ b/src/containers/library/playlist/detail.graphql @@ -39,3 +39,16 @@ query getPlaylistPageData($id: ID!) { } } } + +query getPlaylistFeedData($id: ID!) { + playlist(id: $id) { + id + title + summary + recordings(offset: 0, first: 1500) { + nodes { + ...generateFeed + } + } + } +} diff --git a/src/containers/library/playlist/detail.tsx b/src/containers/library/playlist/detail.tsx index 937594ed0..9c2063127 100644 --- a/src/containers/library/playlist/detail.tsx +++ b/src/containers/library/playlist/detail.tsx @@ -91,7 +91,11 @@ function PlaylistDetail({ playlist }: Must): JSX.Element { /> ) : ( ({ playlist: (playlistId: string | number) => node(`${r}/${playlistId}`, (r) => ({ + feed: node(`${r}/feed.xml`), items: (canonicalPath: string) => node(`${r}/items/${canonicalPath.split('/').slice(3).join('/')}`), })), diff --git a/src/pages/[language]/playlists/[playlist]/feed.xml/index.ts b/src/pages/[language]/playlists/[playlist]/feed.xml/index.ts new file mode 100644 index 000000000..3a61b2c83 --- /dev/null +++ b/src/pages/[language]/playlists/[playlist]/feed.xml/index.ts @@ -0,0 +1,50 @@ +import { GetServerSidePropsContext, GetServerSidePropsResult } from 'next'; + +import { generateFeed, sendRSSHeaders } from '~lib/generateFeed'; +import { getPlaylistFeedData } from '~src/containers/library/playlist/__generated__/detail'; +import root from '~src/lib/routes'; + +export default (): void => void 0; + +export async function getServerSideProps({ + params, + res, +}: GetServerSidePropsContext<{ language: string; playlist: string }>): Promise< + GetServerSidePropsResult> +> { + const id = params?.playlist as string; + const languageRoute = params?.language as string; + + const { playlist } = await getPlaylistFeedData({ + id, + }).catch(() => ({ + playlist: null, + })); + + if (!playlist) { + return { + notFound: true, + }; + } + + if (res) { + sendRSSHeaders(res); + + const feed = await generateFeed( + languageRoute, + { + link: root.lang(languageRoute).playlists.playlist(id).get(), + title: playlist.title, + description: playlist.summary, + }, + playlist.recordings.nodes || [], + ); + res.write(feed); + + res.end(); + } + + return { + props: {}, + }; +} From eeb268cafc246450bc5a1c2563a3866bc14f9f62 Mon Sep 17 00:00:00 2001 From: Henry Orozco Date: Fri, 20 Dec 2024 13:36:51 -0600 Subject: [PATCH 2/3] fix: audit-ci.json --- audit-ci.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/audit-ci.json b/audit-ci.json index 85efb84dd..ed5c5ea47 100644 --- a/audit-ci.json +++ b/audit-ci.json @@ -33,6 +33,8 @@ "GHSA-pxg6-pf52-xh8x|@lhci/cli>*", // Used by lighthouse CI, not at runtime "GHSA-pxg6-pf52-xh8x|@lhci/utils>*", // Used by lighthouse CI, not at runtime "GHSA-pxg6-pf52-xh8x|express>cookie", // Used by lighthouse CI, not at runtime - "GHSA-3xgq-45jj-v275" // cross-spawn is used by @next/eslint-plugin-next, audit-ci, cross-env, eslint, and jest. It is not used at runtime + "GHSA-3xgq-45jj-v275", // cross-spawn is used by @next/eslint-plugin-next, audit-ci, cross-env, eslint, and jest. It is not used at runtime + "GHSA-7gfc-8cq8-jh5f", // If your Next.js application is hosted on Vercel, this vulnerability has been automatically mitigated, regardless of Next.js version + "GHSA-mwcw-c2x4-8c55" // Not used at runtime ] } From 842a492cda9970f889480e6e40ee0d558c3445bb Mon Sep 17 00:00:00 2001 From: Henry Orozco Date: Fri, 20 Dec 2024 15:19:40 -0600 Subject: [PATCH 3/3] fix: RSS links --- src/containers/library/playlist/detail.tsx | 2 +- src/containers/sponsor/detail.tsx | 5 ++++- src/containers/sponsor/teachings.tsx | 5 ++++- src/lib/routes/sponsors.ts | 5 +++-- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/containers/library/playlist/detail.tsx b/src/containers/library/playlist/detail.tsx index 9c2063127..d53d70e2e 100644 --- a/src/containers/library/playlist/detail.tsx +++ b/src/containers/library/playlist/detail.tsx @@ -91,7 +91,7 @@ function PlaylistDetail({ playlist }: Must): JSX.Element { /> ) : ( ): JSX.Element { emailSubject={title} light triggerClassName={styles.iconButton} - rssUrl={root.lang(languageRoute).sponsors.id(id).feed.get()} + rssUrl={root + .lang(languageRoute) + .sponsors.id(id) + .teachings.feed.get()} contentType={CatalogEntityType.Sponsor} id={id} title={title} diff --git a/src/containers/sponsor/teachings.tsx b/src/containers/sponsor/teachings.tsx index c488b40e0..97c5d906b 100644 --- a/src/containers/sponsor/teachings.tsx +++ b/src/containers/sponsor/teachings.tsx @@ -37,7 +37,10 @@ function SponsorTeachings({ return ( ({ id: (sponsorId: Scalars['ID']['output']) => node(`${r}/${sponsorId}`, (r) => ({ - feed: node(`${r}/feed.xml`), - teachings: paginatedNode(`${r}/teachings`), + teachings: paginatedNode(`${r}/teachings`, (r) => ({ + feed: node(`${r}/feed.xml`), + })), conferences: paginatedNode(`${r}/conferences`), series: paginatedNode(`${r}/series`), })),