diff --git a/.env.example b/.env.example index 11d8a452..78205898 100644 --- a/.env.example +++ b/.env.example @@ -117,6 +117,7 @@ EMAIL_SERVER_PASSWORD='' # ********************************************************************************************************** # - APP STORE ********************************************************************************************** +# ⚠️ ⚠️ ⚠️ THESE WILL BE MIGRATED TO THE DATABASE TO PREVENT AWS's 4KB ENV QUOTA ⚠️ ⚠️ ⚠️ # - DAILY.CO VIDEO DAILY_API_KEY= DAILY_SCALE_PLAN='' diff --git a/apps/admin b/apps/admin index 943cd10d..cf71a8b4 160000 --- a/apps/admin +++ b/apps/admin @@ -1 +1 @@ -Subproject commit 943cd10de1f6661273d2ec18acdaa93118852714 +Subproject commit cf71a8b47ec9d37da7e4facb61356a293cb0bd13 diff --git a/apps/api b/apps/api index 2449d90b..6124577b 160000 --- a/apps/api +++ b/apps/api @@ -1 +1 @@ -Subproject commit 2449d90bcbbf4c0a379f4d766aee299caad488a2 +Subproject commit 6124577bc21502c018378a299e50fc96bff14b99 diff --git a/apps/web/components/Shell.tsx b/apps/web/components/Shell.tsx index d8cfa42a..4b69e84c 100644 --- a/apps/web/components/Shell.tsx +++ b/apps/web/components/Shell.tsx @@ -11,15 +11,15 @@ import { MoonIcon, ViewGridIcon, } from "@heroicons/react/solid"; +import { UserPlan } from "@prisma/client"; import { SessionContextValue, signOut, useSession } from "next-auth/react"; import Link from "next/link"; import { useRouter } from "next/router"; import React, { Fragment, ReactNode, useEffect } from "react"; -import toast, { Toaster } from "react-hot-toast"; +import { Toaster } from "react-hot-toast"; import { useIsEmbed } from "@calcom/embed-core"; import { useLocale } from "@calcom/lib/hooks/useLocale"; -import { UserPlan } from "@calcom/prisma/client"; import Button from "@calcom/ui/Button"; import Dropdown, { DropdownMenuContent, diff --git a/apps/web/lib/attendeeToPersonConversionType.ts b/apps/web/lib/attendeeToPersonConversionType.ts index 08be1a25..5e1b2dd8 100644 --- a/apps/web/lib/attendeeToPersonConversionType.ts +++ b/apps/web/lib/attendeeToPersonConversionType.ts @@ -1,6 +1,6 @@ +import { Attendee } from "@prisma/client"; import { TFunction } from "next-i18next"; -import { Attendee } from "@calcom/prisma/client"; import { Person } from "@calcom/types/Calendar"; export const attendeeToPersonConversionType = (attendees: Attendee[], t: TFunction): Person[] => { diff --git a/apps/web/lib/emails/templates/attendee-request-reschedule-email.ts b/apps/web/lib/emails/templates/attendee-request-reschedule-email.ts index 5d0141fa..179b62e0 100644 --- a/apps/web/lib/emails/templates/attendee-request-reschedule-email.ts +++ b/apps/web/lib/emails/templates/attendee-request-reschedule-email.ts @@ -6,7 +6,6 @@ import utc from "dayjs/plugin/utc"; import { createEvent, DateArray, Person } from "ics"; import { getCancelLink } from "@calcom/lib/CalEventParser"; -import { Attendee } from "@calcom/prisma/client"; import { CalendarEvent } from "@calcom/types/Calendar"; import { diff --git a/apps/web/lib/getBooking.tsx b/apps/web/lib/getBooking.tsx index 2c61e93d..50682ae2 100644 --- a/apps/web/lib/getBooking.tsx +++ b/apps/web/lib/getBooking.tsx @@ -1,6 +1,4 @@ -import { PrismaClient } from "@prisma/client"; - -import { Prisma } from "@calcom/prisma/client"; +import { Prisma, PrismaClient } from "@prisma/client"; async function getBooking(prisma: PrismaClient, uid: string) { const booking = await prisma.booking.findFirst({ diff --git a/apps/web/lib/hooks/useExposePlanGlobally.ts b/apps/web/lib/hooks/useExposePlanGlobally.ts index 2e4132f4..77e0829a 100644 --- a/apps/web/lib/hooks/useExposePlanGlobally.ts +++ b/apps/web/lib/hooks/useExposePlanGlobally.ts @@ -1,6 +1,4 @@ -import { useEffect } from "react"; - -import { UserPlan } from "@calcom/prisma/client"; +import { UserPlan } from "@prisma/client"; /** * TODO: It should be exposed at a single place. diff --git a/apps/web/next.config.js b/apps/web/next.config.js index 65de64f7..74cc454a 100644 --- a/apps/web/next.config.js +++ b/apps/web/next.config.js @@ -87,7 +87,7 @@ const nextConfig = { ]; }, async redirects() { - return [ + const redirects = [ { source: "/settings", destination: "/settings/profile", @@ -104,6 +104,28 @@ const nextConfig = { permanent: false, }, ]; + + if (process.env.NEXT_PUBLIC_WEBAPP_URL === "https://app.cal.com") { + redirects.push( + { + source: "/apps/dailyvideo", + destination: "/apps/daily-video", + permanent: true, + }, + { + source: "/apps/huddle01_video", + destination: "/apps/huddle01", + permanent: true, + }, + { + source: "/apps/jitsi_video", + destination: "/apps/jitsi", + permanent: true, + } + ); + } + + return redirects; }, }; diff --git a/apps/web/pages/api/integrations/[...args].ts b/apps/web/pages/api/integrations/[...args].ts index 5a2656fb..27ebf58b 100644 --- a/apps/web/pages/api/integrations/[...args].ts +++ b/apps/web/pages/api/integrations/[...args].ts @@ -1,7 +1,5 @@ import { NextApiHandler, NextApiRequest, NextApiResponse } from "next"; -import appStore from "@calcom/app-store"; - import { getSession } from "@lib/auth"; import { HttpError } from "@lib/core/http/error"; @@ -19,13 +17,10 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => { const appName = _appName.split("_").join(""); // Transform `zoom_video` to `zoomvideo`; try { - // TODO: Find a way to dynamically import these modules - // const app = (await import(`@calcom/${appName}`)).default; - const app = appStore[appName as keyof typeof appStore]; - if (!(app && "api" in app && apiEndpoint in app.api)) - throw new HttpError({ statusCode: 404, message: `API handler not found` }); - - const handler = app.api[apiEndpoint as keyof typeof app.api] as NextApiHandler; + /* Absolute path didn't work */ + const handlerMap = (await import("@calcom/app-store/apiHandlers")).default; + const handlers = await handlerMap[appName as keyof typeof handlerMap]; + const handler = handlers[apiEndpoint as keyof typeof handlers] as NextApiHandler; if (typeof handler !== "function") throw new HttpError({ statusCode: 404, message: `API handler not found` }); diff --git a/apps/web/pages/apps/[slug].tsx b/apps/web/pages/apps/[slug].tsx index bf244935..20049b7d 100644 --- a/apps/web/pages/apps/[slug].tsx +++ b/apps/web/pages/apps/[slug].tsx @@ -1,13 +1,14 @@ import fs from "fs"; import matter from "gray-matter"; -import { GetStaticPaths, GetStaticPathsResult, GetStaticPropsContext } from "next"; +import { GetStaticPaths, GetStaticPropsContext } from "next"; import { MDXRemote } from "next-mdx-remote"; import { serialize } from "next-mdx-remote/serialize"; import Image from "next/image"; import Link from "next/link"; import path from "path"; -import { getAppRegistry } from "@calcom/app-store/_appRegistry"; +import { getAppWithMetadata } from "@calcom/app-store/_appRegistry"; +import prisma from "@calcom/prisma"; import useMediaQuery from "@lib/hooks/useMediaQuery"; import { inferSSRProps } from "@lib/types/inferSSRProps"; @@ -68,11 +69,8 @@ function SingleAppPage({ data, source }: inferSSRProps) { } export const getStaticPaths: GetStaticPaths<{ slug: string }> = async () => { - const appStore = getAppRegistry(); - const paths = appStore.reduce((paths, app) => { - paths.push({ params: { slug: app.slug } }); - return paths; - }, [] as GetStaticPathsResult<{ slug: string }>["paths"]); + const appStore = await prisma.app.findMany({ select: { slug: true } }); + const paths = appStore.map(({ slug }) => ({ params: { slug } })); return { paths, @@ -81,23 +79,19 @@ export const getStaticPaths: GetStaticPaths<{ slug: string }> = async () => { }; export const getStaticProps = async (ctx: GetStaticPropsContext) => { - const appStore = getAppRegistry(); + if (typeof ctx.params?.slug !== "string") return { notFound: true }; - if (typeof ctx.params?.slug !== "string") { - return { - notFound: true, - }; - } + const app = await prisma.app.findUnique({ + where: { slug: ctx.params.slug }, + }); - const singleApp = appStore.find((app) => app.slug === ctx.params?.slug); + if (!app) return { notFound: true }; - if (!singleApp) { - return { - notFound: true, - }; - } + const singleApp = await getAppWithMetadata(app); - const appDirname = singleApp.type.replace("_", ""); + if (!singleApp) return { notFound: true }; + + const appDirname = app.dirName; const README_PATH = path.join(process.cwd(), "..", "..", `packages/app-store/${appDirname}/README.mdx`); const postFilePath = path.join(README_PATH); let source = ""; diff --git a/apps/web/pages/apps/categories/[category].tsx b/apps/web/pages/apps/categories/[category].tsx index 89e7fcdb..91e0db6c 100644 --- a/apps/web/pages/apps/categories/[category].tsx +++ b/apps/web/pages/apps/categories/[category].tsx @@ -50,7 +50,7 @@ export default function Apps({ appStore }: InferGetStaticPropsType { - const appStore = getAppRegistry(); + const appStore = await getAppRegistry(); const paths = appStore.reduce((categories, app) => { if (!categories.includes(app.category)) { categories.push(app.category); @@ -67,7 +67,7 @@ export const getStaticPaths = async () => { export const getStaticProps = async () => { return { props: { - appStore: getAppRegistry(), + appStore: await getAppRegistry(), }, }; }; diff --git a/apps/web/pages/apps/categories/index.tsx b/apps/web/pages/apps/categories/index.tsx index 68444b49..c8830072 100644 --- a/apps/web/pages/apps/categories/index.tsx +++ b/apps/web/pages/apps/categories/index.tsx @@ -30,7 +30,7 @@ export default function Apps({ categories }: InferGetStaticPropsType { - const appStore = getAppRegistry(); + const appStore = await getAppRegistry(); const categories = appStore.reduce((c, app) => { c[app.category] = c[app.category] ? c[app.category] + 1 : 1; return c; diff --git a/apps/web/pages/apps/index.tsx b/apps/web/pages/apps/index.tsx index c1eb729c..94b61b98 100644 --- a/apps/web/pages/apps/index.tsx +++ b/apps/web/pages/apps/index.tsx @@ -24,7 +24,7 @@ export default function Apps({ appStore, categories }: InferGetStaticPropsType { - const appStore = getAppRegistry(); + const appStore = await getAppRegistry(); const categories = appStore.reduce((c, app) => { c[app.category] = c[app.category] ? c[app.category] + 1 : 1; return c; diff --git a/apps/web/pages/d/[link]/book.tsx b/apps/web/pages/d/[link]/book.tsx index 9b04d355..91c309b6 100644 --- a/apps/web/pages/d/[link]/book.tsx +++ b/apps/web/pages/d/[link]/book.tsx @@ -136,26 +136,6 @@ export async function getServerSideProps(context: GetServerSidePropsContext) { }; })[0]; - async function getBooking() { - return prisma.booking.findFirst({ - where: { - uid: asStringOrThrow(context.query.rescheduleUid), - }, - select: { - description: true, - attendees: { - select: { - email: true, - name: true, - }, - }, - }, - }); - } - - type Booking = Prisma.PromiseReturnType; - let booking: Booking | null = null; - const profile = { name: user.name || user.username, image: user.avatar, @@ -173,7 +153,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) { locationLabels: getLocationLabels(t), profile, eventType: eventTypeObject, - booking, + booking: null, trpcState: ssr.dehydrate(), isDynamicGroupBooking: false, hasHashedBookingLink: true, diff --git a/apps/web/pages/event-types/[type].tsx b/apps/web/pages/event-types/[type].tsx index 1c4d4cfc..325910e1 100644 --- a/apps/web/pages/event-types/[type].tsx +++ b/apps/web/pages/event-types/[type].tsx @@ -29,7 +29,7 @@ import { FormattedNumber, IntlProvider } from "react-intl"; import { JSONObject } from "superjson/dist/types"; import { z } from "zod"; -import { SelectGifInput } from "@calcom/app-store/giphyother/components"; +import { SelectGifInput } from "@calcom/app-store/giphy/components"; import getApps, { getLocationOptions, hasIntegration } from "@calcom/app-store/utils"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import showToast from "@calcom/lib/notification"; @@ -2104,6 +2104,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) => type: true, key: true, userId: true, + appId: true, }, }); diff --git a/apps/web/pages/getting-started.tsx b/apps/web/pages/getting-started.tsx index 0d04bbf5..e14d6bf7 100644 --- a/apps/web/pages/getting-started.tsx +++ b/apps/web/pages/getting-started.tsx @@ -708,6 +708,7 @@ export async function getServerSideProps(context: NextPageContext) { type: true, key: true, userId: true, + appId: true, }, }); diff --git a/apps/web/pages/team/[slug]/[type].tsx b/apps/web/pages/team/[slug]/[type].tsx index 8f15f1be..0b55693c 100644 --- a/apps/web/pages/team/[slug]/[type].tsx +++ b/apps/web/pages/team/[slug]/[type].tsx @@ -1,8 +1,7 @@ +import { UserPlan } from "@prisma/client"; import { GetServerSidePropsContext } from "next"; import { JSONObject } from "superjson/dist/types"; -import { UserPlan } from "@calcom/prisma/client"; - import { asStringOrNull } from "@lib/asStringOrNull"; import { getWorkingHours } from "@lib/availability"; import getBooking, { GetBookingType } from "@lib/getBooking"; diff --git a/apps/web/server/createContext.ts b/apps/web/server/createContext.ts index 4c4ef8b4..c17325da 100644 --- a/apps/web/server/createContext.ts +++ b/apps/web/server/createContext.ts @@ -55,6 +55,7 @@ async function getUserFromSession({ type: true, key: true, userId: true, + appId: true, }, orderBy: { id: "asc", diff --git a/apps/web/test/lib/getAvailabilityFromSchedule.test.ts b/apps/web/test/lib/getAvailabilityFromSchedule.test.ts index d6e2861b..51dfe6e0 100644 --- a/apps/web/test/lib/getAvailabilityFromSchedule.test.ts +++ b/apps/web/test/lib/getAvailabilityFromSchedule.test.ts @@ -1,10 +1,9 @@ import { expect, it } from "@jest/globals"; +import { Availability } from "@prisma/client"; import dayjs from "dayjs"; import customParseFormat from "dayjs/plugin/customParseFormat"; import MockDate from "mockdate"; -import { Availability } from "@calcom/prisma/client"; - import { getAvailabilityFromSchedule } from "@lib/availability"; dayjs.extend(customParseFormat); diff --git a/packages/app-store/_appRegistry.ts b/packages/app-store/_appRegistry.ts index 41c6570f..4710649c 100644 --- a/packages/app-store/_appRegistry.ts +++ b/packages/app-store/_appRegistry.ts @@ -1,15 +1,33 @@ +import prisma from "@calcom/prisma"; import { App } from "@calcom/types/App"; -import appStoreMetadata from "./metadata"; +export async function getAppWithMetadata(app: { dirName: string }) { + let appMetadata: App | null = null; + try { + appMetadata = (await import(`./${app.dirName}/_metadata`)).default as App; + } catch (error) { + if (error instanceof Error) { + console.error(`No metadata found for: "${app.dirName}". Message:`, error.message); + } + return null; + } + if (!appMetadata) return null; + // Let's not leak api keys to the front end + const { key, ...metadata } = appMetadata; + return metadata; +} /** Mainly to use in listings for the frontend, use in getStaticProps or getServerSideProps */ -export function getAppRegistry() { - return Object.values(appStoreMetadata).reduce((apps, app) => { +export async function getAppRegistry() { + const dbApps = await prisma.app.findMany({ select: { dirName: true, slug: true, categories: true } }); + const apps = [] as Omit[]; + for await (const dbapp of dbApps) { + const app = await getAppWithMetadata(dbapp); + if (!app) continue; // Skip if app isn't installed - if (!app.installed) return apps; - // Let's not leak api keys to the front end - const { key, ...metadata } = app; - apps.push(metadata); - return apps; - }, [] as Omit[]); + /* This is now handled from the DB */ + // if (!app.installed) return apps; + apps.push(app); + } + return apps; } diff --git a/packages/app-store/_utils/getAppKeysFromSlug.ts b/packages/app-store/_utils/getAppKeysFromSlug.ts new file mode 100644 index 00000000..f76fa9d0 --- /dev/null +++ b/packages/app-store/_utils/getAppKeysFromSlug.ts @@ -0,0 +1,10 @@ +import { Prisma } from "@prisma/client"; + +import prisma from "@calcom/prisma"; + +async function getAppKeysFromSlug(slug: string) { + const app = await prisma.app.findUnique({ where: { slug } }); + return app?.keys as Prisma.JsonObject; +} + +export default getAppKeysFromSlug; diff --git a/packages/app-store/_utils/useAddAppMutation.ts b/packages/app-store/_utils/useAddAppMutation.ts index 20b29a4c..4848348a 100644 --- a/packages/app-store/_utils/useAddAppMutation.ts +++ b/packages/app-store/_utils/useAddAppMutation.ts @@ -5,7 +5,7 @@ import { WEBAPP_URL } from "@calcom/lib/constants"; import { App } from "@calcom/types/App"; function useAddAppMutation(type: App["type"], options?: Parameters[2]) { - const appName = type.replaceAll("_", ""); + const appName = type.replace(/_/g, ""); const mutation = useMutation(async () => { const state: IntegrationOAuthCallbackState = { returnTo: WEBAPP_URL + "/apps/installed" + location.search, diff --git a/packages/app-store/apiHandlers.tsx b/packages/app-store/apiHandlers.tsx new file mode 100644 index 00000000..dffe83e9 --- /dev/null +++ b/packages/app-store/apiHandlers.tsx @@ -0,0 +1,19 @@ +export const apiHandlers = { + // examplevideo: import("./_example/api"), + applecalendar: import("./applecalendar/api"), + caldavcalendar: import("./caldavcalendar/api"), + googlecalendar: import("./googlecalendar/api"), + hubspotothercalendar: import("./hubspotothercalendar/api"), + office365calendar: import("./office365calendar/api"), + slackmessaging: import("./slackmessaging/api"), + stripepayment: import("./stripepayment/api"), + tandemvideo: import("./tandemvideo/api"), + zoomvideo: import("@calcom/zoomvideo/api"), + office365video: import("@calcom/office365video/api"), + wipemycalother: import("./wipemycalother/api"), + jitsivideo: import("./jitsivideo/api"), + huddle01video: import("./huddle01video/api"), + giphy: import("./giphy/api"), +}; + +export default apiHandlers; diff --git a/packages/app-store/applecalendar/api/add.ts b/packages/app-store/applecalendar/api/add.ts index 00f9d880..973df655 100644 --- a/packages/app-store/applecalendar/api/add.ts +++ b/packages/app-store/applecalendar/api/add.ts @@ -24,6 +24,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) type: "apple_calendar", key: symmetricEncrypt(JSON.stringify({ username, password }), process.env.CALENDSO_ENCRYPTION_KEY!), userId: user.id, + appId: "apple-calendar", }; try { diff --git a/packages/app-store/caldavcalendar/api/add.ts b/packages/app-store/caldavcalendar/api/add.ts index bc1699e3..73183999 100644 --- a/packages/app-store/caldavcalendar/api/add.ts +++ b/packages/app-store/caldavcalendar/api/add.ts @@ -27,6 +27,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) process.env.CALENDSO_ENCRYPTION_KEY! ), userId: user.id, + appId: "caldav-calendar", }; try { diff --git a/packages/app-store/components.tsx b/packages/app-store/components.tsx index a40da130..5728fe91 100644 --- a/packages/app-store/components.tsx +++ b/packages/app-store/components.tsx @@ -23,7 +23,7 @@ export const InstallAppButtonMap = { wipemycalother: dynamic(() => import("./wipemycalother/components/InstallAppButton")), jitsivideo: dynamic(() => import("./jitsivideo/components/InstallAppButton")), huddle01video: dynamic(() => import("./huddle01video/components/InstallAppButton")), - giphyother: dynamic(() => import("./giphyother/components/InstallAppButton")), + giphy: dynamic(() => import("./giphy/components/InstallAppButton")), }; export const InstallAppButton = ( @@ -33,8 +33,14 @@ export const InstallAppButton = ( ) => { const { status } = useSession(); const { t } = useLocale(); - const appName = props.type.replaceAll("_", "") as keyof typeof InstallAppButtonMap; - const InstallAppButtonComponent = InstallAppButtonMap[appName]; + let appName = props.type.replace(/_/g, ""); + let InstallAppButtonComponent = InstallAppButtonMap[appName as keyof typeof InstallAppButtonMap]; + /** So we can either call it by simple name (ex. `slack`, `giphy`) instead of + * `slackmessaging`, `giphyother` while maintaining retro-compatibility. */ + if (!InstallAppButtonComponent) { + [appName] = props.type.split("_"); + InstallAppButtonComponent = InstallAppButtonMap[appName as keyof typeof InstallAppButtonMap]; + } if (!InstallAppButtonComponent) return null; if (status === "unauthenticated") return ( diff --git a/packages/app-store/dailyvideo/lib/VideoApiAdapter.ts b/packages/app-store/dailyvideo/lib/VideoApiAdapter.ts index 24eea62c..0cfc6f47 100644 --- a/packages/app-store/dailyvideo/lib/VideoApiAdapter.ts +++ b/packages/app-store/dailyvideo/lib/VideoApiAdapter.ts @@ -57,6 +57,7 @@ export const FAKE_DAILY_CREDENTIAL: Credential = { type: "daily_video", key: { apikey: process.env.DAILY_API_KEY }, userId: +new Date().getTime(), + appId: "daily-video", }; const DailyVideoApiAdapter = (credential: Credential): VideoApiAdapter => { diff --git a/packages/app-store/giphyother/_metadata.ts b/packages/app-store/giphy/_metadata.ts similarity index 85% rename from packages/app-store/giphyother/_metadata.ts rename to packages/app-store/giphy/_metadata.ts index 35dcf5de..57b2c259 100644 --- a/packages/app-store/giphyother/_metadata.ts +++ b/packages/app-store/giphy/_metadata.ts @@ -8,8 +8,8 @@ export const metadata = { installed: !!process.env.GIPHY_API_KEY, category: "other", // If using static next public folder, can then be referenced from the base URL (/). - imageSrc: "/api/app-store/giphyother/icon.svg", - logo: "/api/app-store/giphyother/icon.svg", + imageSrc: "/api/app-store/giphy/icon.svg", + logo: "/api/app-store/giphy/icon.svg", publisher: "Cal.com", rating: 0, reviews: 0, diff --git a/packages/app-store/giphyother/api/add.ts b/packages/app-store/giphy/api/add.ts similarity index 100% rename from packages/app-store/giphyother/api/add.ts rename to packages/app-store/giphy/api/add.ts diff --git a/packages/app-store/giphyother/api/index.ts b/packages/app-store/giphy/api/index.ts similarity index 100% rename from packages/app-store/giphyother/api/index.ts rename to packages/app-store/giphy/api/index.ts diff --git a/packages/app-store/giphyother/api/search.ts b/packages/app-store/giphy/api/search.ts similarity index 100% rename from packages/app-store/giphyother/api/search.ts rename to packages/app-store/giphy/api/search.ts diff --git a/packages/app-store/giphyother/components/InstallAppButton.tsx b/packages/app-store/giphy/components/InstallAppButton.tsx similarity index 76% rename from packages/app-store/giphyother/components/InstallAppButton.tsx rename to packages/app-store/giphy/components/InstallAppButton.tsx index 2e78793b..84710405 100644 --- a/packages/app-store/giphyother/components/InstallAppButton.tsx +++ b/packages/app-store/giphy/components/InstallAppButton.tsx @@ -2,7 +2,8 @@ import useAddAppMutation from "../../_utils/useAddAppMutation"; import { InstallAppButtonProps } from "../../types"; export default function InstallAppButton(props: InstallAppButtonProps) { - const mutation = useAddAppMutation("giphy_other"); + // @ts-ignore TODO: deprecate App types in favor of DB slugs + const mutation = useAddAppMutation("giphy"); return ( <> diff --git a/packages/app-store/giphyother/components/SearchDialog.tsx b/packages/app-store/giphy/components/SearchDialog.tsx similarity index 98% rename from packages/app-store/giphyother/components/SearchDialog.tsx rename to packages/app-store/giphy/components/SearchDialog.tsx index b5e606c5..60055671 100644 --- a/packages/app-store/giphyother/components/SearchDialog.tsx +++ b/packages/app-store/giphy/components/SearchDialog.tsx @@ -30,7 +30,7 @@ export const SearchDialog = (props: ISearchDialog) => { } setIsLoading(true); setErrorMessage(""); - const res = await fetch("/api/integrations/giphyother/search", { + const res = await fetch("/api/integrations/giphy/search", { method: "POST", headers: { "Content-Type": "application/json", diff --git a/packages/app-store/giphyother/components/SelectGifInput.tsx b/packages/app-store/giphy/components/SelectGifInput.tsx similarity index 100% rename from packages/app-store/giphyother/components/SelectGifInput.tsx rename to packages/app-store/giphy/components/SelectGifInput.tsx diff --git a/packages/app-store/giphyother/components/index.ts b/packages/app-store/giphy/components/index.ts similarity index 100% rename from packages/app-store/giphyother/components/index.ts rename to packages/app-store/giphy/components/index.ts diff --git a/packages/app-store/giphyother/index.ts b/packages/app-store/giphy/index.ts similarity index 100% rename from packages/app-store/giphyother/index.ts rename to packages/app-store/giphy/index.ts diff --git a/packages/app-store/giphyother/lib/giphyManager.ts b/packages/app-store/giphy/lib/giphyManager.ts similarity index 65% rename from packages/app-store/giphyother/lib/giphyManager.ts rename to packages/app-store/giphy/lib/giphyManager.ts index 4262ffea..b14e6c5c 100644 --- a/packages/app-store/giphyother/lib/giphyManager.ts +++ b/packages/app-store/giphy/lib/giphyManager.ts @@ -1,6 +1,15 @@ +import { HttpError } from "@calcom/lib/http-error"; + +import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug"; + +let api_key = ""; + export const searchGiphy = async (locale: string, keyword: string, offset: number = 0) => { + const appKeys = await getAppKeysFromSlug("giphy"); + if (typeof appKeys.api_key === "string") api_key = appKeys.api_key; + if (!api_key) throw new HttpError({ statusCode: 400, message: "Missing Giphy api_key" }); const queryParams = new URLSearchParams({ - api_key: String(process.env.GIPHY_API_KEY), + api_key, q: keyword, limit: "1", offset: String(offset), diff --git a/packages/app-store/giphyother/lib/index.ts b/packages/app-store/giphy/lib/index.ts similarity index 100% rename from packages/app-store/giphyother/lib/index.ts rename to packages/app-store/giphy/lib/index.ts diff --git a/packages/app-store/giphyother/package.json b/packages/app-store/giphy/package.json similarity index 100% rename from packages/app-store/giphyother/package.json rename to packages/app-store/giphy/package.json diff --git a/packages/app-store/giphyother/static/icon.svg b/packages/app-store/giphy/static/icon.svg similarity index 100% rename from packages/app-store/giphyother/static/icon.svg rename to packages/app-store/giphy/static/icon.svg diff --git a/packages/app-store/googlecalendar/api/add.ts b/packages/app-store/googlecalendar/api/add.ts index c50501d6..7860bb91 100644 --- a/packages/app-store/googlecalendar/api/add.ts +++ b/packages/app-store/googlecalendar/api/add.ts @@ -4,17 +4,24 @@ import type { NextApiRequest, NextApiResponse } from "next"; import { WEBAPP_URL } from "@calcom/lib/constants"; import { encodeOAuthState } from "../../_utils/encodeOAuthState"; +import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug"; -const credentials = process.env.GOOGLE_API_CREDENTIALS!; const scopes = [ "https://www.googleapis.com/auth/calendar.readonly", "https://www.googleapis.com/auth/calendar.events", ]; +let client_id = ""; +let client_secret = ""; + export default async function handler(req: NextApiRequest, res: NextApiResponse) { if (req.method === "GET") { // Get token from Google Calendar API - const { client_secret, client_id } = JSON.parse(credentials).web; + const appKeys = await getAppKeysFromSlug("google-calendar"); + if (typeof appKeys.client_id === "string") client_id = appKeys.client_id; + if (typeof appKeys.client_secret === "string") client_secret = appKeys.client_secret; + if (!client_id) return res.status(400).json({ message: "Google client_id missing." }); + if (!client_secret) return res.status(400).json({ message: "Google client_secret missing." }); const redirect_uri = WEBAPP_URL + "/api/integrations/googlecalendar/callback"; const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirect_uri); diff --git a/packages/app-store/googlecalendar/api/callback.ts b/packages/app-store/googlecalendar/api/callback.ts index ff9863f9..2058d6f9 100644 --- a/packages/app-store/googlecalendar/api/callback.ts +++ b/packages/app-store/googlecalendar/api/callback.ts @@ -6,8 +6,10 @@ import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl"; import prisma from "@calcom/prisma"; import { decodeOAuthState } from "../../_utils/decodeOAuthState"; +import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug"; -const credentials = process.env.GOOGLE_API_CREDENTIALS; +let client_id = ""; +let client_secret = ""; export default async function handler(req: NextApiRequest, res: NextApiResponse) { const { code } = req.query; @@ -15,11 +17,16 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) res.status(400).json({ message: "`code` must be a string" }); return; } - if (!credentials) { - res.status(400).json({ message: "There are no Google Credentials installed." }); - return; + if (!req.session?.user?.id) { + return res.status(401).json({ message: "You must be logged in to do this" }); } - const { client_secret, client_id } = JSON.parse(credentials).web; + + const appKeys = await getAppKeysFromSlug("google-calendar"); + if (typeof appKeys.client_id === "string") client_id = appKeys.client_id; + if (typeof appKeys.client_secret === "string") client_secret = appKeys.client_secret; + if (!client_id) return res.status(400).json({ message: "Google client_id missing." }); + if (!client_secret) return res.status(400).json({ message: "Google client_secret missing." }); + const redirect_uri = WEBAPP_URL + "/api/integrations/googlecalendar/callback"; const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirect_uri); @@ -36,7 +43,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) data: { type: "google_calendar", key, - userId: req.session?.user.id, + userId: req.session.user.id, + appId: "google-calendar", }, }); const state = decodeOAuthState(req); diff --git a/packages/app-store/googlecalendar/lib/CalendarService.ts b/packages/app-store/googlecalendar/lib/CalendarService.ts index 20fd3acc..092902b2 100644 --- a/packages/app-store/googlecalendar/lib/CalendarService.ts +++ b/packages/app-store/googlecalendar/lib/CalendarService.ts @@ -4,6 +4,7 @@ import { Auth, calendar_v3, google } from "googleapis"; import { getLocation, getRichDescription } from "@calcom/lib/CalEventParser"; import CalendarService from "@calcom/lib/CalendarService"; +import { HttpError } from "@calcom/lib/http-error"; import logger from "@calcom/lib/logger"; import prisma from "@calcom/prisma"; import type { @@ -14,26 +15,38 @@ import type { NewCalendarEventType, } from "@calcom/types/Calendar"; -const GOOGLE_API_CREDENTIALS = process.env.GOOGLE_API_CREDENTIALS || ""; +import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug"; export default class GoogleCalendarService implements Calendar { private url = ""; private integrationName = ""; - private auth: { getToken: () => Promise }; + private auth: Promise<{ getToken: () => Promise }>; private log: typeof logger; + private client_id = ""; + private client_secret = ""; + private redirect_uri = ""; constructor(credential: Credential) { this.integrationName = "google_calendar"; - this.auth = this.googleAuth(credential); + this.auth = this.googleAuth(credential).then((m) => m); this.log = logger.getChildLogger({ prefix: [`[[lib] ${this.integrationName}`] }); } - private googleAuth = (credential: Credential) => { - const { client_secret, client_id, redirect_uris } = JSON.parse(GOOGLE_API_CREDENTIALS).web; + private googleAuth = async (credential: Credential) => { + const appKeys = await getAppKeysFromSlug("google-calendar"); + if (typeof appKeys.client_id === "string") this.client_id = appKeys.client_id; + if (typeof appKeys.client_secret === "string") this.client_secret = appKeys.client_secret; + if (typeof appKeys.redirect_uris === "object" && Array.isArray(appKeys.redirect_uris)) { + this.redirect_uri = appKeys.redirect_uris[0] as string; + } + if (!this.client_id) throw new HttpError({ statusCode: 400, message: "Google client_id missing." }); + if (!this.client_secret) + throw new HttpError({ statusCode: 400, message: "Google client_secret missing." }); + if (!this.redirect_uri) throw new HttpError({ statusCode: 400, message: "Google redirect_uri missing." }); - const myGoogleAuth = new MyGoogleAuth(client_id, client_secret, redirect_uris[0]); + const myGoogleAuth = new MyGoogleAuth(this.client_id, this.client_secret, this.redirect_uri); const googleCredentials = credential.key as Auth.Credentials; myGoogleAuth.setCredentials(googleCredentials); @@ -43,23 +56,20 @@ export default class GoogleCalendarService implements Calendar { const refreshAccessToken = () => myGoogleAuth .refreshToken(googleCredentials.refresh_token) - .then((res: GetTokenResponse) => { + .then(async (res: GetTokenResponse) => { const token = res.res?.data; googleCredentials.access_token = token.access_token; googleCredentials.expiry_date = token.expiry_date; - return prisma.credential - .update({ - where: { - id: credential.id, - }, - data: { - key: googleCredentials as Prisma.InputJsonValue, - }, - }) - .then(() => { - myGoogleAuth.setCredentials(googleCredentials); - return myGoogleAuth; - }); + await prisma.credential.update({ + where: { + id: credential.id, + }, + data: { + key: googleCredentials as Prisma.InputJsonValue, + }, + }); + myGoogleAuth.setCredentials(googleCredentials); + return myGoogleAuth; }) .catch((err) => { this.log.error("Error refreshing google token", err); @@ -73,164 +83,164 @@ export default class GoogleCalendarService implements Calendar { }; async createEvent(calEventRaw: CalendarEvent): Promise { - return new Promise((resolve, reject) => - this.auth.getToken().then((myGoogleAuth) => { - const payload: calendar_v3.Schema$Event = { - summary: calEventRaw.title, - description: getRichDescription(calEventRaw), - start: { - dateTime: calEventRaw.startTime, - timeZone: calEventRaw.organizer.timeZone, - }, - end: { - dateTime: calEventRaw.endTime, - timeZone: calEventRaw.organizer.timeZone, - }, - attendees: calEventRaw.attendees.map((attendee) => ({ - ...attendee, - responseStatus: "accepted", - })), - reminders: { - useDefault: true, - }, - }; + return new Promise(async (resolve, reject) => { + const auth = await this.auth; + const myGoogleAuth = await auth.getToken(); + const payload: calendar_v3.Schema$Event = { + summary: calEventRaw.title, + description: getRichDescription(calEventRaw), + start: { + dateTime: calEventRaw.startTime, + timeZone: calEventRaw.organizer.timeZone, + }, + end: { + dateTime: calEventRaw.endTime, + timeZone: calEventRaw.organizer.timeZone, + }, + attendees: calEventRaw.attendees.map((attendee) => ({ + ...attendee, + responseStatus: "accepted", + })), + reminders: { + useDefault: true, + }, + }; - if (calEventRaw.location) { - payload["location"] = getLocation(calEventRaw); - } + if (calEventRaw.location) { + payload["location"] = getLocation(calEventRaw); + } - if (calEventRaw.conferenceData && calEventRaw.location === "integrations:google:meet") { - payload["conferenceData"] = calEventRaw.conferenceData; - } - const calendar = google.calendar({ - version: "v3", - }); - calendar.events.insert( - { - auth: myGoogleAuth, + if (calEventRaw.conferenceData && calEventRaw.location === "integrations:google:meet") { + payload["conferenceData"] = calEventRaw.conferenceData; + } + const calendar = google.calendar({ + version: "v3", + }); + calendar.events.insert( + { + auth: myGoogleAuth, + calendarId: calEventRaw.destinationCalendar?.externalId + ? calEventRaw.destinationCalendar.externalId + : "primary", + requestBody: payload, + conferenceDataVersion: 1, + }, + function (err, event) { + if (err || !event?.data) { + console.error("There was an error contacting google calendar service: ", err); + return reject(err); + } + + calendar.events.patch({ + // Update the same event but this time we know the hangout link calendarId: calEventRaw.destinationCalendar?.externalId ? calEventRaw.destinationCalendar.externalId : "primary", - requestBody: payload, - conferenceDataVersion: 1, - }, - function (err, event) { - if (err || !event?.data) { - console.error("There was an error contacting google calendar service: ", err); - return reject(err); - } + auth: myGoogleAuth, + eventId: event.data.id || "", + requestBody: { + description: getRichDescription({ + ...calEventRaw, + additionInformation: { hangoutLink: event.data.hangoutLink || "" }, + }), + }, + }); - calendar.events.patch({ - // Update the same event but this time we know the hangout link - calendarId: calEventRaw.destinationCalendar?.externalId - ? calEventRaw.destinationCalendar.externalId - : "primary", - auth: myGoogleAuth, - eventId: event.data.id || "", - requestBody: { - description: getRichDescription({ - ...calEventRaw, - additionInformation: { hangoutLink: event.data.hangoutLink || "" }, - }), - }, - }); - - return resolve({ - uid: "", - ...event.data, - id: event.data.id || "", - additionalInfo: { - hangoutLink: event.data.hangoutLink || "", - }, - type: "google_calendar", - password: "", - url: "", - }); - } - ); - }) - ); + return resolve({ + uid: "", + ...event.data, + id: event.data.id || "", + additionalInfo: { + hangoutLink: event.data.hangoutLink || "", + }, + type: "google_calendar", + password: "", + url: "", + }); + } + ); + }); } async updateEvent(uid: string, event: CalendarEvent): Promise { - return new Promise((resolve, reject) => - this.auth.getToken().then((myGoogleAuth) => { - const payload: calendar_v3.Schema$Event = { - summary: event.title, - description: getRichDescription(event), - start: { - dateTime: event.startTime, - timeZone: event.organizer.timeZone, - }, - end: { - dateTime: event.endTime, - timeZone: event.organizer.timeZone, - }, - attendees: event.attendees, - reminders: { - useDefault: true, - }, - }; + return new Promise(async (resolve, reject) => { + const auth = await this.auth; + const myGoogleAuth = await auth.getToken(); + const payload: calendar_v3.Schema$Event = { + summary: event.title, + description: getRichDescription(event), + start: { + dateTime: event.startTime, + timeZone: event.organizer.timeZone, + }, + end: { + dateTime: event.endTime, + timeZone: event.organizer.timeZone, + }, + attendees: event.attendees, + reminders: { + useDefault: true, + }, + }; - if (event.location) { - payload["location"] = getLocation(event); - } + if (event.location) { + payload["location"] = getLocation(event); + } - const calendar = google.calendar({ - version: "v3", + const calendar = google.calendar({ + version: "v3", + auth: myGoogleAuth, + }); + calendar.events.update( + { auth: myGoogleAuth, - }); - calendar.events.update( - { - auth: myGoogleAuth, - calendarId: event.destinationCalendar?.externalId - ? event.destinationCalendar.externalId - : "primary", - eventId: uid, - sendNotifications: true, - sendUpdates: "all", - requestBody: payload, - }, - function (err, event) { - if (err) { - console.error("There was an error contacting google calendar service: ", err); + calendarId: event.destinationCalendar?.externalId + ? event.destinationCalendar.externalId + : "primary", + eventId: uid, + sendNotifications: true, + sendUpdates: "all", + requestBody: payload, + }, + function (err, event) { + if (err) { + console.error("There was an error contacting google calendar service: ", err); - return reject(err); - } - return resolve(event?.data); + return reject(err); } - ); - }) - ); + return resolve(event?.data); + } + ); + }); } async deleteEvent(uid: string, event: CalendarEvent): Promise { - return new Promise((resolve, reject) => - this.auth.getToken().then((myGoogleAuth) => { - const calendar = google.calendar({ - version: "v3", + return new Promise(async (resolve, reject) => { + const auth = await this.auth; + const myGoogleAuth = await auth.getToken(); + const calendar = google.calendar({ + version: "v3", + auth: myGoogleAuth, + }); + calendar.events.delete( + { auth: myGoogleAuth, - }); - calendar.events.delete( - { - auth: myGoogleAuth, - calendarId: event.destinationCalendar?.externalId - ? event.destinationCalendar.externalId - : "primary", - eventId: uid, - sendNotifications: true, - sendUpdates: "all", - }, - function (err, event) { - if (err) { - console.error("There was an error contacting google calendar service: ", err); - return reject(err); - } - return resolve(event?.data); + calendarId: event.destinationCalendar?.externalId + ? event.destinationCalendar.externalId + : "primary", + eventId: uid, + sendNotifications: true, + sendUpdates: "all", + }, + function (err, event) { + if (err) { + console.error("There was an error contacting google calendar service: ", err); + return reject(err); } - ); - }) - ); + return resolve(event?.data); + } + ); + }); } async getAvailability( @@ -238,96 +248,96 @@ export default class GoogleCalendarService implements Calendar { dateTo: string, selectedCalendars: IntegrationCalendar[] ): Promise { - return new Promise((resolve, reject) => - this.auth.getToken().then((myGoogleAuth) => { - const calendar = google.calendar({ - version: "v3", - auth: myGoogleAuth, - }); - const selectedCalendarIds = selectedCalendars - .filter((e) => e.integration === this.integrationName) - .map((e) => e.externalId); - if (selectedCalendarIds.length === 0 && selectedCalendars.length > 0) { - // Only calendars of other integrations selected - resolve([]); - return; - } + return new Promise(async (resolve, reject) => { + const auth = await this.auth; + const myGoogleAuth = await auth.getToken(); + const calendar = google.calendar({ + version: "v3", + auth: myGoogleAuth, + }); + const selectedCalendarIds = selectedCalendars + .filter((e) => e.integration === this.integrationName) + .map((e) => e.externalId); + if (selectedCalendarIds.length === 0 && selectedCalendars.length > 0) { + // Only calendars of other integrations selected + resolve([]); + return; + } - (selectedCalendarIds.length === 0 - ? calendar.calendarList - .list() - .then((cals) => cals.data.items?.map((cal) => cal.id).filter(Boolean) || []) - : Promise.resolve(selectedCalendarIds) - ) - .then((calsIds) => { - calendar.freebusy.query( - { - requestBody: { - timeMin: dateFrom, - timeMax: dateTo, - items: calsIds.map((id) => ({ id: id })), - }, + (selectedCalendarIds.length === 0 + ? calendar.calendarList + .list() + .then((cals) => cals.data.items?.map((cal) => cal.id).filter(Boolean) || []) + : Promise.resolve(selectedCalendarIds) + ) + .then((calsIds) => { + calendar.freebusy.query( + { + requestBody: { + timeMin: dateFrom, + timeMax: dateTo, + items: calsIds.map((id) => ({ id: id })), }, - (err, apires) => { - if (err) { - reject(err); - } - let result: Prisma.PromiseReturnType = []; - - if (apires?.data.calendars) { - result = Object.values(apires.data.calendars).reduce((c, i) => { - i.busy?.forEach((busyTime) => { - c.push({ - start: busyTime.start || "", - end: busyTime.end || "", - }); - }); - return c; - }, [] as typeof result); - } - resolve(result); + }, + (err, apires) => { + if (err) { + reject(err); } - ); - }) - .catch((err) => { - this.log.error("There was an error contacting google calendar service: ", err); + let result: Prisma.PromiseReturnType = []; - reject(err); - }); - }) - ); + if (apires?.data.calendars) { + result = Object.values(apires.data.calendars).reduce((c, i) => { + i.busy?.forEach((busyTime) => { + c.push({ + start: busyTime.start || "", + end: busyTime.end || "", + }); + }); + return c; + }, [] as typeof result); + } + resolve(result); + } + ); + }) + .catch((err) => { + this.log.error("There was an error contacting google calendar service: ", err); + + reject(err); + }); + }); } async listCalendars(): Promise { - return new Promise((resolve, reject) => - this.auth.getToken().then((myGoogleAuth) => { - const calendar = google.calendar({ - version: "v3", - auth: myGoogleAuth, + return new Promise(async (resolve, reject) => { + const auth = await this.auth; + const myGoogleAuth = await auth.getToken(); + const calendar = google.calendar({ + version: "v3", + auth: myGoogleAuth, + }); + + calendar.calendarList + .list() + .then((cals) => { + resolve( + cals.data.items?.map((cal) => { + const calendar: IntegrationCalendar = { + externalId: cal.id ?? "No id", + integration: this.integrationName, + name: cal.summary ?? "No name", + primary: cal.primary ?? false, + }; + return calendar; + }) || [] + ); + }) + .catch((err: Error) => { + this.log.error("There was an error contacting google calendar service: ", err); + + reject(err); }); - - calendar.calendarList - .list() - .then((cals) => { - resolve( - cals.data.items?.map((cal) => { - const calendar: IntegrationCalendar = { - externalId: cal.id ?? "No id", - integration: this.integrationName, - name: cal.summary ?? "No name", - primary: cal.primary ?? false, - }; - return calendar; - }) || [] - ); - }) - .catch((err: Error) => { - this.log.error("There was an error contacting google calendar service: ", err); - - reject(err); - }); - }) - ); + }); } } diff --git a/packages/app-store/hubspotothercalendar/api/callback.ts b/packages/app-store/hubspotothercalendar/api/callback.ts index b3483e45..6ad251e5 100644 --- a/packages/app-store/hubspotothercalendar/api/callback.ts +++ b/packages/app-store/hubspotothercalendar/api/callback.ts @@ -7,9 +7,10 @@ import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl"; import prisma from "@calcom/prisma"; import { decodeOAuthState } from "../../_utils/decodeOAuthState"; +import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug"; -const client_id = process.env.HUBSPOT_CLIENT_ID; -const client_secret = process.env.HUBSPOT_CLIENT_SECRET; +let client_id = ""; +let client_secret = ""; const hubspotClient = new hubspot.Client(); export type HubspotToken = TokenResponseIF & { @@ -24,15 +25,15 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) return; } - if (!client_id) { - res.status(400).json({ message: "HubSpot client id missing." }); - return; + if (!req.session?.user?.id) { + return res.status(401).json({ message: "You must be logged in to do this" }); } - if (!client_secret) { - res.status(400).json({ message: "HubSpot client secret missing." }); - return; - } + const appKeys = await getAppKeysFromSlug("hubspot"); + if (typeof appKeys.client_id === "string") client_id = appKeys.client_id; + if (typeof appKeys.client_secret === "string") client_secret = appKeys.client_secret; + if (!client_id) return res.status(400).json({ message: "HubSpot client id missing." }); + if (!client_secret) return res.status(400).json({ message: "HubSpot client secret missing." }); const hubspotToken: HubspotToken = await hubspotClient.oauth.tokensApi.createToken( "authorization_code", @@ -48,7 +49,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) data: { type: "hubspot_other_calendar", key: hubspotToken as any, - userId: req.session?.user.id, + userId: req.session.user.id, + appId: "hubspot", }, }); diff --git a/packages/app-store/huddle01video/api/add.ts b/packages/app-store/huddle01video/api/add.ts index 79531647..ca22eaef 100644 --- a/packages/app-store/huddle01video/api/add.ts +++ b/packages/app-store/huddle01video/api/add.ts @@ -27,6 +27,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) type: appType, key: {}, userId: req.session.user.id, + appId: "huddle01", }, }); if (!installation) { diff --git a/packages/app-store/index.ts b/packages/app-store/index.ts index 839f3d1a..52e5cbaa 100644 --- a/packages/app-store/index.ts +++ b/packages/app-store/index.ts @@ -2,7 +2,7 @@ import * as applecalendar from "./applecalendar"; import * as caldavcalendar from "./caldavcalendar"; import * as dailyvideo from "./dailyvideo"; -import * as giphyother from "./giphyother"; +import * as giphy from "./giphy"; import * as googlecalendar from "./googlecalendar"; import * as googlevideo from "./googlevideo"; import * as hubspotothercalendar from "./hubspotothercalendar"; @@ -33,7 +33,7 @@ const appStore = { tandemvideo, zoomvideo, wipemycalother, - giphyother, + giphy, }; export default appStore; diff --git a/packages/app-store/jitsivideo/api/add.ts b/packages/app-store/jitsivideo/api/add.ts index 9885fa75..a33e09d7 100644 --- a/packages/app-store/jitsivideo/api/add.ts +++ b/packages/app-store/jitsivideo/api/add.ts @@ -27,6 +27,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) type: appType, key: {}, userId: req.session.user.id, + appId: "jitsi", }, }); if (!installation) { diff --git a/packages/app-store/metadata.ts b/packages/app-store/metadata.ts index d969e1eb..3725f85e 100644 --- a/packages/app-store/metadata.ts +++ b/packages/app-store/metadata.ts @@ -1,7 +1,7 @@ import { metadata as applecalendar } from "./applecalendar/_metadata"; import { metadata as caldavcalendar } from "./caldavcalendar/_metadata"; import { metadata as dailyvideo } from "./dailyvideo/_metadata"; -import { metadata as giphy } from "./giphyother/_metadata"; +import { metadata as giphy } from "./giphy/_metadata"; import { metadata as googlecalendar } from "./googlecalendar/_metadata"; import { metadata as googlevideo } from "./googlevideo/_metadata"; import { metadata as hubspotothercalendar } from "./hubspotothercalendar/_metadata"; diff --git a/packages/app-store/office365calendar/api/callback.ts b/packages/app-store/office365calendar/api/callback.ts index 91e04b4c..6209abe5 100644 --- a/packages/app-store/office365calendar/api/callback.ts +++ b/packages/app-store/office365calendar/api/callback.ts @@ -1,13 +1,17 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import { BASE_URL } from "@calcom/lib/constants"; +import { WEBAPP_URL } from "@calcom/lib/constants"; import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl"; import prisma from "@calcom/prisma"; import { decodeOAuthState } from "../../_utils/decodeOAuthState"; +import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug"; const scopes = ["offline_access", "Calendars.Read", "Calendars.ReadWrite"]; +let client_id = ""; +let client_secret = ""; + export default async function handler(req: NextApiRequest, res: NextApiResponse) { const { code } = req.query; @@ -16,18 +20,24 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) return; } + const appKeys = await getAppKeysFromSlug("office365-calendar"); + if (typeof appKeys.client_id === "string") client_id = appKeys.client_id; + if (typeof appKeys.client_secret === "string") client_secret = appKeys.client_secret; + if (!client_id) return res.status(400).json({ message: "Office 365 client_id missing." }); + if (!client_secret) return res.status(400).json({ message: "Office 365 client_secret missing." }); + const toUrlEncoded = (payload: Record) => Object.keys(payload) .map((key) => key + "=" + encodeURIComponent(payload[key])) .join("&"); const body = toUrlEncoded({ - client_id: process.env.MS_GRAPH_CLIENT_ID!, + client_id, grant_type: "authorization_code", code, scope: scopes.join(" "), - redirect_uri: BASE_URL + "/api/integrations/office365calendar/callback", - client_secret: process.env.MS_GRAPH_CLIENT_SECRET!, + redirect_uri: WEBAPP_URL + "/api/integrations/office365calendar/callback", + client_secret, }); const response = await fetch("https://login.microsoftonline.com/common/oauth2/v2.0/token", { @@ -59,6 +69,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) type: "office365_calendar", key: responseBody, userId: req.session?.user.id, + appId: "office365-calendar", }, }); diff --git a/packages/app-store/office365video/api/callback.ts b/packages/app-store/office365video/api/callback.ts index 94e26cbd..cb3b55e7 100644 --- a/packages/app-store/office365video/api/callback.ts +++ b/packages/app-store/office365video/api/callback.ts @@ -1,13 +1,17 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import { BASE_URL } from "@calcom/lib/constants"; +import { WEBAPP_URL } from "@calcom/lib/constants"; import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl"; import prisma from "@calcom/prisma"; import { decodeOAuthState } from "../../_utils/decodeOAuthState"; +import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug"; const scopes = ["OnlineMeetings.ReadWrite"]; +let client_id = ""; +let client_secret = ""; + export default async function handler(req: NextApiRequest, res: NextApiResponse) { const { code } = req.query; console.log("🚀 ~ file: callback.ts ~ line 14 ~ handler ~ code", req.query); @@ -17,18 +21,24 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) return; } + const appKeys = await getAppKeysFromSlug("office365-calendar"); + if (typeof appKeys.client_id === "string") client_id = appKeys.client_id; + if (typeof appKeys.client_secret === "string") client_secret = appKeys.client_secret; + if (!client_id) return res.status(400).json({ message: "Office 365 client_id missing." }); + if (!client_secret) return res.status(400).json({ message: "Office 365 client_secret missing." }); + const toUrlEncoded = (payload: Record) => Object.keys(payload) .map((key) => key + "=" + encodeURIComponent(payload[key])) .join("&"); const body = toUrlEncoded({ - client_id: process.env.MS_GRAPH_CLIENT_ID!, + client_id, grant_type: "authorization_code", code, scope: scopes.join(" "), - redirect_uri: BASE_URL + "/api/integrations/office365video/callback", - client_secret: process.env.MS_GRAPH_CLIENT_SECRET!, + redirect_uri: WEBAPP_URL + "/api/integrations/office365video/callback", + client_secret, }); const response = await fetch("https://login.microsoftonline.com/common/oauth2/v2.0/token", { @@ -60,6 +70,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) type: "office365_video", key: responseBody, userId: req.session?.user.id, + appId: "msteams", }, }); diff --git a/packages/app-store/slackmessaging/api/add.ts b/packages/app-store/slackmessaging/api/add.ts index 6796e0af..ec3c190f 100644 --- a/packages/app-store/slackmessaging/api/add.ts +++ b/packages/app-store/slackmessaging/api/add.ts @@ -3,7 +3,9 @@ import { stringify } from "querystring"; import prisma from "@calcom/prisma"; -const client_id = process.env.SLACK_CLIENT_ID; +import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug"; + +let client_id = ""; const scopes = ["commands", "users:read", "users:read.email", "chat:write", "chat:write.public"]; export default async function handler(req: NextApiRequest, res: NextApiResponse) { @@ -12,6 +14,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) } if (req.method === "GET") { + if (!req.session?.user?.id) { + return res.status(401).json({ message: "You must be logged in to do this" }); + } + + const appKeys = await getAppKeysFromSlug("slack"); + if (typeof appKeys.client_id === "string") client_id = appKeys.client_id; + if (!client_id) return res.status(400).json({ message: "Slack client_id missing" }); // Get user await prisma.user.findFirst({ rejectOnNotFound: true, diff --git a/packages/app-store/stripepayment/api/callback.ts b/packages/app-store/stripepayment/api/callback.ts index 8a85a7a1..1440f78c 100644 --- a/packages/app-store/stripepayment/api/callback.ts +++ b/packages/app-store/stripepayment/api/callback.ts @@ -14,6 +14,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) return; } + if (!req.session?.user?.id) { + return res.status(401).json({ message: "You must be logged in to do this" }); + } + const response = await stripe.oauth.token({ grant_type: "authorization_code", code: code.toString(), @@ -29,7 +33,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) data: { type: "stripe_payment", key: data as unknown as Prisma.InputJsonObject, - userId: req.session?.user.id, + userId: req.session.user.id, + appId: "stripe", }, }); diff --git a/packages/app-store/utils.ts b/packages/app-store/utils.ts index ae27fd65..26fb109c 100644 --- a/packages/app-store/utils.ts +++ b/packages/app-store/utils.ts @@ -14,7 +14,7 @@ const ALL_APPS_MAP = Object.keys(appStoreMetadata).reduce((store, key) => { }, {} as Record); const credentialData = Prisma.validator()({ - select: { id: true, type: true, key: true, userId: true }, + select: { id: true, type: true, key: true, userId: true, appId: true }, }); type CredentialData = Prisma.CredentialGetPayload; @@ -66,6 +66,7 @@ function getApps(userCredentials: CredentialData[]) { type: appMeta.type, key: appMeta.key!, userId: +new Date().getTime(), + appId: appMeta.slug, }); } diff --git a/packages/app-store/wipemycalother/api/add.ts b/packages/app-store/wipemycalother/api/add.ts index 8bdfbffc..e8147350 100644 --- a/packages/app-store/wipemycalother/api/add.ts +++ b/packages/app-store/wipemycalother/api/add.ts @@ -27,6 +27,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) type: appType, key: {}, userId: req.session.user.id, + appId: "wipe-my-cal", }, }); if (!installation) { diff --git a/packages/app-store/wipemycalother/lib/calendarManager.ts b/packages/app-store/wipemycalother/lib/calendarManager.ts deleted file mode 100644 index c8964ff6..00000000 --- a/packages/app-store/wipemycalother/lib/calendarManager.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { Credential } from "@prisma/client"; -import _ from "lodash"; - -import { getUid } from "@calcom/lib/CalEventParser"; -import logger from "@calcom/lib/logger"; -import type { CalendarEvent } from "@calcom/types/Calendar"; -import type { EventResult } from "@calcom/types/EventManager"; - -import { getCalendar } from "../../_utils/getCalendar"; - -const log = logger.getChildLogger({ prefix: ["CalendarManager"] }); - -/** TODO: Remove once all references are updated to app-store */ -export { getCalendar }; - -export const createEvent = async (credential: Credential, calEvent: CalendarEvent): Promise => { - const uid: string = getUid(calEvent); - const calendar = getCalendar(credential); - let success = true; - - // Check if the disabledNotes flag is set to true - if (calEvent.hideCalendarNotes) { - calEvent.additionalNotes = "Notes have been hidden by the organizer"; // TODO: i18n this string? - } - - const creationResult = calendar - ? await calendar.createEvent(calEvent).catch((e) => { - log.error("createEvent failed", e, calEvent); - success = false; - return undefined; - }) - : undefined; - - return { - type: credential.type, - success, - uid, - createdEvent: creationResult, - originalEvent: calEvent, - }; -}; - -export const updateEvent = async ( - credential: Credential, - calEvent: CalendarEvent, - bookingRefUid: string | null -): Promise => { - const uid = getUid(calEvent); - const calendar = getCalendar(credential); - let success = true; - - const updatedResult = - calendar && bookingRefUid - ? await calendar.updateEvent(bookingRefUid, calEvent).catch((e) => { - log.error("updateEvent failed", e, calEvent); - success = false; - return undefined; - }) - : undefined; - - return { - type: credential.type, - success, - uid, - updatedEvent: updatedResult, - originalEvent: calEvent, - }; -}; - -export const deleteEvent = (credential: Credential, uid: string, event: CalendarEvent): Promise => { - const calendar = getCalendar(credential); - if (calendar) { - return calendar.deleteEvent(uid, event); - } - - return Promise.resolve({}); -}; diff --git a/packages/app-store/wipemycalother/lib/eventManager.ts b/packages/app-store/wipemycalother/lib/eventManager.ts deleted file mode 100644 index e971249c..00000000 --- a/packages/app-store/wipemycalother/lib/eventManager.ts +++ /dev/null @@ -1,386 +0,0 @@ -import { Credential, DestinationCalendar } from "@prisma/client"; -import async from "async"; -import merge from "lodash/merge"; -import { v5 as uuidv5 } from "uuid"; - -import prisma from "@calcom/prisma"; -import type { AdditionInformation, CalendarEvent } from "@calcom/types/Calendar"; -import type { - CreateUpdateResult, - EventResult, - PartialBooking, - PartialReference, -} from "@calcom/types/EventManager"; -import type { VideoCallData } from "@calcom/types/VideoApiAdapter"; - -import { LocationType } from "../../locations"; -import getApps from "../../utils"; -import { createEvent, updateEvent } from "./calendarManager"; -import { createMeeting, updateMeeting } from "./videoClient"; - -export type Event = AdditionInformation & VideoCallData; - -export const isZoom = (location: string): boolean => { - return location === "integrations:zoom"; -}; - -export const isDaily = (location: string): boolean => { - return location === "integrations:daily"; -}; - -export const isHuddle01 = (location: string): boolean => { - return location === "integrations:huddle01"; -}; - -export const isTandem = (location: string): boolean => { - return location === "integrations:tandem"; -}; - -export const isTeams = (location: string): boolean => { - return location === "integrations:office365_video"; -}; - -export const isJitsi = (location: string): boolean => { - return location === "integrations:jitsi"; -}; - -export const isDedicatedIntegration = (location: string): boolean => { - return ( - isZoom(location) || - isDaily(location) || - isHuddle01(location) || - isTandem(location) || - isJitsi(location) || - isTeams(location) - ); -}; - -export const getLocationRequestFromIntegration = (location: string) => { - if ( - /** TODO: Handle this dynamically */ - location === LocationType.GoogleMeet.valueOf() || - location === LocationType.Zoom.valueOf() || - location === LocationType.Daily.valueOf() || - location === LocationType.Jitsi.valueOf() || - location === LocationType.Huddle01.valueOf() || - location === LocationType.Tandem.valueOf() || - location === LocationType.Teams.valueOf() - ) { - const requestId = uuidv5(location, uuidv5.URL); - - return { - conferenceData: { - createRequest: { - requestId: requestId, - }, - }, - location, - }; - } - - return null; -}; - -export const processLocation = (event: CalendarEvent): CalendarEvent => { - // If location is set to an integration location - // Build proper transforms for evt object - // Extend evt object with those transformations - if (event.location?.includes("integration")) { - const maybeLocationRequestObject = getLocationRequestFromIntegration(event.location); - - event = merge(event, maybeLocationRequestObject); - } - - return event; -}; - -type EventManagerUser = { - credentials: Credential[]; - destinationCalendar: DestinationCalendar | null; -}; - -export default class EventManager { - calendarCredentials: Credential[]; - videoCredentials: Credential[]; - - /** - * Takes an array of credentials and initializes a new instance of the EventManager. - * - * @param user - */ - constructor(user: EventManagerUser) { - const appCredentials = getApps(user.credentials).flatMap((app) => app.credentials); - this.calendarCredentials = appCredentials.filter((cred) => cred.type.endsWith("_calendar")); - this.videoCredentials = appCredentials.filter((cred) => cred.type.endsWith("_video")); - } - - /** - * Takes a CalendarEvent and creates all necessary integration entries for it. - * When a video integration is chosen as the event's location, a video integration - * event will be scheduled for it as well. - * - * @param event - */ - public async create(event: CalendarEvent): Promise { - const evt = processLocation(event); - const isDedicated = evt.location ? isDedicatedIntegration(evt.location) : null; - - const results: Array = []; - // If and only if event type is a dedicated meeting, create a dedicated video meeting. - if (isDedicated) { - const result = await this.createVideoEvent(evt); - if (result.createdEvent) { - evt.videoCallData = result.createdEvent; - } - - results.push(result); - } - - // Create the calendar event with the proper video call data - results.push(...(await this.createAllCalendarEvents(evt))); - - const referencesToCreate: Array = results.map((result: EventResult) => { - return { - type: result.type, - uid: result.createdEvent?.id.toString() ?? "", - meetingId: result.createdEvent?.id.toString(), - meetingPassword: result.createdEvent?.password, - meetingUrl: result.createdEvent?.url, - }; - }); - - return { - results, - referencesToCreate, - }; - } - - /** - * Takes a calendarEvent and a rescheduleUid and updates the event that has the - * given uid using the data delivered in the given CalendarEvent. - * - * @param event - */ - public async update( - event: CalendarEvent, - rescheduleUid: string, - newBookingId?: number - ): Promise { - const evt = processLocation(event); - - if (!rescheduleUid) { - throw new Error("You called eventManager.update without an `rescheduleUid`. This should never happen."); - } - - // Get details of existing booking. - const booking = await prisma.booking.findFirst({ - where: { - uid: rescheduleUid, - }, - select: { - id: true, - references: { - // NOTE: id field removed from select as we don't require for deletingMany - // but was giving error on recreate for reschedule, probably because promise.all() didn't finished - select: { - type: true, - uid: true, - meetingId: true, - meetingPassword: true, - meetingUrl: true, - }, - }, - destinationCalendar: true, - payment: true, - }, - }); - - if (!booking) { - throw new Error("booking not found"); - } - - const isDedicated = evt.location ? isDedicatedIntegration(evt.location) : null; - const results: Array = []; - // If and only if event type is a dedicated meeting, update the dedicated video meeting. - if (isDedicated) { - const result = await this.updateVideoEvent(evt, booking); - const [updatedEvent] = Array.isArray(result.updatedEvent) ? result.updatedEvent : [result.updatedEvent]; - if (updatedEvent) { - evt.videoCallData = updatedEvent; - evt.location = updatedEvent.url; - } - results.push(result); - } - - // Update all calendar events. - results.push(...(await this.updateAllCalendarEvents(evt, booking))); - - const bookingPayment = booking?.payment; - - // Updating all payment to new - if (bookingPayment && newBookingId) { - const paymentIds = bookingPayment.map((payment) => payment.id); - await prisma.payment.updateMany({ - where: { - id: { - in: paymentIds, - }, - }, - data: { - bookingId: newBookingId, - }, - }); - } - - // Now we can delete the old booking and its references. - const bookingReferenceDeletes = prisma.bookingReference.deleteMany({ - where: { - bookingId: booking.id, - }, - }); - const attendeeDeletes = prisma.attendee.deleteMany({ - where: { - bookingId: booking.id, - }, - }); - - const bookingDeletes = prisma.booking.delete({ - where: { - id: booking.id, - }, - }); - - // Wait for all deletions to be applied. - await Promise.all([bookingReferenceDeletes, attendeeDeletes, bookingDeletes]); - - return { - results, - referencesToCreate: [...booking.references], - }; - } - - /** - * Creates event entries for all calendar integrations given in the credentials. - * When noMail is true, no mails will be sent. This is used when the event is - * a video meeting because then the mail containing the video credentials will be - * more important than the mails created for these bare calendar events. - * - * When the optional uid is set, it will be used instead of the auto generated uid. - * - * @param event - * @param noMail - * @private - */ - private async createAllCalendarEvents(event: CalendarEvent): Promise> { - /** Can I use destinationCalendar here? */ - /* How can I link a DC to a cred? */ - if (event.destinationCalendar) { - const destinationCalendarCredentials = this.calendarCredentials.filter( - (c) => c.type === event.destinationCalendar?.integration - ); - return Promise.all(destinationCalendarCredentials.map(async (c) => await createEvent(c, event))); - } - - /** - * Not ideal but, if we don't find a destination calendar, - * fallback to the first connected calendar - */ - const [credential] = this.calendarCredentials; - if (!credential) { - return []; - } - return [await createEvent(credential, event)]; - } - - /** - * Checks which video integration is needed for the event's location and returns - * credentials for that - if existing. - * @param event - * @private - */ - - private getVideoCredential(event: CalendarEvent): Credential | undefined { - if (!event.location) { - return undefined; - } - - const integrationName = event.location.replace("integrations:", ""); - - return this.videoCredentials.find((credential: Credential) => credential.type.includes(integrationName)); - } - - /** - * Creates a video event entry for the selected integration location. - * - * When optional uid is set, it will be used instead of the auto generated uid. - * - * @param event - * @private - */ - private createVideoEvent(event: CalendarEvent): Promise { - const credential = this.getVideoCredential(event); - - if (credential) { - return createMeeting(credential, event); - } else { - return Promise.reject( - `No suitable credentials given for the requested integration name:${event.location}` - ); - } - } - - /** - * Updates the event entries for all calendar integrations given in the credentials. - * When noMail is true, no mails will be sent. This is used when the event is - * a video meeting because then the mail containing the video credentials will be - * more important than the mails created for these bare calendar events. - * - * @param event - * @param booking - * @private - */ - private updateAllCalendarEvents( - event: CalendarEvent, - booking: PartialBooking - ): Promise> { - return async.mapLimit(this.calendarCredentials, 5, async (credential: Credential) => { - const bookingRefUid = booking - ? booking.references.filter((ref) => ref.type === credential.type)[0]?.uid - : null; - - return updateEvent(credential, event, bookingRefUid); - }); - } - - /** - * Updates a single video event. - * - * @param event - * @param booking - * @private - */ - private updateVideoEvent(event: CalendarEvent, booking: PartialBooking) { - const credential = this.getVideoCredential(event); - - if (credential) { - const bookingRef = booking ? booking.references.filter((ref) => ref.type === credential.type)[0] : null; - return updateMeeting(credential, event, bookingRef); - } else { - return Promise.reject( - `No suitable credentials given for the requested integration name:${event.location}` - ); - } - } - - /** - * Update event to set a cancelled event placeholder on users calendar - * remove if virtual calendar is already done and user availability its read from there - * and not only in their calendars - * @param event - * @param booking - * @public - */ - public async updateAndSetCancelledPlaceholder(event: CalendarEvent, booking: PartialBooking) { - await this.updateAllCalendarEvents(event, booking); - } -} diff --git a/packages/app-store/wipemycalother/lib/reschedule.ts b/packages/app-store/wipemycalother/lib/reschedule.ts index dc152669..97f70b9f 100644 --- a/packages/app-store/wipemycalother/lib/reschedule.ts +++ b/packages/app-store/wipemycalother/lib/reschedule.ts @@ -1,9 +1,11 @@ -import { BookingStatus, User, Booking, BookingReference } from "@prisma/client"; +import { Booking, BookingReference, BookingStatus, User } from "@prisma/client"; import dayjs from "dayjs"; import type { TFunction } from "next-i18next"; +import EventManager from "@calcom/core/EventManager"; import { CalendarEventBuilder } from "@calcom/core/builders/CalendarEvent/builder"; import { CalendarEventDirector } from "@calcom/core/builders/CalendarEvent/director"; +import { deleteMeeting } from "@calcom/core/videoClient"; import logger from "@calcom/lib/logger"; import { getTranslation } from "@calcom/lib/server/i18n"; import prisma from "@calcom/prisma"; @@ -11,8 +13,6 @@ import { Person } from "@calcom/types/Calendar"; import { getCalendar } from "../../_utils/getCalendar"; import { sendRequestRescheduleEmail } from "./emailManager"; -import EventManager from "./eventManager"; -import { deleteMeeting } from "./videoClient"; type PersonAttendeeCommonFields = Pick; diff --git a/packages/app-store/wipemycalother/lib/videoClient.ts b/packages/app-store/wipemycalother/lib/videoClient.ts deleted file mode 100644 index 063be0e7..00000000 --- a/packages/app-store/wipemycalother/lib/videoClient.ts +++ /dev/null @@ -1,116 +0,0 @@ -// @NOTE: This was copy from core since core uses app/store and creates circular dependency -// @TODO: Improve import export on appstore/core -import { Credential } from "@prisma/client"; -import short from "short-uuid"; -import { v5 as uuidv5 } from "uuid"; - -import { getUid } from "@calcom/lib/CalEventParser"; -import logger from "@calcom/lib/logger"; -import type { CalendarEvent } from "@calcom/types/Calendar"; -import type { EventResult, PartialReference } from "@calcom/types/EventManager"; -import type { VideoApiAdapter, VideoApiAdapterFactory } from "@calcom/types/VideoApiAdapter"; - -import appStore from "../../index"; - -const log = logger.getChildLogger({ prefix: ["[lib] videoClient"] }); - -const translator = short(); - -// factory -const getVideoAdapters = (withCredentials: Credential[]): VideoApiAdapter[] => - withCredentials.reduce((acc, cred) => { - const appName = cred.type.split("_").join(""); // Transform `zoom_video` to `zoomvideo`; - const app = appStore[appName as keyof typeof appStore]; - if (app && "lib" in app && "VideoApiAdapter" in app.lib) { - const makeVideoApiAdapter = app.lib.VideoApiAdapter as VideoApiAdapterFactory; - const videoAdapter = makeVideoApiAdapter(cred); - acc.push(videoAdapter); - return acc; - } - return acc; - }, []); - -const getBusyVideoTimes = (withCredentials: Credential[]) => - Promise.all(getVideoAdapters(withCredentials).map((c) => c.getAvailability())).then((results) => - results.reduce((acc, availability) => acc.concat(availability), []) - ); - -const createMeeting = async (credential: Credential, calEvent: CalendarEvent): Promise => { - const uid: string = getUid(calEvent); - - if (!credential) { - throw new Error( - "Credentials must be set! Video platforms are optional, so this method shouldn't even be called when no video credentials are set." - ); - } - - const videoAdapters = getVideoAdapters([credential]); - const [firstVideoAdapter] = videoAdapters; - const createdMeeting = await firstVideoAdapter.createMeeting(calEvent).catch((e) => { - log.error("createMeeting failed", e, calEvent); - }); - - if (!createdMeeting) { - return { - type: credential.type, - success: false, - uid, - originalEvent: calEvent, - }; - } - - return { - type: credential.type, - success: true, - uid, - createdEvent: createdMeeting, - originalEvent: calEvent, - }; -}; - -const updateMeeting = async ( - credential: Credential, - calEvent: CalendarEvent, - bookingRef: PartialReference | null -): Promise => { - const uid = translator.fromUUID(uuidv5(JSON.stringify(calEvent), uuidv5.URL)); - - let success = true; - - const [firstVideoAdapter] = getVideoAdapters([credential]); - const updatedMeeting = - credential && bookingRef - ? await firstVideoAdapter.updateMeeting(bookingRef, calEvent).catch((e) => { - log.error("updateMeeting failed", e, calEvent); - success = false; - return undefined; - }) - : undefined; - - if (!updatedMeeting) { - return { - type: credential.type, - success, - uid, - originalEvent: calEvent, - }; - } - - return { - type: credential.type, - success, - uid, - updatedEvent: updatedMeeting, - originalEvent: calEvent, - }; -}; - -const deleteMeeting = (credential: Credential, uid: string): Promise => { - if (credential) { - return getVideoAdapters([credential])[0].deleteMeeting(uid); - } - - return Promise.resolve({}); -}; - -export { getBusyVideoTimes, createMeeting, updateMeeting, deleteMeeting }; diff --git a/packages/core/EventManager.ts b/packages/core/EventManager.ts index c8e30a69..fdfb1c0c 100644 --- a/packages/core/EventManager.ts +++ b/packages/core/EventManager.ts @@ -304,6 +304,7 @@ export default class EventManager { return undefined; } + /** @fixme potential bug since Google Meet are saved as `integrations:google:meet` and there are no `google:meet` type in our DB */ const integrationName = event.location.replace("integrations:", ""); return this.videoCredentials.find((credential: Credential) => credential.type.includes(integrationName)); diff --git a/packages/lib/availability.ts b/packages/lib/availability.ts index a5e1b88d..4bb39609 100644 --- a/packages/lib/availability.ts +++ b/packages/lib/availability.ts @@ -1,10 +1,10 @@ +import type { Availability } from "@prisma/client"; import dayjs, { ConfigType } from "dayjs"; import customParseFormat from "dayjs/plugin/customParseFormat"; import timezone from "dayjs/plugin/timezone"; import utc from "dayjs/plugin/utc"; import { nameOfDay } from "@calcom/lib/weekday"; -import type { Availability } from "@calcom/prisma/client"; import type { Schedule, TimeRange, WorkingHours } from "@calcom/types/schedule"; dayjs.extend(utc); diff --git a/packages/prisma/migrations/20220502154345_adds_apps/migration.sql b/packages/prisma/migrations/20220502154345_adds_apps/migration.sql new file mode 100644 index 00000000..ae44691d --- /dev/null +++ b/packages/prisma/migrations/20220502154345_adds_apps/migration.sql @@ -0,0 +1,43 @@ +-- CreateEnum +CREATE TYPE "AppCategories" AS ENUM ('calendar', 'messaging', 'other', 'payment', 'video', 'web3'); + +-- AlterTable +ALTER TABLE "Credential" ADD COLUMN "appId" TEXT; + +-- CreateTable +CREATE TABLE "App" ( + "slug" TEXT NOT NULL, + "dirName" TEXT NOT NULL, + "keys" JSONB, + "categories" "AppCategories"[], + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "App_pkey" PRIMARY KEY ("slug") +); + +-- CreateIndex +CREATE UNIQUE INDEX "App_slug_key" ON "App"("slug"); + +-- CreateIndex +CREATE UNIQUE INDEX "App_dirName_key" ON "App"("dirName"); + +-- AddForeignKey +ALTER TABLE "Credential" ADD CONSTRAINT "Credential_appId_fkey" FOREIGN KEY ("appId") REFERENCES "App"("slug") ON DELETE CASCADE ON UPDATE CASCADE; + +-- Connects each saved Credential to their respective App +UPDATE "Credential" SET "appId" = 'apple-calendar' WHERE "type" = 'apple_calendar'; +UPDATE "Credential" SET "appId" = 'caldav-calendar' WHERE "type" = 'caldav_calendar'; +UPDATE "Credential" SET "appId" = 'google-calendar' WHERE "type" = 'google_calendar'; +UPDATE "Credential" SET "appId" = 'google-meet' WHERE "type" = 'google_video'; +UPDATE "Credential" SET "appId" = 'office365-calendar' WHERE "type" = 'office365_calendar'; +UPDATE "Credential" SET "appId" = 'msteams' WHERE "type" = 'office365_video'; +UPDATE "Credential" SET "appId" = 'dailyvideo' WHERE "type" = 'daily_video'; +UPDATE "Credential" SET "appId" = 'tandem' WHERE "type" = 'tandem_video'; +UPDATE "Credential" SET "appId" = 'zoom' WHERE "type" = 'zoom_video'; +UPDATE "Credential" SET "appId" = 'jitsi' WHERE "type" = 'jitsi_video'; +UPDATE "Credential" SET "appId" = 'hubspot' WHERE "type" = 'hubspot_other_calendar'; +UPDATE "Credential" SET "appId" = 'wipe-my-cal' WHERE "type" = 'wipemycal_other'; +UPDATE "Credential" SET "appId" = 'huddle01' WHERE "type" = 'huddle01_video'; +UPDATE "Credential" SET "appId" = 'slack' WHERE "type" = 'slack_messaging'; +UPDATE "Credential" SET "appId" = 'stripe' WHERE "type" = 'stripe_payment'; diff --git a/packages/prisma/package.json b/packages/prisma/package.json index 7bbc4994..b6184c0e 100644 --- a/packages/prisma/package.json +++ b/packages/prisma/package.json @@ -13,21 +13,22 @@ "db-setup": "run-s db-up db-deploy db-seed", "db-studio": "yarn prisma studio", "db-up": "docker-compose up -d", - "deploy": "yarn prisma migrate deploy", + "deploy": "yarn prisma migrate deploy && yarn seed-app-store", "dx": "yarn db-setup", "generate-schemas": "prisma generate && prisma format", - "postinstall": "yarn generate-schemas" + "postinstall": "yarn generate-schemas", + "seed-app-store": "ts-node --transpile-only ./seed-app-store.ts" }, "devDependencies": { "npm-run-all": "^4.1.5", - "prisma": "3.10.0", + "prisma": "^3.13.0", "ts-node": "^10.6.0", "zod": "^3.14.4", "zod-prisma": "^0.5.4" }, "dependencies": { "@calcom/lib": "*", - "@prisma/client": "^3.12.0" + "@prisma/client": "^3.13.0" }, "main": "index.ts", "types": "index.d.ts", @@ -37,6 +38,6 @@ "zod-utils.ts" ], "prisma": { - "seed": "ts-node ./seed.ts" + "seed": "ts-node --transpile-only ./seed.ts" } } diff --git a/packages/prisma/schema.prisma b/packages/prisma/schema.prisma index 2c7e14e9..f67cf873 100644 --- a/packages/prisma/schema.prisma +++ b/packages/prisma/schema.prisma @@ -77,11 +77,13 @@ model EventType { } model Credential { - id Int @id @default(autoincrement()) + id Int @id @default(autoincrement()) type String key Json - user User? @relation(fields: [userId], references: [id], onDelete: Cascade) + user User? @relation(fields: [userId], references: [id], onDelete: Cascade) userId Int? + app App? @relation(fields: [appId], references: [slug], onDelete: Cascade) + appId String? } enum UserPlan { @@ -440,3 +442,26 @@ model Session { expires DateTime user User? @relation(fields: [userId], references: [id], onDelete: Cascade) } + +enum AppCategories { + calendar + messaging + other + payment + video + web3 +} + +model App { + // The slug for the app store public page inside `/apps/[slug]` + slug String @id @unique + // The directory name for `/packages/app-store/[dirName]` + dirName String @unique + // Needed API Keys + keys Json? + // One or multiple categories to which this app belongs + categories AppCategories[] + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + credentials Credential[] +} diff --git a/packages/prisma/seed-app-store.ts b/packages/prisma/seed-app-store.ts new file mode 100644 index 00000000..4b5368ac --- /dev/null +++ b/packages/prisma/seed-app-store.ts @@ -0,0 +1,113 @@ +import { Prisma } from "@prisma/client"; + +import prisma from "."; + +require("dotenv").config({ path: "../../.env" }); + +async function createApp( + slug: Prisma.AppCreateInput["slug"], + /** The directory name for `/packages/app-store/[dirName]` */ + dirName: Prisma.AppCreateInput["dirName"], + categories: Prisma.AppCreateInput["categories"], + keys?: Prisma.AppCreateInput["keys"] +) { + await prisma.app.upsert({ + where: { slug }, + create: { slug, dirName, categories, keys }, + update: { dirName, categories, keys }, + }); + console.log(`📲 Upserted app: '${slug}'`); +} + +async function main() { + // Calendar apps + await createApp("apple-calendar", "applecalendar", ["calendar"]); + await createApp("caldav-calendar", "caldavcalendar", ["calendar"]); + try { + const { client_secret, client_id, redirect_uris } = JSON.parse(process.env.GOOGLE_API_CREDENTIALS).web; + await createApp("google-calendar", "googlecalendar", ["calendar"], { + client_id, + client_secret, + redirect_uris, + }); + await createApp("google-meet", "googlevideo", ["video"], { client_id, client_secret, redirect_uris }); + } catch (e) { + if (e instanceof Error) console.error("Error adding google credentials to DB:", e.message); + } + if (process.env.MS_GRAPH_CLIENT_ID && process.env.MS_GRAPH_CLIENT_SECRET) { + await createApp("office365-calendar", "office365calendar", ["calendar"], { + client_id: process.env.MS_GRAPH_CLIENT_ID, + client_secret: process.env.MS_GRAPH_CLIENT_SECRET, + }); + await createApp("msteams", "office365video", ["video"]); + } + // Video apps + if (process.env.DAILY_API_KEY) { + await createApp("dailyvideo", "dailyvideo", ["video"], { + api_key: process.env.DAILY_API_KEY, + scale_plan: process.env.DAILY_SCALE_PLAN, + }); + } + if (process.env.TANDEM_CLIENT_ID && process.env.TANDEM_CLIENT_SECRET) { + await createApp("tandem", "tandemvideo", ["video"], { + client_id: process.env.TANDEM_CLIENT_ID as string, + client_secret: process.env.TANDEM_CLIENT_SECRET as string, + base_url: (process.env.TANDEM_BASE_URL as string) || "https://tandem.chat", + }); + } + if (process.env.ZOOM_CLIENT_ID && process.env.ZOOM_CLIENT_SECRET) { + await createApp("zoom", "zoomvideo", ["video"], { + client_id: process.env.ZOOM_CLIENT_ID, + client_secret: process.env.ZOOM_CLIENT_SECRET, + }); + } + await createApp("jitsi", "jitsivideo", ["video"]); + // Other apps + if (process.env.HUBSPOT_CLIENT_ID && process.env.HUBSPOT_CLIENT_SECRET) { + await createApp("hubspot", "hubspotothercalendar", ["other"], { + client_id: process.env.HUBSPOT_CLIENT_ID, + client_secret: process.env.HUBSPOT_CLIENT_SECRET, + }); + } + await createApp("wipe-my-cal", "wipemycalother", ["other"]); + if (process.env.GIPHY_API_KEY) { + await createApp("giphy", "giphy", ["other"], { + api_key: process.env.GIPHY_API_KEY, + }); + } + // Web3 apps + await createApp("huddle01", "huddle01video", ["web3", "video"]); + // Messaging apps + if (process.env.SLACK_CLIENT_ID && process.env.SLACK_CLIENT_SECRET && process.env.SLACK_SIGNING_SECRET) { + await createApp("slack", "slackmessaging", ["messaging"], { + client_id: process.env.SLACK_CLIENT_ID, + client_secret: process.env.SLACK_CLIENT_SECRET, + signing_secret: process.env.SLACK_SIGNING_SECRET, + }); + } + // Payment apps + if ( + process.env.STRIPE_CLIENT_ID && + process.env.STRIPE_PRIVATE_KEY && + process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY && + process.env.STRIPE_WEBHOOK_SECRET + ) { + await createApp("stripe", "stripepayment", ["payment"], { + client_id: process.env.STRIPE_CLIENT_ID, + client_secret: process.env.STRIPE_PRIVATE_KEY, + payment_fee_fixed: 10, + payment_fee_percentage: 0.005, + public_key: process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY, + webhook_secret: process.env.STRIPE_WEBHOOK_SECRET, + }); + } +} + +main() + .catch((e) => { + console.error(e); + process.exit(1); + }) + .finally(async () => { + await prisma.$disconnect(); + }); diff --git a/packages/prisma/seed.ts b/packages/prisma/seed.ts index d303002f..c822eef7 100644 --- a/packages/prisma/seed.ts +++ b/packages/prisma/seed.ts @@ -1,13 +1,14 @@ -import { MembershipRole, Prisma, PrismaClient, UserPlan } from "@prisma/client"; +import { MembershipRole, Prisma, UserPlan } from "@prisma/client"; import dayjs from "dayjs"; import { uuid } from "short-uuid"; import { hashPassword } from "@calcom/lib/auth"; import { DEFAULT_SCHEDULE, getAvailabilityFromSchedule } from "@calcom/lib/availability"; -require("dotenv").config({ path: "../../.env" }); +import prisma from "."; +import "./seed-app-store"; -const prisma = new PrismaClient(); +require("dotenv").config({ path: "../../.env" }); async function createUserAndEventType(opts: { user: { diff --git a/test b/test deleted file mode 100644 index e69de29b..00000000 diff --git a/yarn.lock b/yarn.lock index 5fb0e2e9..a9c1dee6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -48,7 +48,7 @@ dependencies: "@babel/highlight" "^7.16.7" -"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.8", "@babel/compat-data@^7.17.0", "@babel/compat-data@^7.17.7": +"@babel/compat-data@^7.17.7": version "7.17.7" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.7.tgz#078d8b833fbbcc95286613be8c716cef2b519fa2" integrity sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ== @@ -172,15 +172,7 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz#38d138561ea207f0f69eb1626a418e4f7e6a580b" - integrity sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA== - dependencies: - "@babel/helper-explode-assignable-expression" "^7.16.7" - "@babel/types" "^7.16.7" - -"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.13.10", "@babel/helper-compilation-targets@^7.16.7", "@babel/helper-compilation-targets@^7.17.7": +"@babel/helper-compilation-targets@^7.13.10", "@babel/helper-compilation-targets@^7.16.7", "@babel/helper-compilation-targets@^7.17.7": version "7.17.7" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz#a3c2924f5e5f0379b356d4cfb313d1414dc30e46" integrity sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w== @@ -203,41 +195,6 @@ "@babel/helper-replace-supers" "^7.16.7" "@babel/helper-split-export-declaration" "^7.16.7" -"@babel/helper-create-class-features-plugin@^7.17.6": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.9.tgz#71835d7fb9f38bd9f1378e40a4c0902fdc2ea49d" - integrity sha512-kUjip3gruz6AJKOq5i3nC6CoCEEF/oHH3cp6tOZhB+IyyyPyW0g1Gfsxn3mkk6S08pIA2y8GQh609v9G/5sHVQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-function-name" "^7.17.9" - "@babel/helper-member-expression-to-functions" "^7.17.7" - "@babel/helper-optimise-call-expression" "^7.16.7" - "@babel/helper-replace-supers" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" - -"@babel/helper-create-regexp-features-plugin@^7.16.7": - version "7.17.0" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz#1dcc7d40ba0c6b6b25618997c5dbfd310f186fe1" - integrity sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - regexpu-core "^5.0.1" - -"@babel/helper-define-polyfill-provider@^0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz#52411b445bdb2e676869e5a74960d2d3826d2665" - integrity sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA== - dependencies: - "@babel/helper-compilation-targets" "^7.13.0" - "@babel/helper-module-imports" "^7.12.13" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/traverse" "^7.13.0" - debug "^4.1.1" - lodash.debounce "^4.0.8" - resolve "^1.14.2" - semver "^6.1.2" - "@babel/helper-environment-visitor@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" @@ -245,13 +202,6 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-explode-assignable-expression@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz#12a6d8522fdd834f194e868af6354e8650242b7a" - integrity sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ== - dependencies: - "@babel/types" "^7.16.7" - "@babel/helper-function-name@^7.12.13", "@babel/helper-function-name@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f" @@ -283,7 +233,7 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-member-expression-to-functions@^7.16.7", "@babel/helper-member-expression-to-functions@^7.17.7": +"@babel/helper-member-expression-to-functions@^7.16.7": version "7.17.7" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.17.7.tgz#a34013b57d8542a8c4ff8ba3f747c02452a4d8c4" integrity sha512-thxXgnQ8qQ11W2wVUObIqDL4p148VMxkt5T/qpN5k2fboRyzFGFmKsTGViquyM5QHKUy48OZoca8kw4ajaDPyw== @@ -318,20 +268,11 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-plugin-utils@7.16.7", "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": +"@babel/helper-plugin-utils@7.16.7", "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== -"@babel/helper-remap-async-to-generator@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz#29ffaade68a367e2ed09c90901986918d25e57e3" - integrity sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-wrap-function" "^7.16.8" - "@babel/types" "^7.16.8" - "@babel/helper-replace-supers@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz#e9f5f5f32ac90429c1a4bdec0f231ef0c2838ab1" @@ -374,16 +315,6 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== -"@babel/helper-wrap-function@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz#58afda087c4cd235de92f7ceedebca2c41274200" - integrity sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw== - dependencies: - "@babel/helper-function-name" "^7.16.7" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.16.8" - "@babel/types" "^7.16.8" - "@babel/helpers@^7.13.10", "@babel/helpers@^7.16.7": version "7.17.2" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.2.tgz#23f0a0746c8e287773ccd27c14be428891f63417" @@ -426,32 +357,7 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.9.tgz#9c94189a6062f0291418ca021077983058e171ef" integrity sha512-vqUSBLP8dQHFPdPi9bc5GK9vRkYHJ49fsZdtoJ8EQ8ibpwk5rPKfvNIwChB0KVXcIjcepEBBd2VHC5r9Gy8ueg== -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.7.tgz#4eda6d6c2a0aa79c70fa7b6da67763dfe2141050" - integrity sha512-anv/DObl7waiGEnC24O9zqL0pSuI9hljihqiDuFHC8d7/bjr/4RLGPWuc8rYOff/QPzbEPSkzG8wGG9aDuhHRg== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz#cc001234dfc139ac45f6bcf801866198c8c72ff9" - integrity sha512-di8vUHRdf+4aJ7ltXhaDbPoszdkh59AQtJM5soLsuHpQJdFQZOA4uGj0V2u/CZ8bJ/u8ULDL5yq6FO/bCXnKHw== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" - "@babel/plugin-proposal-optional-chaining" "^7.16.7" - -"@babel/plugin-proposal-async-generator-functions@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz#3bdd1ebbe620804ea9416706cd67d60787504bc8" - integrity sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-remap-async-to-generator" "^7.16.8" - "@babel/plugin-syntax-async-generators" "^7.8.4" - -"@babel/plugin-proposal-class-properties@7.16.7", "@babel/plugin-proposal-class-properties@^7.16.7": +"@babel/plugin-proposal-class-properties@7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz#925cad7b3b1a2fcea7e59ecc8eb5954f961f91b0" integrity sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww== @@ -459,16 +365,7 @@ "@babel/helper-create-class-features-plugin" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-proposal-class-static-block@^7.16.7": - version "7.17.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.17.6.tgz#164e8fd25f0d80fa48c5a4d1438a6629325ad83c" - integrity sha512-X/tididvL2zbs7jZCeeRJ8167U/+Ac135AM6jCAx6gYXDUviZV5Ku9UDvWS2NCuWlFjIRXklYhwo6HhAC7ETnA== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.17.6" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - -"@babel/plugin-proposal-dynamic-import@7.16.7", "@babel/plugin-proposal-dynamic-import@^7.16.7": +"@babel/plugin-proposal-dynamic-import@7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz#c19c897eaa46b27634a00fee9fb7d829158704b2" integrity sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg== @@ -476,7 +373,7 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-dynamic-import" "^7.8.3" -"@babel/plugin-proposal-export-namespace-from@7.16.7", "@babel/plugin-proposal-export-namespace-from@^7.16.7": +"@babel/plugin-proposal-export-namespace-from@7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz#09de09df18445a5786a305681423ae63507a6163" integrity sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA== @@ -484,15 +381,7 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-proposal-json-strings@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz#9732cb1d17d9a2626a08c5be25186c195b6fa6e8" - integrity sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-json-strings" "^7.8.3" - -"@babel/plugin-proposal-logical-assignment-operators@7.16.7", "@babel/plugin-proposal-logical-assignment-operators@^7.16.7": +"@babel/plugin-proposal-logical-assignment-operators@7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz#be23c0ba74deec1922e639832904be0bea73cdea" integrity sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg== @@ -500,7 +389,7 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-proposal-nullish-coalescing-operator@7.16.7", "@babel/plugin-proposal-nullish-coalescing-operator@^7.16.7": +"@babel/plugin-proposal-nullish-coalescing-operator@7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz#141fc20b6857e59459d430c850a0011e36561d99" integrity sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ== @@ -508,7 +397,7 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-proposal-numeric-separator@7.16.7", "@babel/plugin-proposal-numeric-separator@^7.16.7": +"@babel/plugin-proposal-numeric-separator@7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz#d6b69f4af63fb38b6ca2558442a7fb191236eba9" integrity sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw== @@ -516,26 +405,7 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-object-rest-spread@^7.16.7": - version "7.17.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.17.3.tgz#d9eb649a54628a51701aef7e0ea3d17e2b9dd390" - integrity sha512-yuL5iQA/TbZn+RGAfxQXfi7CNLmKi1f8zInn4IgobuCWcAb7i+zj4TYzQ9l8cEzVyJ89PDGuqxK1xZpUDISesw== - dependencies: - "@babel/compat-data" "^7.17.0" - "@babel/helper-compilation-targets" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.16.7" - -"@babel/plugin-proposal-optional-catch-binding@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz#c623a430674ffc4ab732fd0a0ae7722b67cb74cf" - integrity sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - -"@babel/plugin-proposal-optional-chaining@7.16.7", "@babel/plugin-proposal-optional-chaining@^7.16.7": +"@babel/plugin-proposal-optional-chaining@7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz#7cd629564724816c0e8a969535551f943c64c39a" integrity sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA== @@ -544,7 +414,7 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-proposal-private-methods@7.16.11", "@babel/plugin-proposal-private-methods@^7.16.11": +"@babel/plugin-proposal-private-methods@7.16.11": version "7.16.11" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz#e8df108288555ff259f4527dbe84813aac3a1c50" integrity sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw== @@ -552,7 +422,7 @@ "@babel/helper-create-class-features-plugin" "^7.16.10" "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-proposal-private-property-in-object@7.16.7", "@babel/plugin-proposal-private-property-in-object@^7.16.7": +"@babel/plugin-proposal-private-property-in-object@7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz#b0b8cef543c2c3d57e59e2c611994861d46a3fce" integrity sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ== @@ -562,14 +432,6 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" -"@babel/plugin-proposal-unicode-property-regex@^7.16.7", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz#635d18eb10c6214210ffc5ff4932552de08188a2" - integrity sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-async-generators@7.8.4", "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" @@ -584,20 +446,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3": +"@babel/plugin-syntax-class-properties@^7.8.3": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-syntax-class-static-block@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" - integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" @@ -682,7 +537,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-top-level-await@^7.14.5", "@babel/plugin-syntax-top-level-await@^7.8.3": +"@babel/plugin-syntax-top-level-await@^7.8.3": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== @@ -696,126 +551,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-arrow-functions@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz#44125e653d94b98db76369de9c396dc14bef4154" - integrity sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-async-to-generator@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz#b83dff4b970cf41f1b819f8b49cc0cfbaa53a808" - integrity sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg== - dependencies: - "@babel/helper-module-imports" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-remap-async-to-generator" "^7.16.8" - -"@babel/plugin-transform-block-scoped-functions@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz#4d0d57d9632ef6062cdf354bb717102ee042a620" - integrity sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-block-scoping@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz#f50664ab99ddeaee5bc681b8f3a6ea9d72ab4f87" - integrity sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-classes@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz#8f4b9562850cd973de3b498f1218796eb181ce00" - integrity sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-function-name" "^7.16.7" - "@babel/helper-optimise-call-expression" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-replace-supers" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" - globals "^11.1.0" - -"@babel/plugin-transform-computed-properties@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz#66dee12e46f61d2aae7a73710f591eb3df616470" - integrity sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-destructuring@^7.16.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.17.7.tgz#49dc2675a7afa9a5e4c6bdee636061136c3408d1" - integrity sha512-XVh0r5yq9sLR4vZ6eVZe8FKfIcSgaTBxVBRSYokRj2qksf6QerYnTxz9/GTuKTH/n/HwLP7t6gtlybHetJ/6hQ== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-dotall-regex@^7.16.7", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz#6b2d67686fab15fb6a7fd4bd895d5982cfc81241" - integrity sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-duplicate-keys@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz#2207e9ca8f82a0d36a5a67b6536e7ef8b08823c9" - integrity sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-exponentiation-operator@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz#efa9862ef97e9e9e5f653f6ddc7b665e8536fe9b" - integrity sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA== - dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-for-of@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz#649d639d4617dff502a9a158c479b3b556728d8c" - integrity sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-function-name@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz#5ab34375c64d61d083d7d2f05c38d90b97ec65cf" - integrity sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA== - dependencies: - "@babel/helper-compilation-targets" "^7.16.7" - "@babel/helper-function-name" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-literals@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz#254c9618c5ff749e87cb0c0cef1a0a050c0bdab1" - integrity sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-member-expression-literals@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz#6e5dcf906ef8a098e630149d14c867dd28f92384" - integrity sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-modules-amd@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz#b28d323016a7daaae8609781d1f8c9da42b13186" - integrity sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g== - dependencies: - "@babel/helper-module-transforms" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - babel-plugin-dynamic-import-node "^2.3.3" - "@babel/plugin-transform-modules-commonjs@7.16.8": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz#cdee19aae887b16b9d331009aa9a219af7c86afe" @@ -826,71 +561,6 @@ "@babel/helper-simple-access" "^7.16.7" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-commonjs@^7.16.8": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.17.9.tgz#274be1a2087beec0254d4abd4d86e52442e1e5b6" - integrity sha512-2TBFd/r2I6VlYn0YRTz2JdazS+FoUuQ2rIFHoAxtyP/0G3D82SBLaRq9rnUkpqlLg03Byfl/+M32mpxjO6KaPw== - dependencies: - "@babel/helper-module-transforms" "^7.17.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-simple-access" "^7.17.7" - babel-plugin-dynamic-import-node "^2.3.3" - -"@babel/plugin-transform-modules-systemjs@^7.16.7": - version "7.17.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.17.8.tgz#81fd834024fae14ea78fbe34168b042f38703859" - integrity sha512-39reIkMTUVagzgA5x88zDYXPCMT6lcaRKs1+S9K6NKBPErbgO/w/kP8GlNQTC87b412ZTlmNgr3k2JrWgHH+Bw== - dependencies: - "@babel/helper-hoist-variables" "^7.16.7" - "@babel/helper-module-transforms" "^7.17.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-validator-identifier" "^7.16.7" - babel-plugin-dynamic-import-node "^2.3.3" - -"@babel/plugin-transform-modules-umd@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz#23dad479fa585283dbd22215bff12719171e7618" - integrity sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ== - dependencies: - "@babel/helper-module-transforms" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-named-capturing-groups-regex@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz#7f860e0e40d844a02c9dcf9d84965e7dfd666252" - integrity sha512-j3Jw+n5PvpmhRR+mrgIh04puSANCk/T/UA3m3P1MjJkhlK906+ApHhDIqBQDdOgL/r1UYpz4GNclTXxyZrYGSw== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.16.7" - -"@babel/plugin-transform-new-target@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz#9967d89a5c243818e0800fdad89db22c5f514244" - integrity sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-object-super@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz#ac359cf8d32cf4354d27a46867999490b6c32a94" - integrity sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-replace-supers" "^7.16.7" - -"@babel/plugin-transform-parameters@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz#a1721f55b99b736511cb7e0152f61f17688f331f" - integrity sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-property-literals@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz#2dadac85155436f22c696c4827730e0fe1057a55" - integrity sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-transform-react-jsx-development@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.16.7.tgz#43a00724a3ed2557ed3f276a01a929e6686ac7b8" @@ -923,56 +593,6 @@ "@babel/plugin-syntax-jsx" "^7.16.7" "@babel/types" "^7.17.0" -"@babel/plugin-transform-regenerator@^7.16.7": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.17.9.tgz#0a33c3a61cf47f45ed3232903683a0afd2d3460c" - integrity sha512-Lc2TfbxR1HOyn/c6b4Y/b6NHoTb67n/IoWLxTu4kC7h4KQnWlhCq2S8Tx0t2SVvv5Uu87Hs+6JEJ5kt2tYGylQ== - dependencies: - regenerator-transform "^0.15.0" - -"@babel/plugin-transform-reserved-words@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz#1d798e078f7c5958eec952059c460b220a63f586" - integrity sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-shorthand-properties@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz#e8549ae4afcf8382f711794c0c7b6b934c5fbd2a" - integrity sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-spread@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz#a303e2122f9f12e0105daeedd0f30fb197d8ff44" - integrity sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" - -"@babel/plugin-transform-sticky-regex@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz#c84741d4f4a38072b9a1e2e3fd56d359552e8660" - integrity sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-template-literals@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz#f3d1c45d28967c8e80f53666fc9c3e50618217ab" - integrity sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-typeof-symbol@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz#9cdbe622582c21368bd482b660ba87d5545d4f7e" - integrity sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-transform-typescript@^7.16.7": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.8.tgz#591ce9b6b83504903fa9dd3652c357c2ba7a1ee0" @@ -982,113 +602,7 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-typescript" "^7.16.7" -"@babel/plugin-transform-unicode-escapes@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz#da8717de7b3287a2c6d659750c964f302b31ece3" - integrity sha512-TAV5IGahIz3yZ9/Hfv35TV2xEm+kaBDaZQCn2S/hG9/CZ0DktxJv9eKfPc7yYCvOYR4JGx1h8C+jcSOvgaaI/Q== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-unicode-regex@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz#0f7aa4a501198976e25e82702574c34cfebe9ef2" - integrity sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/preset-env@^7.16.11": - version "7.16.11" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.16.11.tgz#5dd88fd885fae36f88fd7c8342475c9f0abe2982" - integrity sha512-qcmWG8R7ZW6WBRPZK//y+E3Cli151B20W1Rv7ln27vuPaXU/8TKms6jFdiJtF7UDTxcrb7mZd88tAeK9LjdT8g== - dependencies: - "@babel/compat-data" "^7.16.8" - "@babel/helper-compilation-targets" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-validator-option" "^7.16.7" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.16.7" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.16.7" - "@babel/plugin-proposal-async-generator-functions" "^7.16.8" - "@babel/plugin-proposal-class-properties" "^7.16.7" - "@babel/plugin-proposal-class-static-block" "^7.16.7" - "@babel/plugin-proposal-dynamic-import" "^7.16.7" - "@babel/plugin-proposal-export-namespace-from" "^7.16.7" - "@babel/plugin-proposal-json-strings" "^7.16.7" - "@babel/plugin-proposal-logical-assignment-operators" "^7.16.7" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.16.7" - "@babel/plugin-proposal-numeric-separator" "^7.16.7" - "@babel/plugin-proposal-object-rest-spread" "^7.16.7" - "@babel/plugin-proposal-optional-catch-binding" "^7.16.7" - "@babel/plugin-proposal-optional-chaining" "^7.16.7" - "@babel/plugin-proposal-private-methods" "^7.16.11" - "@babel/plugin-proposal-private-property-in-object" "^7.16.7" - "@babel/plugin-proposal-unicode-property-regex" "^7.16.7" - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-class-properties" "^7.12.13" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - "@babel/plugin-syntax-top-level-await" "^7.14.5" - "@babel/plugin-transform-arrow-functions" "^7.16.7" - "@babel/plugin-transform-async-to-generator" "^7.16.8" - "@babel/plugin-transform-block-scoped-functions" "^7.16.7" - "@babel/plugin-transform-block-scoping" "^7.16.7" - "@babel/plugin-transform-classes" "^7.16.7" - "@babel/plugin-transform-computed-properties" "^7.16.7" - "@babel/plugin-transform-destructuring" "^7.16.7" - "@babel/plugin-transform-dotall-regex" "^7.16.7" - "@babel/plugin-transform-duplicate-keys" "^7.16.7" - "@babel/plugin-transform-exponentiation-operator" "^7.16.7" - "@babel/plugin-transform-for-of" "^7.16.7" - "@babel/plugin-transform-function-name" "^7.16.7" - "@babel/plugin-transform-literals" "^7.16.7" - "@babel/plugin-transform-member-expression-literals" "^7.16.7" - "@babel/plugin-transform-modules-amd" "^7.16.7" - "@babel/plugin-transform-modules-commonjs" "^7.16.8" - "@babel/plugin-transform-modules-systemjs" "^7.16.7" - "@babel/plugin-transform-modules-umd" "^7.16.7" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.16.8" - "@babel/plugin-transform-new-target" "^7.16.7" - "@babel/plugin-transform-object-super" "^7.16.7" - "@babel/plugin-transform-parameters" "^7.16.7" - "@babel/plugin-transform-property-literals" "^7.16.7" - "@babel/plugin-transform-regenerator" "^7.16.7" - "@babel/plugin-transform-reserved-words" "^7.16.7" - "@babel/plugin-transform-shorthand-properties" "^7.16.7" - "@babel/plugin-transform-spread" "^7.16.7" - "@babel/plugin-transform-sticky-regex" "^7.16.7" - "@babel/plugin-transform-template-literals" "^7.16.7" - "@babel/plugin-transform-typeof-symbol" "^7.16.7" - "@babel/plugin-transform-unicode-escapes" "^7.16.7" - "@babel/plugin-transform-unicode-regex" "^7.16.7" - "@babel/preset-modules" "^0.1.5" - "@babel/types" "^7.16.8" - babel-plugin-polyfill-corejs2 "^0.3.0" - babel-plugin-polyfill-corejs3 "^0.5.0" - babel-plugin-polyfill-regenerator "^0.3.0" - core-js-compat "^3.20.2" - semver "^6.3.0" - -"@babel/preset-modules@^0.1.5": - version "0.1.5" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9" - integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" - "@babel/plugin-transform-dotall-regex" "^7.4.4" - "@babel/types" "^7.4.4" - esutils "^2.0.2" - -"@babel/preset-typescript@7.16.7", "@babel/preset-typescript@^7.16.7": +"@babel/preset-typescript@7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.16.7.tgz#ab114d68bb2020afc069cd51b37ff98a046a70b9" integrity sha512-WbVEmgXdIyvzB77AQjGBEyYPZx+8tTsO50XtfozQrkW8QB2rLJpH2lgx0TRw5EJrBxOZQ+wCcyPVQvS8tjEHpQ== @@ -1120,7 +634,7 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.3.1", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.3.1", "@babel/runtime@^7.9.2": version "7.17.9" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.9.tgz#d19fbf802d01a8cb6cf053a64e472d42c434ba72" integrity sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg== @@ -1167,7 +681,7 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/traverse@^7.16.8", "@babel/traverse@^7.17.9", "@babel/traverse@^7.7.2": +"@babel/traverse@^7.17.9", "@babel/traverse@^7.7.2": version "7.17.9" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.9.tgz#1f9b207435d9ae4a8ed6998b2b82300d83c37a0d" integrity sha512-PQO8sDIJ8SIwipTPiR71kJQCKQYB5NGImbOviK8K+kg5xkNSYXLBupuX9QhatFowrsvo9Hj8WgArg3W7ijNAQw== @@ -1192,7 +706,7 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" -"@babel/types@^7.0.0", "@babel/types@^7.13.0", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": +"@babel/types@^7.0.0", "@babel/types@^7.13.0", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3": version "7.17.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== @@ -1244,6 +758,14 @@ resolved "https://registry.yarnpkg.com/@braintree/sanitize-url/-/sanitize-url-6.0.0.tgz#fe364f025ba74f6de6c837a84ef44bdb1d61e68f" integrity sha512-mgmE7XBYY/21erpzhexk4Cj1cyTQ9LzvnTxtzM17BJ7ERMNE6W72mQRo0I1Ud8eFJ+RVVIcBNhLFZ3GX4XFz5w== +"@calcom/embed-react@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@calcom/embed-react/-/embed-react-1.0.2.tgz#b27230f333893573c02cb2aa35a162b5ca976705" + integrity sha512-6E8m9A6XW9nY7V0Ey54IAqbr5mABx0f5y9GYHXwBdLu8Pqq0f1H/JFmiVvlvs+DIgdMRMFa0qwQF7iM8QNkNxQ== + dependencies: + playwright "^1.21.1" + typescript "^4.6.3" + "@cnakazawa/watch@^1.0.3": version "1.0.4" resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" @@ -1369,6 +891,21 @@ resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46" integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA== +"@eslint/eslintrc@^1.2.0": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.2.tgz#4989b9e8c0216747ee7cca314ae73791bb281aae" + integrity sha512-lTVWHs7O2hjBFZunXTZYnYqtB9GakA1lnxIf+gKq2nY5gxkkNi/lQvveW6t8gFdOHTg6nG50Xs95PrLqVpcaLg== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.3.1" + globals "^13.9.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + "@eslint/eslintrc@^1.2.1": version "1.2.1" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.1.tgz#8b5e1c49f4077235516bc9ec7d41378c0f69b8c6" @@ -1656,7 +1193,12 @@ resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.5.0.tgz#483b44ba2c8b8d4391e1d2c863898d7dd0cc0296" integrity sha512-aaRnYxBb3MU2FNJf3Ut9RMTUqqU3as0aI1lQhgo2n9Fa67wRu14iOGqx93xB+uMNVfNwZ5B3y/Ndm7qZGuFeMQ== -"@heroicons/react@^1.0.6": +"@headlessui/react@^1.5.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.6.0.tgz#5943c0b1e5b1a02566ab45f665a05188b1d079c5" + integrity sha512-PlDuytBC6iDC/uMvpANm5VpRSuayyXMEeo/dNIwAZNHCfhZUqDQgLXjGu48SHsvMw22Kc3c3u9TOAMZNg+1vzw== + +"@heroicons/react@^1.0.4", "@heroicons/react@^1.0.6": version "1.0.6" resolved "https://registry.yarnpkg.com/@heroicons/react/-/react-1.0.6.tgz#35dd26987228b39ef2316db3b1245c42eb19e324" integrity sha512-JJCXydOFWMDpCP4q13iEplA503MQO3xLoZiKum+955ZCtHINWnx26CUxVxxFQu/uLb4LW3ge15ZpzIkXKkJ8oQ== @@ -2466,6 +2008,11 @@ dependencies: webpack-bundle-analyzer "4.3.0" +"@next/env@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/env/-/env-12.1.0.tgz#73713399399b34aa5a01771fb73272b55b22c314" + integrity sha512-nrIgY6t17FQ9xxwH3jj0a6EOiQ/WDHUos35Hghtr+SWN/ntHIQ7UpuvSi0vaLzZVHQWaDupKI+liO5vANcDeTQ== + "@next/env@12.1.4": version "12.1.4" resolved "https://registry.yarnpkg.com/@next/env/-/env-12.1.4.tgz#5af629b43075281ecd7f87938802b7cf5b67e94b" @@ -2493,6 +2040,11 @@ resolved "https://registry.yarnpkg.com/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-12.1.5.tgz#36729ab3dfd7743e82cfe536b43254dcb146620c" integrity sha512-SKnGTdYcoN04Y2DvE0/Y7/MjkA+ltsmbuH/y/hR7Ob7tsj+8ZdOYuk+YvW1B8dY20nDPHP58XgDTSm2nA8BzzA== +"@next/swc-android-arm64@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-12.1.0.tgz#865ba3a9afc204ff2bdeea49dd64d58705007a39" + integrity sha512-/280MLdZe0W03stA69iL+v6I+J1ascrQ6FrXBlXGCsGzrfMaGr7fskMa0T5AhQIVQD4nA/46QQWxG//DYuFBcA== + "@next/swc-android-arm64@12.1.4": version "12.1.4" resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-12.1.4.tgz#f320d60639e19ecffa1f9034829f2d95502a9a51" @@ -2503,6 +2055,11 @@ resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-12.1.5.tgz#52578f552305c92d0b9b81d603c9643fb71e0835" integrity sha512-YXiqgQ/9Rxg1dXp6brXbeQM1JDx9SwUY/36JiE+36FXqYEmDYbxld9qkX6GEzkc5rbwJ+RCitargnzEtwGW0mw== +"@next/swc-darwin-arm64@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.1.0.tgz#08e8b411b8accd095009ed12efbc2f1d4d547135" + integrity sha512-R8vcXE2/iONJ1Unf5Ptqjk6LRW3bggH+8drNkkzH4FLEQkHtELhvcmJwkXcuipyQCsIakldAXhRbZmm3YN1vXg== + "@next/swc-darwin-arm64@12.1.4": version "12.1.4" resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.1.4.tgz#fd578278312613eddcf3aee26910100509941b63" @@ -2513,6 +2070,11 @@ resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.1.5.tgz#3d5b53211484c72074f4975ba0ec2b1107db300e" integrity sha512-y8mhldb/WFZ6lFeowkGfi0cO/lBdiBqDk4T4LZLvCpoQp4Or/NzUN6P5NzBQZ5/b4oUHM/wQICEM+1wKA4qIVw== +"@next/swc-darwin-x64@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-12.1.0.tgz#fcd684497a76e8feaca88db3c394480ff0b007cd" + integrity sha512-ieAz0/J0PhmbZBB8+EA/JGdhRHBogF8BWaeqR7hwveb6SYEIJaDNQy0I+ZN8gF8hLj63bEDxJAs/cEhdnTq+ug== + "@next/swc-darwin-x64@12.1.4": version "12.1.4" resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-12.1.4.tgz#ace5f80d8c8348efe194f6d7074c6213c52b3944" @@ -2523,6 +2085,11 @@ resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-12.1.5.tgz#adcabb732d226453777c0d37d58eaff9328b66fd" integrity sha512-wqJ3X7WQdTwSGi0kIDEmzw34QHISRIQ5uvC+VXmsIlCPFcMA+zM5723uh8NfuKGquDMiEMS31a83QgkuHMYbwQ== +"@next/swc-linux-arm-gnueabihf@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.1.0.tgz#9ec6380a27938a5799aaa6035c205b3c478468a7" + integrity sha512-njUd9hpl6o6A5d08dC0cKAgXKCzm5fFtgGe6i0eko8IAdtAPbtHxtpre3VeSxdZvuGFh+hb0REySQP9T1ttkog== + "@next/swc-linux-arm-gnueabihf@12.1.4": version "12.1.4" resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.1.4.tgz#2bf2c83863635f19c71c226a2df936e001cce29c" @@ -2533,6 +2100,11 @@ resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.1.5.tgz#82a7cde67482b756bc65fbebf1dfa8a782074e93" integrity sha512-WnhdM5duONMvt2CncAl+9pim0wBxDS2lHoo7ub/o/i1bRbs11UTzosKzEXVaTDCUkCX2c32lIDi1WcN2ZPkcdw== +"@next/swc-linux-arm64-gnu@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.1.0.tgz#7f4196dff1049cea479607c75b81033ae2dbd093" + integrity sha512-OqangJLkRxVxMhDtcb7Qn1xjzFA3s50EIxY7mljbSCLybU+sByPaWAHY4px97ieOlr2y4S0xdPKkQ3BCAwyo6Q== + "@next/swc-linux-arm64-gnu@12.1.4": version "12.1.4" resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.1.4.tgz#d577190f641c9b4b463719dd6b8953b6ba9be8d9" @@ -2543,6 +2115,11 @@ resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.1.5.tgz#f82ca014504950aab751e81f467492e9be0bad5d" integrity sha512-Jq2H68yQ4bLUhR/XQnbw3LDW0GMQn355qx6rU36BthDLeGue7YV7MqNPa8GKvrpPocEMW77nWx/1yI6w6J07gw== +"@next/swc-linux-arm64-musl@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.1.0.tgz#b445f767569cdc2dddee785ca495e1a88c025566" + integrity sha512-hB8cLSt4GdmOpcwRe2UzI5UWn6HHO/vLkr5OTuNvCJ5xGDwpPXelVkYW/0+C3g5axbDW2Tym4S+MQCkkH9QfWA== + "@next/swc-linux-arm64-musl@12.1.4": version "12.1.4" resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.1.4.tgz#e70ffe70393d8f9242deecdb282ce5a8fd588b14" @@ -2553,6 +2130,11 @@ resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.1.5.tgz#f811ec9f4b12a978426c284c95ab2f515ddf7f9e" integrity sha512-KgPjwdbhDqXI7ghNN8V/WAiLquc9Ebe8KBrNNEL0NQr+yd9CyKJ6KqjayVkmX+hbHzbyvbui/5wh/p3CZQ9xcQ== +"@next/swc-linux-x64-gnu@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.1.0.tgz#67610e9be4fbc987de7535f1bcb17e45fe12f90e" + integrity sha512-OKO4R/digvrVuweSw/uBM4nSdyzsBV5EwkUeeG4KVpkIZEe64ZwRpnFB65bC6hGwxIBnTv5NMSnJ+0K/WmG78A== + "@next/swc-linux-x64-gnu@12.1.4": version "12.1.4" resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.1.4.tgz#91498a130387fb1961902f2bee55863f8e910cff" @@ -2563,6 +2145,11 @@ resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.1.5.tgz#d44857257e6d20dc841998951d584ab1f25772c3" integrity sha512-O2ErUTvCJ6DkNTSr9pbu1n3tcqykqE/ebty1rwClzIYdOgpB3T2MfEPP+K7GhUR87wmN/hlihO9ch7qpVFDGKw== +"@next/swc-linux-x64-musl@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.1.0.tgz#ea19a23db08a9f2e34ac30401f774cf7d1669d31" + integrity sha512-JohhgAHZvOD3rQY7tlp7NlmvtvYHBYgY0x5ZCecUT6eCCcl9lv6iV3nfu82ErkxNk1H893fqH0FUpznZ/H3pSw== + "@next/swc-linux-x64-musl@12.1.4": version "12.1.4" resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.1.4.tgz#78057b03c148c121553d41521ad38f6c732762ff" @@ -2573,6 +2160,11 @@ resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.1.5.tgz#3cc523abadc9a2a6de680593aff06e71cc29ecef" integrity sha512-1eIlZmlO/VRjxxzUBcVosf54AFU3ltAzHi+BJA+9U/lPxCYIsT+R4uO3QksRzRjKWhVQMRjEnlXyyq5SKJm7BA== +"@next/swc-win32-arm64-msvc@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.1.0.tgz#eadf054fc412085659b98e145435bbba200b5283" + integrity sha512-T/3gIE6QEfKIJ4dmJk75v9hhNiYZhQYAoYm4iVo1TgcsuaKLFa+zMPh4056AHiG6n9tn2UQ1CFE8EoybEsqsSw== + "@next/swc-win32-arm64-msvc@12.1.4": version "12.1.4" resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.1.4.tgz#05bbaabacac23b8edf6caa99eb86b17550a09051" @@ -2583,6 +2175,11 @@ resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.1.5.tgz#c62232d869f1f9b22e8f24e4e7f05307c20f30ca" integrity sha512-oromsfokbEuVb0CBLLE7R9qX3KGXucZpsojLpzUh1QJjuy1QkrPJncwr8xmWQnwgtQ6ecMWXgXPB+qtvizT9Tw== +"@next/swc-win32-ia32-msvc@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.1.0.tgz#68faeae10c89f698bf9d28759172b74c9c21bda1" + integrity sha512-iwnKgHJdqhIW19H9PRPM9j55V6RdcOo6rX+5imx832BCWzkDbyomWnlzBfr6ByUYfhohb8QuH4hSGEikpPqI0Q== + "@next/swc-win32-ia32-msvc@12.1.4": version "12.1.4" resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.1.4.tgz#8fd2fb48f04a2802e51fc320878bf6b411c1c866" @@ -2593,6 +2190,11 @@ resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.1.5.tgz#2bd9b28a9ba730d12a493e7d9d18e150fe89d496" integrity sha512-a/51L5KzBpeZSW9LbekMo3I3Cwul+V+QKwbEIMA+Qwb2qrlcn1L9h3lt8cHqNTFt2y72ce6aTwDTw1lyi5oIRA== +"@next/swc-win32-x64-msvc@12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.1.0.tgz#d27e7e76c87a460a4da99c5bfdb1618dcd6cd064" + integrity sha512-aBvcbMwuanDH4EMrL2TthNJy+4nP59Bimn8egqv6GHMVj0a44cU6Au4PjOhLNqEh9l+IpRGBqMTzec94UdC5xg== + "@next/swc-win32-x64-msvc@12.1.4": version "12.1.4" resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.1.4.tgz#a72ed44c9b1f850986a30fe36c59e01f8a79b5f3" @@ -2880,12 +2482,12 @@ resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1" integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g== -"@prisma/client@^3.12.0": - version "3.12.0" - resolved "https://registry.yarnpkg.com/@prisma/client/-/client-3.12.0.tgz#a0eb49ffea5c128dd11dffb896d7139a60073d12" - integrity sha512-4NEQjUcWja/NVBvfuDFscWSk1/rXg3+wj+TSkqXCb1tKlx/bsUE00rxsvOvGg7VZ6lw1JFpGkwjwmsOIc4zvQw== +"@prisma/client@^3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@prisma/client/-/client-3.13.0.tgz#84511ebdf6ba75f77ca08495b9f73f22c4255654" + integrity sha512-lnEA2tTyVbO5mS1ehmHJQKBDiKB8shaR6s3azwj3Azfi5XHIfnqmkolLCvUeFYnkDCNVzGXJpUgKwQt/UOOYVQ== dependencies: - "@prisma/engines-version" "3.12.0-37.22b822189f46ef0dc5c5b503368d1bee01213980" + "@prisma/engines-version" "3.13.0-17.efdf9b1183dddfd4258cd181a72125755215ab7b" "@prisma/debug@3.8.1": version "3.8.1" @@ -2896,15 +2498,15 @@ ms "2.1.3" strip-ansi "6.0.1" -"@prisma/engines-version@3.12.0-37.22b822189f46ef0dc5c5b503368d1bee01213980": - version "3.12.0-37.22b822189f46ef0dc5c5b503368d1bee01213980" - resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-3.12.0-37.22b822189f46ef0dc5c5b503368d1bee01213980.tgz#829ca3d9d0d92555f44644606d4edfd45b2f5886" - integrity sha512-o+jo8d7ZEiVpcpNWUDh3fj2uPQpBxl79XE9ih9nkogJbhw6P33274SHnqheedZ7PyvPIK/mvU8MLNYgetgXPYw== +"@prisma/engines-version@3.13.0-17.efdf9b1183dddfd4258cd181a72125755215ab7b": + version "3.13.0-17.efdf9b1183dddfd4258cd181a72125755215ab7b" + resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-3.13.0-17.efdf9b1183dddfd4258cd181a72125755215ab7b.tgz#676aca309d66d9be2aad8911ca31f1ee5561041c" + integrity sha512-TGp9rvgJIKo8NgvAHSwOosbut9mTA7VC6/rpQI9gh+ySSRjdQFhbGyNUiOcQrlI9Ob2DWeO7y4HEnhdKxYiECg== -"@prisma/engines@3.10.0-50.73e60b76d394f8d37d8ebd1f8918c79029f0db86": - version "3.10.0-50.73e60b76d394f8d37d8ebd1f8918c79029f0db86" - resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-3.10.0-50.73e60b76d394f8d37d8ebd1f8918c79029f0db86.tgz#2964113729a78b8b21e186b5592affd1fde73c16" - integrity sha512-LjRssaWu9w2SrXitofnutRIyURI7l0veQYIALz7uY4shygM9nMcK3omXcObRm7TAcw3Z+9ytfK1B+ySOsOesxQ== +"@prisma/engines@3.13.0-17.efdf9b1183dddfd4258cd181a72125755215ab7b": + version "3.13.0-17.efdf9b1183dddfd4258cd181a72125755215ab7b" + resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-3.13.0-17.efdf9b1183dddfd4258cd181a72125755215ab7b.tgz#d3a457cec4ef7a3b3412c45b1f2eac68c974474b" + integrity sha512-Ip9CcCeUocH61eXu4BUGpvl5KleQyhcUVLpWCv+0ZmDv44bFaDpREqjGHHdRupvPN/ugB6gTlD9b9ewdj02yVA== "@prisma/generator-helper@~3.8.1": version "3.8.1" @@ -3791,11 +3393,6 @@ dependencies: "@types/node" "*" -"@types/debounce@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@types/debounce/-/debounce-1.2.1.tgz#79b65710bc8b6d44094d286aecf38e44f9627852" - integrity sha512-epMsEE85fi4lfmJUH/89/iV/LI+F5CvNIvmgs5g5jYFPfhO2S/ae8WSsLOKWdwtoaZw9Q2IhJ4tQ5tFCcS/4HA== - "@types/debug@4.1.7", "@types/debug@^4.0.0": version "4.1.7" resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82" @@ -3987,21 +3584,31 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.23.tgz#3b41a6e643589ac6442bdbd7a4a3ded62f33f7da" integrity sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw== -"@types/node@16.11.26", "@types/node@^16.11.24": - version "16.11.26" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.26.tgz#63d204d136c9916fb4dcd1b50f9740fe86884e47" - integrity sha512-GZ7bu5A6+4DtG7q9GsoHXy3ALcgeIHP4NnL0Vv2wu0uUB/yQex26v0tf6/na1mm0+bS9Uw+0DFex7aaKr2qawQ== - "@types/node@16.9.1": version "16.9.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.9.1.tgz#0611b37db4246c937feef529ddcc018cf8e35708" integrity sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g== +"@types/node@17.0.21": + version "17.0.21" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.21.tgz#864b987c0c68d07b4345845c3e63b75edd143644" + integrity sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ== + +"@types/node@17.0.27": + version "17.0.27" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.27.tgz#f4df3981ae8268c066e8f49995639f855469081e" + integrity sha512-4/Ke7bbWOasuT3kceBZFGakP1dYN2XFd8v2l9bqF2LNWrmeU07JLpp56aEeG6+Q3olqO5TvXpW0yaiYnZJ5CXg== + "@types/node@^12.12.6": version "12.20.47" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.47.tgz#ca9237d51f2a2557419688511dab1c8daf475188" integrity sha512-BzcaRsnFuznzOItW1WpQrDHM7plAa7GIDMZ6b5pnMbkqEtM/6WCOhvZar39oeMQP79gwvFUWjjptE7/KGcNqFg== +"@types/node@^16.11.24": + version "16.11.26" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.26.tgz#63d204d136c9916fb4dcd1b50f9740fe86884e47" + integrity sha512-GZ7bu5A6+4DtG7q9GsoHXy3ALcgeIHP4NnL0Vv2wu0uUB/yQex26v0tf6/na1mm0+bS9Uw+0DFex7aaKr2qawQ== + "@types/nodemailer@^6.4.4": version "6.4.4" resolved "https://registry.yarnpkg.com/@types/nodemailer/-/nodemailer-6.4.4.tgz#c265f7e7a51df587597b3a49a023acaf0c741f4b" @@ -4125,6 +3732,15 @@ "@types/scheduler" "*" csstype "^3.0.2" +"@types/react@17.0.40": + version "17.0.40" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.40.tgz#dc010cee6254d5239a138083f3799a16638e6bad" + integrity sha512-UrXhD/JyLH+W70nNSufXqMZNuUD2cXHu6UjCllC6pmOQgBX4SGXOH8fjRka0O0Ee0HrFxapDD8Bwn81Kmiz6jQ== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + "@types/react@^17", "@types/react@^17.0.0": version "17.0.44" resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.44.tgz#c3714bd34dd551ab20b8015d9d0dbec812a51ec7" @@ -4806,6 +4422,18 @@ autoprefixer@^10.3.4, autoprefixer@^10.4.0, autoprefixer@^10.4.4: picocolors "^1.0.0" postcss-value-parser "^4.2.0" +autoprefixer@^10.4.2: + version "10.4.5" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.5.tgz#662193c744094b53d3637f39be477e07bd904998" + integrity sha512-Fvd8yCoA7lNX/OUllvS+aS1I7WRBclGXsepbvT8ZaPgrH24rgXpZzF0/6Hh3ZEkwg+0AES/Osd196VZmYoEFtw== + dependencies: + browserslist "^4.20.2" + caniuse-lite "^1.0.30001332" + fraction.js "^4.2.0" + normalize-range "^0.1.2" + picocolors "^1.0.0" + postcss-value-parser "^4.2.0" + available-typed-arrays@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" @@ -4913,30 +4541,6 @@ babel-plugin-macros@^2.6.1: cosmiconfig "^6.0.0" resolve "^1.12.0" -babel-plugin-polyfill-corejs2@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz#440f1b70ccfaabc6b676d196239b138f8a2cfba5" - integrity sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w== - dependencies: - "@babel/compat-data" "^7.13.11" - "@babel/helper-define-polyfill-provider" "^0.3.1" - semver "^6.1.1" - -babel-plugin-polyfill-corejs3@^0.5.0: - version "0.5.2" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz#aabe4b2fa04a6e038b688c5e55d44e78cd3a5f72" - integrity sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.1" - core-js-compat "^3.21.0" - -babel-plugin-polyfill-regenerator@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz#2c0678ea47c75c8cc2fbb1852278d8fb68233990" - integrity sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.1" - babel-preset-current-node-syntax@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" @@ -4998,7 +4602,7 @@ base-x@^3.0.2, base-x@^3.0.8: dependencies: safe-buffer "^5.0.1" -base64-js@^1.3.0, base64-js@^1.3.1, base64-js@^1.5.1: +base64-js@^1.1.2, base64-js@^1.3.0, base64-js@^1.3.1, base64-js@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -5212,6 +4816,13 @@ brorand@^1.0.1, brorand@^1.1.0: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= +brotli@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/brotli/-/brotli-1.3.2.tgz#525a9cad4fcba96475d7d388f6aecb13eed52f46" + integrity sha1-UlqcrU/LqWR119OI9q7LE+7VL0Y= + dependencies: + base64-js "^1.1.2" + browser-process-hrtime@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" @@ -5519,6 +5130,11 @@ caniuse-lite@^1.0.30001283, caniuse-lite@^1.0.30001313, caniuse-lite@^1.0.300013 resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001325.tgz#2b4ad19b77aa36f61f2eaf72e636d7481d55e606" integrity sha512-sB1bZHjseSjDtijV1Hb7PB2Zd58Kyx+n/9EotvZ4Qcz2K3d0lWB8dB4nb8wN/TsOGFq3UuAm0zQZNQ4SoR7TrQ== +caniuse-lite@^1.0.30001332: + version "1.0.30001334" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001334.tgz#892e9965b35285033fc2b8a8eff499fe02f13d8b" + integrity sha512-kbaCEBRRVSoeNs74sCuq92MJyGrMtjWVfhltoHUCW4t4pXFvGjUBrfo47weBRViHkiV3eBYyIsfl956NtHGazw== + capture-exit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" @@ -5623,6 +5239,11 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== +chart.js@^3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.7.1.tgz#0516f690c6a8680c6c707e31a4c1807a6f400ada" + integrity sha512-8knRegQLFnPQAheZV8MjxIXc5gQEfDFD897BJgv/klO/vtIyFFmgMXrNfgrXpbTr/XbTturxRgxIXx/Y+ASJBA== + chokidar@^3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" @@ -6008,14 +5629,6 @@ copy-to-clipboard@^3: dependencies: toggle-selection "^1.0.6" -core-js-compat@^3.20.2, core-js-compat@^3.21.0: - version "3.22.0" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.22.0.tgz#7ce17ab57c378be2c717c7c8ed8f82a50a25b3e4" - integrity sha512-WwA7xbfRGrk8BGaaHlakauVXrlYmAIkk8PNGb1FDQS+Rbrewc3pgFfwJFRw6psmJVAll7Px9UHRYE16oRQnwAQ== - dependencies: - browserslist "^4.20.2" - semver "7.0.0" - core-js-pure@^3.20.2: version "3.21.1" resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.21.1.tgz#8c4d1e78839f5f46208de7230cebfb72bc3bdb51" @@ -7166,6 +6779,47 @@ eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.3.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== +eslint@8.10.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.10.0.tgz#931be395eb60f900c01658b278e05b6dae47199d" + integrity sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw== + dependencies: + "@eslint/eslintrc" "^1.2.0" + "@humanwhocodes/config-array" "^0.9.2" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.1.1" + eslint-utils "^3.0.0" + eslint-visitor-keys "^3.3.0" + espree "^9.3.1" + esquery "^1.4.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^6.0.1" + globals "^13.6.0" + ignore "^5.2.0" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.0.4" + natural-compare "^1.4.0" + optionator "^0.9.1" + regexpp "^3.2.0" + strip-ansi "^6.0.1" + strip-json-comments "^3.1.0" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + eslint@^8.10.0, eslint@^8.11.0: version "8.11.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.11.0.tgz#88b91cfba1356fc10bb9eb592958457dfe09fb37" @@ -8874,7 +8528,7 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== -husky@^7.0.1, husky@^7.0.4: +husky@^7.0.1: version "7.0.4" resolved "https://registry.yarnpkg.com/husky/-/husky-7.0.4.tgz#242048245dc49c8fb1bf0cc7cfb98dd722531535" integrity sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ== @@ -10540,11 +10194,6 @@ jsesc@^2.5.1: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= - json-bigint@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-1.0.0.tgz#ae547823ac0cad8398667f8cd9ef4730f5b01ff1" @@ -10979,7 +10628,7 @@ lodash.clonedeep@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= -lodash.debounce@^4, lodash.debounce@^4.0.8: +lodash.debounce@^4: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= @@ -11989,6 +11638,13 @@ mockdate@^3.0.5: resolved "https://registry.yarnpkg.com/mockdate/-/mockdate-3.0.5.tgz#789be686deb3149e7df2b663d2bc4392bc3284fb" integrity sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ== +modify-response-middleware@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/modify-response-middleware/-/modify-response-middleware-1.1.0.tgz#8713182390a7c7ec32dfc79b9bc626d14060d4ce" + integrity sha512-oAyioDzMvyYwbq8tH7DvahHtGzQvDwZlN2CxL2fZQdUZNz8JJvC3PYaagiMGN58sM45Veo1GA8g/aJI7Hogpxw== + dependencies: + brotli "^1.3.2" + module-alias@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/module-alias/-/module-alias-2.2.2.tgz#151cdcecc24e25739ff0aa6e51e1c5716974c0e0" @@ -12262,30 +11918,30 @@ next-validations@^0.1.11: resolved "https://registry.yarnpkg.com/next-validations/-/next-validations-0.1.11.tgz#fcc62dea5be8f9793d410de175f96e3fc1dac54d" integrity sha512-rdyRgZ3f3jwhLigdi9MC5R74BvRpB3cewa8LVnMHDiDRnSThvX0CdZ5KHK4t/SgrIGaVXiXOQ59KtvBqjcm5pA== -next@12.1.4, next@^12.1.0: - version "12.1.4" - resolved "https://registry.yarnpkg.com/next/-/next-12.1.4.tgz#597a9bdec7aec778b442c4f6d41afd2c64a54b23" - integrity sha512-DA4g97BM4Z0nKtDvCTm58RxdvoQyYzeg0AeVbh0N4Y/D8ELrNu47lQeEgRGF8hV4eQ+Sal90zxrJQQG/mPQ8CQ== +next@12.1.0: + version "12.1.0" + resolved "https://registry.yarnpkg.com/next/-/next-12.1.0.tgz#c33d753b644be92fc58e06e5a214f143da61dd5d" + integrity sha512-s885kWvnIlxsUFHq9UGyIyLiuD0G3BUC/xrH0CEnH5lHEWkwQcHOORgbDF0hbrW9vr/7am4ETfX4A7M6DjrE7Q== dependencies: - "@next/env" "12.1.4" + "@next/env" "12.1.0" caniuse-lite "^1.0.30001283" postcss "8.4.5" - styled-jsx "5.0.1" + styled-jsx "5.0.0" + use-subscription "1.5.1" optionalDependencies: - "@next/swc-android-arm-eabi" "12.1.4" - "@next/swc-android-arm64" "12.1.4" - "@next/swc-darwin-arm64" "12.1.4" - "@next/swc-darwin-x64" "12.1.4" - "@next/swc-linux-arm-gnueabihf" "12.1.4" - "@next/swc-linux-arm64-gnu" "12.1.4" - "@next/swc-linux-arm64-musl" "12.1.4" - "@next/swc-linux-x64-gnu" "12.1.4" - "@next/swc-linux-x64-musl" "12.1.4" - "@next/swc-win32-arm64-msvc" "12.1.4" - "@next/swc-win32-ia32-msvc" "12.1.4" - "@next/swc-win32-x64-msvc" "12.1.4" + "@next/swc-android-arm64" "12.1.0" + "@next/swc-darwin-arm64" "12.1.0" + "@next/swc-darwin-x64" "12.1.0" + "@next/swc-linux-arm-gnueabihf" "12.1.0" + "@next/swc-linux-arm64-gnu" "12.1.0" + "@next/swc-linux-arm64-musl" "12.1.0" + "@next/swc-linux-x64-gnu" "12.1.0" + "@next/swc-linux-x64-musl" "12.1.0" + "@next/swc-win32-arm64-msvc" "12.1.0" + "@next/swc-win32-ia32-msvc" "12.1.0" + "@next/swc-win32-x64-msvc" "12.1.0" -next@^12.1.4: +next@12.1.5, next@^12.1.4: version "12.1.5" resolved "https://registry.yarnpkg.com/next/-/next-12.1.5.tgz#7a07687579ddce61ee519493e1c178d83abac063" integrity sha512-YGHDpyfgCfnT5GZObsKepmRnne7Kzp7nGrac07dikhutWQug7hHg85/+sPJ4ZW5Q2pDkb+n0FnmLkmd44htIJQ== @@ -12308,6 +11964,29 @@ next@^12.1.4: "@next/swc-win32-ia32-msvc" "12.1.5" "@next/swc-win32-x64-msvc" "12.1.5" +next@^12.1.0: + version "12.1.4" + resolved "https://registry.yarnpkg.com/next/-/next-12.1.4.tgz#597a9bdec7aec778b442c4f6d41afd2c64a54b23" + integrity sha512-DA4g97BM4Z0nKtDvCTm58RxdvoQyYzeg0AeVbh0N4Y/D8ELrNu47lQeEgRGF8hV4eQ+Sal90zxrJQQG/mPQ8CQ== + dependencies: + "@next/env" "12.1.4" + caniuse-lite "^1.0.30001283" + postcss "8.4.5" + styled-jsx "5.0.1" + optionalDependencies: + "@next/swc-android-arm-eabi" "12.1.4" + "@next/swc-android-arm64" "12.1.4" + "@next/swc-darwin-arm64" "12.1.4" + "@next/swc-darwin-x64" "12.1.4" + "@next/swc-linux-arm-gnueabihf" "12.1.4" + "@next/swc-linux-arm64-gnu" "12.1.4" + "@next/swc-linux-arm64-musl" "12.1.4" + "@next/swc-linux-x64-gnu" "12.1.4" + "@next/swc-linux-x64-musl" "12.1.4" + "@next/swc-win32-arm64-msvc" "12.1.4" + "@next/swc-win32-ia32-msvc" "12.1.4" + "@next/swc-win32-x64-msvc" "12.1.4" + nextra-theme-docs@^1.2.2: version "1.2.6" resolved "https://registry.yarnpkg.com/nextra-theme-docs/-/nextra-theme-docs-1.2.6.tgz#e6d5d8788534ae62d589db96df65f1a6e8b60bcc" @@ -13406,7 +13085,7 @@ postcss@8.4.5: picocolors "^1.0.0" source-map-js "^1.0.1" -postcss@^8.3.6, postcss@^8.4.12, postcss@^8.4.4, postcss@^8.4.6: +postcss@^8.3.6, postcss@^8.4.12, postcss@^8.4.4, postcss@^8.4.6, postcss@^8.4.8: version "8.4.12" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.12.tgz#1e7de78733b28970fa4743f7da6f3763648b1905" integrity sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg== @@ -13481,7 +13160,7 @@ prettier-plugin-tailwindcss@^0.1.8: resolved "https://registry.yarnpkg.com/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.1.8.tgz#ba0f606ed91959ede670303d905b99106e9e6293" integrity sha512-hwarSBCswAXa+kqYtaAkFr3Vop9o04WOyZs0qo3NyvW8L7f1rif61wRyq0+ArmVThOuRBcJF5hjGXYk86cwemg== -prettier@^2.5.1, prettier@^2.6.1: +prettier@^2.5.1: version "2.6.2" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.2.tgz#e26d71a18a74c3d0f0597f55f01fb6c06c206032" integrity sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew== @@ -13520,12 +13199,13 @@ prism-react-renderer@^1.1.1: resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-1.3.1.tgz#88fc9d0df6bed06ca2b9097421349f8c2f24e30d" integrity sha512-xUeDMEz074d0zc5y6rxiMp/dlC7C+5IDDlaEUlcBOFE2wddz7hz5PNupb087mPwTt7T9BrFmewObfCBuf/LKwQ== -prisma@3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/prisma/-/prisma-3.10.0.tgz#872d87afbeb1cbcaa77c3d6a63c125e0d704b04d" - integrity sha512-dAld12vtwdz9Rz01nOjmnXe+vHana5PSog8t0XGgLemKsUVsaupYpr74AHaS3s78SaTS5s2HOghnJF+jn91ZrA== +prisma@^3.13.0: + version "3.13.0" + resolved "https://registry.yarnpkg.com/prisma/-/prisma-3.13.0.tgz#b11edd5631222ff1bf1d5324732d47801386aa8c" + integrity sha512-oO1auBnBtieGdiN+57IgsA9Vr7Sy4HkILi1KSaUG4mpKfEbnkTGnLOxAqjLed+K2nsG/GtE1tJBtB7JxN1a78Q== dependencies: - "@prisma/engines" "3.10.0-50.73e60b76d394f8d37d8ebd1f8918c79029f0db86" + "@prisma/engines" "3.13.0-17.efdf9b1183dddfd4258cd181a72125755215ab7b" + ts-pattern "^4.0.1" prismjs@^1.27.0: version "1.28.0" @@ -13831,6 +13511,11 @@ react-calendar@^3.3.1: merge-class-names "^1.1.1" prop-types "^15.6.0" +react-chartjs-2@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/react-chartjs-2/-/react-chartjs-2-4.1.0.tgz#2a123df16d3a987c54eb4e810ed766d3c03adf8d" + integrity sha512-AsUihxEp8Jm1oBhbEovE+w50m9PVNhz1sfwEIT4hZduRC0m14gHWHd0cUaxkFDb8HNkdMIGzsNlmVqKiOpU74g== + react-colorful@^5.5.1: version "5.5.1" resolved "https://registry.yarnpkg.com/react-colorful/-/react-colorful-5.5.1.tgz#29d9c4e496f2ca784dd2bb5053a3a4340cfaf784" @@ -14296,30 +13981,11 @@ refractor@^3.6.0: parse-entities "^2.0.0" prismjs "~1.27.0" -regenerate-unicode-properties@^10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz#7f442732aa7934a3740c779bb9b3340dccc1fb56" - integrity sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw== - dependencies: - regenerate "^1.4.2" - -regenerate@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" - integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== - regenerator-runtime@^0.13.3, regenerator-runtime@^0.13.4: version "0.13.9" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== -regenerator-transform@^0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.0.tgz#cbd9ead5d77fae1a48d957cf889ad0586adb6537" - integrity sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg== - dependencies: - "@babel/runtime" "^7.8.4" - regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" @@ -14341,30 +14007,6 @@ regexpp@^3.2.0: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== -regexpu-core@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.0.1.tgz#c531122a7840de743dcf9c83e923b5560323ced3" - integrity sha512-CriEZlrKK9VJw/xQGJpQM5rY88BtuL8DM+AEwvcThHilbxiTAy8vq4iJnd2tqq8wLmjbGZzP7ZcKFjbGkmEFrw== - dependencies: - regenerate "^1.4.2" - regenerate-unicode-properties "^10.0.1" - regjsgen "^0.6.0" - regjsparser "^0.8.2" - unicode-match-property-ecmascript "^2.0.0" - unicode-match-property-value-ecmascript "^2.0.0" - -regjsgen@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.6.0.tgz#83414c5354afd7d6627b16af5f10f41c4e71808d" - integrity sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA== - -regjsparser@^0.8.2: - version "0.8.4" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.8.4.tgz#8a14285ffcc5de78c5b95d62bbf413b6bc132d5f" - integrity sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA== - dependencies: - jsesc "~0.5.0" - remark-gfm@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/remark-gfm/-/remark-gfm-1.0.0.tgz#9213643001be3f277da6256464d56fd28c3b3c0d" @@ -14559,7 +14201,7 @@ resolve.exports@^1.1.0: resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== -resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.20.0, resolve@^1.22.0: +resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.20.0, resolve@^1.22.0: version "1.22.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== @@ -14796,11 +14438,6 @@ seek-bzip@^1.0.5: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" - integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== - semver@7.x, semver@^7.3.2, semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" @@ -14808,7 +14445,7 @@ semver@7.x, semver@^7.3.2, semver@^7.3.5: dependencies: lru-cache "^6.0.0" -semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: +semver@^6.0.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -15506,6 +15143,11 @@ style-to-object@^0.3.0: dependencies: inline-style-parser "0.1.1" +styled-jsx@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.0.0.tgz#816b4b92e07b1786c6b7111821750e0ba4d26e77" + integrity sha512-qUqsWoBquEdERe10EW8vLp3jT25s/ssG1/qX5gZ4wu15OZpmSMFI2v+fWlRhLfykA5rFtlJ1ME8A8pm/peV4WA== + styled-jsx@5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.0.1.tgz#78fecbbad2bf95ce6cd981a08918ce4696f5fc80" @@ -15614,10 +15256,10 @@ swagger-parser@10.0.2: dependencies: "@apidevtools/swagger-parser" "10.0.2" -swagger-ui-react@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/swagger-ui-react/-/swagger-ui-react-4.8.1.tgz#552c45696ad127173f1851e8e776e09fc86da7df" - integrity sha512-SB2y+eGb+gjNKQyrJuo80YK1y2uyIVVfiLO/orqBDpEtuLVzzuEls7afDTRKy4vW2eMjkmjaWPugT6RFBwe1TA== +swagger-ui-react@4.10.3: + version "4.10.3" + resolved "https://registry.yarnpkg.com/swagger-ui-react/-/swagger-ui-react-4.10.3.tgz#72b7eb432f3e1ad09a81556af75d22ac3a66ae40" + integrity sha512-rxLVM8hv6aH+8BEJuyfejt2BweV2TLB8KiifE/8CAk96PoDyQeCTnLgivTdXIuDqdSSSajlzTq0ccw0QMYQbvA== dependencies: "@babel/runtime-corejs3" "^7.16.8" "@braintree/sanitize-url" "=6.0.0" @@ -15670,6 +15312,11 @@ swarm-js@^0.1.40: tar "^4.0.2" xhr-request "^1.0.1" +swr@^1.2.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/swr/-/swr-1.3.0.tgz#c6531866a35b4db37b38b72c45a63171faf9f4e8" + integrity sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw== + symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" @@ -16054,6 +15701,11 @@ ts-node@^10.6.0: v8-compile-cache-lib "^3.0.0" yn "3.1.1" +ts-pattern@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/ts-pattern/-/ts-pattern-4.0.2.tgz#b36afdb2de1ec0224539dcb7cea3a57c41453b9f" + integrity sha512-eHqR/7A6fcw05vCOfnL6RwgGJbVi9G/YHTdYdjYmElhDdJ1SMn7pWs+6+YuxygaFwQS/g+cIDlu+UD8IVpur1A== + tsc@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/tsc/-/tsc-2.0.4.tgz#5f6499146abea5dca4420b451fa4f2f9345238f5" @@ -16329,6 +15981,11 @@ typescript@4.6.3, typescript@^4.5.3, typescript@^4.6.3: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.3.tgz#eefeafa6afdd31d725584c67a0eaba80f6fc6c6c" integrity sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw== +tzdata@^1.0.30: + version "1.0.30" + resolved "https://registry.yarnpkg.com/tzdata/-/tzdata-1.0.30.tgz#d9d5a4b4b5e1ed95f6255f98c0564c4256316f52" + integrity sha512-/0yogZsIRUVhGIEGZahL+Nnl9gpMD6jtQ9MlVtPVofFwhaqa+cFTgRy1desTAKqdmIJjS6CL+i6F/mnetrLaxw== + uglify-js@^3.1.4: version "3.15.3" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.15.3.tgz#9aa82ca22419ba4c0137642ba0df800cb06e0471" @@ -16357,29 +16014,6 @@ unbzip2-stream@^1.0.9: buffer "^5.2.1" through "^2.3.8" -unicode-canonical-property-names-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" - integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== - -unicode-match-property-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" - integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== - dependencies: - unicode-canonical-property-names-ecmascript "^2.0.0" - unicode-property-aliases-ecmascript "^2.0.0" - -unicode-match-property-value-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" - integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== - -unicode-property-aliases-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" - integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== - unified@^10.0.0: version "10.1.2" resolved "https://registry.yarnpkg.com/unified/-/unified-10.1.2.tgz#b1d64e55dafe1f0b98bb6c719881103ecf6c86df" @@ -16616,6 +16250,13 @@ use-sidecar@^1.0.1: detect-node-es "^1.1.0" tslib "^1.9.3" +use-subscription@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/use-subscription/-/use-subscription-1.5.1.tgz#73501107f02fad84c6dd57965beb0b75c68c42d1" + integrity sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA== + dependencies: + object-assign "^4.1.1" + use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"