From 160fe4ecb37864a7ad8e0d31ca699f5e32f33580 Mon Sep 17 00:00:00 2001 From: SKINMAKER Date: Mon, 17 Feb 2025 07:34:12 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=ED=88=AC=ED=91=9C=20=EC=95=8C=EB=A6=BC?= =?UTF-8?q?=20=EA=B8=B0=EB=8A=A5=20(#669)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: ensure djs clients are singleton instances * feat: add votes table * feat: vote notification * chore: reduce vote cooldown to 15 min * feat: add SetNotification to server * chore: add debug logs * fix: do not add notification when token and voteid already exists * feat: add loading indicator * feat: refresh notification when voted * feat: add opt-out * feat: add debug log * fix: initialize firebase app * fix: remove app on messaging * feat: show notifications only with service worker * fix: state improperly used * fix: schedule notification if notification is newly added * chore: remove duplicated notification * chore: add spacing * chore: get token if notification is granted * chore: change vote cooldown to 12 hours * chore: remove logging --- .gitignore | 5 +- components/FCM.tsx | 165 +++++ package.json | 2 + pages/api/v2/bots/[id]/vote.ts | 14 +- pages/api/v2/servers/[id]/vote.ts | 14 +- pages/api/v2/users/notification.ts | 49 ++ pages/bots/[id]/vote.tsx | 30 +- pages/servers/[id]/vote.tsx | 37 +- public/vote-notification-sw.js | 41 ++ types/global.d.ts | 8 + utils/DiscordBot.ts | 41 +- utils/NotificationManager.ts | 114 ++++ utils/Query.ts | 182 +++++- yarn.lock | 972 ++++++++++++++++++++++++++++- 14 files changed, 1597 insertions(+), 77 deletions(-) create mode 100644 components/FCM.tsx create mode 100644 pages/api/v2/users/notification.ts create mode 100644 public/vote-notification-sw.js create mode 100644 utils/NotificationManager.ts diff --git a/.gitignore b/.gitignore index 4939a0a..dcd5ed2 100644 --- a/.gitignore +++ b/.gitignore @@ -43,4 +43,7 @@ yarn-error.log* package-lock.json # sub module -api-docs/ \ No newline at end of file +api-docs/ + +# Firebase +service-account.json \ No newline at end of file diff --git a/components/FCM.tsx b/components/FCM.tsx new file mode 100644 index 0000000..07d1d33 --- /dev/null +++ b/components/FCM.tsx @@ -0,0 +1,165 @@ +import Fetch from '@utils/Fetch' +import { initializeApp } from 'firebase/app' +import { getMessaging, getToken as getFirebaseToken } from 'firebase/messaging' +import { useState } from 'react' +import Button from './Button' + +export async function getFCMToken() { + try { + const app = initializeApp({ + apiKey: 'AIzaSyDWnwXCBaP1C627gfIBQxyZbmNnAU_b_1Q', + authDomain: 'koreanlist-e95d9.firebaseapp.com', + projectId: 'koreanlist-e95d9', + storageBucket: 'koreanlist-e95d9.firebasestorage.app', + messagingSenderId: '716438516411', + appId: '1:716438516411:web:cddd6c7cc3b0571fa4af9e', + }) + + const worker = await navigator.serviceWorker.register('/vote-notification-sw.js') + + const messaging = getMessaging(app) + const token = await getFirebaseToken(messaging, { + vapidKey: process.env.NEXT_PUBLIC_FCM_VAPID_KEY, + serviceWorkerRegistration: worker, + }) + return token + } catch (e) { + return null + } +} + +function SetNotification({ id, notificationSet }: { id: string; notificationSet: boolean }) { + const [state, setState] = useState(notificationSet ? 1 : 0) + const [hold, setHold] = useState(false) + + const getToken = async () => { + if (!('serviceWorker' in navigator)) { + setState(4) + return 'NO_SERVICE_WORKER' + } + + if (!('Notification' in window)) { + setState(4) + return 'NO_NOTIFICATION' + } + + const p = await Notification.requestPermission() + if (p !== 'granted') { + setState(5) + return 'PERMISSION_DENIED' + } + + const token = await getFCMToken() + + if (!token) { + setState(4) + return + } + + const result = await Fetch('/users/notification', { + method: 'POST', + body: JSON.stringify({ + token, + targetId: id, + }), + }) + + if (result.code === 200) { + setState(2) + } else { + setState(4) + } + } + const components = { + 0: ( + <> +

+ 12시간 후에 이 기기로 알림을 받으려면 아래 버튼을 눌러주세요. +

+ + + ), + 1: ( + <> +

+ 이 기기로 알림을 수신하고 있습니다. 알림을 해제하려면 아래 버튼을 눌러주세요. +

+ + + ), + 2: ( + <> +

알림이 설정되었습니다.

+ + ), + 3: ( + <> +

알림이 해제되었습니다.

+ + ), + 4: ( + <> +

+ 알림을 설정할 수 없습니다. 사용하는 브라우저를 점검해주세요. {'\n'} + iOS 사용자는 Safari 브라우저에서 한국 디스코드 리스트를 홈 화면에 추가해야 합니다. +

+ + ), + 5: ( + <> +

+ 알림이 허용되지 않았습니다. 브라우저 설정에서 알림을 허용해주세요. +

+ + ), + } + return ( + components[state] ?? ( +

+ 알림을 설정할 수 없습니다. 사용하는 브라우저를 점검해주세요. +

+ ) + ) +} + +export default SetNotification diff --git a/package.json b/package.json index 628fa79..f0445e9 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,8 @@ "emoji-mart": "3.0.1", "erlpack": "0.1.4", "express-rate-limit": "^5.3.0", + "firebase": "^11.2.0", + "firebase-admin": "^13.0.2", "formik": "2.4.2", "generate-license-file": "1.1.0", "josa": "3.0.1", diff --git a/pages/api/v2/bots/[id]/vote.ts b/pages/api/v2/bots/[id]/vote.ts index 1d670fb..7653626 100644 --- a/pages/api/v2/bots/[id]/vote.ts +++ b/pages/api/v2/bots/[id]/vote.ts @@ -41,6 +41,15 @@ const BotVote = RequestHandler() if (!captcha) return ResponseWrapper(res, { code: 400, message: '캡챠 검증에 실패하였습니다.' }) const vote = await put.voteBot(user, bot.id) + + const token = req.body.firebaseToken + let notificationSet = false + + if (token) { + const noti = await get.notifications.token(token, bot.id) + notificationSet = !!noti + } + if (vote === null) return ResponseWrapper(res, { code: 401 }) else if (vote === true) { get.bot.clear(req.query.id) @@ -55,8 +64,8 @@ const BotVote = RequestHandler() }, timestamp: Date.now(), }) - return ResponseWrapper(res, { code: 200 }) - } else return ResponseWrapper(res, { code: 429, data: { retryAfter: vote } }) + return ResponseWrapper(res, { code: 200, data: { notificationSet } }) + } else return ResponseWrapper(res, { code: 429, data: { retryAfter: vote, notificationSet } }) }) interface ApiRequest extends NextApiRequest { @@ -75,6 +84,7 @@ interface PostApiRequest extends ApiRequest { body: { _captcha: string _csrf: string + firebaseToken?: string | null } } export default BotVote diff --git a/pages/api/v2/servers/[id]/vote.ts b/pages/api/v2/servers/[id]/vote.ts index 28da6f8..bd03905 100644 --- a/pages/api/v2/servers/[id]/vote.ts +++ b/pages/api/v2/servers/[id]/vote.ts @@ -41,6 +41,15 @@ const ServerVote = RequestHandler() if (!captcha) return ResponseWrapper(res, { code: 400, message: '캡챠 검증에 실패하였습니다.' }) const vote = await put.voteServer(user, server.id) + + const token = req.body.firebaseToken + let notificationSet = false + + if (token) { + const result = await get.notifications.token(token, server.id) + notificationSet = !!result + } + if (vote === null) return ResponseWrapper(res, { code: 401 }) else if (vote === true) { get.server.clear(req.query.id) @@ -55,8 +64,8 @@ const ServerVote = RequestHandler() }, timestamp: Date.now(), }) - return ResponseWrapper(res, { code: 200 }) - } else return ResponseWrapper(res, { code: 429, data: { retryAfter: vote } }) + return ResponseWrapper(res, { code: 200, data: { notificationSet } }) + } else return ResponseWrapper(res, { code: 429, data: { retryAfter: vote, notificationSet } }) }) interface ApiRequest extends NextApiRequest { @@ -75,6 +84,7 @@ interface PostApiRequest extends ApiRequest { body: { _captcha: string _csrf: string + firebaseToken?: string | null } } export default ServerVote diff --git a/pages/api/v2/users/notification.ts b/pages/api/v2/users/notification.ts new file mode 100644 index 0000000..0b0693f --- /dev/null +++ b/pages/api/v2/users/notification.ts @@ -0,0 +1,49 @@ +import { addNotification, get } from '@utils/Query' +import RequestHandler from '@utils/RequestHandler' + +const Notification = RequestHandler() + .get(async (req, res) => { + const token = req.query.token as string + const target = req.query.target as string + const user = await get.Authorization(req.cookies.token) + if (!user) return res.status(401).json({ code: 401 }) + + const result = token + ? await get.notifications.token(token, target) + : await get.notifications.user(user) + + if (!result) return res.status(400).json({ code: 400 }) + + return res.status(200).json({ code: 200, data: result }) + }) + .post(async (req, res) => { + const user = await get.Authorization(req.cookies.token) + if (!user) return res.status(401).json({ code: 401 }) + + const { token, targetId } = req.body + + if (!token || !targetId) + return res.status(400).json({ code: 400, message: 'Either token or targetId is missing' }) + + const result = await addNotification({ token, targetId, userId: user }) + if (typeof result === 'string') return res.status(400).json({ code: 400, message: result }) + + return res.status(200).json({ code: 200 }) + }) + .delete(async (req, res) => { + const user = await get.Authorization(req.cookies.token) + + if (!user) return res.status(401).json({ code: 401 }) + + const { token, targetId } = req.body + + if (!token) return res.status(400).json({ code: 400 }) + + const result = global.notification.removeNotification({ userId: user, targetId, token }) + + if (!result) return res.status(400).json({ code: 400 }) + + return res.status(200).json({ code: 200 }) + }) + +export default Notification diff --git a/pages/bots/[id]/vote.tsx b/pages/bots/[id]/vote.tsx index 42e7913..4411556 100644 --- a/pages/bots/[id]/vote.tsx +++ b/pages/bots/[id]/vote.tsx @@ -12,12 +12,13 @@ import { ParsedUrlQuery } from 'querystring' import NotFound from 'pages/404' import { getToken } from '@utils/Csrf' import Captcha from '@components/Captcha' -import { useState } from 'react' +import { useEffect, useRef, useState } from 'react' import Fetch from '@utils/Fetch' import Day from '@utils/Day' import { getJosaPicker } from 'josa' import { KoreanbotsEndPoints } from '@utils/Constants' import { NextSeo } from 'next-seo' +import SetNotification, { getFCMToken } from '@components/FCM' const Container = dynamic(() => import('@components/Container')) const DiscordAvatar = dynamic(() => import('@components/DiscordAvatar')) @@ -30,7 +31,18 @@ const Message = dynamic(() => import('@components/Message')) const VoteBot: NextPage = ({ data, user, theme, csrfToken }) => { const [votingStatus, setVotingStatus] = useState(0) - const [result, setResult] = useState>(null) + const [result, setResult] = + useState>(null) + const fcmTokenRef = useRef('') + + useEffect(() => { + if ('Notification' in window && Notification.permission === 'granted') { + getFCMToken().then((token) => { + fcmTokenRef.current = token + }) + } + }, []) + const router = useRouter() if (!data?.id) return if (!user) @@ -116,11 +128,15 @@ const VoteBot: NextPage = ({ data, user, theme, csrfToken }) => { { - const res = await Fetch<{ retryAfter: number } | unknown>( + const res = await Fetch<{ retryAfter: number; notificationSet: boolean }>( `/bots/${data.id}/vote`, { method: 'POST', - body: JSON.stringify({ _csrf: csrfToken, _captcha: key }), + body: JSON.stringify({ + _csrf: csrfToken, + _captcha: key, + firebaseToken: fcmTokenRef.current, + }), } ) setResult(res) @@ -128,7 +144,10 @@ const VoteBot: NextPage = ({ data, user, theme, csrfToken }) => { }} /> ) : result.code === 200 ? ( -

해당 봇에 투표했습니다!

+ <> +

해당 봇에 투표했습니다!

+ + ) : result.code === 429 ? ( <>

이미 해당 봇에 투표하였습니다.

@@ -136,6 +155,7 @@ const VoteBot: NextPage = ({ data, user, theme, csrfToken }) => { {Day(+new Date() + result.data?.retryAfter).fromNow()} 다시 투표하실 수 있습니다. + ) : (

{result.message}

diff --git a/pages/servers/[id]/vote.tsx b/pages/servers/[id]/vote.tsx index 042bc81..d47d25d 100644 --- a/pages/servers/[id]/vote.tsx +++ b/pages/servers/[id]/vote.tsx @@ -12,12 +12,13 @@ import { ParsedUrlQuery } from 'querystring' import NotFound from 'pages/404' import { getToken } from '@utils/Csrf' import Captcha from '@components/Captcha' -import { useState } from 'react' +import { useEffect, useRef, useState } from 'react' import Fetch from '@utils/Fetch' import Day from '@utils/Day' import { getJosaPicker } from 'josa' import { KoreanbotsEndPoints } from '@utils/Constants' import { NextSeo } from 'next-seo' +import SetNotification, { getFCMToken } from '@components/FCM' const Container = dynamic(() => import('@components/Container')) const ServerIcon = dynamic(() => import('@components/ServerIcon')) @@ -30,7 +31,19 @@ const Message = dynamic(() => import('@components/Message')) const VoteServer: NextPage = ({ data, user, theme, csrfToken }) => { const [votingStatus, setVotingStatus] = useState(0) - const [result, setResult] = useState>(null) + const [result, setResult] = + useState>(null) + + const fcmTokenRef = useRef('') + + useEffect(() => { + if ('Notification' in window && Notification.permission === 'granted') { + getFCMToken().then((token) => { + fcmTokenRef.current = token + }) + } + }, []) + const router = useRouter() if (!data?.id) return if (!user) @@ -90,7 +103,11 @@ const VoteServer: NextPage = ({ data, user, theme, csrfToken })
- + @@ -112,11 +129,15 @@ const VoteServer: NextPage = ({ data, user, theme, csrfToken }) { - const res = await Fetch<{ retryAfter: number } | unknown>( + const res = await Fetch<{ retryAfter: number; notificationSet: boolean }>( `/servers/${data.id}/vote`, { method: 'POST', - body: JSON.stringify({ _csrf: csrfToken, _captcha: key }), + body: JSON.stringify({ + _csrf: csrfToken, + _captcha: key, + firebaseToken: fcmTokenRef.current, + }), } ) setResult(res) @@ -124,7 +145,10 @@ const VoteServer: NextPage = ({ data, user, theme, csrfToken }) }} /> ) : result.code === 200 ? ( -

해당 서버에 투표했습니다!

+ <> +

해당 서버에 투표했습니다!

+ + ) : result.code === 429 ? ( <>

이미 해당 서버에 투표하였습니다.

@@ -132,6 +156,7 @@ const VoteServer: NextPage = ({ data, user, theme, csrfToken }) {Day(+new Date() + result.data?.retryAfter).fromNow()} 다시 투표하실 수 있습니다. + ) : (

{result.message}

diff --git a/public/vote-notification-sw.js b/public/vote-notification-sw.js new file mode 100644 index 0000000..df9b343 --- /dev/null +++ b/public/vote-notification-sw.js @@ -0,0 +1,41 @@ +/* eslint-disable no-undef */ + +importScripts('https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js') +importScripts('https://www.gstatic.com/firebasejs/8.10.0/firebase-messaging.js') + +firebase.initializeApp({ + apiKey: 'AIzaSyDWnwXCBaP1C627gfIBQxyZbmNnAU_b_1Q', + authDomain: 'koreanlist-e95d9.firebaseapp.com', + projectId: 'koreanlist-e95d9', + storageBucket: 'koreanlist-e95d9.firebasestorage.app', + messagingSenderId: '716438516411', + appId: '1:716438516411:web:cddd6c7cc3b0571fa4af9e', +}) + +const messaging = firebase.messaging() + +/* +{ + type: 'vote-available', + name: target.name, + imageUrl: image ?? undefined, + url: `/${isBot ? 'bots' : 'servers'}/${noti.target_id}`, +} +*/ + +messaging.onBackgroundMessage(function (payload) { + if (payload.data.type !== 'vote-available') return + const notificationTitle = '투표 알림' + const notificationOptions = { + body: `${payload.data.name}의 투표가 가능합니다.`, + icon: payload.data.imageUrl, + } + notificationOptions.data = payload.data + + self.addEventListener('notificationclick', function (event) { + event.notification.close() + clients.openWindow(event.notification.data.url) + }) + + self.registration.showNotification(notificationTitle, notificationOptions) +}) diff --git a/types/global.d.ts b/types/global.d.ts index c019089..12ececf 100644 --- a/types/global.d.ts +++ b/types/global.d.ts @@ -1,4 +1,7 @@ +/* eslint-disable no-var */ import * as Yup from 'yup' +import { Client } from 'discord.js' +import NotificationManager from '@utils/NotificationManager' declare global { interface Window { @@ -8,6 +11,9 @@ declare global { highlightBlock(e: Element): void } } + var kodl: Client + var serverlist: Client + var notification: NotificationManager interface Navigator { standalone?: boolean } @@ -21,3 +27,5 @@ declare module 'yup' { declare module 'difflib' { export function unifiedDiff(before: string, after: string): string[] } + +export {} diff --git a/utils/DiscordBot.ts b/utils/DiscordBot.ts index 6ddef93..928041f 100644 --- a/utils/DiscordBot.ts +++ b/utils/DiscordBot.ts @@ -1,13 +1,33 @@ import * as Discord from 'discord.js' +import NotificationManager from './NotificationManager' -export const DiscordBot = new Discord.Client({ - intents: Number(process.env.DISCORD_CLIENT_INTENTS ?? 32767), -}) +if (!global.kodl) { + global.kodl = new Discord.Client({ + intents: Number(process.env.DISCORD_CLIENT_INTENTS ?? 32767), + }) + global.serverlist = new Discord.Client({ + intents: [], + }) -export const ServerListDiscordBot = new Discord.Client({ - intents: [], -}) + console.log('Discord Client is initializing') + global.kodl.on('ready', async () => { + console.log('Discord Client is ready') + await getMainGuild().members.fetch() + console.log(`Fetched ${getMainGuild().members.cache.size} Members`) + }) + + global.kodl.login(process.env.DISCORD_TOKEN ?? '') + global.serverlist.login(process.env.DISCORD_SERVERLIST_TOKEN) +} + +if (!global.notification) { + global.notification = new NotificationManager() +} + +export const DiscordBot = global.kodl as Discord.Client + +export const ServerListDiscordBot = global.serverlist as Discord.Client const dummyURL = 'https://discord.com/api/webhooks/123123123123123123/asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf' @@ -40,15 +60,6 @@ export const webhookClients = { }, } -DiscordBot.on('ready', async () => { - console.log('Discord Client is ready') - await getMainGuild().members.fetch() - console.log(`Fetched ${getMainGuild().members.cache.size} Members`) -}) - -DiscordBot.login(process.env.DISCORD_TOKEN ?? '') -ServerListDiscordBot.login(process.env.DISCORD_SERVERLIST_TOKEN) - export const getMainGuild = () => DiscordBot.guilds.cache.get(process.env.GUILD_ID ?? '') export const discordLog = async ( diff --git a/utils/NotificationManager.ts b/utils/NotificationManager.ts new file mode 100644 index 0000000..2f835f1 --- /dev/null +++ b/utils/NotificationManager.ts @@ -0,0 +1,114 @@ +import { initializeApp } from 'firebase-admin/app' +import { KoreanbotsEndPoints, VOTE_COOLDOWN } from './Constants' +import { get, getNotifications, removeNotification as removeNotificationData } from './Query' +import { ObjectType } from '@types' +import { messaging } from 'firebase-admin' + +export type Notification = { + vote_id: number + token: string + user_id: string + target_id: string + type: ObjectType + last_voted: Date +} + +export default class NotificationManager { + private timeouts: Record<`${string}:${string}:${string}`, NodeJS.Timeout> = {} + private firebaseApp: ReturnType + + public constructor() { + this.initVotes() + this.firebaseApp = initializeApp() + console.log('NotificationManager initialized') + } + + public async setNotification(token: string, userId: string, targetId: string) { + const noti = await get.notifications.token(token, targetId) + + if (!noti) return false + await this.scheduleNotification(noti) + } + + /** + * This is a service. This removes the timeout and the notification data. + */ + public async removeNotification({ + userId, + targetId, + token, + }: { + userId: string + targetId: string + token: string + }): ReturnType { + clearTimeout(this.timeouts[`${userId}:${targetId}:${token}`]) + return await removeNotificationData({ targetId, token }) + } + + public async scheduleNotification(noti: Notification) { + const time = noti.last_voted.getTime() + VOTE_COOLDOWN + 1000 * 60 - Date.now() + + if (time <= 0) { + return + } + + const key = `${noti.user_id}:${noti.target_id}:${noti.token}` + + this.timeouts[key] = setTimeout(() => { + this.pushNotification(noti) + clearTimeout(this.timeouts[key]) + }, time) + } + + public async refresh(userId: string, targetId: string) { + const notifications = await getNotifications(userId, targetId) + + for (const noti of notifications) { + clearTimeout(this.timeouts[`${userId}:${targetId}:${noti.token}`]) + this.scheduleNotification(noti) + } + } + + public async initVotes() { + const res = await getNotifications() + for (const noti of res) { + this.scheduleNotification(noti) + } + } + + private async pushNotification(noti: Notification) { + const isBot = noti.type === ObjectType.Bot + const target = isBot + ? await get.bot.load(noti.target_id) + : await get.server.load(noti.target_id) + + const image = + process.env.KOREANBOTS_URL + + ('avatar' in target + ? KoreanbotsEndPoints.CDN.avatar(target.id, { size: 256 }) + : KoreanbotsEndPoints.CDN.icon(target.id, { size: 256 })) + + await messaging() + .send({ + token: noti.token, + data: { + type: 'vote-available', + name: target.name, + imageUrl: image ?? undefined, + url: `/${isBot ? 'bots' : 'servers'}/${noti.target_id}`, + }, + }) + .catch((e) => { + if ('code' in e) { + if (e.code === 'messaging/registration-token-not-registered') { + this.removeNotification({ + userId: noti.user_id, + token: noti.token, + targetId: null, + }) + } + } + }) + } +} diff --git a/utils/Query.ts b/utils/Query.ts index 83b3bf2..6d6c9aa 100644 --- a/utils/Query.ts +++ b/utils/Query.ts @@ -39,6 +39,7 @@ import { sign, verify } from './Jwt' import { areArraysEqual, camoUrl, formData, getYYMMDD, serialize } from './Tools' import { AddBotSubmit, AddServerSubmit, ManageBot, ManageServer } from './Yup' import { markdownImage } from './Regex' +import { Notification } from './NotificationManager' export const imageRateLimit = new TLRU({ maxAgeMs: 60000 }) @@ -76,7 +77,7 @@ async function getBot(id: string, topLevel = true): Promise { if (res) { const discordBot = await get.discord.user.load(res.id) - if(!discordBot) { + if (!discordBot) { return null } if (Number(discordBot.discriminator) === 0) { @@ -528,18 +529,32 @@ async function getWebhook(id: string, type: 'bots' | 'servers'): Promise { - const user = await knex('users').select(['votes']).where({ id: userID }) - const key = `bot:${botID}` - if (user.length === 0) return null - const date = +new Date() - const data = JSON.parse(user[0].votes) - const lastDate = data[key] || 0 - if (date - lastDate < VOTE_COOLDOWN) return VOTE_COOLDOWN - (date - lastDate) - data[key] = date + const [vote] = await knex('votes').select('*').where({ user_id: userID, target: botID }) + const date = new Date() + if (vote) { + const lastDate = vote.last_voted.getTime() || 0 + if (date.getTime() - lastDate < VOTE_COOLDOWN) + return VOTE_COOLDOWN - (date.getTime() - lastDate) + } + await knex('bots').where({ id: botID }).increment('votes', 1) - await knex('users') - .where({ id: userID }) - .update({ votes: JSON.stringify(data) }) + + const votes = await knex('votes') + .select('id') + .where({ user_id: userID, target: botID, type: ObjectType.Bot }) + if (votes.length === 0) { + await knex('votes').insert({ + user_id: userID, + target: botID, + type: ObjectType.Bot, + last_voted: date, + }) + } else { + await knex('votes').where({ id: votes[0].id }).update({ last_voted: date }) + } + + global.notification.refresh(userID, botID) + const record = await Bots.updateOne( { _id: botID, 'voteMetrix.day': getYYMMDD() }, { $inc: { 'voteMetrix.$.increasement': 1, 'voteMetrix.$.count': 1 } } @@ -554,18 +569,22 @@ async function voteBot(userID: string, botID: string): Promise } async function voteServer(userID: string, serverID: string): Promise { - const user = await knex('users').select(['votes']).where({ id: userID }) - const key = `server:${serverID}` - if (user.length === 0) return null - const date = +new Date() - const data = JSON.parse(user[0].votes) - const lastDate = data[key] || 0 - if (date - lastDate < VOTE_COOLDOWN) return VOTE_COOLDOWN - (date - lastDate) - data[key] = date + const [vote] = await knex('votes').select('*').where({ user_id: userID, target: serverID }) + const date = new Date() + if (vote) { + const lastDate = vote.last_voted.getTime() || 0 + if (date.getTime() - lastDate < VOTE_COOLDOWN) + return VOTE_COOLDOWN - (date.getTime() - lastDate) + } + await knex('servers').where({ id: serverID }).increment('votes', 1) - await knex('users') - .where({ id: userID }) - .update({ votes: JSON.stringify(data) }) + await knex('votes') + .insert({ user_id: userID, target: serverID, type: ObjectType.Server, last_voted: date }) + .onConflict(['user_id', 'target', 'type']) + .merge({ last_voted: date }) + + global.notification.refresh(userID, serverID) + // const record = await Servers.updateOne({ _id: serverID, 'voteMetrix.day': getYYMMDD() }, { $inc: { 'voteMetrix.$.increasement': 1, 'voteMetrix.$.count': 1 } }) // if(record.n === 0) await Servers.findByIdAndUpdate(serverID, { $push: { voteMetrix: { count: (await knex('servers').where({ id: serverID }))[0].votes } } }, { upsert: true }) return true @@ -947,6 +966,119 @@ export async function CaptchaVerify(response: string): Promise { return res.success } +// FCM + +export async function addNotification({ + token, + userId, + targetId, +}: { + token: string + userId: string + targetId: string +}) { + const [vote] = await knex('votes').select('id').where({ user_id: userId, target: targetId }) + + if (!vote) { + return 'Vote does not exist' + } + + const voteId = vote.id + + const { length } = await knex('notifications').select('vote_id').where({ token, vote_id: voteId }) + + if (length === 0) { + await knex('notifications').insert({ token, vote_id: voteId }) + } + + console.log('Notification added to database', token, userId, targetId) + + global.notification.setNotification(token, userId, targetId) + + return true +} + +export async function removeNotification({ + token, + targetId, +}: { + token: string + targetId: string | null +}) { + if (targetId === null) { + await knex('notifications').delete().where({ token }) + return true + } + + await knex('notifications') + .delete() + .leftJoin('votes', 'votes.id', 'notifications.vote_id') + .where({ + 'notifications.token': token, + 'votes.target': targetId, + }) + + return true +} + +/** + * We consider that multiple devices could listen to the same topic. + * @param userId + * @param targetId + */ +export async function getNotifications(userId?: string, targetId?: string) { + const q = knex('notifications') + .select([ + 'notifications.*', + 'votes.user_id as user_id', + 'votes.target as target_id', + 'votes.type as type', + 'votes.last_voted as last_voted', + ]) + .leftJoin('votes', 'votes.id', 'notifications.vote_id') + + if (userId) q.where('votes.user_id', userId) + if (targetId) q.where('votes.target', targetId) + + const res = await q + + return res as Notification[] +} + +export async function getNotificationsByToken(token: string, targetId?: string) { + const q = knex('notifications') + .select([ + 'notifications.*', + 'votes.user_id as user_id', + 'votes.target as target_id', + 'votes.type as type', + 'votes.last_voted as last_voted', + ]) + .leftJoin('votes', 'votes.id', 'notifications.vote_id') + .where('notifications.token', token) + + if (targetId) q.where('votes.target', targetId) + + const [res] = await q + + return res as Notification +} + +export async function getNotificationsByUserId(userId: string) { + const res = await knex('notifications') + .select([ + 'notifications.*', + 'votes.user_id as user_id', + 'votes.target as target_id', + 'votes.type as type', + 'votes.last_voted as last_voted', + ]) + .leftJoin('votes', 'votes.id', 'notifications.vote_id') + .where('votes.user_id', userId) + + return res as Notification[] +} + // Private APIs async function getBotSubmitList() { @@ -1257,6 +1389,10 @@ export const get = { botSubmitHistory: getBotSubmitHistory, botSubmitStrikes: getBotSubmitStrikes, serverOwners: fetchServerOwners, + notifications: { + user: getNotificationsByUserId, + token: getNotificationsByToken, + }, } export const update = { diff --git a/yarn.lock b/yarn.lock index efa06d8..3e28b48 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2341,6 +2341,401 @@ resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.0.0.tgz#f22824caff3ae506b18207bad4126dbc6ccdb6b8" integrity sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ== +"@fastify/busboy@^3.0.0": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-3.1.1.tgz#af3aea7f1e52ec916d8b5c9dcc0f09d4c060a3fc" + integrity sha512-5DGmA8FTdB2XbDeEwc/5ZXBl6UbBAyBOOLlPuBnZ/N1SwdH9Ii+cOX3tBROlDgcTXxjOYnLMVoKk9+FXAw0CJw== + +"@firebase/analytics-compat@0.2.17": + version "0.2.17" + resolved "https://registry.yarnpkg.com/@firebase/analytics-compat/-/analytics-compat-0.2.17.tgz#c3cfc8ffb863d574ec26d86f9c8344d752832995" + integrity sha512-SJNVOeTvzdqZQvXFzj7yAirXnYcLDxh57wBFROfeowq/kRN1AqOw1tG6U4OiFOEhqi7s3xLze/LMkZatk2IEww== + dependencies: + "@firebase/analytics" "0.10.11" + "@firebase/analytics-types" "0.8.3" + "@firebase/component" "0.6.12" + "@firebase/util" "1.10.3" + tslib "^2.1.0" + +"@firebase/analytics-types@0.8.3": + version "0.8.3" + resolved "https://registry.yarnpkg.com/@firebase/analytics-types/-/analytics-types-0.8.3.tgz#d08cd39a6209693ca2039ba7a81570dfa6c1518f" + integrity sha512-VrIp/d8iq2g501qO46uGz3hjbDb8xzYMrbu8Tp0ovzIzrvJZ2fvmj649gTjge/b7cCCcjT0H37g1gVtlNhnkbg== + +"@firebase/analytics@0.10.11": + version "0.10.11" + resolved "https://registry.yarnpkg.com/@firebase/analytics/-/analytics-0.10.11.tgz#6896413e92613573af775c45050af889a43676da" + integrity sha512-zwuPiRE0+hgcS95JZbJ6DFQN4xYFO8IyGxpeePTV51YJMwCf3lkBa6FnZ/iXIqDKcBPMgMuuEZozI0BJWaLEYg== + dependencies: + "@firebase/component" "0.6.12" + "@firebase/installations" "0.6.12" + "@firebase/logger" "0.4.4" + "@firebase/util" "1.10.3" + tslib "^2.1.0" + +"@firebase/app-check-compat@0.3.18": + version "0.3.18" + resolved "https://registry.yarnpkg.com/@firebase/app-check-compat/-/app-check-compat-0.3.18.tgz#abe63858fca86b61ea431e0d9e58ccb8bac1b275" + integrity sha512-qjozwnwYmAIdrsVGrJk+hnF1WBois54IhZR6gO0wtZQoTvWL/GtiA2F31TIgAhF0ayUiZhztOv1RfC7YyrZGDQ== + dependencies: + "@firebase/app-check" "0.8.11" + "@firebase/app-check-types" "0.5.3" + "@firebase/component" "0.6.12" + "@firebase/logger" "0.4.4" + "@firebase/util" "1.10.3" + tslib "^2.1.0" + +"@firebase/app-check-interop-types@0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz#ed9c4a4f48d1395ef378f007476db3940aa5351a" + integrity sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A== + +"@firebase/app-check-types@0.5.3": + version "0.5.3" + resolved "https://registry.yarnpkg.com/@firebase/app-check-types/-/app-check-types-0.5.3.tgz#38ba954acf4bffe451581a32fffa20337f11d8e5" + integrity sha512-hyl5rKSj0QmwPdsAxrI5x1otDlByQ7bvNvVt8G/XPO2CSwE++rmSVf3VEhaeOR4J8ZFaF0Z0NDSmLejPweZ3ng== + +"@firebase/app-check@0.8.11": + version "0.8.11" + resolved "https://registry.yarnpkg.com/@firebase/app-check/-/app-check-0.8.11.tgz#3c67148046fea0a0a9a1eecf1a17fdc31a76eda7" + integrity sha512-42zIfRI08/7bQqczAy7sY2JqZYEv3a1eNa4fLFdtJ54vNevbBIRSEA3fZgRqWFNHalh5ohsBXdrYgFqaRIuCcQ== + dependencies: + "@firebase/component" "0.6.12" + "@firebase/logger" "0.4.4" + "@firebase/util" "1.10.3" + tslib "^2.1.0" + +"@firebase/app-compat@0.2.48": + version "0.2.48" + resolved "https://registry.yarnpkg.com/@firebase/app-compat/-/app-compat-0.2.48.tgz#4cc013dc53b12c9c2ebda6369bbeb99f3cc59975" + integrity sha512-wVNU1foBIaJncUmiALyRxhHHHC3ZPMLIETTAk+2PG87eP9B/IDBsYUiTpHyboDPEI8CgBPat/zN2v+Snkz6lBw== + dependencies: + "@firebase/app" "0.10.18" + "@firebase/component" "0.6.12" + "@firebase/logger" "0.4.4" + "@firebase/util" "1.10.3" + tslib "^2.1.0" + +"@firebase/app-types@0.9.3": + version "0.9.3" + resolved "https://registry.yarnpkg.com/@firebase/app-types/-/app-types-0.9.3.tgz#8408219eae9b1fb74f86c24e7150a148460414ad" + integrity sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw== + +"@firebase/app@0.10.18": + version "0.10.18" + resolved "https://registry.yarnpkg.com/@firebase/app/-/app-0.10.18.tgz#219d897beedcc833ab6d7bdc4ea810ece9e32df6" + integrity sha512-VuqEwD/QRisKd/zsFsqgvSAx34mZ3WEF47i97FD6Vw4GWAhdjepYf0Hmi6K0b4QMSgWcv/x0C30Slm5NjjERXg== + dependencies: + "@firebase/component" "0.6.12" + "@firebase/logger" "0.4.4" + "@firebase/util" "1.10.3" + idb "7.1.1" + tslib "^2.1.0" + +"@firebase/auth-compat@0.5.17": + version "0.5.17" + resolved "https://registry.yarnpkg.com/@firebase/auth-compat/-/auth-compat-0.5.17.tgz#60d9222dae734fb8740ac565e342dc11f92d2392" + integrity sha512-Shi6rqLqzU9KLXnUCmlLvVByq1kiG3oe7Wpbf5m1CgS7NiRx2pSSn0HLaRRozdkaizNzMGGj+3oHmNYQ7kU6xA== + dependencies: + "@firebase/auth" "1.8.2" + "@firebase/auth-types" "0.12.3" + "@firebase/component" "0.6.12" + "@firebase/util" "1.10.3" + tslib "^2.1.0" + +"@firebase/auth-interop-types@0.2.4": + version "0.2.4" + resolved "https://registry.yarnpkg.com/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz#176a08686b0685596ff03d7879b7e4115af53de0" + integrity sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA== + +"@firebase/auth-types@0.12.3": + version "0.12.3" + resolved "https://registry.yarnpkg.com/@firebase/auth-types/-/auth-types-0.12.3.tgz#650e54a36060b5ea012075ddbd3cb26566334c41" + integrity sha512-Zq9zI0o5hqXDtKg6yDkSnvMCMuLU6qAVS51PANQx+ZZX5xnzyNLEBO3GZgBUPsV5qIMFhjhqmLDxUqCbnAYy2A== + +"@firebase/auth@1.8.2": + version "1.8.2" + resolved "https://registry.yarnpkg.com/@firebase/auth/-/auth-1.8.2.tgz#4559dfabe40bc7a0605fb2a73f401d83cb32fe80" + integrity sha512-q+071y2LWe0bVnjqaX3BscqZwzdP0GKN2YBKapLq4bV88MPfCtWwGKmDhNDEDUmioOjudGXkUY5cvvKqk3mlUg== + dependencies: + "@firebase/component" "0.6.12" + "@firebase/logger" "0.4.4" + "@firebase/util" "1.10.3" + tslib "^2.1.0" + +"@firebase/component@0.6.12": + version "0.6.12" + resolved "https://registry.yarnpkg.com/@firebase/component/-/component-0.6.12.tgz#08905a534e9b769164e7e1b1e80f6e7611eb67f3" + integrity sha512-YnxqjtohLbnb7raXt2YuA44cC1wA9GiehM/cmxrsoxKlFxBLy2V0OkRSj9gpngAE0UoJ421Wlav9ycO7lTPAUw== + dependencies: + "@firebase/util" "1.10.3" + tslib "^2.1.0" + +"@firebase/data-connect@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@firebase/data-connect/-/data-connect-0.2.0.tgz#7133cb40096466dc17ad01a50a5f2c383605df20" + integrity sha512-7OrZtQoLSk2fiGijhIdUnTSqEFti3h1EMhw9nNiSZ6jJGduw4Pz6jrVvxjpZJtGH/JiljbMkBnPBS2h8CTRKEw== + dependencies: + "@firebase/auth-interop-types" "0.2.4" + "@firebase/component" "0.6.12" + "@firebase/logger" "0.4.4" + "@firebase/util" "1.10.3" + tslib "^2.1.0" + +"@firebase/database-compat@2.0.2", "@firebase/database-compat@^2.0.0": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@firebase/database-compat/-/database-compat-2.0.2.tgz#9ddf474b593766a41ea576185cdf115e28f0cb50" + integrity sha512-5zvdnMsfDHvrQAVM6jBS7CkBpu+z3YbpFdhxRsrK1FP45IEfxlzpeuEUb17D/tpM10vfq4Ok0x5akIBaCv7gfA== + dependencies: + "@firebase/component" "0.6.12" + "@firebase/database" "1.0.11" + "@firebase/database-types" "1.0.8" + "@firebase/logger" "0.4.4" + "@firebase/util" "1.10.3" + tslib "^2.1.0" + +"@firebase/database-types@1.0.8", "@firebase/database-types@^1.0.6": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@firebase/database-types/-/database-types-1.0.8.tgz#eddcce594be118bf9aebb043b5a6d51cfb6de620" + integrity sha512-6lPWIGeufhUq1heofZULyVvWFhD01TUrkkB9vyhmksjZ4XF7NaivQp9rICMk7QNhqwa+uDCaj4j+Q8qqcSVZ9g== + dependencies: + "@firebase/app-types" "0.9.3" + "@firebase/util" "1.10.3" + +"@firebase/database@1.0.11": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@firebase/database/-/database-1.0.11.tgz#5b9960a07a0d49361f67fc69affc779cae4e07e3" + integrity sha512-gLrw/XeioswWUXgpVKCPAzzoOuvYNqK5fRUeiJTzO7Mlp9P6ylFEyPJlRBl1djqYye641r3MX6AmIeMXwjgwuQ== + dependencies: + "@firebase/app-check-interop-types" "0.3.3" + "@firebase/auth-interop-types" "0.2.4" + "@firebase/component" "0.6.12" + "@firebase/logger" "0.4.4" + "@firebase/util" "1.10.3" + faye-websocket "0.11.4" + tslib "^2.1.0" + +"@firebase/firestore-compat@0.3.41": + version "0.3.41" + resolved "https://registry.yarnpkg.com/@firebase/firestore-compat/-/firestore-compat-0.3.41.tgz#434d86fd603b5ebcde19b5695b9b2a53bb23be8b" + integrity sha512-J/PgWKEt0yugETOE7lOabT16hsV21cLzSxERD7ZhaiwBQkBTSf0Mx9RhjZRT0Ttqe4weM90HGZFyUBqYA73fVA== + dependencies: + "@firebase/component" "0.6.12" + "@firebase/firestore" "4.7.6" + "@firebase/firestore-types" "3.0.3" + "@firebase/util" "1.10.3" + tslib "^2.1.0" + +"@firebase/firestore-types@3.0.3": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@firebase/firestore-types/-/firestore-types-3.0.3.tgz#7d0c3dd8850c0193d8f5ee0cc8f11961407742c1" + integrity sha512-hD2jGdiWRxB/eZWF89xcK9gF8wvENDJkzpVFb4aGkzfEaKxVRD1kjz1t1Wj8VZEp2LCB53Yx1zD8mrhQu87R6Q== + +"@firebase/firestore@4.7.6": + version "4.7.6" + resolved "https://registry.yarnpkg.com/@firebase/firestore/-/firestore-4.7.6.tgz#877a37b615d86c61ac9ba7ddd0a967feb99380ac" + integrity sha512-aVDboR+upR/44qZDLR4tnZ9pepSOFBbDJnwk7eWzmTyQq2nZAVG+HIhrqpQawmUVcDRkuJv2K2UT2+oqR8F8TA== + dependencies: + "@firebase/component" "0.6.12" + "@firebase/logger" "0.4.4" + "@firebase/util" "1.10.3" + "@firebase/webchannel-wrapper" "1.0.3" + "@grpc/grpc-js" "~1.9.0" + "@grpc/proto-loader" "^0.7.8" + tslib "^2.1.0" + +"@firebase/functions-compat@0.3.18": + version "0.3.18" + resolved "https://registry.yarnpkg.com/@firebase/functions-compat/-/functions-compat-0.3.18.tgz#c6a4f6b0762c6990db0aab244420c3e1240fda2b" + integrity sha512-N7+RN5GVus2ORB8cqfSNhfSn4iaYws6F8uCCfn4mtjC7zYS/KH6muzNAhZUdUqlv5YazbVmvxlAoYYF39i8Qzg== + dependencies: + "@firebase/component" "0.6.12" + "@firebase/functions" "0.12.1" + "@firebase/functions-types" "0.6.3" + "@firebase/util" "1.10.3" + tslib "^2.1.0" + +"@firebase/functions-types@0.6.3": + version "0.6.3" + resolved "https://registry.yarnpkg.com/@firebase/functions-types/-/functions-types-0.6.3.tgz#f5faf770248b13f45d256f614230da6a11bfb654" + integrity sha512-EZoDKQLUHFKNx6VLipQwrSMh01A1SaL3Wg6Hpi//x6/fJ6Ee4hrAeswK99I5Ht8roiniKHw4iO0B1Oxj5I4plg== + +"@firebase/functions@0.12.1": + version "0.12.1" + resolved "https://registry.yarnpkg.com/@firebase/functions/-/functions-0.12.1.tgz#09ca7386619b0c50c535f6695e5be0712d3e4730" + integrity sha512-QucRiFrvMMmIGTRhL7ZK2IeBnAWP7lAmfFREMpEtX47GjVqDqGxdFs+Mg7XBzxSc9UjDO4Rxf+aE9xJHU6bGwg== + dependencies: + "@firebase/app-check-interop-types" "0.3.3" + "@firebase/auth-interop-types" "0.2.4" + "@firebase/component" "0.6.12" + "@firebase/messaging-interop-types" "0.2.3" + "@firebase/util" "1.10.3" + tslib "^2.1.0" + +"@firebase/installations-compat@0.2.12": + version "0.2.12" + resolved "https://registry.yarnpkg.com/@firebase/installations-compat/-/installations-compat-0.2.12.tgz#ee6396f3cc787c0dd4fc5dd87fec1db9dbb40c97" + integrity sha512-RhcGknkxmFu92F6Jb3rXxv6a4sytPjJGifRZj8MSURPuv2Xu+/AispCXEfY1ZraobhEHTG5HLGsP6R4l9qB5aA== + dependencies: + "@firebase/component" "0.6.12" + "@firebase/installations" "0.6.12" + "@firebase/installations-types" "0.5.3" + "@firebase/util" "1.10.3" + tslib "^2.1.0" + +"@firebase/installations-types@0.5.3": + version "0.5.3" + resolved "https://registry.yarnpkg.com/@firebase/installations-types/-/installations-types-0.5.3.tgz#cac8a14dd49f09174da9df8ae453f9b359c3ef2f" + integrity sha512-2FJI7gkLqIE0iYsNQ1P751lO3hER+Umykel+TkLwHj6plzWVxqvfclPUZhcKFVQObqloEBTmpi2Ozn7EkCABAA== + +"@firebase/installations@0.6.12": + version "0.6.12" + resolved "https://registry.yarnpkg.com/@firebase/installations/-/installations-0.6.12.tgz#6d9ad14e60caa8fae4ec0120c0e46ceb9d6fbdae" + integrity sha512-ES/WpuAV2k2YtBTvdaknEo7IY8vaGjIjS3zhnHSAIvY9KwTR8XZFXOJoZ3nSkjN1A5R4MtEh+07drnzPDg9vaw== + dependencies: + "@firebase/component" "0.6.12" + "@firebase/util" "1.10.3" + idb "7.1.1" + tslib "^2.1.0" + +"@firebase/logger@0.4.4": + version "0.4.4" + resolved "https://registry.yarnpkg.com/@firebase/logger/-/logger-0.4.4.tgz#29e8379d20fd1149349a195ee6deee4573a86f48" + integrity sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g== + dependencies: + tslib "^2.1.0" + +"@firebase/messaging-compat@0.2.16": + version "0.2.16" + resolved "https://registry.yarnpkg.com/@firebase/messaging-compat/-/messaging-compat-0.2.16.tgz#533af4542a54b932146d175d5687aedd428be972" + integrity sha512-9HZZ88Ig3zQ0ok/Pwt4gQcNsOhoEy8hDHoGsV1am6ulgMuGuDVD2gl11Lere2ksL+msM12Lddi2x/7TCqmODZw== + dependencies: + "@firebase/component" "0.6.12" + "@firebase/messaging" "0.12.16" + "@firebase/util" "1.10.3" + tslib "^2.1.0" + +"@firebase/messaging-interop-types@0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.3.tgz#e647c9cd1beecfe6a6e82018a6eec37555e4da3e" + integrity sha512-xfzFaJpzcmtDjycpDeCUj0Ge10ATFi/VHVIvEEjDNc3hodVBQADZ7BWQU7CuFpjSHE+eLuBI13z5F/9xOoGX8Q== + +"@firebase/messaging@0.12.16": + version "0.12.16" + resolved "https://registry.yarnpkg.com/@firebase/messaging/-/messaging-0.12.16.tgz#bd8a768274bdc4368396bd9eaa356bffb998bef2" + integrity sha512-VJ8sCEIeP3+XkfbJA7410WhYGHdloYFZXoHe/vt+vNVDGw8JQPTQSVTRvjrUprEf5I4Tbcnpr2H34lS6zhCHSA== + dependencies: + "@firebase/component" "0.6.12" + "@firebase/installations" "0.6.12" + "@firebase/messaging-interop-types" "0.2.3" + "@firebase/util" "1.10.3" + idb "7.1.1" + tslib "^2.1.0" + +"@firebase/performance-compat@0.2.12": + version "0.2.12" + resolved "https://registry.yarnpkg.com/@firebase/performance-compat/-/performance-compat-0.2.12.tgz#069284005e3f29339b570ee517b813d9bdbc0a89" + integrity sha512-DyCbDTIwtBTGsEiQxTz/TD23a0na2nrDozceQ5kVkszyFYvliB0YK/9el0wAGIG91SqgTG9pxHtYErzfZc0VWw== + dependencies: + "@firebase/component" "0.6.12" + "@firebase/logger" "0.4.4" + "@firebase/performance" "0.6.12" + "@firebase/performance-types" "0.2.3" + "@firebase/util" "1.10.3" + tslib "^2.1.0" + +"@firebase/performance-types@0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@firebase/performance-types/-/performance-types-0.2.3.tgz#5ce64e90fa20ab5561f8b62a305010cf9fab86fb" + integrity sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ== + +"@firebase/performance@0.6.12": + version "0.6.12" + resolved "https://registry.yarnpkg.com/@firebase/performance/-/performance-0.6.12.tgz#58763cbbe31673351e1494875a5c10c6b68e1322" + integrity sha512-8mYL4z2jRlKXAi2hjk4G7o2sQLnJCCuTbyvti/xmHf5ZvOIGB01BZec0aDuBIXO+H1MLF62dbye/k91Fr+yc8g== + dependencies: + "@firebase/component" "0.6.12" + "@firebase/installations" "0.6.12" + "@firebase/logger" "0.4.4" + "@firebase/util" "1.10.3" + tslib "^2.1.0" + +"@firebase/remote-config-compat@0.2.12": + version "0.2.12" + resolved "https://registry.yarnpkg.com/@firebase/remote-config-compat/-/remote-config-compat-0.2.12.tgz#ae0b597b3228deef0e3c6b2c6e631f19213eca4c" + integrity sha512-91jLWPtubIuPBngg9SzwvNCWzhMLcyBccmt7TNZP+y1cuYFNOWWHKUXQ3IrxCLB7WwLqQaEu7fTDAjHsTyBsSw== + dependencies: + "@firebase/component" "0.6.12" + "@firebase/logger" "0.4.4" + "@firebase/remote-config" "0.5.0" + "@firebase/remote-config-types" "0.4.0" + "@firebase/util" "1.10.3" + tslib "^2.1.0" + +"@firebase/remote-config-types@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@firebase/remote-config-types/-/remote-config-types-0.4.0.tgz#91b9a836d5ca30ced68c1516163b281fbb544537" + integrity sha512-7p3mRE/ldCNYt8fmWMQ/MSGRmXYlJ15Rvs9Rk17t8p0WwZDbeK7eRmoI1tvCPaDzn9Oqh+yD6Lw+sGLsLg4kKg== + +"@firebase/remote-config@0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@firebase/remote-config/-/remote-config-0.5.0.tgz#30212fa77adba8a62fc6408eb32122147ae80790" + integrity sha512-weiEbpBp5PBJTHUWR4GwI7ZacaAg68BKha5QnZ8Go65W4oQjEWqCW/rfskABI/OkrGijlL3CUmCB/SA6mVo0qA== + dependencies: + "@firebase/component" "0.6.12" + "@firebase/installations" "0.6.12" + "@firebase/logger" "0.4.4" + "@firebase/util" "1.10.3" + tslib "^2.1.0" + +"@firebase/storage-compat@0.3.15": + version "0.3.15" + resolved "https://registry.yarnpkg.com/@firebase/storage-compat/-/storage-compat-0.3.15.tgz#02a18e0e1866849206dba7b075a4dcd99489aae7" + integrity sha512-Z9afjrK2O9o1ZHWCpprCGZ1BTc3BbvpZvi6tkSteC8H3W/fMM6x+RoSunlzD3hEVV5bkbwdJIqNClLMchvyoPA== + dependencies: + "@firebase/component" "0.6.12" + "@firebase/storage" "0.13.5" + "@firebase/storage-types" "0.8.3" + "@firebase/util" "1.10.3" + tslib "^2.1.0" + +"@firebase/storage-types@0.8.3": + version "0.8.3" + resolved "https://registry.yarnpkg.com/@firebase/storage-types/-/storage-types-0.8.3.tgz#2531ef593a3452fc12c59117195d6485c6632d3d" + integrity sha512-+Muk7g9uwngTpd8xn9OdF/D48uiQ7I1Fae7ULsWPuKoCH3HU7bfFPhxtJYzyhjdniowhuDpQcfPmuNRAqZEfvg== + +"@firebase/storage@0.13.5": + version "0.13.5" + resolved "https://registry.yarnpkg.com/@firebase/storage/-/storage-0.13.5.tgz#108c86c9cd359aebd306882eb61ce6a8b1deb417" + integrity sha512-sB/7HNuW0N9tITyD0RxVLNCROuCXkml5i/iPqjwOGKC0xiUfpCOjBE+bb0ABMoN1qYZfqk0y9IuI2TdomjmkNw== + dependencies: + "@firebase/component" "0.6.12" + "@firebase/util" "1.10.3" + tslib "^2.1.0" + +"@firebase/util@1.10.3": + version "1.10.3" + resolved "https://registry.yarnpkg.com/@firebase/util/-/util-1.10.3.tgz#63fc5fea7b36236219c4875731597494416678d1" + integrity sha512-wfoF5LTy0m2ufUapV0ZnpcGQvuavTbJ5Qr1Ze9OJGL70cSMvhDyjS4w2121XdA3lGZSTOsDOyGhpoDtYwck85A== + dependencies: + tslib "^2.1.0" + +"@firebase/vertexai@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@firebase/vertexai/-/vertexai-1.0.3.tgz#815efed8c16105676ea090daed963be72a01fb68" + integrity sha512-SQHg/RPb3LwQs/xiLcvAZYz9NXyDSZUIIwvgsKh6e4wdULAfyPCZIu6Y2ZYIhZLfk9Q44cKZ+++7RPTaqQJdYA== + dependencies: + "@firebase/app-check-interop-types" "0.3.3" + "@firebase/component" "0.6.12" + "@firebase/logger" "0.4.4" + "@firebase/util" "1.10.3" + tslib "^2.1.0" + +"@firebase/webchannel-wrapper@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.3.tgz#a73bab8eb491d7b8b7be2f0e6c310647835afe83" + integrity sha512-2xCRM9q9FlzGZCdgDMJwc0gyUkWFtkosy7Xxr6sFgQwn+wMNIWd7xIvYNauU1r64B5L5rsGKy/n9TKJ0aAFeqQ== + "@floating-ui/core@^1.4.2": version "1.5.0" resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.5.0.tgz#5c05c60d5ae2d05101c3021c1a2a350ddc027f8c" @@ -2366,6 +2761,82 @@ resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz#ecda5712b61ac852c760d8b3c79c96adca5554e5" integrity sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg== +"@google-cloud/firestore@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@google-cloud/firestore/-/firestore-7.11.0.tgz#a8a2b61d5069ba23ff2a1b98eac78d15a904a40f" + integrity sha512-88uZ+jLsp1aVMj7gh3EKYH1aulTAMFAp8sH/v5a9w8q8iqSG27RiWLoxSAFr/XocZ9hGiWH1kEnBw+zl3xAgNA== + dependencies: + "@opentelemetry/api" "^1.3.0" + fast-deep-equal "^3.1.1" + functional-red-black-tree "^1.0.1" + google-gax "^4.3.3" + protobufjs "^7.2.6" + +"@google-cloud/paginator@^5.0.0": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@google-cloud/paginator/-/paginator-5.0.2.tgz#86ad773266ce9f3b82955a8f75e22cd012ccc889" + integrity sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg== + dependencies: + arrify "^2.0.0" + extend "^3.0.2" + +"@google-cloud/projectify@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@google-cloud/projectify/-/projectify-4.0.0.tgz#d600e0433daf51b88c1fa95ac7f02e38e80a07be" + integrity sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA== + +"@google-cloud/promisify@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@google-cloud/promisify/-/promisify-4.0.0.tgz#a906e533ebdd0f754dca2509933334ce58b8c8b1" + integrity sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g== + +"@google-cloud/storage@^7.14.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@google-cloud/storage/-/storage-7.15.0.tgz#a9f26314f911a9e7f3d5b443f4bd2304936e80e9" + integrity sha512-/j/+8DFuEOo33fbdX0V5wjooOoFahEaMEdImHBmM2tH9MPHJYNtmXOf2sGUmZmiufSukmBEvdlzYgDkkgeBiVQ== + dependencies: + "@google-cloud/paginator" "^5.0.0" + "@google-cloud/projectify" "^4.0.0" + "@google-cloud/promisify" "^4.0.0" + abort-controller "^3.0.0" + async-retry "^1.3.3" + duplexify "^4.1.3" + fast-xml-parser "^4.4.1" + gaxios "^6.0.2" + google-auth-library "^9.6.3" + html-entities "^2.5.2" + mime "^3.0.0" + p-limit "^3.0.1" + retry-request "^7.0.0" + teeny-request "^9.0.0" + uuid "^8.0.0" + +"@grpc/grpc-js@^1.10.9": + version "1.12.5" + resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.12.5.tgz#0064a28fe9b1ec54ac27e1c9bf70720aa01285e8" + integrity sha512-d3iiHxdpg5+ZcJ6jnDSOT8Z0O0VMVGy34jAnYLUX8yd36b1qn8f1TwOA/Lc7TsOh03IkPJ38eGI5qD2EjNkoEA== + dependencies: + "@grpc/proto-loader" "^0.7.13" + "@js-sdsl/ordered-map" "^4.4.2" + +"@grpc/grpc-js@~1.9.0": + version "1.9.15" + resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.9.15.tgz#433d7ac19b1754af690ea650ab72190bd700739b" + integrity sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ== + dependencies: + "@grpc/proto-loader" "^0.7.8" + "@types/node" ">=12.12.47" + +"@grpc/proto-loader@^0.7.13", "@grpc/proto-loader@^0.7.8": + version "0.7.13" + resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.7.13.tgz#f6a44b2b7c9f7b609f5748c6eac2d420e37670cf" + integrity sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw== + dependencies: + lodash.camelcase "^4.3.0" + long "^5.0.0" + protobufjs "^7.2.5" + yargs "^17.7.2" + "@hcaptcha/react-hcaptcha@^1.8.1": version "1.8.1" resolved "https://registry.yarnpkg.com/@hcaptcha/react-hcaptcha/-/react-hcaptcha-1.8.1.tgz#3e6e0423100158bae089e4ef6507db0d4c62ec3f" @@ -2662,6 +3133,11 @@ "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" +"@js-sdsl/ordered-map@^4.4.2": + version "4.4.2" + resolved "https://registry.yarnpkg.com/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz#9299f82874bab9e4c7f9c48d865becbfe8d6907c" + integrity sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw== + "@mongodb-js/saslprep@^1.1.0": version "1.1.9" resolved "https://registry.yarnpkg.com/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz#e974bab8eca9faa88677d4ea4da8d09a52069004" @@ -2759,6 +3235,11 @@ resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.8.0.tgz#5aa7abb48f23f693068ed2999ae627d2f7d902ec" integrity sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w== +"@opentelemetry/api@^1.3.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.9.0.tgz#d03eba68273dc0f7509e2a3d5cba21eae10379fe" + integrity sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg== + "@opentelemetry/core@^1.14.0": version "1.14.0" resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.14.0.tgz#64e876b29cb736c984d54164cd47433f513eafd3" @@ -3166,6 +3647,11 @@ "@types/connect" "*" "@types/node" "*" +"@types/caseless@*": + version "0.12.5" + resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.5.tgz#db9468cb1b1b5a925b8f34822f1669df0c5472f5" + integrity sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg== + "@types/connect@*": version "3.4.35" resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" @@ -3222,6 +3708,16 @@ "@types/qs" "*" "@types/serve-static" "*" +"@types/express@^4.17.17": + version "4.17.21" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d" + integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.33" + "@types/qs" "*" + "@types/serve-static" "*" + "@types/glob@^7.1.1": version "7.2.0" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" @@ -3286,11 +3782,24 @@ dependencies: "@types/node" "*" +"@types/jsonwebtoken@^9.0.2": + version "9.0.8" + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.8.tgz#313490052801edfb031bb32b6bbd77cc9f230852" + integrity sha512-7fx54m60nLFUVYlxAB1xpe9CBWX2vSrk50Y6ogRJ1v5xxtba7qXTg5BgYDN5dq+yuQQ9HaVlHJyAAt1/mxryFg== + dependencies: + "@types/ms" "*" + "@types/node" "*" + "@types/lodash@^4.14.165": version "4.14.195" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.195.tgz#bafc975b252eb6cea78882ce8a7b6bf22a6de632" integrity sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg== +"@types/long@^4.0.0": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" + integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== + "@types/mime@*": version "3.0.1" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" @@ -3306,6 +3815,11 @@ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== +"@types/ms@*": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@types/ms/-/ms-2.1.0.tgz#052aa67a48eccc4309d7f0191b7e41434b90bb78" + integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA== + "@types/node-fetch@^2.5.12": version "2.6.4" resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.4.tgz#1bc3a26de814f6bf466b25aeb1473fa1afe6a660" @@ -3324,6 +3838,13 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-16.4.3.tgz#c01c1a215721f6dec71b47d88b4687463601ba48" integrity sha512-GKM4FLMkWDc0sfx7tXqPWkM6NBow1kge0fgQh0bOnlqo4iT1kvTvMEKE0c1RtUGnbLlGRXiAA8SumE//90uKAg== +"@types/node@>=12.12.47", "@types/node@^22.8.7": + version "22.12.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.12.0.tgz#bf8af3b2af0837b5a62a368756ff2b705ae0048c" + integrity sha512-Fll2FZ1riMjNmlmJOdAyY5pUbkftXslB5DgEzlIuNaiWhXd00FhWxVC/r4yV/4wBb9JfImTu+jiSvXTkJ7F/gA== + dependencies: + undici-types "~6.20.0" + "@types/nprogress@0.2.0": version "0.2.0" resolved "https://registry.yarnpkg.com/@types/nprogress/-/nprogress-0.2.0.tgz#86c593682d4199212a0509cc3c4d562bbbd6e45f" @@ -3386,6 +3907,16 @@ "@types/scheduler" "*" csstype "^3.0.2" +"@types/request@^2.48.8": + version "2.48.12" + resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.12.tgz#0f590f615a10f87da18e9790ac94c29ec4c5ef30" + integrity sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw== + dependencies: + "@types/caseless" "*" + "@types/node" "*" + "@types/tough-cookie" "*" + form-data "^2.5.0" + "@types/resolve@1.17.1": version "1.17.1" resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" @@ -3431,6 +3962,11 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== +"@types/tough-cookie@*": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.5.tgz#cb6e2a691b70cb177c6e3ae9c1d2e8b2ea8cd304" + integrity sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA== + "@types/trusted-types@^2.0.2": version "2.0.3" resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.3.tgz#a136f83b0758698df454e328759dbd3d44555311" @@ -3567,6 +4103,13 @@ abbrev@1, abbrev@^1.0.0: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + acorn-import-attributes@^1.9.5: version "1.9.5" resolved "https://registry.yarnpkg.com/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz#7eb1557b1ba05ef18b5ed0ec67591bfab04688ef" @@ -3594,6 +4137,11 @@ agent-base@6, agent-base@^6.0.2: dependencies: debug "4" +agent-base@^7.1.2: + version "7.1.3" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.3.tgz#29435eb821bc4194633a5b89e5bc4703bafc25a1" + integrity sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw== + agentkeepalive@^4.2.1: version "4.3.0" resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.3.0.tgz#bb999ff07412653c1803b3ced35e50729830a255" @@ -3814,6 +4362,11 @@ array.prototype.tosorted@^1.1.1: es-shim-unscopables "^1.0.0" get-intrinsic "^1.1.3" +arrify@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" + integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== + asap@^2.0.0: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" @@ -3824,6 +4377,13 @@ ast-types-flow@^0.0.7: resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" integrity sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag== +async-retry@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.3.3.tgz#0e7f36c04d8478e7a58bdbed80cedf977785f280" + integrity sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw== + dependencies: + retry "0.13.1" + async@^3.2.3: version "3.2.4" resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" @@ -3981,7 +4541,7 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base64-js@^1.3.1: +base64-js@^1.3.0, base64-js@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -4001,6 +4561,11 @@ bignumber.js@9.0.0: resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.0.tgz#805880f84a329b5eac6e7cb6f8274b6d82bdf075" integrity sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A== +bignumber.js@^9.0.0: + version "9.1.2" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" + integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug== + binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" @@ -4347,7 +4912,7 @@ colorette@2.0.19: resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== -combined-stream@^1.0.8: +combined-stream@^1.0.6, combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -4829,12 +5394,22 @@ domutils@^3.0.1: domelementtype "^2.3.0" domhandler "^5.0.3" +duplexify@^4.0.0, duplexify@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-4.1.3.tgz#a07e1c0d0a2c001158563d32592ba58bddb0236f" + integrity sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA== + dependencies: + end-of-stream "^1.4.1" + inherits "^2.0.3" + readable-stream "^3.1.1" + stream-shift "^1.0.2" + eastasianwidth@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== -ecdsa-sig-formatter@1.0.11: +ecdsa-sig-formatter@1.0.11, ecdsa-sig-formatter@^1.0.11: version "1.0.11" resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== @@ -4898,6 +5473,13 @@ encoding@^0.1.13: dependencies: iconv-lite "^0.6.2" +end-of-stream@^1.4.1: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + enhanced-resolve@^5.12.0: version "5.15.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" @@ -5283,6 +5865,11 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + execa@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" @@ -5339,6 +5926,11 @@ express-rate-limit@^5.3.0: resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-5.5.1.tgz#110c23f6a65dfa96ab468eda95e71697bc6987a2" integrity sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg== +extend@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + external-editor@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" @@ -5348,6 +5940,11 @@ external-editor@^3.0.3: iconv-lite "^0.4.24" tmp "^0.0.33" +farmhash-modern@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/farmhash-modern/-/farmhash-modern-1.1.0.tgz#c36b34ad196290d57b0b482dc89e637d0b59835f" + integrity sha512-6ypT4XfgqJk/F3Yuv4SX26I3doUjt0GTG4a+JgWxXQpxXzTBq8fPUeGHfcYMMDPHJHm3yPOSjaeBwBGAHWXCdA== + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -5386,6 +5983,13 @@ fast-xml-parser@4.2.4: dependencies: strnum "^1.0.5" +fast-xml-parser@^4.4.1: + version "4.5.1" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.5.1.tgz#a7e665ff79b7919100a5202f23984b6150f9b31e" + integrity sha512-y655CeyUQ+jj7KBbYMc4FG01V8ZQqjN+gDYGJ50RtfsUB8iG9AmwmwoAgeKLJdmueKKMrH1RJ7yXHTSoczdv5w== + dependencies: + strnum "^1.0.5" + fastq@^1.6.0: version "1.15.0" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" @@ -5393,6 +5997,13 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" +faye-websocket@0.11.4: + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + fb-watchman@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" @@ -5470,6 +6081,59 @@ find-up@^5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" +firebase-admin@^13.0.2: + version "13.0.2" + resolved "https://registry.yarnpkg.com/firebase-admin/-/firebase-admin-13.0.2.tgz#ea4d9a739dde467d584820d8c38086bc4884a6a2" + integrity sha512-YWVpoN+tZVSRXF0qC0gojoF5bSqvBRbnBk8+xUtFiguM2L4vB7f0moAwV1VVWDDHvTnvQ68OyTMpdp6wKo/clw== + dependencies: + "@fastify/busboy" "^3.0.0" + "@firebase/database-compat" "^2.0.0" + "@firebase/database-types" "^1.0.6" + "@types/node" "^22.8.7" + farmhash-modern "^1.1.0" + google-auth-library "^9.14.2" + jsonwebtoken "^9.0.0" + jwks-rsa "^3.1.0" + node-forge "^1.3.1" + uuid "^11.0.2" + optionalDependencies: + "@google-cloud/firestore" "^7.11.0" + "@google-cloud/storage" "^7.14.0" + +firebase@^11.2.0: + version "11.2.0" + resolved "https://registry.yarnpkg.com/firebase/-/firebase-11.2.0.tgz#843de48382fcaf8050a4a278f35d094fb9960fda" + integrity sha512-ztwPhBLAZMVNZjBeQzzTM4rk2rsRXmdFYcnvjAXh+StbiFVshHKaPO9VRGMUzF48du4Mkz6jN1wkmYCuUJPxLA== + dependencies: + "@firebase/analytics" "0.10.11" + "@firebase/analytics-compat" "0.2.17" + "@firebase/app" "0.10.18" + "@firebase/app-check" "0.8.11" + "@firebase/app-check-compat" "0.3.18" + "@firebase/app-compat" "0.2.48" + "@firebase/app-types" "0.9.3" + "@firebase/auth" "1.8.2" + "@firebase/auth-compat" "0.5.17" + "@firebase/data-connect" "0.2.0" + "@firebase/database" "1.0.11" + "@firebase/database-compat" "2.0.2" + "@firebase/firestore" "4.7.6" + "@firebase/firestore-compat" "0.3.41" + "@firebase/functions" "0.12.1" + "@firebase/functions-compat" "0.3.18" + "@firebase/installations" "0.6.12" + "@firebase/installations-compat" "0.2.12" + "@firebase/messaging" "0.12.16" + "@firebase/messaging-compat" "0.2.16" + "@firebase/performance" "0.6.12" + "@firebase/performance-compat" "0.2.12" + "@firebase/remote-config" "0.5.0" + "@firebase/remote-config-compat" "0.2.12" + "@firebase/storage" "0.13.5" + "@firebase/storage-compat" "0.3.15" + "@firebase/util" "1.10.3" + "@firebase/vertexai" "1.0.3" + flat-cache@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" @@ -5498,6 +6162,16 @@ foreground-child@^3.1.0: cross-spawn "^7.0.0" signal-exit "^4.0.1" +form-data@^2.5.0: + version "2.5.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.2.tgz#dc653743d1de2fcc340ceea38079daf6e9069fd2" + integrity sha512-GgwY0PS7DbXqajuGf4OYlsrIu3zgxD6Vvql43IBhm6MahqA5SK/7mwhtNj2AdH2z35YR34ujJ7BN+3fFC3jP5Q== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + safe-buffer "^5.2.1" + form-data@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" @@ -5593,6 +6267,11 @@ function.prototype.name@^1.1.5: es-abstract "^1.19.0" functions-have-names "^1.2.2" +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== + functions-have-names@^1.2.2, functions-have-names@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" @@ -5612,6 +6291,25 @@ gauge@^4.0.3: strip-ansi "^6.0.1" wide-align "^1.1.5" +gaxios@^6.0.0, gaxios@^6.0.2, gaxios@^6.1.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/gaxios/-/gaxios-6.7.1.tgz#ebd9f7093ede3ba502685e73390248bb5b7f71fb" + integrity sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ== + dependencies: + extend "^3.0.2" + https-proxy-agent "^7.0.1" + is-stream "^2.0.0" + node-fetch "^2.6.9" + uuid "^9.0.1" + +gcp-metadata@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/gcp-metadata/-/gcp-metadata-6.1.0.tgz#9b0dd2b2445258e7597f2024332d20611cbd6b8c" + integrity sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg== + dependencies: + gaxios "^6.0.0" + json-bigint "^1.0.0" + generate-license-file@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/generate-license-file/-/generate-license-file-1.1.0.tgz#080811e8b8c6b7b5225d15e2fcd33ba00e1880ba" @@ -5806,6 +6504,36 @@ globby@^6.1.0: pify "^2.0.0" pinkie-promise "^2.0.0" +google-auth-library@^9.14.2, google-auth-library@^9.3.0, google-auth-library@^9.6.3: + version "9.15.1" + resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-9.15.1.tgz#0c5d84ed1890b2375f1cd74f03ac7b806b392928" + integrity sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng== + dependencies: + base64-js "^1.3.0" + ecdsa-sig-formatter "^1.0.11" + gaxios "^6.1.1" + gcp-metadata "^6.1.0" + gtoken "^7.0.0" + jws "^4.0.0" + +google-gax@^4.3.3: + version "4.4.1" + resolved "https://registry.yarnpkg.com/google-gax/-/google-gax-4.4.1.tgz#95a9cf7ee7777ac22d1926a45b5f886dd8beecae" + integrity sha512-Phyp9fMfA00J3sZbJxbbB4jC55b7DBjE3F6poyL3wKMEBVKA79q6BGuHcTiM28yOzVql0NDbRL8MLLh8Iwk9Dg== + dependencies: + "@grpc/grpc-js" "^1.10.9" + "@grpc/proto-loader" "^0.7.13" + "@types/long" "^4.0.0" + abort-controller "^3.0.0" + duplexify "^4.0.0" + google-auth-library "^9.3.0" + node-fetch "^2.7.0" + object-hash "^3.0.0" + proto3-json-serializer "^2.0.2" + protobufjs "^7.3.2" + retry-request "^7.0.0" + uuid "^9.0.1" + gopd@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" @@ -5823,6 +6551,14 @@ graphemer@^1.4.0: resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== +gtoken@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-7.1.0.tgz#d61b4ebd10132222817f7222b1e6064bd463fc26" + integrity sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw== + dependencies: + gaxios "^6.0.0" + jws "^4.0.0" + has-bigints@^1.0.1, has-bigints@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" @@ -5898,6 +6634,11 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== +html-entities@^2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.5.2.tgz#201a3cf95d3a15be7099521620d19dfb4f65359f" + integrity sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA== + html-escaper@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" @@ -5928,6 +6669,11 @@ http-cache-semantics@^4.1.1: resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== +http-parser-js@>=0.5.1: + version "0.5.9" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.9.tgz#b817b3ca0edea6236225000d795378707c169cec" + integrity sha512-n1XsPy3rXVxlqxVioEWdC+0+M+SQw0DpJynwtOPo1X+ZlvdzTLtDBIJJlDQTnwZIFJrZSzSGmIOUdP8tu+SgLw== + http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -5945,6 +6691,14 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +https-proxy-agent@^7.0.1: + version "7.0.6" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz#da8dfeac7da130b05c2ba4b59c9b6cd66611a6b9" + integrity sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw== + dependencies: + agent-base "^7.1.2" + debug "4" + human-signals@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" @@ -5976,7 +6730,7 @@ iconv-lite@^0.6.2: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" -idb@^7.0.1: +idb@7.1.1, idb@^7.0.1: version "7.1.1" resolved "https://registry.yarnpkg.com/idb/-/idb-7.1.1.tgz#d910ded866d32c7ced9befc5bfdf36f572ced72b" integrity sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ== @@ -6820,6 +7574,11 @@ josa@3.0.1, josa@^3.0.1: dependencies: jongseong "^0.4.2" +jose@^4.14.6: + version "4.15.9" + resolved "https://registry.yarnpkg.com/jose/-/jose-4.15.9.tgz#9b68eda29e9a0614c042fa29387196c7dd800100" + integrity sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -6850,6 +7609,13 @@ jsesc@~0.5.0: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== +json-bigint@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-1.0.0.tgz#ae547823ac0cad8398667f8cd9ef4730f5b01ff1" + integrity sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ== + dependencies: + bignumber.js "^9.0.0" + json-parse-even-better-errors@^2.3.0: version "2.3.1" resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" @@ -6944,6 +7710,27 @@ jwa@^1.4.1: ecdsa-sig-formatter "1.0.11" safe-buffer "^5.0.1" +jwa@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-2.0.0.tgz#a7e9c3f29dae94027ebcaf49975c9345593410fc" + integrity sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jwks-rsa@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/jwks-rsa/-/jwks-rsa-3.1.0.tgz#50406f23e38c9b2682cd437f824d7d61aa983171" + integrity sha512-v7nqlfezb9YfHHzYII3ef2a2j1XnGeSE/bK3WfumaYCqONAIstJbrEGapz4kadScZzEt7zYCN7bucj8C0Mv/Rg== + dependencies: + "@types/express" "^4.17.17" + "@types/jsonwebtoken" "^9.0.2" + debug "^4.3.4" + jose "^4.14.6" + limiter "^1.1.5" + lru-memoizer "^2.2.0" + jws@^3.2.2: version "3.2.2" resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" @@ -6952,6 +7739,14 @@ jws@^3.2.2: jwa "^1.4.1" safe-buffer "^5.0.1" +jws@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jws/-/jws-4.0.0.tgz#2d4e8cf6a318ffaa12615e9dec7e86e6c97310f4" + integrity sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg== + dependencies: + jwa "^2.0.0" + safe-buffer "^5.0.1" + kareem@2.5.1: version "2.5.1" resolved "https://registry.yarnpkg.com/kareem/-/kareem-2.5.1.tgz#7b8203e11819a8e77a34b3517d3ead206764d15d" @@ -7040,7 +7835,7 @@ lilconfig@^2.0.5, lilconfig@^2.1.0: resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== -limiter@1.1.5: +limiter@1.1.5, limiter@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/limiter/-/limiter-1.1.5.tgz#8f92a25b3b16c6131293a0cc834b4a838a2aa7c2" integrity sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA== @@ -7093,6 +7888,16 @@ lodash-es@^4.17.15, lodash-es@^4.17.21: resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== + +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== + lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" @@ -7142,6 +7947,13 @@ loose-envify@^1.1.0, loose-envify@^1.4.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" +lru-cache@6.0.0, lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -7149,13 +7961,6 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - lru-cache@^7.14.0, lru-cache@^7.7.1: version "7.18.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" @@ -7166,6 +7971,14 @@ lru-cache@^9.1.1: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-9.1.2.tgz#255fdbc14b75589d6d0e73644ca167a8db506835" integrity sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ== +lru-memoizer@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/lru-memoizer/-/lru-memoizer-2.3.0.tgz#ef0fbc021bceb666794b145eefac6be49dc47f31" + integrity sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug== + dependencies: + lodash.clonedeep "^4.5.0" + lru-cache "6.0.0" + magic-bytes.js@^1.0.15: version "1.0.15" resolved "https://registry.yarnpkg.com/magic-bytes.js/-/magic-bytes.js-1.0.15.tgz#3c9d2b7d45bb8432482646b5f74bbf6725274616" @@ -7265,6 +8078,11 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" +mime@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7" + integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A== + mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" @@ -7565,6 +8383,18 @@ node-fetch@^2.6.7: dependencies: whatwg-url "^5.0.0" +node-fetch@^2.6.9, node-fetch@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== + dependencies: + whatwg-url "^5.0.0" + +node-forge@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + node-gyp-build@<4.0, node-gyp-build@^3.9.0: version "3.9.0" resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-3.9.0.tgz#53a350187dd4d5276750da21605d1cb681d09e25" @@ -7736,7 +8566,7 @@ object.values@^1.1.6: define-properties "^1.1.4" es-abstract "^1.20.4" -once@^1.3.0: +once@^1.3.0, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== @@ -7823,7 +8653,7 @@ p-limit@^2.0.0, p-limit@^2.2.0: dependencies: p-try "^2.0.0" -p-limit@^3.0.2, p-limit@^3.1.0: +p-limit@^3.0.1, p-limit@^3.0.2, p-limit@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== @@ -8373,6 +9203,13 @@ property-expr@^2.0.4: resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.5.tgz#278bdb15308ae16af3e3b9640024524f4dc02cb4" integrity sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA== +proto3-json-serializer@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/proto3-json-serializer/-/proto3-json-serializer-2.0.2.tgz#5b705203b4d58f3880596c95fad64902617529dd" + integrity sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ== + dependencies: + protobufjs "^7.2.5" + protobufjs@^7.2.5: version "7.2.6" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.6.tgz#4a0ccd79eb292717aacf07530a07e0ed20278215" @@ -8391,6 +9228,24 @@ protobufjs@^7.2.5: "@types/node" ">=13.7.0" long "^5.0.0" +protobufjs@^7.2.6, protobufjs@^7.3.2: + version "7.4.0" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.4.0.tgz#7efe324ce9b3b61c82aae5de810d287bc08a248a" + integrity sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/node" ">=13.7.0" + long "^5.0.0" + proxy-from-env@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" @@ -8620,7 +9475,7 @@ readable-stream@2.3.7: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.6.0: +readable-stream@^3.1.1, readable-stream@^3.6.0: version "3.6.2" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== @@ -8783,16 +9638,25 @@ restore-cursor@^3.1.0: onetime "^5.1.0" signal-exit "^3.0.2" +retry-request@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/retry-request/-/retry-request-7.0.2.tgz#60bf48cfb424ec01b03fca6665dee91d06dd95f3" + integrity sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w== + dependencies: + "@types/request" "^2.48.8" + extend "^3.0.2" + teeny-request "^9.0.0" + +retry@0.13.1, retry@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + retry@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== -retry@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" - integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== - reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" @@ -8877,7 +9741,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: +safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -9213,6 +10077,18 @@ stacktrace-parser@^0.1.10: dependencies: type-fest "^0.7.1" +stream-events@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/stream-events/-/stream-events-1.0.5.tgz#bbc898ec4df33a4902d892333d47da9bf1c406d5" + integrity sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg== + dependencies: + stubs "^3.0.0" + +stream-shift@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.3.tgz#85b8fab4d71010fc3ba8772e8046cc49b8a3864b" + integrity sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ== + streamsearch@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" @@ -9389,6 +10265,11 @@ strnum@^1.0.5: resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db" integrity sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA== +stubs@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/stubs/-/stubs-3.0.0.tgz#e8d2ba1fa9c90570303c030b6900f7d5f89abe5b" + integrity sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw== + styled-jsx@5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.1.1.tgz#839a1c3aaacc4e735fed0781b8619ea5d0009d1f" @@ -9499,6 +10380,17 @@ tarn@^3.0.2: resolved "https://registry.yarnpkg.com/tarn/-/tarn-3.0.2.tgz#73b6140fbb881b71559c4f8bfde3d9a4b3d27693" integrity sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ== +teeny-request@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/teeny-request/-/teeny-request-9.0.0.tgz#18140de2eb6595771b1b02203312dfad79a4716d" + integrity sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g== + dependencies: + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" + node-fetch "^2.6.9" + stream-events "^1.0.5" + uuid "^9.0.0" + temp-dir@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e" @@ -9709,6 +10601,11 @@ tslib@^2.0.0, tslib@^2.3.1, tslib@^2.4.0, tslib@^2.5.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3" integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA== +tslib@^2.1.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== + tslib@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.1.tgz#fd8c9a0ff42590b25703c0acb3de3d3f4ede0410" @@ -9804,6 +10701,11 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" +undici-types@~6.20.0: + version "6.20.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433" + integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg== + undici@^5.22.1: version "5.28.5" resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.5.tgz#b2b94b6bf8f1d919bc5a6f31f2c01deb02e54d4b" @@ -9919,11 +10821,21 @@ util-extend@^1.0.1: resolved "https://registry.yarnpkg.com/util-extend/-/util-extend-1.0.3.tgz#a7c216d267545169637b3b6edc6ca9119e2ff93f" integrity sha512-mLs5zAK+ctllYBj+iAQvlDCwoxU/WDOUaJkcFudeiAX6OajC6BKXJUa9a+tbtkC11dz2Ufb7h0lyvIOVn4LADA== -uuid@^8.3.2: +uuid@^11.0.2: + version "11.0.5" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-11.0.5.tgz#07b46bdfa6310c92c3fb3953a8720f170427fc62" + integrity sha512-508e6IcKLrhxKdBbcA2b4KQZlLVp2+J5UwQ6F7Drckkc5N9ZJwFa4TgWtsww9UG8fGHbm6gbV19TdM5pQ4GaIA== + +uuid@^8.0.0, uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== +uuid@^9.0.0, uuid@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== + v8-to-istanbul@^9.0.1: version "9.1.0" resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz#1b83ed4e397f58c85c266a570fc2558b5feb9265" @@ -9983,6 +10895,20 @@ webpack-sources@^1.4.3: resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== +websocket-driver@>=0.5.1: + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + whatwg-url@^11.0.0: version "11.0.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-11.0.0.tgz#0a849eebb5faf2119b901bb76fd795c2848d4018" @@ -10333,7 +11259,7 @@ yargs@^14.2: y18n "^4.0.0" yargs-parser "^15.0.1" -yargs@^17.3.1: +yargs@^17.3.1, yargs@^17.7.2: version "17.7.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==