From 5625cf226b513662526248ff6c93fa0332ae40ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Omar=20L=C3=B3pez?= Date: Wed, 9 Mar 2022 15:56:05 -0700 Subject: [PATCH] Stripe to monorepo (#2063) * downgrade func * fix security hole lol * fix query conditions * - set to trial not free - auto create stripe customer if missing - fix production check * Extracts downgrade logic to script, fixes ts-node conflicts with prisma * Adds trialEndsAt field to users * Updates trial/downgrade logic * Typo * Legibility fixes * Update team-billing.ts * Legibility improvements * Updates illegal logic * WIP * WIP migrating stripe to package * Update website * Import fixes * Import fixes * Fixes to downgrade script * Check for premium usernames before downgrading * Fixed formatting * Delete deploy-env.sh * Locks dayjs to 1.10.6 * Type fixes * Seems like we're stuck with dayjs 1.10.4 * Script fixes * Adds first name to dump * Loop fix Co-authored-by: Jamie Co-authored-by: Peer Richelsen Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../components/booking/pages/BookingPage.tsx | 2 +- apps/web/ee/components/stripe/Payment.tsx | 2 +- apps/web/ee/components/stripe/PaymentPage.tsx | 2 +- apps/web/ee/lib/stripe/downgrade.ts | 90 ------- apps/web/ee/lib/stripe/server.ts | 20 +- .../integrations/stripepayment/callback.ts | 2 +- .../api/integrations/stripepayment/portal.ts | 4 +- .../api/integrations/stripepayment/webhook.ts | 2 +- apps/web/ee/pages/api/teams/[team]/upgrade.ts | 2 +- apps/web/ee/pages/payment/[uid].tsx | 2 +- apps/web/next.config.js | 8 +- apps/web/package.json | 7 +- apps/web/pages/api/upgrade.ts | 2 +- apps/web/pages/api/user/me.ts | 2 +- apps/web/pages/event-types/[type].tsx | 2 +- apps/web/server/routers/viewer.tsx | 2 +- apps/web/server/routers/viewer/teams.tsx | 2 +- apps/website | 2 +- packages/ee/LICENSE | 42 +++ packages/ee/README.md | 38 +++ .../ee/lib/core/checkPremiumUsername.ts | 19 +- packages/ee/package.json | 16 ++ packages/ee/tsconfig.json | 8 + packages/lib/constants.ts | 6 + packages/lib/http-error.ts | 33 +++ packages/lib/package.json | 2 +- packages/prisma/index.ts | 2 +- packages/stripe/LICENSE | 42 +++ packages/stripe/README.md | 38 +++ .../web/ee/lib => packages}/stripe/client.ts | 2 +- packages/stripe/constants.ts | 4 + .../ee/lib => packages}/stripe/customer.ts | 6 +- packages/stripe/downgrade.ts | 95 +++++++ packages/stripe/index.ts | 1 + packages/stripe/package.json | 29 +++ packages/stripe/server.ts | 18 ++ .../lib => packages}/stripe/team-billing.ts | 28 +- packages/stripe/tsconfig.json | 8 + packages/stripe/utils.ts | 21 ++ yarn.lock | 246 +----------------- 40 files changed, 454 insertions(+), 405 deletions(-) delete mode 100755 apps/web/ee/lib/stripe/downgrade.ts create mode 100644 packages/ee/LICENSE create mode 100644 packages/ee/README.md rename {apps/web => packages}/ee/lib/core/checkPremiumUsername.ts (55%) create mode 100644 packages/ee/package.json create mode 100644 packages/ee/tsconfig.json create mode 100644 packages/lib/constants.ts create mode 100644 packages/lib/http-error.ts create mode 100644 packages/stripe/LICENSE create mode 100644 packages/stripe/README.md rename {apps/web/ee/lib => packages}/stripe/client.ts (95%) create mode 100644 packages/stripe/constants.ts rename {apps/web/ee/lib => packages}/stripe/customer.ts (95%) create mode 100755 packages/stripe/downgrade.ts create mode 100644 packages/stripe/index.ts create mode 100644 packages/stripe/package.json create mode 100644 packages/stripe/server.ts rename {apps/web/ee/lib => packages}/stripe/team-billing.ts (91%) create mode 100644 packages/stripe/tsconfig.json create mode 100644 packages/stripe/utils.ts diff --git a/apps/web/components/booking/pages/BookingPage.tsx b/apps/web/components/booking/pages/BookingPage.tsx index c2cf64523a..7c72be9c08 100644 --- a/apps/web/components/booking/pages/BookingPage.tsx +++ b/apps/web/components/booking/pages/BookingPage.tsx @@ -12,7 +12,7 @@ import { ReactMultiEmail } from "react-multi-email"; import { useMutation } from "react-query"; import { v4 as uuidv4 } from "uuid"; -import { createPaymentLink } from "@ee/lib/stripe/client"; +import { createPaymentLink } from "@calcom/stripe/client"; import { asStringOrNull } from "@lib/asStringOrNull"; import { timeZone } from "@lib/clock"; diff --git a/apps/web/ee/components/stripe/Payment.tsx b/apps/web/ee/components/stripe/Payment.tsx index 3debcdb855..ccbe3db8dd 100644 --- a/apps/web/ee/components/stripe/Payment.tsx +++ b/apps/web/ee/components/stripe/Payment.tsx @@ -4,7 +4,7 @@ import { useRouter } from "next/router"; import { stringify } from "querystring"; import React, { SyntheticEvent, useEffect, useState } from "react"; -import { PaymentData } from "@ee/lib/stripe/server"; +import { PaymentData } from "@calcom/stripe/server"; import { useLocale } from "@lib/hooks/useLocale"; diff --git a/apps/web/ee/components/stripe/PaymentPage.tsx b/apps/web/ee/components/stripe/PaymentPage.tsx index 28ac7334bd..e4e0c89725 100644 --- a/apps/web/ee/components/stripe/PaymentPage.tsx +++ b/apps/web/ee/components/stripe/PaymentPage.tsx @@ -8,8 +8,8 @@ import Head from "next/head"; import React, { FC, useEffect, useState } from "react"; import { FormattedNumber, IntlProvider } from "react-intl"; +import getStripe from "@calcom/stripe/client"; import PaymentComponent from "@ee/components/stripe/Payment"; -import getStripe from "@ee/lib/stripe/client"; import { PaymentPageProps } from "@ee/pages/payment/[uid]"; import { useLocale } from "@lib/hooks/useLocale"; diff --git a/apps/web/ee/lib/stripe/downgrade.ts b/apps/web/ee/lib/stripe/downgrade.ts deleted file mode 100755 index 4dc2024f61..0000000000 --- a/apps/web/ee/lib/stripe/downgrade.ts +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env ts-node -// To run this script: `yarn downgrade 2>&1 | tee result.log` -import { MembershipRole, Prisma, UserPlan } from "@prisma/client"; -import dayjs from "dayjs"; - -import prisma from "@calcom/prisma"; - -import { TRIAL_LIMIT_DAYS } from "@lib/config/constants"; - -import { getStripeCustomerIdFromUserId } from "./customer"; -import stripe from "./server"; -import { getPremiumPlanPrice, getProPlanPrice } from "./team-billing"; - -export async function downgradeIllegalProUsers() { - const usersDowngraded: string[] = []; - const illegalProUsers = await prisma.membership.findMany({ - where: { - role: { - not: MembershipRole.OWNER, - }, - user: { - plan: { - not: UserPlan.PRO, - }, - }, - }, - include: { - user: true, - }, - }); - const downgrade = async (member: typeof illegalProUsers[number]) => { - console.log(`Downgrading: ${member.user.email}`); - await prisma.user.update({ - where: { id: member.user.id }, - data: { - plan: UserPlan.TRIAL, - trialEndsAt: dayjs().add(TRIAL_LIMIT_DAYS, "day").toDate(), - }, - }); - console.log(`Downgraded: ${member.user.email}`); - usersDowngraded.push(member.user.username || `${member.user.id}`); - }; - for (const member of illegalProUsers) { - const metadata = (member.user.metadata as Prisma.JsonObject) ?? {}; - // if their pro is already sponsored by a team, do not downgrade - if (metadata.proPaidForTeamId !== undefined) continue; - - const stripeCustomerId = await getStripeCustomerIdFromUserId(member.user.id); - if (!stripeCustomerId) { - await downgrade(member); - continue; - } - - const customer = await stripe.customers.retrieve(stripeCustomerId, { - expand: ["subscriptions.data.plan"], - }); - if (!customer || customer.deleted) { - await downgrade(member); - continue; - } - - const subscription = customer.subscriptions?.data[0]; - if (!subscription) { - await downgrade(member); - continue; - } - - const hasProPlan = !!subscription.items.data.find( - (item) => item.plan.id === getProPlanPrice() || item.plan.id === getPremiumPlanPrice() - ); - // if they're pro, do not downgrade - if (hasProPlan) continue; - - await downgrade(member); - } - return { - usersDowngraded, - usersDowngradedAmount: usersDowngraded.length, - }; -} - -downgradeIllegalProUsers() - .then(({ usersDowngraded, usersDowngradedAmount }) => { - console.log(`Downgraded ${usersDowngradedAmount} illegal pro users`); - console.table(usersDowngraded); - }) - .catch((e) => { - console.error(e); - process.exit(1); - }); diff --git a/apps/web/ee/lib/stripe/server.ts b/apps/web/ee/lib/stripe/server.ts index 41ba27b8ff..04747ed066 100644 --- a/apps/web/ee/lib/stripe/server.ts +++ b/apps/web/ee/lib/stripe/server.ts @@ -3,36 +3,22 @@ import Stripe from "stripe"; import { v4 as uuidv4 } from "uuid"; import prisma from "@calcom/prisma"; +import { createPaymentLink } from "@calcom/stripe/client"; +import stripe, { PaymentData } from "@calcom/stripe/server"; import { sendAwaitingPaymentEmail, sendOrganizerPaymentRefundFailedEmail } from "@lib/emails/email-manager"; import { getErrorFromUnknown } from "@lib/errors"; import { CalendarEvent } from "@lib/integrations/calendar/interfaces/Calendar"; -import { createPaymentLink } from "./client"; - export type PaymentInfo = { link?: string | null; reason?: string | null; id?: string | null; }; -export type PaymentData = Stripe.Response & { - stripe_publishable_key: string; - stripeAccount: string; -}; - -export type StripeData = Stripe.OAuthToken & { - default_currency: string; -}; - -const stripePrivateKey = process.env.STRIPE_PRIVATE_KEY!; const paymentFeePercentage = process.env.PAYMENT_FEE_PERCENTAGE!; const paymentFeeFixed = process.env.PAYMENT_FEE_FIXED!; -const stripe = new Stripe(stripePrivateKey, { - apiVersion: "2020-08-27", -}); - export async function handlePayment( evt: CalendarEvent, selectedEventType: { @@ -168,5 +154,3 @@ async function handleRefundError(opts: { event: CalendarEvent; reason: string; p paymentInfo: { reason: opts.reason, id: opts.paymentId }, }); } - -export default stripe; diff --git a/apps/web/ee/pages/api/integrations/stripepayment/callback.ts b/apps/web/ee/pages/api/integrations/stripepayment/callback.ts index 038238eb6d..a1cbffff54 100644 --- a/apps/web/ee/pages/api/integrations/stripepayment/callback.ts +++ b/apps/web/ee/pages/api/integrations/stripepayment/callback.ts @@ -2,7 +2,7 @@ import { Prisma } from "@prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; import { stringify } from "querystring"; -import stripe, { StripeData } from "@ee/lib/stripe/server"; +import stripe, { StripeData } from "@calcom/stripe/server"; import { getSession } from "@lib/auth"; import prisma from "@lib/prisma"; diff --git a/apps/web/ee/pages/api/integrations/stripepayment/portal.ts b/apps/web/ee/pages/api/integrations/stripepayment/portal.ts index d1ba86824e..acb4a828e2 100644 --- a/apps/web/ee/pages/api/integrations/stripepayment/portal.ts +++ b/apps/web/ee/pages/api/integrations/stripepayment/portal.ts @@ -1,7 +1,7 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import { getStripeCustomerIdFromUserId } from "@ee/lib/stripe/customer"; -import stripe from "@ee/lib/stripe/server"; +import { getStripeCustomerIdFromUserId } from "@calcom/stripe/customer"; +import stripe from "@calcom/stripe/server"; import { getSession } from "@lib/auth"; diff --git a/apps/web/ee/pages/api/integrations/stripepayment/webhook.ts b/apps/web/ee/pages/api/integrations/stripepayment/webhook.ts index 817c492262..190ac67bb6 100644 --- a/apps/web/ee/pages/api/integrations/stripepayment/webhook.ts +++ b/apps/web/ee/pages/api/integrations/stripepayment/webhook.ts @@ -2,7 +2,7 @@ import { buffer } from "micro"; import type { NextApiRequest, NextApiResponse } from "next"; import Stripe from "stripe"; -import stripe from "@ee/lib/stripe/server"; +import stripe from "@calcom/stripe/server"; import { IS_PRODUCTION } from "@lib/config/constants"; import { HttpError as HttpCode } from "@lib/core/http/error"; diff --git a/apps/web/ee/pages/api/teams/[team]/upgrade.ts b/apps/web/ee/pages/api/teams/[team]/upgrade.ts index 4ae88336eb..8a5b5fc745 100644 --- a/apps/web/ee/pages/api/teams/[team]/upgrade.ts +++ b/apps/web/ee/pages/api/teams/[team]/upgrade.ts @@ -1,6 +1,6 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import { upgradeTeam } from "@ee/lib/stripe/team-billing"; +import { upgradeTeam } from "@calcom/stripe/team-billing"; import { getSession } from "@lib/auth"; diff --git a/apps/web/ee/pages/payment/[uid].tsx b/apps/web/ee/pages/payment/[uid].tsx index df2932469c..23b44b9003 100644 --- a/apps/web/ee/pages/payment/[uid].tsx +++ b/apps/web/ee/pages/payment/[uid].tsx @@ -1,6 +1,6 @@ import { GetServerSidePropsContext } from "next"; -import { PaymentData } from "@ee/lib/stripe/server"; +import { PaymentData } from "@calcom/stripe/server"; import { asStringOrThrow } from "@lib/asStringOrNull"; import prisma from "@lib/prisma"; diff --git a/apps/web/next.config.js b/apps/web/next.config.js index 6c4e133400..71f7cf9e57 100644 --- a/apps/web/next.config.js +++ b/apps/web/next.config.js @@ -1,4 +1,10 @@ -const withTM = require("next-transpile-modules")(["@calcom/lib", "@calcom/prisma", "@calcom/ui"]); +const withTM = require("next-transpile-modules")([ + "@calcom/ee", + "@calcom/lib", + "@calcom/prisma", + "@calcom/stripe", + "@calcom/ui", +]); const { i18n } = require("./next-i18next.config"); // So we can test deploy previews preview diff --git a/apps/web/package.json b/apps/web/package.json index a576bbdaff..8e4db68957 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -19,8 +19,7 @@ "lint": "next lint", "lint:report": "eslint . --format json --output-file ../../lint-results/web.json", "lint:fix": "next lint . --ext .ts,.js,.tsx,.jsx --fix", - "check-changed-files": "ts-node scripts/ts-check-changed-files.ts", - "downgrade": "ts-node ee/lib/stripe/downgrade.ts" + "check-changed-files": "ts-node scripts/ts-check-changed-files.ts" }, "engines": { "node": ">=14.x", @@ -28,8 +27,10 @@ }, "dependencies": { "@boxyhq/saml-jackson": "0.3.6", + "@calcom/ee": "*", "@calcom/lib": "*", "@calcom/prisma": "*", + "@calcom/stripe": "*", "@calcom/tsconfig": "*", "@calcom/ui": "*", "@daily-co/daily-js": "^0.21.0", @@ -61,7 +62,7 @@ "async": "^3.2.1", "bcryptjs": "^2.4.3", "classnames": "^2.3.1", - "dayjs": "^1.10.6", + "dayjs": "^1.10.4", "dayjs-business-time": "^1.0.4", "googleapis": "^84.0.0", "handlebars": "^4.7.7", diff --git a/apps/web/pages/api/upgrade.ts b/apps/web/pages/api/upgrade.ts index ddee63c267..9baddda3fb 100644 --- a/apps/web/pages/api/upgrade.ts +++ b/apps/web/pages/api/upgrade.ts @@ -1,7 +1,7 @@ import { Prisma } from "@prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; -import { getStripeCustomerId } from "@ee/lib/stripe/customer"; +import { getStripeCustomerId } from "@calcom/stripe/customer"; import { getSession } from "@lib/auth"; import { WEBSITE_URL } from "@lib/config/constants"; diff --git a/apps/web/pages/api/user/me.ts b/apps/web/pages/api/user/me.ts index e2dfaa629d..698b281873 100644 --- a/apps/web/pages/api/user/me.ts +++ b/apps/web/pages/api/user/me.ts @@ -1,6 +1,6 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import { deleteStripeCustomer } from "@ee/lib/stripe/customer"; +import { deleteStripeCustomer } from "@calcom/stripe/customer"; import { getSession } from "@lib/auth"; import prisma from "@lib/prisma"; diff --git a/apps/web/pages/event-types/[type].tsx b/apps/web/pages/event-types/[type].tsx index d8bde9dbdd..851c09ae28 100644 --- a/apps/web/pages/event-types/[type].tsx +++ b/apps/web/pages/event-types/[type].tsx @@ -27,7 +27,7 @@ import { FormattedNumber, IntlProvider } from "react-intl"; import Select from "react-select"; import { JSONObject } from "superjson/dist/types"; -import { StripeData } from "@ee/lib/stripe/server"; +import { StripeData } from "@calcom/stripe/server"; import { asStringOrThrow, asStringOrUndefined } from "@lib/asStringOrNull"; import { getSession } from "@lib/auth"; diff --git a/apps/web/server/routers/viewer.tsx b/apps/web/server/routers/viewer.tsx index 85bc9ee336..dbf6a03c14 100644 --- a/apps/web/server/routers/viewer.tsx +++ b/apps/web/server/routers/viewer.tsx @@ -3,7 +3,7 @@ import _ from "lodash"; import { JSONObject } from "superjson/dist/types"; import { z } from "zod"; -import { checkPremiumUsername } from "@ee/lib/core/checkPremiumUsername"; +import { checkPremiumUsername } from "@calcom/ee/lib/core/checkPremiumUsername"; import { checkRegularUsername } from "@lib/core/checkRegularUsername"; import { getCalendarCredentials, getConnectedCalendars } from "@lib/integrations/calendar/CalendarManager"; diff --git a/apps/web/server/routers/viewer/teams.tsx b/apps/web/server/routers/viewer/teams.tsx index f9d0c9f260..0c638f84ee 100644 --- a/apps/web/server/routers/viewer/teams.tsx +++ b/apps/web/server/routers/viewer/teams.tsx @@ -10,7 +10,7 @@ import { downgradeTeamMembers, upgradeTeam, ensureSubscriptionQuantityCorrectness, -} from "@ee/lib/stripe/team-billing"; +} from "@calcom/stripe/team-billing"; import { BASE_URL } from "@lib/config/constants"; import { HOSTED_CAL_FEATURES } from "@lib/config/constants"; diff --git a/apps/website b/apps/website index 59cd13be0a..6545bb5cf0 160000 --- a/apps/website +++ b/apps/website @@ -1 +1 @@ -Subproject commit 59cd13be0a9dc9e3bfc7b9acf774e6ac292f57db +Subproject commit 6545bb5cf0d5e38dcab9cce47853b7a7a4859033 diff --git a/packages/ee/LICENSE b/packages/ee/LICENSE new file mode 100644 index 0000000000..60f0a2a1d0 --- /dev/null +++ b/packages/ee/LICENSE @@ -0,0 +1,42 @@ +The Cal.com Enterprise Edition (EE) license (the “EE License”) +Copyright (c) 2020-present Cal.com, Inc + +With regard to the Cal.com Software: + +This software and associated documentation files (the "Software") may only be +used in production, if you (and any entity that you represent) have agreed to, +and are in compliance with, the Cal.com Subscription Terms available +at https://cal.com/terms (the “EE Terms”), or other agreements governing +the use of the Software, as mutually agreed by you and Cal.com, Inc ("Cal.com"), +and otherwise have a valid Cal.com Enterprise Edition subscription ("EE Subscription") +for the correct number of hosts as defined in the EE Terms ("Hosts"). Subject to the foregoing sentence, +you are free to modify this Software and publish patches to the Software. You agree +that Cal.com and/or its licensors (as applicable) retain all right, title and interest in +and to all such modifications and/or patches, and all such modifications and/or +patches may only be used, copied, modified, displayed, distributed, or otherwise +exploited with a valid EE Subscription for the correct number of hosts. +Notwithstanding the foregoing, you may copy and modify the Software for development +and testing purposes, without requiring a subscription. You agree that Cal.com and/or +its licensors (as applicable) retain all right, title and interest in and to all such +modifications. You are not granted any other rights beyond what is expressly stated herein. +Subject to the foregoing, it is forbidden to copy, merge, publish, distribute, sublicense, +and/or sell the Software. + +This EE License applies only to the part of this Software that is not distributed under +the AGPLv3 license. Any part of this Software distributed under the MIT license or which +is served client-side as an image, font, cascading stylesheet (CSS), file which produces +or is compiled, arranged, augmented, or combined into client-side JavaScript, in whole or +in part, is copyrighted under the AGPLv3 license. The full text of this EE License shall +be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +For all third party components incorporated into the Cal.com Software, those +components are licensed under the original license provided by the owner of the +applicable component. diff --git a/packages/ee/README.md b/packages/ee/README.md new file mode 100644 index 0000000000..d5af7e20d8 --- /dev/null +++ b/packages/ee/README.md @@ -0,0 +1,38 @@ + +
+ + Logo + + + Get Started with Enterprise +
+ +# Enterprise Edition + +Welcome to the Enterprise Edition ("/ee") of Cal.com. + +The [/ee](https://github.com/calcom/cal.com/tree/main/apps/web/ee) subfolder is the place for all the **Pro** features from our [hosted](https://cal.com/pricing) plan and [enterprise-grade](https://cal.com/enterprise) features such as SSO, SAML, ADFS, OIDC, SCIM, SIEM, HRIS and much more. + +> _❗ WARNING: This repository is copyrighted (unlike our [main repo](https://github.com/calcom/cal.com)). You are not allowed to use this code to host your own version of app.cal.com without obtaining a proper [license](https://cal.com/enterprise) first❗_ + +## Setting up Stripe + +1. Create a stripe account or use an existing one. For testing, you should use all stripe dashboard functions with the Test-Mode toggle in the top right activated. +2. Open [Stripe ApiKeys](https://dashboard.stripe.com/apikeys) save the token starting with `pk_...` to `NEXT_PUBLIC_STRIPE_PUBLIC_KEY` and `sk_...` to `STRIPE_PRIVATE_KEY` in the .env file. +3. Open [Stripe Connect Settings](https://dashboard.stripe.com/settings/connect) and activate OAuth for Standard Accounts +4. Add `/api/integrations/stripepayment/callback` as redirect URL. +5. Copy your client*id (`ca*...`) to `STRIPE_CLIENT_ID` in the .env file. +6. Open [Stripe Webhooks](https://dashboard.stripe.com/webhooks) and add `/api/integrations/stripepayment/webhook` as webhook for connected applications. +7. Select all `payment_intent` events for the webhook. +8. Copy the webhook secret (`whsec_...`) to `STRIPE_WEBHOOK_SECRET` in the .env file. + +## Setting up SAML login + +1. Set SAML_DATABASE_URL to a postgres database. Please use a different database than the main Cal instance since the migrations are separate for this database. For example `postgresql://postgres:@localhost:5450/cal-saml` +2. Set SAML_ADMINS to a comma separated list of admin emails from where the SAML metadata can be uploaded and configured. +3. Create a SAML application with your Identity Provider (IdP) using the instructions here - [SAML Setup](../docs/saml-setup.md) +4. Remember to configure access to the IdP SAML app for all your users (who need access to Cal). +5. You will need the XML metadata from your IdP later, so keep it accessible. +6. Log in to one of the admin accounts configured in SAML_ADMINS and then navigate to Settings -> Security. +7. You should see a SAML configuration section, copy and paste the XML metadata from step 5 and click on Save. +8. Your provisioned users can now log into Cal using SAML. diff --git a/apps/web/ee/lib/core/checkPremiumUsername.ts b/packages/ee/lib/core/checkPremiumUsername.ts similarity index 55% rename from apps/web/ee/lib/core/checkPremiumUsername.ts rename to packages/ee/lib/core/checkPremiumUsername.ts index 504f4a283e..5a00094641 100644 --- a/apps/web/ee/lib/core/checkPremiumUsername.ts +++ b/packages/ee/lib/core/checkPremiumUsername.ts @@ -1,6 +1,11 @@ -import slugify from "@lib/slugify"; +import slugify from "@calcom/lib/slugify"; -export async function checkPremiumUsername(_username: string) { +export async function checkPremiumUsername(_username: string): Promise<{ + available: boolean; + premium: boolean; + message?: string; + suggestion?: string; +}> { const username = slugify(_username); const response = await fetch("https://cal.com/api/username", { credentials: "include", @@ -12,14 +17,6 @@ export async function checkPremiumUsername(_username: string) { mode: "cors", }); - if (response.ok) { - return { - available: true as const, - }; - } const json = await response.json(); - return { - available: false as const, - message: json.message as string, - }; + return json; } diff --git a/packages/ee/package.json b/packages/ee/package.json new file mode 100644 index 0000000000..b65842585f --- /dev/null +++ b/packages/ee/package.json @@ -0,0 +1,16 @@ +{ + "name": "@calcom/ee", + "description": "Cal.com Enterprise Edition features", + "version": "0.0.0", + "private": true, + "license": "AGPLv3", + "scripts": { + "clean": "rm -rf .turbo && rm -rf node_modules" + }, + "dependencies": { + "@calcom/lib": "*" + }, + "devDependencies": { + "@calcom/tsconfig": "*" + } +} diff --git a/packages/ee/tsconfig.json b/packages/ee/tsconfig.json new file mode 100644 index 0000000000..184d5dec70 --- /dev/null +++ b/packages/ee/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "@calcom/tsconfig/base.json", + "compilerOptions": { + "baseUrl": "." + }, + "include": ["."], + "exclude": ["dist", "build", "node_modules"] +} diff --git a/packages/lib/constants.ts b/packages/lib/constants.ts new file mode 100644 index 0000000000..b2f1800efd --- /dev/null +++ b/packages/lib/constants.ts @@ -0,0 +1,6 @@ +export const BASE_URL = process.env.BASE_URL || `https://${process.env.VERCEL_URL}`; +export const WEBSITE_URL = process.env.NEXT_PUBLIC_APP_URL || "https://cal.com"; +export const IS_PRODUCTION = process.env.NODE_ENV === "production"; +export const TRIAL_LIMIT_DAYS = 14; +export const HOSTED_CAL_FEATURES = process.env.HOSTED_CAL_FEATURES || BASE_URL === "https://app.cal.com"; +export const NEXT_PUBLIC_BASE_URL = process.env.NEXT_PUBLIC_BASE_URL || `https://${process.env.VERCEL_URL}`; diff --git a/packages/lib/http-error.ts b/packages/lib/http-error.ts new file mode 100644 index 0000000000..2237614803 --- /dev/null +++ b/packages/lib/http-error.ts @@ -0,0 +1,33 @@ +export class HttpError extends Error { + public readonly cause?: Error; + public readonly statusCode: TCode; + public readonly message: string; + public readonly url: string | undefined; + public readonly method: string | undefined; + + constructor(opts: { url?: string; method?: string; message?: string; statusCode: TCode; cause?: Error }) { + super(opts.message ?? `HTTP Error ${opts.statusCode} `); + + Object.setPrototypeOf(this, HttpError.prototype); + this.name = HttpError.prototype.constructor.name; + + this.cause = opts.cause; + this.statusCode = opts.statusCode; + this.url = opts.url; + this.method = opts.method; + this.message = opts.message ?? `HTTP Error ${opts.statusCode}`; + + if (opts.cause instanceof Error && opts.cause.stack) { + this.stack = opts.cause.stack; + } + } + + public static fromRequest(request: Request, response: Response) { + return new HttpError({ + message: response.statusText, + url: response.url, + method: request.method, + statusCode: response.status, + }); + } +} diff --git a/packages/lib/package.json b/packages/lib/package.json index 8d375e9674..8842647906 100644 --- a/packages/lib/package.json +++ b/packages/lib/package.json @@ -6,7 +6,7 @@ "license": "MIT", "dependencies": { "bcryptjs": "^2.4.3", - "dayjs": "^1.10.6", + "dayjs": "^1.10.4", "dayjs-business-time": "^1.0.4" }, "devDependencies": { diff --git a/packages/prisma/index.ts b/packages/prisma/index.ts index 70180d6054..1f92195d15 100644 --- a/packages/prisma/index.ts +++ b/packages/prisma/index.ts @@ -7,7 +7,7 @@ declare global { export const prisma = globalThis.prisma || new PrismaClient({ - log: ["query", "error", "warn"], + // log: ["query", "error", "warn"], }); if (process.env.NODE_ENV !== "production") { diff --git a/packages/stripe/LICENSE b/packages/stripe/LICENSE new file mode 100644 index 0000000000..60f0a2a1d0 --- /dev/null +++ b/packages/stripe/LICENSE @@ -0,0 +1,42 @@ +The Cal.com Enterprise Edition (EE) license (the “EE License”) +Copyright (c) 2020-present Cal.com, Inc + +With regard to the Cal.com Software: + +This software and associated documentation files (the "Software") may only be +used in production, if you (and any entity that you represent) have agreed to, +and are in compliance with, the Cal.com Subscription Terms available +at https://cal.com/terms (the “EE Terms”), or other agreements governing +the use of the Software, as mutually agreed by you and Cal.com, Inc ("Cal.com"), +and otherwise have a valid Cal.com Enterprise Edition subscription ("EE Subscription") +for the correct number of hosts as defined in the EE Terms ("Hosts"). Subject to the foregoing sentence, +you are free to modify this Software and publish patches to the Software. You agree +that Cal.com and/or its licensors (as applicable) retain all right, title and interest in +and to all such modifications and/or patches, and all such modifications and/or +patches may only be used, copied, modified, displayed, distributed, or otherwise +exploited with a valid EE Subscription for the correct number of hosts. +Notwithstanding the foregoing, you may copy and modify the Software for development +and testing purposes, without requiring a subscription. You agree that Cal.com and/or +its licensors (as applicable) retain all right, title and interest in and to all such +modifications. You are not granted any other rights beyond what is expressly stated herein. +Subject to the foregoing, it is forbidden to copy, merge, publish, distribute, sublicense, +and/or sell the Software. + +This EE License applies only to the part of this Software that is not distributed under +the AGPLv3 license. Any part of this Software distributed under the MIT license or which +is served client-side as an image, font, cascading stylesheet (CSS), file which produces +or is compiled, arranged, augmented, or combined into client-side JavaScript, in whole or +in part, is copyrighted under the AGPLv3 license. The full text of this EE License shall +be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +For all third party components incorporated into the Cal.com Software, those +components are licensed under the original license provided by the owner of the +applicable component. diff --git a/packages/stripe/README.md b/packages/stripe/README.md new file mode 100644 index 0000000000..d5af7e20d8 --- /dev/null +++ b/packages/stripe/README.md @@ -0,0 +1,38 @@ + + + +# Enterprise Edition + +Welcome to the Enterprise Edition ("/ee") of Cal.com. + +The [/ee](https://github.com/calcom/cal.com/tree/main/apps/web/ee) subfolder is the place for all the **Pro** features from our [hosted](https://cal.com/pricing) plan and [enterprise-grade](https://cal.com/enterprise) features such as SSO, SAML, ADFS, OIDC, SCIM, SIEM, HRIS and much more. + +> _❗ WARNING: This repository is copyrighted (unlike our [main repo](https://github.com/calcom/cal.com)). You are not allowed to use this code to host your own version of app.cal.com without obtaining a proper [license](https://cal.com/enterprise) first❗_ + +## Setting up Stripe + +1. Create a stripe account or use an existing one. For testing, you should use all stripe dashboard functions with the Test-Mode toggle in the top right activated. +2. Open [Stripe ApiKeys](https://dashboard.stripe.com/apikeys) save the token starting with `pk_...` to `NEXT_PUBLIC_STRIPE_PUBLIC_KEY` and `sk_...` to `STRIPE_PRIVATE_KEY` in the .env file. +3. Open [Stripe Connect Settings](https://dashboard.stripe.com/settings/connect) and activate OAuth for Standard Accounts +4. Add `/api/integrations/stripepayment/callback` as redirect URL. +5. Copy your client*id (`ca*...`) to `STRIPE_CLIENT_ID` in the .env file. +6. Open [Stripe Webhooks](https://dashboard.stripe.com/webhooks) and add `/api/integrations/stripepayment/webhook` as webhook for connected applications. +7. Select all `payment_intent` events for the webhook. +8. Copy the webhook secret (`whsec_...`) to `STRIPE_WEBHOOK_SECRET` in the .env file. + +## Setting up SAML login + +1. Set SAML_DATABASE_URL to a postgres database. Please use a different database than the main Cal instance since the migrations are separate for this database. For example `postgresql://postgres:@localhost:5450/cal-saml` +2. Set SAML_ADMINS to a comma separated list of admin emails from where the SAML metadata can be uploaded and configured. +3. Create a SAML application with your Identity Provider (IdP) using the instructions here - [SAML Setup](../docs/saml-setup.md) +4. Remember to configure access to the IdP SAML app for all your users (who need access to Cal). +5. You will need the XML metadata from your IdP later, so keep it accessible. +6. Log in to one of the admin accounts configured in SAML_ADMINS and then navigate to Settings -> Security. +7. You should see a SAML configuration section, copy and paste the XML metadata from step 5 and click on Save. +8. Your provisioned users can now log into Cal using SAML. diff --git a/apps/web/ee/lib/stripe/client.ts b/packages/stripe/client.ts similarity index 95% rename from apps/web/ee/lib/stripe/client.ts rename to packages/stripe/client.ts index a89840f0f8..89da11d73e 100644 --- a/apps/web/ee/lib/stripe/client.ts +++ b/packages/stripe/client.ts @@ -2,7 +2,7 @@ import { Stripe } from "@stripe/stripe-js"; import { loadStripe } from "@stripe/stripe-js/pure"; import { stringify } from "querystring"; -import { Maybe } from "@trpc/server"; +export type Maybe = T | undefined | null; const stripePublicKey = process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY!; let stripePromise: Promise; diff --git a/packages/stripe/constants.ts b/packages/stripe/constants.ts new file mode 100644 index 0000000000..fe9bec7379 --- /dev/null +++ b/packages/stripe/constants.ts @@ -0,0 +1,4 @@ +export const FREE_PLAN_PRICE = process.env.NEXT_PUBLIC_STRIPE_FREE_PLAN_PRICE || ""; +export const PREMIUM_PLAN_PRICE = process.env.NEXT_PUBLIC_STRIPE_PREMIUM_PLAN_PRICE || ""; +export const PRO_PLAN_PRICE = process.env.NEXT_PUBLIC_STRIPE_PRO_PLAN_PRICE || ""; +export const PRO_PLAN_PRODUCT = process.env.NEXT_PUBLIC_STRIPE_PRO_PLAN_PRODUCT || ""; diff --git a/apps/web/ee/lib/stripe/customer.ts b/packages/stripe/customer.ts similarity index 95% rename from apps/web/ee/lib/stripe/customer.ts rename to packages/stripe/customer.ts index 88bd7cdec8..162d5f5c5b 100644 --- a/apps/web/ee/lib/stripe/customer.ts +++ b/packages/stripe/customer.ts @@ -1,10 +1,8 @@ import { Prisma } from "@prisma/client"; +import { HttpError as HttpCode } from "@calcom/lib/http-error"; import prisma from "@calcom/prisma"; - -import { HttpError as HttpCode } from "@lib/core/http/error"; - -import stripe from "./server"; +import stripe from "@calcom/stripe/server"; export async function getStripeCustomerIdFromUserId(userId: number) { // Get user diff --git a/packages/stripe/downgrade.ts b/packages/stripe/downgrade.ts new file mode 100755 index 0000000000..91e8ec4afd --- /dev/null +++ b/packages/stripe/downgrade.ts @@ -0,0 +1,95 @@ +#!/usr/bin/env ts-node +// To run this script: `yarn downgrade 2>&1 | tee result.log` +import { Prisma, UserPlan } from "@prisma/client"; +import dayjs from "dayjs"; + +import { TRIAL_LIMIT_DAYS } from "@calcom/lib/constants"; +import prisma from "@calcom/prisma"; +import stripe from "@calcom/stripe/server"; + +// import { isPremiumUserName } from "../../apps/website/lib/username"; +import { getStripeCustomerIdFromUserId } from "./customer"; +import { getPremiumPlanPrice, getProPlanPrice, getProPlanProduct } from "./utils"; + +export async function downgradeIllegalProUsers() { + const illegalProUsers = await prisma.user.findMany({ + where: { + plan: UserPlan.PRO, + }, + select: { + id: true, + name: true, + email: true, + username: true, + plan: true, + metadata: true, + }, + }); + const usersDowngraded: Partial[] = []; + const downgrade = async (user: typeof illegalProUsers[number]) => { + await prisma.user.update({ + where: { id: user.id }, + data: { + plan: UserPlan.TRIAL, + trialEndsAt: dayjs().add(TRIAL_LIMIT_DAYS, "day").toDate(), + }, + }); + console.log(`Downgraded: ${user.email}`); + usersDowngraded.push({ + id: user.id, + username: user.username, + name: user.name, + email: user.email, + plan: user.plan, + metadata: user.metadata, + }); + }; + for (const suspectUser of illegalProUsers) { + console.log(`Checking: ${suspectUser.email}`); + const metadata = (suspectUser.metadata as Prisma.JsonObject) ?? {}; + // if their pro is already sponsored by a team, do not downgrade + if (metadata.proPaidForByTeamId !== undefined) continue; + + const stripeCustomerId = await getStripeCustomerIdFromUserId(suspectUser.id); + const customer = await stripe.customers.retrieve(stripeCustomerId, { + expand: ["subscriptions.data.plan"], + }); + if (!customer || customer.deleted) { + await downgrade(suspectUser); + continue; + } + + const subscription = customer.subscriptions?.data[0]; + if (!subscription) { + await downgrade(suspectUser); + continue; + } + + const hasProPlan = !!subscription.items.data.find( + (item) => + item.plan.product === getProPlanProduct() || + [getProPlanPrice(), getPremiumPlanPrice()].includes(item.plan.id) + ); + // if they're pro, do not downgrade + if (hasProPlan) continue; + + // If they already have a premium username, do not downgrade + // if (suspectUser.username && isPremiumUserName(suspectUser.username)) continue; + + await downgrade(suspectUser); + } + return { + usersDowngraded, + usersDowngradedAmount: usersDowngraded.length, + }; +} + +downgradeIllegalProUsers() + .then(({ usersDowngraded, usersDowngradedAmount }) => { + console.log(`Downgraded ${usersDowngradedAmount} illegal pro users`); + console.table(usersDowngraded); + }) + .catch((e) => { + console.error(e); + process.exit(1); + }); diff --git a/packages/stripe/index.ts b/packages/stripe/index.ts new file mode 100644 index 0000000000..b04bfcf75e --- /dev/null +++ b/packages/stripe/index.ts @@ -0,0 +1 @@ +export * from "./constants"; diff --git a/packages/stripe/package.json b/packages/stripe/package.json new file mode 100644 index 0000000000..6932ac8283 --- /dev/null +++ b/packages/stripe/package.json @@ -0,0 +1,29 @@ +{ + "name": "@calcom/stripe", + "version": "0.0.0", + "private": true, + "license": "AGPLv3", + "scripts": { + "clean": "rm -rf .turbo && rm -rf node_modules", + "downgrade": "ts-node ./downgrade.ts" + }, + "devDependencies": { + "ts-node": "^10.6.0" + }, + "dependencies": { + "@calcom/ee": "*", + "@calcom/lib": "*", + "@stripe/react-stripe-js": "^1.4.1", + "@stripe/stripe-js": "^1.16.0", + "dayjs": "^1.10.4", + "stripe": "^8.191.0" + }, + "main": "index.ts", + "types": "index.d.ts", + "files": [ + "client.ts", + "constants.ts", + "server.ts", + "utils.ts" + ] +} diff --git a/packages/stripe/server.ts b/packages/stripe/server.ts new file mode 100644 index 0000000000..ffb7a57ec4 --- /dev/null +++ b/packages/stripe/server.ts @@ -0,0 +1,18 @@ +import Stripe from "stripe"; + +export type PaymentData = Stripe.Response & { + stripe_publishable_key: string; + stripeAccount: string; +}; + +export type StripeData = Stripe.OAuthToken & { + default_currency: string; +}; + +const stripePrivateKey = process.env.STRIPE_PRIVATE_KEY!; + +const stripe = new Stripe(stripePrivateKey, { + apiVersion: "2020-08-27", +}); + +export default stripe; diff --git a/apps/web/ee/lib/stripe/team-billing.ts b/packages/stripe/team-billing.ts similarity index 91% rename from apps/web/ee/lib/stripe/team-billing.ts rename to packages/stripe/team-billing.ts index caeee245e3..cfddbfd2d9 100644 --- a/apps/web/ee/lib/stripe/team-billing.ts +++ b/packages/stripe/team-billing.ts @@ -1,13 +1,13 @@ import { MembershipRole, Prisma, UserPlan } from "@prisma/client"; import Stripe from "stripe"; +import { HOSTED_CAL_FEATURES } from "@calcom/lib/constants"; +import { HttpError } from "@calcom/lib/http-error"; import prisma from "@calcom/prisma"; -import { getStripeCustomerIdFromUserId } from "@ee/lib/stripe/customer"; +import stripe from "@calcom/stripe/server"; -import { HOSTED_CAL_FEATURES } from "@lib/config/constants"; -import { HttpError } from "@lib/core/http/error"; - -import stripe from "./server"; +import { getStripeCustomerIdFromUserId } from "./customer"; +import { getPerSeatProPlanPrice, getPremiumPlanPrice, getProPlanPrice } from "./utils"; // get team owner's Pro Plan subscription from Cal userId export async function getProPlanSubscription(userId: number) { @@ -262,21 +262,3 @@ export async function ensureSubscriptionQuantityCorrectness(userId: number, team await updatePerSeatQuantity(subscription, membersMissingSeats.length); } } - -const isProductionSite = - process.env.NEXT_PUBLIC_BASE_URL === "https://app.cal.com" && process.env.VERCEL_ENV === "production"; - -// TODO: these should be moved to env vars -export function getPerSeatProPlanPrice(): string { - return isProductionSite ? "price_1KHkoeH8UDiwIftkkUbiggsM" : "price_1KLD4GH8UDiwIftkWQfsh1Vh"; -} -export function getProPlanPrice(): string { - return isProductionSite ? "price_1KHkoeH8UDiwIftkkUbiggsM" : "price_1JZ0J3H8UDiwIftk0YIHYKr8"; -} -export function getPremiumPlanPrice(): string { - return isProductionSite ? "price_1Jv3CMH8UDiwIftkFgyXbcHN" : "price_1Jv3CMH8UDiwIftkFgyXbcHN"; -} - -export function getProPlanProduct(): string { - return isProductionSite ? "prod_JVxwoOF5odFiZ8" : "prod_KDRBg0E4HyVZee"; -} diff --git a/packages/stripe/tsconfig.json b/packages/stripe/tsconfig.json new file mode 100644 index 0000000000..184d5dec70 --- /dev/null +++ b/packages/stripe/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "@calcom/tsconfig/base.json", + "compilerOptions": { + "baseUrl": "." + }, + "include": ["."], + "exclude": ["dist", "build", "node_modules"] +} diff --git a/packages/stripe/utils.ts b/packages/stripe/utils.ts new file mode 100644 index 0000000000..5d0fac13ad --- /dev/null +++ b/packages/stripe/utils.ts @@ -0,0 +1,21 @@ +import { FREE_PLAN_PRICE, PREMIUM_PLAN_PRICE, PRO_PLAN_PRICE, PRO_PLAN_PRODUCT } from "./constants"; + +export function getPerSeatProPlanPrice(): string { + return PRO_PLAN_PRICE; +} + +export function getPremiumPlanPrice(): string { + return PREMIUM_PLAN_PRICE; +} + +export function getProPlanPrice(): string { + return PRO_PLAN_PRICE; +} + +export function getProPlanProduct(): string { + return PRO_PLAN_PRODUCT; +} + +export function getFreePlanPrice(): string { + return FREE_PLAN_PRICE; +} diff --git a/yarn.lock b/yarn.lock index 63b828909b..93df2209ee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2606,13 +2606,6 @@ dependencies: defer-to-connect "^1.0.1" -"@tailwindcss/forms@^0.3.3": - version "0.3.4" - resolved "https://registry.yarnpkg.com/@tailwindcss/forms/-/forms-0.3.4.tgz#e4939dc16450eccf4fd2029770096f38cbb556d4" - integrity sha512-vlAoBifNJUkagB+PAdW4aHMe4pKmSLroH398UPgIogBFc91D2VlHUxe4pjxQhiJl0Nfw53sHSJSQBSTQBZP3vA== - dependencies: - mini-svg-data-uri "^1.2.3" - "@tailwindcss/forms@^0.5.0": version "0.5.0" resolved "https://registry.yarnpkg.com/@tailwindcss/forms/-/forms-0.5.0.tgz#d4bea2560a10aac642573e72d3b4d62a88960449" @@ -2620,16 +2613,6 @@ dependencies: mini-svg-data-uri "^1.2.3" -"@tailwindcss/typography@^0.4.1": - version "0.4.1" - resolved "https://registry.yarnpkg.com/@tailwindcss/typography/-/typography-0.4.1.tgz#51ddbceea6a0ee9902c649dbe58871c81a831212" - integrity sha512-ovPPLUhs7zAIJfr0y1dbGlyCuPhpuv/jpBoFgqAc658DWGGrOBWBMpAWLw2KlzbNeVk4YBJMzue1ekvIbdw6XA== - dependencies: - lodash.castarray "^4.4.0" - lodash.isplainobject "^4.0.6" - lodash.merge "^4.6.2" - lodash.uniq "^4.5.0" - "@tailwindcss/typography@^0.5.2": version "0.5.2" resolved "https://registry.yarnpkg.com/@tailwindcss/typography/-/typography-0.5.2.tgz#24b069dab24d7a2467d01aca0dd432cb4b29f0ee" @@ -4341,7 +4324,7 @@ bytes@3.1.1: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.1.tgz#3f018291cb4cbad9accb6e6970bca9c8889e879a" integrity sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg== -bytes@3.1.2, bytes@^3.0.0: +bytes@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== @@ -4726,27 +4709,11 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -color-name@^1.0.0, color-name@^1.1.4, color-name@~1.1.4: +color-name@^1.1.4, color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -color-string@^1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.0.tgz#63b6ebd1bec11999d1df3a79a7569451ac2be8aa" - integrity sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ== - dependencies: - color-name "^1.0.0" - simple-swizzle "^0.2.2" - -color@^4.0.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/color/-/color-4.2.1.tgz#498aee5fce7fc982606c8875cab080ac0547c884" - integrity sha512-MFJr0uY4RvTQUKvPq7dh9grVOTYSFeXja2mBXioCGjnjJoXrAp9jJ1NQTDR73c9nwBSAQiNKloKl5zq9WB9UPw== - dependencies: - color-convert "^2.0.1" - color-string "^1.9.0" - colorette@^2.0.16: version "2.0.16" resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" @@ -4784,7 +4751,7 @@ commander@^6.2.0: resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== -commander@^8.0.0, commander@^8.2.0, commander@^8.3.0: +commander@^8.2.0, commander@^8.3.0: version "8.3.0" resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== @@ -5020,16 +4987,6 @@ crypto-random-string@^2.0.0: resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== -css-color-names@^0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" - integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA= - -css-unit-converter@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.2.tgz#4c77f5a1954e6dbff60695ecb214e3270436ab21" - integrity sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA== - cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" @@ -5093,16 +5050,11 @@ dayjs-business-time@^1.0.4: dependencies: dayjs "^1.10.4" -dayjs@^1.10.4, dayjs@^1.10.6: +dayjs@^1.10.4: version "1.10.7" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.7.tgz#2cf5f91add28116748440866a0a1d26f3a6ce468" integrity sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig== -dayjs@^1.10.7: - version "1.10.8" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.8.tgz#267df4bc6276fcb33c04a6735287e3f429abec41" - integrity sha512-wbNwDfBHHur9UOzNUjeKUOJ0fCb0a52Wx0xInmQ7Y8FstyajiV1NmK1e00cxsr9YrE9r7yAChE0VvpuY5Rnlow== - debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -6736,15 +6688,6 @@ fs-constants@^1.0.0: resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-extra@^10.0.0: - version "10.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.1.tgz#27de43b4320e833f6867cc044bfce29fdf0ef3b8" - integrity sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - fs-extra@^4.0.2: version "4.0.3" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" @@ -7339,11 +7282,6 @@ hast-util-whitespace@^2.0.0: resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-2.0.0.tgz#4fc1086467cc1ef5ba20673cb6b03cec3a970f1c" integrity sha512-Pkw+xBHuV6xFeJprJe2BBEoDV+AvQySaz3pPDRUs5PNZEMQjpXJJueqrpcHIXxnWTcAGi/UOCgVShlkY6kLoqg== -hex-color-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" - integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== - hexoid@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/hexoid/-/hexoid-1.0.0.tgz#ad10c6573fb907de23d9ec63a711267d9dc9bc18" @@ -7387,16 +7325,6 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== -hsl-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/hsl-regex/-/hsl-regex-1.0.0.tgz#d49330c789ed819e276a4c0d272dffa30b18fe6e" - integrity sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4= - -hsla-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38" - integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg= - html-encoding-sniffer@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" @@ -7416,11 +7344,6 @@ html-parse-stringify@^3.0.1: dependencies: void-elements "3.1.0" -html-tags@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140" - integrity sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg== - html-void-elements@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-2.0.1.tgz#29459b8b05c200b6c5ee98743c41b979d577549f" @@ -7780,11 +7703,6 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= -is-arrayish@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" - integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== - is-bigint@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" @@ -7829,18 +7747,6 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" -is-color-stop@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-color-stop/-/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345" - integrity sha1-z/9HGu5N1cnhWFmPvhKWe1za00U= - dependencies: - css-color-names "^0.0.4" - hex-color-regex "^1.1.0" - hsl-regex "^1.0.0" - hsla-regex "^1.0.0" - rgb-regex "^1.0.1" - rgba-regex "^1.0.0" - is-core-module@^2.2.0, is-core-module@^2.8.0, is-core-module@^2.8.1: version "2.8.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" @@ -8937,15 +8843,6 @@ jsonfile@^5.0.0: optionalDependencies: graceful-fs "^4.1.6" -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - jsprim@^1.2.2: version "1.4.2" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" @@ -9302,21 +9199,11 @@ lodash.once@^4.1.1: resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= -lodash.topath@^4.5.2: - version "4.5.2" - resolved "https://registry.yarnpkg.com/lodash.topath/-/lodash.topath-4.5.2.tgz#3616351f3bba61994a0931989660bd03254fd009" - integrity sha1-NhY1Hzu6YZlKCTGYlmC9AyVP0Ak= - lodash.truncate@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= -lodash.uniq@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" - integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= - lodash@4.17.21, lodash@4.x, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -10254,11 +10141,6 @@ mockdate@^3.0.5: resolved "https://registry.yarnpkg.com/mockdate/-/mockdate-3.0.5.tgz#789be686deb3149e7df2b663d2bc4392bc3284fb" integrity sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ== -modern-normalize@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/modern-normalize/-/modern-normalize-1.1.0.tgz#da8e80140d9221426bd4f725c6e11283d34f90b7" - integrity sha512-2lMlY1Yc1+CUy0gw4H95uNN7vjbpoED7NNRSBHE25nWfLBdmMzFCsPshlzbxHz+gYMcBEUN8V4pU16prcdPSgA== - module-alias@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/module-alias/-/module-alias-2.2.2.tgz#151cdcecc24e25739ff0aa6e51e1c5716974c0e0" @@ -10580,13 +10462,6 @@ node-addon-api@^2.0.0: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== -node-emoji@^1.11.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.11.0.tgz#69a0150e6946e2f115e9d7ea4df7971e2628301c" - integrity sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A== - dependencies: - lodash "^4.17.21" - node-fetch@2.6.7, node-fetch@^2.6.1: version "2.6.7" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" @@ -11475,14 +11350,6 @@ posix-character-classes@^0.1.0: resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= -postcss-js@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-3.0.3.tgz#2f0bd370a2e8599d45439f6970403b5873abda33" - integrity sha512-gWnoWQXKFw65Hk/mi2+WTQTHdPD5UJdDXZmX073EY/B3BWnYjO4F4t0VneTCnCGQ5E5GsCdMkzPaTXwl3r5dJw== - dependencies: - camelcase-css "^2.0.1" - postcss "^8.1.6" - postcss-js@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.0.tgz#31db79889531b80dc7bc9b0ad283e418dce0ac00" @@ -11513,12 +11380,7 @@ postcss-selector-parser@^6.0.6, postcss-selector-parser@^6.0.9: cssesc "^3.0.0" util-deprecate "^1.0.2" -postcss-value-parser@^3.3.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" - integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== - -postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: +postcss-value-parser@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== @@ -11532,7 +11394,7 @@ postcss@8.4.5: picocolors "^1.0.0" source-map-js "^1.0.1" -postcss@^8.1.6, postcss@^8.3.5, postcss@^8.3.6, postcss@^8.4.6: +postcss@^8.3.6, postcss@^8.4.6: version "8.4.8" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.8.tgz#dad963a76e82c081a0657d3a2f3602ce10c2e032" integrity sha512-2tXEqGxrjvAO6U+CJzDL2Fk2kPHTv1jQsYkSoMeOis2SsYaXRO2COxTdQp99cYvif9JTXaAk9lYGc3VhJt7JPQ== @@ -11645,11 +11507,6 @@ pretty-format@^3.8.0: resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-3.8.0.tgz#bfbed56d5e9a776645f4b1ff7aa1a3ac4fa3c385" integrity sha1-v77VbV6ad2ZF9LH/eqGjrE+jw4U= -pretty-hrtime@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" - integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE= - printj@~1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/printj/-/printj-1.3.1.tgz#9af6b1d55647a1587ac44f4c1654a4b95b8e12cb" @@ -11798,16 +11655,6 @@ pupa@^2.1.1: dependencies: escape-goat "^2.0.0" -purgecss@^4.0.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/purgecss/-/purgecss-4.1.3.tgz#683f6a133c8c4de7aa82fe2746d1393b214918f7" - integrity sha512-99cKy4s+VZoXnPxaoM23e5ABcP851nC2y2GROkkjS8eJaJtlciGavd7iYAw2V84WeBqggZ12l8ef44G99HmTaw== - dependencies: - commander "^8.0.0" - glob "^7.1.7" - postcss "^8.3.5" - postcss-selector-parser "^6.0.6" - pvtsutils@^1.2.0, pvtsutils@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/pvtsutils/-/pvtsutils-1.2.1.tgz#8212e846ca9afb21e40cebb0691755649f9f498a" @@ -12325,14 +12172,6 @@ redis@4.0.1: "@node-redis/search" "^1.0.1" "@node-redis/time-series" "^1.0.0" -reduce-css-calc@^2.1.8: - version "2.1.8" - resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz#7ef8761a28d614980dc0c982f772c93f7a99de03" - integrity sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg== - dependencies: - css-unit-converter "^1.1.1" - postcss-value-parser "^3.3.0" - reflect-metadata@0.1.13, reflect-metadata@^0.1.13: version "0.1.13" resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" @@ -12611,16 +12450,6 @@ rfdc@^1.3.0: resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== -rgb-regex@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/rgb-regex/-/rgb-regex-1.0.1.tgz#c0e0d6882df0e23be254a475e8edd41915feaeb1" - integrity sha1-wODWiC3w4jviVKR16O3UGRX+rrE= - -rgba-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" - integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= - rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -12966,13 +12795,6 @@ simple-get@^2.7.0: once "^1.3.1" simple-concat "^1.0.0" -simple-swizzle@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" - integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= - dependencies: - is-arrayish "^0.3.1" - sirv@^1.0.7: version "1.0.19" resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.19.tgz#1d73979b38c7fe91fcba49c85280daa9c2363b49" @@ -13574,44 +13396,6 @@ table@^6.0.9: string-width "^4.2.3" strip-ansi "^6.0.1" -tailwindcss@^2.2.15: - version "2.2.19" - resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-2.2.19.tgz#540e464832cd462bb9649c1484b0a38315c2653c" - integrity sha512-6Ui7JSVtXadtTUo2NtkBBacobzWiQYVjYW0ZnKaP9S1ZCKQ0w7KVNz+YSDI/j7O7KCMHbOkz94ZMQhbT9pOqjw== - dependencies: - arg "^5.0.1" - bytes "^3.0.0" - chalk "^4.1.2" - chokidar "^3.5.2" - color "^4.0.1" - cosmiconfig "^7.0.1" - detective "^5.2.0" - didyoumean "^1.2.2" - dlv "^1.1.3" - fast-glob "^3.2.7" - fs-extra "^10.0.0" - glob-parent "^6.0.1" - html-tags "^3.1.0" - is-color-stop "^1.1.0" - is-glob "^4.0.1" - lodash "^4.17.21" - lodash.topath "^4.5.2" - modern-normalize "^1.1.0" - node-emoji "^1.11.0" - normalize-path "^3.0.0" - object-hash "^2.2.0" - postcss-js "^3.0.3" - postcss-load-config "^3.1.0" - postcss-nested "5.0.6" - postcss-selector-parser "^6.0.6" - postcss-value-parser "^4.1.0" - pretty-hrtime "^1.0.3" - purgecss "^4.0.3" - quick-lru "^5.1.1" - reduce-css-calc "^2.1.8" - resolve "^1.20.0" - tmp "^0.2.1" - tailwindcss@^3.0.23: version "3.0.23" resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.0.23.tgz#c620521d53a289650872a66adfcb4129d2200d10" @@ -13771,13 +13555,6 @@ titleize@1.0.0: resolved "https://registry.yarnpkg.com/titleize/-/titleize-1.0.0.tgz#7d350722061830ba6617631e0cfd3ea08398d95a" integrity sha1-fTUHIgYYMLpmF2MeDP0+oIOY2Vo= -tmp@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" - integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== - dependencies: - rimraf "^3.0.0" - tmpl@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" @@ -13930,9 +13707,9 @@ ts-morph@^13.0.2: code-block-writer "^11.0.0" ts-node@^10.6.0: - version "10.6.0" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.6.0.tgz#c3f4195d5173ce3affdc8f2fd2e9a7ac8de5376a" - integrity sha512-CJen6+dfOXolxudBQXnVjRVvYTmTWbyz7cn+xq2XTsvnaXbHqr4gXSCNbS2Jj8yTZMuGwUoBESLaOkLascVVvg== + version "10.7.0" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.7.0.tgz#35d503d0fab3e2baa672a0e94f4b40653c2463f5" + integrity sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A== dependencies: "@cspotcode/source-map-support" "0.7.0" "@tsconfig/node10" "^1.0.7" @@ -14396,11 +14173,6 @@ universalify@^0.1.0, universalify@^0.1.2: resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== -universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== - unload@2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/unload/-/unload-2.2.0.tgz#ccc88fdcad345faa06a92039ec0f80b488880ef7"