From 1df6a9d92de697e61715122dfd7fff182cb4deaa Mon Sep 17 00:00:00 2001 From: Cyrus Yiu Date: Sat, 16 Mar 2024 17:17:32 -0400 Subject: [PATCH] RSS feed --- .gitignore | 3 +- .prettierignore | 4 ++ content/posts/Awesome-Arcades-First-Blog.md | 2 +- package.json | 1 + .../AwesomeArcadeList/extension.tsx | 2 +- src/components/AwesomeArcadeList/list.tsx | 2 +- src/components/AwesomeArcadeList/tool.tsx | 2 +- src/components/Blog/Post/Post.tsx | 2 +- src/components/Blog/Post/Preview.tsx | 9 +-- .../extension.tsx | 6 +- .../OldAwesomeArcadeExtensionList/list.tsx | 2 +- .../OldAwesomeArcadeExtensionList/tool.tsx | 4 +- src/components/WithAppProps/appProps.ts | 16 ++++- src/pages/blog/index.tsx | 33 ++++++++++- src/pages/extensions.tsx | 4 +- src/pages/index.tsx | 9 ++- src/pages/old.tsx | 4 +- src/pages/tools.tsx | 4 +- .../{Utils => }/ParseListXML/helpers.ts | 2 +- src/scripts/{Utils => }/ParseListXML/index.ts | 0 src/scripts/{Utils => }/ParseListXML/parse.ts | 4 +- src/scripts/{Utils => }/ParseListXML/types.ts | 0 .../ParseOldExtensionsXML/index.ts | 0 .../ParseOldExtensionsXML/parse.ts | 14 ++--- src/scripts/RSS/index.ts | 58 +++++++++++++++++++ .../{Utils => }/SiteWebmanifest/index.ts | 0 .../{Utils => }/SiteWebmanifest/manifest.ts | 2 +- tina/config.ts | 7 ++- tina/tina-lock.json | 12 ++-- yarn.lock | 50 +++++++--------- 30 files changed, 182 insertions(+), 76 deletions(-) rename src/scripts/{Utils => }/ParseListXML/helpers.ts (97%) rename src/scripts/{Utils => }/ParseListXML/index.ts (100%) rename src/scripts/{Utils => }/ParseListXML/parse.ts (98%) rename src/scripts/{Utils => }/ParseListXML/types.ts (100%) rename src/scripts/{Utils => }/ParseOldExtensionsXML/index.ts (100%) rename src/scripts/{Utils => }/ParseOldExtensionsXML/parse.ts (77%) create mode 100644 src/scripts/RSS/index.ts rename src/scripts/{Utils => }/SiteWebmanifest/index.ts (100%) rename src/scripts/{Utils => }/SiteWebmanifest/manifest.ts (93%) diff --git a/.gitignore b/.gitignore index 5181727..5490eb0 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ next-env.d.ts /public/oldExtensions.json /public/extensions.json /public/tools.json +/public/rss.xml node_modules -.env \ No newline at end of file +.env diff --git a/.prettierignore b/.prettierignore index 2f1a02b..5490eb0 100644 --- a/.prettierignore +++ b/.prettierignore @@ -39,3 +39,7 @@ next-env.d.ts /public/oldExtensions.json /public/extensions.json /public/tools.json +/public/rss.xml + +node_modules +.env diff --git a/content/posts/Awesome-Arcades-First-Blog.md b/content/posts/Awesome-Arcades-First-Blog.md index 1fb0f64..ee38f9b 100644 --- a/content/posts/Awesome-Arcades-First-Blog.md +++ b/content/posts/Awesome-Arcades-First-Blog.md @@ -1,7 +1,7 @@ --- title: Awesome Arcade's First Blog! author: content/authors/UnsignedArduino.md -description: "*The last time I started a blog, I forgot about it after two posts. Hopefully, that doesn't happen this time! \U0001F92A*\n" +description: "The last time I started a blog, I forgot about it after two posts. Hopefully, that doesn't happen this time! \U0001F92A" tags: - Experiences - Tips and tricks diff --git a/package.json b/package.json index 32e58bd..11ff20e 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "bootstrap-icons": "^1.11.3", "dompurify": "^3.0.8", "fast-xml-parser": "^4.3.4", + "feed": "^4.2.2", "isomorphic-dompurify": "^2.3.0", "midifile-ts": "^1.5.1", "next": "14.1.0", diff --git a/src/components/AwesomeArcadeList/extension.tsx b/src/components/AwesomeArcadeList/extension.tsx index 126406c..f3e9225 100644 --- a/src/components/AwesomeArcadeList/extension.tsx +++ b/src/components/AwesomeArcadeList/extension.tsx @@ -1,4 +1,4 @@ -import { Extension, ExtensionRef, URLLink } from "@/scripts/Utils/ParseListXML"; +import { Extension, ExtensionRef, URLLink } from "../../scripts/ParseListXML"; import React from "react"; import "tippy.js/dist/tippy.css"; import { copyTextToClipboard } from "@/scripts/Utils/Clipboard"; diff --git a/src/components/AwesomeArcadeList/list.tsx b/src/components/AwesomeArcadeList/list.tsx index 6ad4fd3..5f0a23f 100644 --- a/src/components/AwesomeArcadeList/list.tsx +++ b/src/components/AwesomeArcadeList/list.tsx @@ -3,7 +3,7 @@ import getElement from "@/scripts/Utils/Element"; import { forceOutboundLinksToNewPage } from "@/scripts/Utils/PageUtils"; import { AwesomeArcadeExtensionGroup } from "@/components/AwesomeArcadeList/extension"; import { AwesomeArcadeToolGroup } from "@/components/AwesomeArcadeList/tool"; -import { Extension, Tool } from "@/scripts/Utils/ParseListXML"; +import { Extension, Tool } from "../../scripts/ParseListXML"; export function AwesomeArcadeExtensionsList({ list, diff --git a/src/components/AwesomeArcadeList/tool.tsx b/src/components/AwesomeArcadeList/tool.tsx index 9096da6..3eb2904 100644 --- a/src/components/AwesomeArcadeList/tool.tsx +++ b/src/components/AwesomeArcadeList/tool.tsx @@ -1,4 +1,4 @@ -import { Tool, ToolRef, URLLink } from "@/scripts/Utils/ParseListXML"; +import { Tool, ToolRef, URLLink } from "../../scripts/ParseListXML"; import React from "react"; import Link from "next/link"; import { smoothScrollHash } from "@/components/Linkable/Header"; diff --git a/src/components/Blog/Post/Post.tsx b/src/components/Blog/Post/Post.tsx index 4e68830..ad8a0b5 100644 --- a/src/components/Blog/Post/Post.tsx +++ b/src/components/Blog/Post/Post.tsx @@ -22,7 +22,7 @@ export default function BlogPost({ ) : null}

- +

{data.post.description}

diff --git a/src/components/Blog/Post/Preview.tsx b/src/components/Blog/Post/Preview.tsx index 3e139b4..3aff0b0 100644 --- a/src/components/Blog/Post/Preview.tsx +++ b/src/components/Blog/Post/Preview.tsx @@ -1,9 +1,6 @@ import { Authors } from "../../../../tina/__generated__/types"; import React from "react"; -import { - RichTextSectionRenderer, - ShortAuthorRenderer, -} from "@/components/Blog/Elements"; +import { ShortAuthorRenderer } from "@/components/Blog/Elements"; import { formatDateAndTime } from "@/scripts/Utils/DateAndTime/Format"; import Link from "next/link"; @@ -35,9 +32,7 @@ export default function BlogPostPreviewRenderer({ )} -
- -
+

{preview.description}

View post diff --git a/src/components/OldAwesomeArcadeExtensionList/extension.tsx b/src/components/OldAwesomeArcadeExtensionList/extension.tsx index 03d5403..3c94194 100644 --- a/src/components/OldAwesomeArcadeExtensionList/extension.tsx +++ b/src/components/OldAwesomeArcadeExtensionList/extension.tsx @@ -2,7 +2,7 @@ import { Extension, ExtensionRef, URLLink, -} from "@/scripts/Utils/ParseOldExtensionsXML"; +} from "../../scripts/ParseOldExtensionsXML"; import React from "react"; import "tippy.js/dist/tippy.css"; import { copyTextToClipboard } from "@/scripts/Utils/Clipboard"; @@ -109,14 +109,14 @@ export function AwesomeArcadeExtension({ setTooltip("Copied!"); } else { setTooltip( - "Failed to copy - did you give us clipboard permission?" + "Failed to copy - did you give us clipboard permission?", ); } tipRef.current.setContent(tooltip); window.document.documentElement.dispatchEvent( new CustomEvent("clickrepo", { detail: ext.repo, - }) + }), ); AnalyticEvents.sendAwesomeClick(ext.repo); }} diff --git a/src/components/OldAwesomeArcadeExtensionList/list.tsx b/src/components/OldAwesomeArcadeExtensionList/list.tsx index 6eb214c..fe6e584 100644 --- a/src/components/OldAwesomeArcadeExtensionList/list.tsx +++ b/src/components/OldAwesomeArcadeExtensionList/list.tsx @@ -1,4 +1,4 @@ -import { ExtensionList } from "@/scripts/Utils/ParseOldExtensionsXML"; +import { ExtensionList } from "../../scripts/ParseOldExtensionsXML"; import React from "react"; import getElement from "@/scripts/Utils/Element"; import { forceOutboundLinksToNewPage } from "@/scripts/Utils/PageUtils"; diff --git a/src/components/OldAwesomeArcadeExtensionList/tool.tsx b/src/components/OldAwesomeArcadeExtensionList/tool.tsx index 7839610..b714a2e 100644 --- a/src/components/OldAwesomeArcadeExtensionList/tool.tsx +++ b/src/components/OldAwesomeArcadeExtensionList/tool.tsx @@ -1,4 +1,4 @@ -import { Tool, ToolRef, URLLink } from "@/scripts/Utils/ParseOldExtensionsXML"; +import { Tool, ToolRef, URLLink } from "../../scripts/ParseOldExtensionsXML"; import React from "react"; import Link from "next/link"; import { smoothScrollHash } from "@/components/OldAwesomeArcadeExtensionList/linkableHeader"; @@ -57,7 +57,7 @@ export function AwesomeArcadeTool({ window.document.documentElement.dispatchEvent( new CustomEvent("clicktool", { detail: tool.repo, - }) + }), ); AnalyticEvents.sendAwesomeClick(tool.repo); }; diff --git a/src/components/WithAppProps/appProps.ts b/src/components/WithAppProps/appProps.ts index 6decc25..1f43296 100644 --- a/src/components/WithAppProps/appProps.ts +++ b/src/components/WithAppProps/appProps.ts @@ -1,4 +1,4 @@ -import { parseExtensionXML, parseToolXML } from "@/scripts/Utils/ParseListXML"; +import { parseExtensionXML, parseToolXML } from "../../scripts/ParseListXML"; import { promises as fs } from "fs"; import path from "path"; @@ -12,6 +12,20 @@ export function getEnvironment(): Environment { : "production"; } +export function getBaseURL(): string { + switch (getEnvironment()) { + case "production": { + return "https://awesome-arcade.vercel.app"; + } + case "preview": { + return "https://awesome-arcade-beta.vercel.app"; + } + case "development": { + return "http://localhost:3000"; + } + } +} + export function getBranch(): "main" | "staging" { return getEnvironment() === "production" ? "main" : "staging"; } diff --git a/src/pages/blog/index.tsx b/src/pages/blog/index.tsx index a043466..0d2ba1a 100644 --- a/src/pages/blog/index.tsx +++ b/src/pages/blog/index.tsx @@ -7,6 +7,8 @@ import BlogPostPreviewRenderer, { BlogPostPreview, } from "@/components/Blog/Post/Preview"; import Link from "next/link"; +import { promises as fs } from "fs"; +import generateRSSFeed from "@/scripts/RSS"; type BlogProps = { blogPostPreviews: BlogPostPreview[]; @@ -31,7 +33,31 @@ export default function BlogPage(props: BlogProps) { MakeCode Arcade.

- Find all blog posts here. + I hope you find these posts useful and interesting. If you have any + questions, suggestions, or feedback, feel free to reach out to me on{" "} + + GitHub Discussions + {" "} + or the{" "} + + MakeCode forums + + . +

+

+ You can also subscribe to this blog with a{" "} + + RSS feed reader + + !

Latest blog posts

{ @@ -43,6 +69,9 @@ export default function BlogPage(props: BlogProps) { })} } +

+ View all here. +

); } @@ -78,6 +107,8 @@ export async function getStaticProps(): Promise<{ return new Date(b.postedDate).getTime() - new Date(a.postedDate).getTime(); }); + await fs.writeFile("./public/rss.xml", await generateRSSFeed(previews)); + previews.splice(5); return { diff --git a/src/pages/extensions.tsx b/src/pages/extensions.tsx index 6d4a1d6..e3059ab 100644 --- a/src/pages/extensions.tsx +++ b/src/pages/extensions.tsx @@ -9,10 +9,10 @@ import { AwesomeArcadeExtensionsList } from "@/components/AwesomeArcadeList"; import { debounce } from "@/scripts/Utils/Timers"; import { AnalyticEvents } from "@/components/Analytics"; import { useSession } from "next-auth/react"; -import { Extension, parseExtensionXML } from "@/scripts/Utils/ParseListXML"; +import { Extension, parseExtensionXML } from "../scripts/ParseListXML"; import { useFeatureIsOn } from "@growthbook/growthbook-react"; import Tippy from "@tippyjs/react"; -import { stringToBool } from "@/scripts/Utils/ParseListXML/helpers"; +import { stringToBool } from "@/scripts/ParseListXML/helpers"; const pageName = "Extensions"; diff --git a/src/pages/index.tsx b/src/pages/index.tsx index b9bd979..85528f4 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -2,7 +2,7 @@ import React from "react"; import { promises as fs } from "fs"; import Layout from "../components/Layout"; import getAppProps, { AppProps } from "../components/WithAppProps"; -import generateSiteWebmanifest from "../scripts/Utils/SiteWebmanifest/manifest"; +import generateSiteWebmanifest from "@/scripts/SiteWebmanifest/manifest"; import Link from "next/link"; import { useSession } from "next-auth/react"; import { useFeatureIsOn } from "@growthbook/growthbook-react"; @@ -31,6 +31,13 @@ export function Home({ appProps }: HomeProps): JSX.Element { link: "/tools", linkText: "View awesome tools", }, + { + name: "Blog", + description: + "Read about the latest news and updates in the MakeCode Arcade world!", + link: "/blog", + linkText: "Read the blog", + }, ]; return ( diff --git a/src/pages/old.tsx b/src/pages/old.tsx index 1c2ee9d..9b0f9b9 100644 --- a/src/pages/old.tsx +++ b/src/pages/old.tsx @@ -2,9 +2,7 @@ import React from "react"; import Layout from "../components/Layout"; import getAppProps, { AppProps } from "@/components/WithAppProps"; import AwesomeArcadeExtensionList from "@/components/OldAwesomeArcadeExtensionList/list"; -import parseListXML, { - ExtensionList, -} from "../scripts/Utils/ParseOldExtensionsXML"; +import parseListXML, { ExtensionList } from "../scripts/ParseOldExtensionsXML"; import { smoothScrollToID } from "@/components/OldAwesomeArcadeExtensionList/linkableHeader"; import { debounce } from "@/scripts/Utils/Timers"; import { AnalyticEvents } from "@/components/Analytics"; diff --git a/src/pages/tools.tsx b/src/pages/tools.tsx index 4e18a4b..bb802a3 100644 --- a/src/pages/tools.tsx +++ b/src/pages/tools.tsx @@ -10,9 +10,9 @@ import { debounce } from "@/scripts/Utils/Timers"; import { AnalyticEvents } from "@/components/Analytics"; import Tippy from "@tippyjs/react"; import { useSession } from "next-auth/react"; -import { parseToolXML, Tool } from "@/scripts/Utils/ParseListXML"; +import { parseToolXML, Tool } from "../scripts/ParseListXML"; import { useFeatureIsOn } from "@growthbook/growthbook-react"; -import { stringToBool } from "@/scripts/Utils/ParseListXML/helpers"; +import { stringToBool } from "@/scripts/ParseListXML/helpers"; const pageName = "Tools"; diff --git a/src/scripts/Utils/ParseListXML/helpers.ts b/src/scripts/ParseListXML/helpers.ts similarity index 97% rename from src/scripts/Utils/ParseListXML/helpers.ts rename to src/scripts/ParseListXML/helpers.ts index 2db2a26..eae8510 100644 --- a/src/scripts/Utils/ParseListXML/helpers.ts +++ b/src/scripts/ParseListXML/helpers.ts @@ -27,7 +27,7 @@ export function findElementInElement(element: any, elementName: string): any { export function findElementWithAttributeValue( elements: any[], attributeName: string, - attributeValue: string + attributeValue: string, ): any { for (const element of elements) { const attributes = element[":@"]; diff --git a/src/scripts/Utils/ParseListXML/index.ts b/src/scripts/ParseListXML/index.ts similarity index 100% rename from src/scripts/Utils/ParseListXML/index.ts rename to src/scripts/ParseListXML/index.ts diff --git a/src/scripts/Utils/ParseListXML/parse.ts b/src/scripts/ParseListXML/parse.ts similarity index 98% rename from src/scripts/Utils/ParseListXML/parse.ts rename to src/scripts/ParseListXML/parse.ts index 6a7bed5..df48aa8 100644 --- a/src/scripts/Utils/ParseListXML/parse.ts +++ b/src/scripts/ParseListXML/parse.ts @@ -6,12 +6,12 @@ import { Tool, ToolRef, URLLink, -} from "@/scripts/Utils/ParseListXML/types"; +} from "@/scripts/ParseListXML/types"; import { findElementInElement, findElementWithAttributeValue, stringToBool, -} from "@/scripts/Utils/ParseListXML/helpers"; +} from "@/scripts/ParseListXML/helpers"; export function gatherExtensionRefList(exts: any[]): ExtensionRef[] { const newExtsRef = []; diff --git a/src/scripts/Utils/ParseListXML/types.ts b/src/scripts/ParseListXML/types.ts similarity index 100% rename from src/scripts/Utils/ParseListXML/types.ts rename to src/scripts/ParseListXML/types.ts diff --git a/src/scripts/Utils/ParseOldExtensionsXML/index.ts b/src/scripts/ParseOldExtensionsXML/index.ts similarity index 100% rename from src/scripts/Utils/ParseOldExtensionsXML/index.ts rename to src/scripts/ParseOldExtensionsXML/index.ts diff --git a/src/scripts/Utils/ParseOldExtensionsXML/parse.ts b/src/scripts/ParseOldExtensionsXML/parse.ts similarity index 77% rename from src/scripts/Utils/ParseOldExtensionsXML/parse.ts rename to src/scripts/ParseOldExtensionsXML/parse.ts index af92fc0..be5baa4 100644 --- a/src/scripts/Utils/ParseOldExtensionsXML/parse.ts +++ b/src/scripts/ParseOldExtensionsXML/parse.ts @@ -1,10 +1,10 @@ import { XMLParser } from "fast-xml-parser"; -import { Extension, Tool } from "@/scripts/Utils/ParseListXML"; +import { Extension, Tool } from "@/scripts/ParseListXML"; import { gatherExtensionList, gatherToolList, -} from "@/scripts/Utils/ParseListXML/parse"; -import { findElementWithAttributeValue } from "@/scripts/Utils/ParseListXML/helpers"; +} from "@/scripts/ParseListXML/parse"; +import { findElementWithAttributeValue } from "@/scripts/ParseListXML/helpers"; export type ExtensionList = { builtIn: Extension[]; @@ -13,7 +13,7 @@ export type ExtensionList = { }; export default async function parseListXML( - xml: string + xml: string, ): Promise { const parser = new XMLParser({ preserveOrder: true, @@ -26,17 +26,17 @@ export default async function parseListXML( const builtIn = findElementWithAttributeValue( allExtensions, "label", - "Built in" + "Built in", ).extensionList; const notBuiltIn = findElementWithAttributeValue( allExtensions, "label", - "Not built in" + "Not built in", ).extensionList; const tools = findElementWithAttributeValue( allExtensions, "label", - "Tools" + "Tools", ).toolList; return { diff --git a/src/scripts/RSS/index.ts b/src/scripts/RSS/index.ts new file mode 100644 index 0000000..d987b67 --- /dev/null +++ b/src/scripts/RSS/index.ts @@ -0,0 +1,58 @@ +import { Feed } from "feed"; +import { getBaseURL, getEnvironment } from "@/components/WithAppProps/appProps"; +import { BlogPostPreview } from "@/components/Blog/Post/Preview"; + +export default async function generateRSSFeed( + posts: BlogPostPreview[], +): Promise { + const siteURL = getBaseURL(); + const name = `Awesome Arcade${(() => { + switch (getEnvironment()) { + case "development": { + return " Development"; + } + case "preview": { + return " Beta"; + } + default: + case "production": { + return ""; + } + } + })()}`; + + let description = "All of Awesome Arcade's blog posts!"; + + if (getEnvironment() === "development") { + description += ` This is the development server's RSS feed. (You probably want to subscribe to the production server's feed which you can find at https://awesome-arcade.vercel.app)`; + } else if (getEnvironment() === "preview") { + description += ` This is the beta server's RSS feed! (You probably want to subscribe to the production server's feed which you can find at https://awesome-arcade.vercel.app)`; + } + + const feed = new Feed({ + title: `${name} Blog`, + description, + id: siteURL, + link: siteURL, + language: "en", + image: `${siteURL}/android-chrome-512x512.png`, + favicon: `${siteURL}/favicon.ico`, + copyright: "© 2024 UnsignedArduino. All rights reserved.", + generator: name, + feedLinks: { + rss2: `${siteURL}/rss.xml`, + }, + }); + + for (const post of posts) { + feed.addItem({ + title: post.title, + id: `${siteURL}${post.link}`, + link: `${siteURL}${post.link}`, + description: post.description, + date: new Date(post.postedDate ?? 0), + }); + } + + return feed.rss2(); +} diff --git a/src/scripts/Utils/SiteWebmanifest/index.ts b/src/scripts/SiteWebmanifest/index.ts similarity index 100% rename from src/scripts/Utils/SiteWebmanifest/index.ts rename to src/scripts/SiteWebmanifest/index.ts diff --git a/src/scripts/Utils/SiteWebmanifest/manifest.ts b/src/scripts/SiteWebmanifest/manifest.ts similarity index 93% rename from src/scripts/Utils/SiteWebmanifest/manifest.ts rename to src/scripts/SiteWebmanifest/manifest.ts index 2c8c508..3a875e8 100644 --- a/src/scripts/Utils/SiteWebmanifest/manifest.ts +++ b/src/scripts/SiteWebmanifest/manifest.ts @@ -1,4 +1,4 @@ -import { getEnvironment } from "../../../components/WithAppProps"; +import { getEnvironment } from "../../components/WithAppProps"; export default async function generateSiteWebmanifest(): Promise { const json = JSON.parse(`{ diff --git a/tina/config.ts b/tina/config.ts index 71eaaab..297aba1 100644 --- a/tina/config.ts +++ b/tina/config.ts @@ -76,9 +76,12 @@ export default defineConfig({ required: true, }, { - type: "rich-text", - name: "description", label: "Description", + name: "description", + type: "string", + ui: { + component: "textarea", + }, }, { type: "string", diff --git a/tina/tina-lock.json b/tina/tina-lock.json index 19c6416..18845a9 100644 --- a/tina/tina-lock.json +++ b/tina/tina-lock.json @@ -80,12 +80,12 @@ "uid": false }, { - "type": "rich-text", - "name": "description", "label": "Description", + "name": "description", + "type": "string", + "ui": { "component": "textarea" }, "namespace": ["post", "description"], "searchable": true, - "parser": { "type": "markdown" }, "uid": false }, { @@ -1396,7 +1396,7 @@ "arguments": [], "type": { "kind": "NamedType", - "name": { "kind": "Name", "value": "JSON" } + "name": { "kind": "Name", "value": "String" } } }, { @@ -1555,7 +1555,7 @@ "name": { "kind": "Name", "value": "description" }, "type": { "kind": "NamedType", - "name": { "kind": "Name", "value": "RichTextFilter" } + "name": { "kind": "Name", "value": "StringFilter" } } }, { @@ -2089,7 +2089,7 @@ "name": { "kind": "Name", "value": "description" }, "type": { "kind": "NamedType", - "name": { "kind": "Name", "value": "JSON" } + "name": { "kind": "Name", "value": "String" } } }, { diff --git a/yarn.lock b/yarn.lock index 0d11e3a..7d62c4f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4834,6 +4834,13 @@ fbjs@^3.0.0: setimmediate "^1.0.5" ua-parser-js "^1.0.35" +feed@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/feed/-/feed-4.2.2.tgz#865783ef6ed12579e2c44bbef3c9113bc4956a7e" + integrity sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ== + dependencies: + xml-js "^1.6.11" + fergies-inverted-index@12.0.0: version "12.0.0" resolved "https://registry.yarnpkg.com/fergies-inverted-index/-/fergies-inverted-index-12.0.0.tgz#105101f303454e7e12b1044743780d086392c50e" @@ -9438,6 +9445,11 @@ sass@^1.70.0: immutable "^4.0.0" source-map-js ">=0.6.2 <2.0.0" +sax@^1.2.4: + version "1.3.0" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.3.0.tgz#a5dbe77db3be05c9d1ee7785dbd3ea9de51593d0" + integrity sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA== + saxes@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/saxes/-/saxes-6.0.0.tgz#fe5b4a4768df4f14a201b1ba6a65c1f3d9988cc5" @@ -9827,16 +9839,7 @@ string-argv@0.3.2: resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6" integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q== -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -9927,14 +9930,7 @@ stringify-entities@4.0.3, stringify-entities@^4.0.0: character-entities-html4 "^2.0.0" character-entities-legacy "^3.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -11004,7 +11000,7 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -11022,15 +11018,6 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" @@ -11064,6 +11051,13 @@ ws@^8.16.0: resolved "https://registry.yarnpkg.com/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4" integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ== +xml-js@^1.6.11: + version "1.6.11" + resolved "https://registry.yarnpkg.com/xml-js/-/xml-js-1.6.11.tgz#927d2f6947f7f1c19a316dd8eea3614e8b18f8e9" + integrity sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g== + dependencies: + sax "^1.2.4" + xml-name-validator@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-5.0.0.tgz#82be9b957f7afdacf961e5980f1bf227c0bf7673"