From 70e31cf20cadedc244d35da58aa5291465e504af Mon Sep 17 00:00:00 2001 From: Kalidou Diagne Date: Wed, 14 Feb 2024 13:43:35 +0000 Subject: [PATCH] recent updates section --- app/[lang]/page.tsx | 5 +- app/api/news/route.ts | 14 + app/i18n/locales/en/news-section.json | 29 +- app/i18n/locales/es/news-section.json | 31 +- app/i18n/locales/it/news-section.json | 11 + app/i18n/locales/zh-TW/news-section.json | 31 +- common/discord.js | 34 ++ components/icons.tsx | 8 +- components/sections/News.tsx | 105 ---- components/sections/NewsSection.tsx | 120 +++++ config/site.ts | 2 + lib/types.ts | 16 +- lib/utils.ts | 13 + package-lock.json | 594 ++++++++++++++++++++++- package.json | 8 +- tailwind.config.js | 2 + tsconfig.json | 2 +- 17 files changed, 822 insertions(+), 203 deletions(-) create mode 100644 app/api/news/route.ts create mode 100644 app/i18n/locales/it/news-section.json create mode 100644 common/discord.js delete mode 100644 components/sections/News.tsx create mode 100644 components/sections/NewsSection.tsx diff --git a/app/[lang]/page.tsx b/app/[lang]/page.tsx index 7e2943f..a3c7627 100644 --- a/app/[lang]/page.tsx +++ b/app/[lang]/page.tsx @@ -9,11 +9,10 @@ import { siteConfig } from "@/config/site" import { AppContent } from "@/components/ui/app-content" import { Button } from "@/components/ui/button" import { Icons } from "@/components/icons" -import { News } from "@/components/sections/News" +import { NewsSection } from "@/components/sections/NewsSection" import { WhatWeDo } from "@/components/sections/WhatWeDo" import { useTranslation } from "../i18n/client" -import { LocaleTypes } from "../i18n/settings" export default function IndexPage({ params: { lang } }: any) { const { t } = useTranslation(lang, "homepage") @@ -53,7 +52,7 @@ export default function IndexPage({ params: { lang } }: any) { - +
diff --git a/app/api/news/route.ts b/app/api/news/route.ts new file mode 100644 index 0000000..8731d42 --- /dev/null +++ b/app/api/news/route.ts @@ -0,0 +1,14 @@ +import { NextResponse } from "next/server" +import { getAnnouncementChannelMessages } from "@/common/discord" + +export async function GET(request: Request) { + try { + const announcements = await getAnnouncementChannelMessages() + return NextResponse.json( + { announcements: announcements ?? [] }, + { status: 200 } + ) + } catch (error) { + return NextResponse.json({ error }, { status: 500 }) + } +} diff --git a/app/i18n/locales/en/news-section.json b/app/i18n/locales/en/news-section.json index 36df713..b8340cb 100644 --- a/app/i18n/locales/en/news-section.json +++ b/app/i18n/locales/en/news-section.json @@ -5,30 +5,7 @@ "watch": "Watch", "read": "Read", "attend": "Attend", - "news": [ - { - "type": "post", - "title": "Learnings from the KZG Ceremony", - "action": { - "label": "Read", - "url": "https://mirror.xyz/privacy-scaling-explorations.eth/naTdx-u7kyirczTLSAnWwH6ZdedfTQu1yCWQj1m_n-E" - } - }, - { - "type": "learn", - "title": "Public events hosted by PSE members to learn about each other's projects, share ideas, and get feedback.", - "action": { - "label": "See full schedule", - "url": "https://pse-team.notion.site/50dcf22c5191485e93406a902ae9e93b?v=453023f8227646dd949abc34a7a4a138&pvs=4" - } - }, - { - "type": "learn", - "title": "Folding Circom Circuit: A ZKML Case Study by Dr. Cathie So", - "action": { - "label": "Watch", - "url": "https://www.youtube.com/live/jb6HDEtY4CI" - } - } - ] + "recentUpdates": "Recent Updates", + "seeAllUpdates": "See all updates", + "reportOnSocial": "Report on {{socialName}}" } \ No newline at end of file diff --git a/app/i18n/locales/es/news-section.json b/app/i18n/locales/es/news-section.json index 36d490c..77a99e0 100644 --- a/app/i18n/locales/es/news-section.json +++ b/app/i18n/locales/es/news-section.json @@ -5,30 +5,7 @@ "watch": "Ver", "read": "Leer", "attend": "Asistir", - "news": [ - { - "type": "post", - "title": "Lecciones de la Ceremonia KZG", - "action": { - "label": "Leer", - "url": "https://mirror.xyz/privacy-scaling-explorations.eth/naTdx-u7kyirczTLSAnWwH6ZdedfTQu1yCWQj1m_n-E" - } - }, - { - "type": "aprendizaje", - "title": "Eventos públicos organizados por miembros de PSE para aprender sobre los proyectos de los demás, compartir ideas y obtener retroalimentación.", - "action": { - "label": "Ver calendario completo", - "url": "https://pse-team.notion.site/50dcf22c5191485e93406a902ae9e93b?v=453023f8227646dd949abc34a7a4a138&pvs=4" - } - }, - { - "type": "aprendizaje", - "title": "Circuito Circom Plegado: Un Estudio de Caso de ZKML por la Dra. Cathie So", - "action": { - "label": "Ver", - "url": "https://www.youtube.com/live/jb6HDEtY4CI" - } - } - ] -} + "recentUpdates": "Recent Updates", + "seeAllUpdates": "See all updates", + "reportOnSocial": "Report on {{socialName}}" +} \ No newline at end of file diff --git a/app/i18n/locales/it/news-section.json b/app/i18n/locales/it/news-section.json new file mode 100644 index 0000000..4d7ead1 --- /dev/null +++ b/app/i18n/locales/it/news-section.json @@ -0,0 +1,11 @@ +{ + "learnAndShare": "Impara & condividi", + "event": "Eventi", + "blogPost": "Blog", + "watch": "Guarda", + "read": "Leggi", + "attend": "Partecipa", + "recentUpdates": "Aggiornamenti recenti", + "seeAllUpdates": "Ultimi aggiornamenti", + "reportOnSocial": "Condividi su {x}" +} \ No newline at end of file diff --git a/app/i18n/locales/zh-TW/news-section.json b/app/i18n/locales/zh-TW/news-section.json index 9e56c00..3cf532c 100644 --- a/app/i18n/locales/zh-TW/news-section.json +++ b/app/i18n/locales/zh-TW/news-section.json @@ -5,30 +5,7 @@ "watch": "觀看", "read": "閱讀", "attend": "參加", - "news": [ - { - "type": "post", - "title": "KZG 儀式的經驗與挑戰", - "action": { - "label": "閱讀", - "url": "https://mirror.xyz/privacy-scaling-explorations.eth/naTdx-u7kyirczTLSAnWwH6ZdedfTQu1yCWQj1m_n-E" - } - }, - { - "type": "learn", - "title": "由 PSE 成員主持的公開活動,旨在了解彼此的專案,分享想法並獲得回饋。", - "action": { - "label": "查看完整時間表", - "url": "https://pse-team.notion.site/50dcf22c5191485e93406a902ae9e93b?v=453023f8227646dd949abc34a7a4a138&pvs=4" - } - }, - { - "type": "learn", - "title": "Folding 的 Circom 電路:由 Cathie So 博士分享的 ZKML 案例研究", - "action": { - "label": "觀看", - "url": "https://www.youtube.com/live/jb6HDEtY4CI" - } - } - ] -} + "recentUpdates": "Recent Updates", + "seeAllUpdates": "See all updates", + "reportOnSocial": "Report on {{socialName}}" +} \ No newline at end of file diff --git a/common/discord.js b/common/discord.js new file mode 100644 index 0000000..ca530ac --- /dev/null +++ b/common/discord.js @@ -0,0 +1,34 @@ +const { Client, Routes } = require("discord.js") +const { config } = require("dotenv") +const { REST } = require("@discordjs/rest") + +config() + +const TOKEN = process.env.DISCORD_TOKEN +const MESSAGES_LIMIT = 1 // Number of messages to retrieve from the discord channel +const GUILD_ID = process.env.DISCORD_GUILD_ID + +const client = new Client({ + intents: ["Guilds", "GuildMessages", "MessageContent"], +}) + +const rest = new REST({ version: "10" }).setToken(TOKEN) + + + +export const getAnnouncementChannelMessages = async () => { + console.log("Retrieve announcements from discord channel...") + const MESSAGES_URL = `${Routes.channelMessages(GUILD_ID)}?limit=${MESSAGES_LIMIT}` + // If operating on a guild channel, this endpoint requires the current user to have the VIEW_CHANNEL permission + const messages = await rest.get(MESSAGES_URL) + return messages +} + +const runDiscordBot = () => { + client.login(TOKEN) + client.on("ready", async () => { + await getAnnouncementChannelMessages() + }) +} + +runDiscordBot() diff --git a/components/icons.tsx b/components/icons.tsx index 3556b94..3645d3b 100644 --- a/components/icons.tsx +++ b/components/icons.tsx @@ -16,8 +16,8 @@ export const Icons = { twitter: (props: LucideProps) => ( ( { - const { t } = useTranslation(lang, "news-section") - - const newsTypes = { - learn: { - type: t("learnAndShare"), - icon: PSELearnIcon, - defaultActionLabel: t("watch"), - }, - event: { - type: "Event", - icon: PSEEventIcon, - defaultActionLabel: t("attend"), - }, - post: { - type: t("blogPost"), - icon: PSEPostIcon, - defaultActionLabel: t("read"), - }, - } - - const newsItems: any[] = t("news", { - returnObjects: true, - }) - - return ( -
    - {newsItems.map((item: NewsInterface, index) => { - const newsType = - newsTypes[item.type as keyof NewsType] ?? newsTypes["learn"] - - return ( - - -
  • -
    -
    - -

    - {newsType?.["type"]} -

    -
    -

    -

    - {item.title} -

    -
    - - - {item.action.label || newsType?.["defaultActionLabel"]} - - - -
  • -
    -
    - ) - })} -
- ) -} diff --git a/components/sections/NewsSection.tsx b/components/sections/NewsSection.tsx new file mode 100644 index 0000000..37f7911 --- /dev/null +++ b/components/sections/NewsSection.tsx @@ -0,0 +1,120 @@ +import { useEffect, useState } from "react" +import Link from "next/link" + +import { siteConfig } from "@/config/site" +import { AnnounceInterface } from "@/lib/types" +import { convertDirtyStringToHtml } from "@/lib/utils" +import { useTranslation } from "@/app/i18n/client" +import { LocaleTypes } from "@/app/i18n/settings" + +import { Icons } from "../icons" +import { AppContent } from "../ui/app-content" + +const HtmlToReactParser = require("html-to-react").Parser + +interface NewsSectionProps { + lang: LocaleTypes +} + +const ContentPlaceholder = () => ( +
+
+
+
+
+
+
+
+) + +export const NewsSection = ({ lang }: NewsSectionProps) => { + const { t } = useTranslation(lang, "news-section") + + const [newsItems, setNewsItems] = useState([]) + const [loading, setLoading] = useState(true) + + useEffect(() => { + const getDiscordAnnouncements = async () => { + setLoading(true) + await fetch("/api/news") + .then((res) => res.json()) + .then(({ announcements }: { announcements: AnnounceInterface[] }) => { + setNewsItems(announcements ?? []) + }) + .finally(() => setLoading(false)) + } + + getDiscordAnnouncements() + }, []) + + const [news] = newsItems ?? [] + + const htmlToReactParser = new HtmlToReactParser() + const announcementContent = htmlToReactParser.parse( + convertDirtyStringToHtml(news?.content) + ) + + const twitterShareUrl = `https://twitter.com/intent/tweet?text=${encodeURIComponent( + news?.content + )}&url=${encodeURIComponent(siteConfig?.links?.discordAnnouncementChannel)}` + + return ( +
+
+

+ {t("recentUpdates")} +

+ +
+
+ {!loading ? ( + news?.timestamp && ( + + {new Intl.DateTimeFormat(lang, { + month: "long", + day: "numeric", + year: "numeric", + }).format(new Date(news?.timestamp))} + + ) + ) : ( +
+ )} + + + + {t("reportOnSocial", { + socialName: "X", + })} + + +
+ + {!loading ? announcementContent : } + +
+ + + {t("seeAllUpdates")} + + +
+
+
+ ) +} + +NewsSection.displayName = "NewsSection" diff --git a/config/site.ts b/config/site.ts index 3720739..f7ff5a3 100644 --- a/config/site.ts +++ b/config/site.ts @@ -16,6 +16,8 @@ export const siteConfig = { jobs: "https://jobs.lever.co/ethereumfoundation/?department=Ethereum%20Foundation&team=Privacy%20and%20Scaling%20Explorations", termOfUse: "https://ethereum.org/en/terms-of-use/", privacyPolicy: "https://ethereum.org/en/privacy-policy/", + discordAnnouncementChannel: + "https://discord.com/channels/943612659163602974/969614451089227876", }, addGithubResource: "https://github.com/privacy-scaling-explorations/website-v2/blob/main/app/%5Blang%5D/content/resources.md", diff --git a/lib/types.ts b/lib/types.ts index 9069ab5..f7f5531 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -1,5 +1,17 @@ -import { type } from "os" - +export interface AnnounceInterface { + id: number + type?: number + content: string + attachments?: string[] + timestamp: string + embeds?: { + type: "link" | "article" + url: string + title: string + description: string + color: number + }[] +} export interface NewsInterface { type: string title: string diff --git a/lib/utils.ts b/lib/utils.ts index f077360..098986e 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -27,3 +27,16 @@ export function queryStringToObject( export function shuffleArray(array: T[]) { return array.sort(() => 0.5 - Math.random()) } + +export function convertDirtyStringToHtml(string: string) { + const urlPattern = + /\b(?:https?|ftp):\/\/[a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|]/gim + const pseudoUrlPattern = /(^|[^\/])(www\.[\S]+(\b|$))/gim + + if (!string) return "" + return string + .replace(/\n/g, "
") + .replace(urlPattern, '$&') + .replace(pseudoUrlPattern, '$1$2') + .toLowerCase() +} diff --git a/package-lock.json b/package-lock.json index 9552c1c..4d07497 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "next-template", "version": "0.0.2", "dependencies": { + "@discordjs/rest": "^2.0.1", "@next/mdx": "^13.5.0", "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-checkbox": "^1.0.4", @@ -17,15 +18,19 @@ "accept-language": "^3.0.18", "class-variance-authority": "^0.4.0", "clsx": "^1.2.1", + "discord.js": "14.4.0", + "dotenv": "^16.4.4", "framer-motion": "^10.12.17", "fuse.js": "^6.6.2", "gsap": "^3.12.1", + "html-to-react": "^1.7.0", "i18next": "^23.7.16", "i18next-browser-languagedetector": "^7.2.0", "i18next-resources-to-backend": "^1.2.0", "lucide-react": "0.105.0-alpha.4", "next": "^13.4.10", "next-themes": "^0.2.1", + "nodemon": "^3.0.3", "react": "^18.2.0", "react-cookie": "^7.0.1", "react-dom": "^18.2.0", @@ -395,6 +400,85 @@ "node": ">=6.9.0" } }, + "node_modules/@discordjs/builders": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.7.0.tgz", + "integrity": "sha512-GDtbKMkg433cOZur8Dv6c25EHxduNIBsxeHrsRoIM8+AwmEZ8r0tEpckx/sHwTLwQPOF3e2JWloZh9ofCaMfAw==", + "dependencies": { + "@discordjs/formatters": "^0.3.3", + "@discordjs/util": "^1.0.2", + "@sapphire/shapeshift": "^3.9.3", + "discord-api-types": "0.37.61", + "fast-deep-equal": "^3.1.3", + "ts-mixer": "^6.0.3", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.11.0" + } + }, + "node_modules/@discordjs/formatters": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.3.tgz", + "integrity": "sha512-wTcI1Q5cps1eSGhl6+6AzzZkBBlVrBdc9IUhJbijRgVjCNIIIZPgqnUj3ntFODsHrdbGU8BEG9XmDQmgEEYn3w==", + "dependencies": { + "discord-api-types": "0.37.61" + }, + "engines": { + "node": ">=16.11.0" + } + }, + "node_modules/@discordjs/rest": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.0.1.tgz", + "integrity": "sha512-/eWAdDRvwX/rIE2tuQUmKaxmWeHmGealttIzGzlYfI4+a7y9b6ZoMp8BG/jaohs8D8iEnCNYaZiOFLVFLQb8Zg==", + "dependencies": { + "@discordjs/collection": "^1.5.3", + "@discordjs/util": "^1.0.1", + "@sapphire/async-queue": "^1.5.0", + "@sapphire/snowflake": "^3.5.1", + "@vladfrangu/async_event_emitter": "^2.2.2", + "discord-api-types": "0.37.50", + "magic-bytes.js": "^1.0.15", + "tslib": "^2.6.1", + "undici": "5.22.1" + }, + "engines": { + "node": ">=16.11.0" + } + }, + "node_modules/@discordjs/rest/node_modules/@discordjs/collection": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz", + "integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==", + "engines": { + "node": ">=16.11.0" + } + }, + "node_modules/@discordjs/rest/node_modules/discord-api-types": { + "version": "0.37.50", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.50.tgz", + "integrity": "sha512-X4CDiMnDbA3s3RaUXWXmgAIbY1uxab3fqe3qwzg5XutR3wjqi7M3IkgQbsIBzpqBN2YWr/Qdv7JrFRqSgb4TFg==" + }, + "node_modules/@discordjs/rest/node_modules/undici": { + "version": "5.22.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.22.1.tgz", + "integrity": "sha512-Ji2IJhFXZY0x/0tVBXeQwgPlLWw13GVzpsWPQ3rV50IFMMof2I55PZZxtm4P6iNq+L5znYN9nSTAq0ZyE6lSJw==", + "dependencies": { + "busboy": "^1.6.0" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/@discordjs/util": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.0.2.tgz", + "integrity": "sha512-IRNbimrmfb75GMNEjyznqM1tkI7HrZOf14njX7tCAAUetyZM1Pr8hX/EK2lxBCOgWDRmigbp24fD1hdMfQK5lw==", + "engines": { + "node": ">=16.11.0" + } + }, "node_modules/@emotion/is-prop-valid": { "version": "0.8.8", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", @@ -481,6 +565,14 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@fastify/busboy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz", + "integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==", + "engines": { + "node": ">=14" + } + }, "node_modules/@floating-ui/core": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.3.tgz", @@ -1501,6 +1593,36 @@ "integrity": "sha512-V+MvGwaHH03hYhY+k6Ef/xKd6RYlc4q8WBx+2ANmipHJcKuktNcI/NgEsJgdSUF6Lw32njT6OnrRsKYCdgHjYw==", "dev": true }, + "node_modules/@sapphire/async-queue": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.2.tgz", + "integrity": "sha512-7X7FFAA4DngXUl95+hYbUF19bp1LGiffjJtu7ygrZrbdCSsdDDBaSjB7Akw0ZbOu6k0xpXyljnJ6/RZUvLfRdg==", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@sapphire/shapeshift": { + "version": "3.9.6", + "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.6.tgz", + "integrity": "sha512-4+Na/fxu2SEepZRb9z0dbsVh59QtwPuBg/UVaDib3av7ZY14b14+z09z6QVn0P6Dv6eOU2NDTsjIi0mbtgP56g==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@sapphire/snowflake": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.3.tgz", + "integrity": "sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, "node_modules/@swc/helpers": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.1.tgz", @@ -1509,6 +1631,11 @@ "tslib": "^2.4.0" } }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" + }, "node_modules/@types/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", @@ -1566,8 +1693,7 @@ "node_modules/@types/node": { "version": "17.0.45", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", - "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", - "dev": true + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" }, "node_modules/@types/prop-types": { "version": "15.7.5", @@ -1603,6 +1729,14 @@ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" }, + "node_modules/@types/ws": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@typescript-eslint/parser": { "version": "5.60.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.60.1.tgz", @@ -1737,11 +1871,25 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@vladfrangu/async_event_emitter": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.4.tgz", + "integrity": "sha512-ButUPz9E9cXMLgvAW8aLAKKJJsPu1dY1/l/E8xzLFuysowXygs6GBcyunK9rnGC4zTsnIc2mQo71rGw9U+Ykug==", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, "node_modules/@xobotyi/scrollbar-width": { "version": "1.9.5", "resolved": "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz", "integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==" }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, "node_modules/accept-language": { "version": "3.0.18", "resolved": "https://registry.npmjs.org/accept-language/-/accept-language-3.0.18.tgz", @@ -2590,6 +2738,67 @@ "node": ">=8" } }, + "node_modules/discord-api-types": { + "version": "0.37.61", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.61.tgz", + "integrity": "sha512-o/dXNFfhBpYHpQFdT6FWzeO7pKc838QeeZ9d91CfVAtpr5XLK4B/zYxQbYgPdoMiTDvJfzcsLW5naXgmHGDNXw==" + }, + "node_modules/discord.js": { + "version": "14.4.0", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.4.0.tgz", + "integrity": "sha512-U2CTmVOep2qgMhbSDzmjd1qFUiuKNQqnnwvEYEh18vyU0looj66+wgcMOXQRq72BUCJM5fi+Hir8gfKZ35J88g==", + "deprecated": "Hard crashes on interactions with a channel in the payload, use 14.8.0 and up", + "dependencies": { + "@discordjs/builders": "^1.2.0", + "@discordjs/collection": "^1.1.0", + "@discordjs/rest": "^1.1.0", + "@sapphire/snowflake": "^3.2.2", + "@types/ws": "^8.5.3", + "discord-api-types": "^0.37.10", + "fast-deep-equal": "^3.1.3", + "lodash.snakecase": "^4.1.1", + "tslib": "^2.4.0", + "undici": "^5.10.0", + "ws": "^8.8.1" + }, + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/discord.js/node_modules/@discordjs/collection": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz", + "integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==", + "engines": { + "node": ">=16.11.0" + } + }, + "node_modules/discord.js/node_modules/@discordjs/rest": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-1.7.1.tgz", + "integrity": "sha512-Ofa9UqT0U45G/eX86cURQnX7gzOJLG2oC28VhIk/G6IliYgQF7jFByBJEykPSHE4MxPhqCleYvmsrtfKh1nYmQ==", + "dependencies": { + "@discordjs/collection": "^1.5.1", + "@discordjs/util": "^0.3.0", + "@sapphire/async-queue": "^1.5.0", + "@sapphire/snowflake": "^3.4.2", + "discord-api-types": "^0.37.41", + "file-type": "^18.3.0", + "tslib": "^2.5.0", + "undici": "^5.22.0" + }, + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/discord.js/node_modules/@discordjs/util": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-0.3.1.tgz", + "integrity": "sha512-HxXKYKg7vohx2/OupUN/4Sd02Ev3PBJ5q0gtjdcvXb0ErCva8jNHWfe/v5sU3UKjIB/uxOhc+TDOnhqffj9pRA==", + "engines": { + "node": ">=16.9.0" + } + }, "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", @@ -2607,6 +2816,68 @@ "node": ">=6.0.0" } }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dotenv": { + "version": "16.4.4", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.4.tgz", + "integrity": "sha512-XvPXc8XAQThSjAbY6cQ/9PcBXmFoWuw1sQ3b8HqUCR6ziGXjkTi//kB9SWa2UwqlgdAIuRqAa/9hVljzPehbYg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/electron-to-chromium": { "version": "1.4.445", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.445.tgz", @@ -2627,6 +2898,17 @@ "once": "^1.4.0" } }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/error-stack-parser": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", @@ -3362,6 +3644,22 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/file-type": { + "version": "18.7.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-18.7.0.tgz", + "integrity": "sha512-ihHtXRzXEziMrQ56VSgU7wkxh55iNchFkosu7Y9/S+tXHdKyrGjVK0ujbqNnsxzea+78MaLhN6PGmfYSAv1ACw==", + "dependencies": { + "readable-web-to-node-stream": "^3.0.2", + "strtok3": "^7.0.0", + "token-types": "^5.0.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -3701,7 +3999,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, "engines": { "node": ">=4" } @@ -3782,6 +4079,37 @@ "void-elements": "3.1.0" } }, + "node_modules/html-to-react": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/html-to-react/-/html-to-react-1.7.0.tgz", + "integrity": "sha512-b5HTNaTGyOj5GGIMiWVr1k57egAZ/vGy0GGefnCQ1VW5hu9+eku8AXHtf2/DeD95cj/FKBKYa1J7SWBOX41yUQ==", + "dependencies": { + "domhandler": "^5.0", + "htmlparser2": "^9.0", + "lodash.camelcase": "^4.3.0" + }, + "peerDependencies": { + "react": "^0.13.0 || ^0.14.0 || >=15" + } + }, + "node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, "node_modules/hyphenate-style-name": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", @@ -3853,6 +4181,11 @@ "node": ">= 4" } }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==" + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -4371,6 +4704,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + }, "node_modules/lodash.clone": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", @@ -4389,6 +4732,11 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==" + }, "node_modules/longest-streak": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", @@ -4426,6 +4774,11 @@ "react": "^16.5.1 || ^17.0.0 || ^18.0.0" } }, + "node_modules/magic-bytes.js": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.8.0.tgz", + "integrity": "sha512-lyWpfvNGVb5lu8YUAbER0+UMBTdR63w2mcSUlhhBTyVbxJvjgqwyAf3AZD6MprgK0uHuBoWXSDAMWLupX83o3Q==" + }, "node_modules/markdown-table": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", @@ -5449,6 +5802,77 @@ "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==", "dev": true }, + "node_modules/nodemon": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.3.tgz", + "integrity": "sha512-7jH/NXbFPxVaMwmBCC2B9F/V6X1VkEdNgx3iu9jji8WxWcvhMWkmhNWhI5077zknOnZnBzba9hZP6bCPJLSReQ==", + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/nodemon/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/nodemon/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -5686,6 +6110,18 @@ "node": ">=8" } }, + "node_modules/peek-readable": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.0.0.tgz", + "integrity": "sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -5910,6 +6346,11 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" + }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -6188,6 +6629,21 @@ "node": ">= 6" } }, + "node_modules/readable-web-to-node-stream": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", + "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", + "dependencies": { + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -6567,6 +7023,47 @@ "is-arrayish": "^0.3.1" } }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/simple-update-notifier/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/simple-update-notifier/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/simple-update-notifier/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -6760,6 +7257,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strtok3": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-7.0.0.tgz", + "integrity": "sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ==", + "dependencies": { + "@tokenizer/token": "^0.3.0", + "peek-readable": "^5.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/style-to-object": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", @@ -6839,7 +7352,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -6996,6 +7508,33 @@ "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" }, + "node_modules/token-types": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-5.0.1.tgz", + "integrity": "sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg==", + "dependencies": { + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, "node_modules/trim-lines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", @@ -7024,6 +7563,11 @@ "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" }, + "node_modules/ts-mixer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz", + "integrity": "sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ==" + }, "node_modules/tsconfig-paths": { "version": "3.14.2", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", @@ -7049,9 +7593,9 @@ } }, "node_modules/tslib": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz", - "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==" + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/tsutils": { "version": "3.21.0", @@ -7151,6 +7695,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" + }, + "node_modules/undici": { + "version": "5.28.3", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.3.tgz", + "integrity": "sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, "node_modules/unified": { "version": "10.1.2", "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", @@ -7464,6 +8024,26 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", diff --git a/package.json b/package.json index 042bc7b..16806c1 100644 --- a/package.json +++ b/package.json @@ -17,9 +17,11 @@ "typecheck": "tsc --noEmit", "format:write": "prettier --write \"**/*.{ts,tsx,mdx}\" --cache", "format:check": "prettier --check \"**/*.{ts,tsx,mdx}\" --cache", - "clean": "rm -rf .next/ out/" + "clean": "rm -rf .next/ out/", + "dev:discordbot": "nodemon --watch ./common/discord" }, "dependencies": { + "@discordjs/rest": "^2.0.1", "@next/mdx": "^13.5.0", "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-checkbox": "^1.0.4", @@ -29,15 +31,19 @@ "accept-language": "^3.0.18", "class-variance-authority": "^0.4.0", "clsx": "^1.2.1", + "discord.js": "14.4.0", + "dotenv": "^16.4.4", "framer-motion": "^10.12.17", "fuse.js": "^6.6.2", "gsap": "^3.12.1", + "html-to-react": "^1.7.0", "i18next": "^23.7.16", "i18next-browser-languagedetector": "^7.2.0", "i18next-resources-to-backend": "^1.2.0", "lucide-react": "0.105.0-alpha.4", "next": "^13.4.10", "next-themes": "^0.2.1", + "nodemon": "^3.0.3", "react": "^18.2.0", "react-cookie": "^7.0.1", "react-dom": "^18.2.0", diff --git a/tailwind.config.js b/tailwind.config.js index 28654e3..f2ce887 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -37,7 +37,9 @@ module.exports = { 300: "#A3DFF0", 400: "#50C3E0", 500: "#29ACCE", + 600: "#1A8BAF", 700: "#166F8E", + 900: "#184F62", 950: "#103241", }, tuatara: { diff --git a/tsconfig.json b/tsconfig.json index 9f832d1..e40dcbd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -24,6 +24,6 @@ ], "strictNullChecks": true }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "middleware.ts"], + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "middleware.ts", "common/discord.js"], "exclude": ["node_modules"] }