diff --git a/cypress.config.ts b/cypress.config.ts new file mode 100644 index 0000000..a43fe1b --- /dev/null +++ b/cypress.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from "cypress"; + +export default defineConfig({ + e2e: { + viewportWidth: 1200, + viewportHeight: 800, + fixturesFolder: "tests/e2e/fixtures", + supportFile: false, + defaultCommandTimeout: 100, + }, +}); diff --git a/cypress/e2e/access.cy.ts b/cypress/e2e/access.cy.ts new file mode 100644 index 0000000..8a6724f --- /dev/null +++ b/cypress/e2e/access.cy.ts @@ -0,0 +1,110 @@ +describe("Форма Входа", () => { + beforeEach(() => { + cy.visit("http://localhost:3000"); + }); + + it("должна успешно входить с правильными учетными данными", () => { + const email = "valid_user@example.com"; + const password = "valid_password"; + + cy.get('input[name="email"]').type(email); + cy.get('input[name="password"]').type(password); + cy.get('button[type="submit"]').click(); + + cy.url().should("include", "http://localhost:3000/users"); + }); + + it("должна отображать сообщение об ошибке при неверном формате электронной почты", () => { + const invalidEmail = "invalid_email"; + + cy.get('input[name="email"]').type(invalidEmail); + cy.get('input[name="password"]').type("valid_password"); + cy.get('button[type="submit"]').click(); + + cy.contains("Неверный формат эл. почты"); + }); + + it("должна отображать сообщение об ошибке при отсутствии пароля", () => { + cy.get('input[name="email"]').type("valid_email@example.com"); + cy.get('button[type="submit"]').click(); + + cy.contains("Введите пароль"); + }); + + it("должна отображать сообщение об ошибке для недопустимого пароля", () => { + const invalidPassword = "short"; + + cy.get('input[name="email"]').type("valid_email@example.com"); + cy.get('input[name="password"]').type(invalidPassword); + cy.get('button[type="submit"]').click(); + + cy.contains("Invalid password"); + }); +}); + +describe("Форма регистрации", () => { + beforeEach(() => { + cy.visit("http://localhost:3000/signup"); + }); + + it("должна регистрировать нового пользователя с правильными данными", () => { + const email = Cypress._.random(1000) + "@example.com"; + const password = "valid_password"; + + cy.get('input[name="email"]').type(email); + cy.get('input[name="password"]').type(password); + cy.get('input[name="repeatPassword"]').type(password); + + cy.get('button[type="submit"]').click(); + cy.wait(5000); + + cy.url().should("include", "http://localhost:3000/users"); + }); + + it("должна отображать ошибку при неверном формате электронной почты", () => { + const invalidEmail = "invalid_email"; + + cy.get('input[name="email"]').type(invalidEmail); + cy.get('input[name="password"]').type("valid_password"); + cy.get('input[name="repeatPassword"]').type("valid_password"); + + cy.get('button[type="submit"]').click(); + + cy.contains("Неверный формат эл. почты"); + }); + + it("должна отображать ошибку при отсутствии пароля", () => { + cy.get('input[name="email"]').type("valid_email@example.com"); + cy.get('input[name="repeatPassword"]').type("valid_password"); + + cy.get('button[type="submit"]').click(); + + cy.contains("Обязательное поле").should("have.length", 1); + }); + + it("должна отображать ошибку при несовпадении паролей", () => { + cy.get('input[name="email"]').type("valid_email@example.com"); + cy.get('input[name="password"]').type("valid_password"); + cy.get('input[name="repeatPassword"]').type("different_password"); + + cy.get('button[type="submit"]').click(); + + cy.contains("Пароли не совпадают"); + }); + + it("попытка отправки запроса при уже зарегистрированном пользователе", () => { + const email = "users@gmail.com"; + const password = "12344321"; + + cy.get('input[name="email"]').type(email); + cy.get('input[name="password"]').type(password); + cy.get('input[name="repeatPassword"]').type(password); + + cy.intercept("POST", "https://admin.pena.digital/auth/register").as("registerRequest"); + cy.get('button[type="submit"]').click(); + cy.wait("@registerRequest"); + + cy.wait(5000); + cy.contains("user with this login is exist"); + }); +}); diff --git a/cypress/e2e/tariffs.cy.ts b/cypress/e2e/tariffs.cy.ts new file mode 100644 index 0000000..d9fbb21 --- /dev/null +++ b/cypress/e2e/tariffs.cy.ts @@ -0,0 +1,195 @@ +describe("Форма Создания Тарифа", () => { + beforeEach(() => { + cy.visit("http://localhost:3000"); + cy.get('input[name="email"]').type("valid_user@example.com"); + cy.get('input[name="password"]').type("valid_password"); + cy.get('button[type="submit"]').click(); + cy.wait(3000); + cy.url().should("include", "http://localhost:3000/users"); + cy.visit("http://localhost:3000/tariffs"); + }); + + it("должна отображать сообщение об ошибке при пустом названии тарифа", () => { + cy.get('input[id="tariff-amount"]').type("10"); + + // Выбрать первую привилегию с нужным текстом из выпадающего списка + cy.get("#privilege-select").click(); + + cy.get(`[data-cy = "select-option-Количество шаблонов, которые может сделать пользователь сервиса"]`).click(); + + cy.get(".btn_createTariffBackend").click({ force: true }); + + cy.contains("Пустое название тарифа"); + }); + + it("должна отображать сообщение об ошибке при отсутствии выбора привилегии", () => { + cy.get('input[id="tariff-name"]').type("Тестовый Тариф"); + cy.get('input[id="tariff-amount"]').type("10"); + + cy.get(".btn_createTariffBackend").click({ force: true }); + + cy.contains("Не выбрана привилегия"); + }); + + it("Создание трех тарифов", () => { + cy.get('input[id="tariff-name"]').type("Тестовый Тариф 1"); + cy.get('input[id="tariff-amount"]').type("10"); + cy.get("#privilege-select").click(); + cy.get(`[data-cy="select-option-Количество шаблонов, которые может сделать пользователь сервиса"]`).click(); + cy.get(".btn_createTariffBackend").click({ force: true }); + + cy.get('input[id="tariff-name"]').scrollIntoView().clear({ force: true }).type("Тестовый Тариф 2"); + cy.get('input[id="tariff-amount"]').scrollIntoView().clear({ force: true }).type("15"); + cy.get("#privilege-select").click(); + cy.wait(800); + cy.get(`[data-cy="select-option-Количество дней, в течении которых пользование сервисом безлимитно"]`).click(); + cy.get(".btn_createTariffBackend").click({ force: true }); + + cy.get('input[id="tariff-name"]').scrollIntoView().clear({ force: true }).type("Тестовый Тариф 3"); + cy.get('input[id="tariff-amount"]').scrollIntoView().clear({ force: true }).type("20"); + cy.get("#privilege-select").click(); + cy.wait(800); + cy.get(`[data-cy="select-option-Обьём ПенаДиска для хранения шаблонов и результатов шаблонизации"]`).click(); + cy.get(".btn_createTariffBackend").click({ force: true }); + }); +}); + +describe("Форма Создания Тарифа", () => { + beforeEach(() => { + cy.visit("http://localhost:3000"); + cy.get('input[name="email"]').type("valid_user@example.com"); + cy.get('input[name="password"]').type("valid_password"); + cy.get('button[type="submit"]').click(); + cy.wait(3000); + cy.url().should("include", "http://localhost:3000/users"); + cy.visit("http://localhost:3000/tariffs"); + }); + + it("Удаление тарифа единично, одного за другим ", () => { + const tariffNamesToFind = ["Тестовый Тариф 1", "Тестовый Тариф 2", "Тестовый Тариф 3"]; + + // Поиск каждого тарифа в DataGrid + cy.wait(3000); + tariffNamesToFind.forEach((tariffName) => { + cy.get(".tariffs-data-grid").scrollIntoView().contains(tariffName).should("be.visible"); + }); + + const deleteTariffs = () => { + let tariffsFound = true; + + cy.get(".tariffs-data-grid .MuiDataGrid-row").then(($rows) => { + const rowCount = $rows.length; + + if (rowCount === 1) { + cy.log("Тарифы не найдены. Тест завершен."); + tariffsFound = false; + } + + cy.wrap($rows).each(($row) => { + // Шаг 2: В каждом элементе найдите все дивы вложенные внутрь и выберите последний див + cy.wrap($row).find("div").last().scrollIntoView().get(".delete-tariff-button").last().click({ force: true }); + }); + + cy.wait(2000); + cy.contains("Да") + .click() + .then(() => { + if (!tariffsFound) { + return; + } + + cy.wait(5000); + deleteTariffs(); + }); + }); + }; + + deleteTariffs(); + + // Проверяем что Дата грид тарифов пустой + cy.wait(2000); + cy.get(".tariffs-data-grid .MuiDataGrid-row").should("not.exist"); + }); + + describe("Форма Создания Тарифа", () => {}); + + it("Удаление тарифов массово через DataGrid", () => { + // Добавляем 3 тариффа + cy.get('input[id="tariff-name"]').type("Тестовый Тариф 1"); + cy.get('input[id="tariff-amount"]').type("10"); + cy.get("#privilege-select").click(); + cy.get(`[data-cy="select-option-Количество шаблонов, которые может сделать пользователь сервиса"]`).click(); + cy.get(".btn_createTariffBackend").click({ force: true }); + + cy.get('input[id="tariff-name"]').scrollIntoView().clear({ force: true }).type("Тестовый Тариф 2"); + cy.get('input[id="tariff-amount"]').scrollIntoView().clear({ force: true }).type("15"); + cy.get("#privilege-select").click(); + cy.wait(800); + cy.get(`[data-cy="select-option-Количество дней, в течении которых пользование сервисом безлимитно"]`).click(); + cy.get(".btn_createTariffBackend").click({ force: true }); + + cy.get('input[id="tariff-name"]').scrollIntoView().clear({ force: true }).type("Тестовый Тариф 3"); + cy.get('input[id="tariff-amount"]').scrollIntoView().clear({ force: true }).type("20"); + cy.get("#privilege-select").click(); + cy.wait(800); + cy.get(`[data-cy="select-option-Обьём ПенаДиска для хранения шаблонов и результатов шаблонизации"]`).click(); + cy.get(".btn_createTariffBackend").click({ force: true }); + // Добавляем 3 тариффа + + cy.wait(3000); + cy.get(".tariffs-data-grid .PrivateSwitchBase-input").first().click({ multiple: true }); + + // Проверить, что кнопка "Удалить" появилась + cy.wait(2000); + cy.contains("Удаление").should("be.visible"); + + // Нажать на кнопку "Удалить" + cy.contains("Удаление").click(); + + // Подтверждение удаления (если нужно) + cy.contains("Да").click(); + + // Проверяем что Дата грид тарифов пустой + cy.wait(2000); + cy.get(".tariffs-data-grid .MuiDataGrid-row").should("not.exist"); + }); + + it("Добавление тарифом в корзину", () => { + // Добавляем 3 тариффа + + cy.get('input[id="tariff-name"]').type("Тестовый Тариф 1"); + cy.get('input[id="tariff-amount"]').type("10"); + cy.get("#privilege-select").click(); + cy.get(`[data-cy="select-option-Количество шаблонов, которые может сделать пользователь сервиса"]`).click(); + cy.get(".btn_createTariffBackend").click({ force: true }); + + cy.get('input[id="tariff-name"]').scrollIntoView().clear({ force: true }).type("Тестовый Тариф 2"); + cy.get('input[id="tariff-amount"]').scrollIntoView().clear({ force: true }).type("15"); + cy.get("#privilege-select").click(); + cy.wait(800); + cy.get(`[data-cy="select-option-Количество дней, в течении которых пользование сервисом безлимитно"]`).click(); + cy.get(".btn_createTariffBackend").click({ force: true }); + + cy.get('input[id="tariff-name"]').scrollIntoView().clear({ force: true }).type("Тестовый Тариф 3"); + cy.get('input[id="tariff-amount"]').scrollIntoView().clear({ force: true }).type("20"); + cy.get("#privilege-select").click(); + cy.wait(800); + cy.get(`[data-cy="select-option-Обьём ПенаДиска для хранения шаблонов и результатов шаблонизации"]`).click(); + cy.get(".btn_createTariffBackend").click({ force: true }); + // Добавляем 3 тариффа + + cy.wait(3000); + cy.get(".tariffs-data-grid .PrivateSwitchBase-input").first().click({ multiple: true }); + + // Проверить, что кнопка "Удалить" появилась + cy.wait(2000); + cy.contains("рассчитать").should("be.visible"); + + // Нажать на кнопку "Удалить" + cy.contains("рассчитать").click(); + + // смотрим что в корзине ровно столько тарифом, сколько мы добовляли + cy.wait(5000); + cy.get(".MuiTable-root tbody tr").its("length").should("eq", 3); + }); +}); diff --git a/package.json b/package.json index a953803..62d283d 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "@types/react-router-dom": "^5.3.3", "axios": "^1.3.4", "craco": "^0.0.3", + "cypress": "^12.17.2", "dayjs": "^1.11.5", "formik": "^2.2.9", "immer": "^10.0.2", @@ -37,6 +38,7 @@ "react-router-dom": "^6.3.0", "react-scripts": "^5.0.1", "reconnecting-eventsource": "^1.6.2", + "start-server-and-test": "^2.0.0", "styled-components": "^5.3.5", "typescript": "^4.8.2", "web-vitals": "^2.1.4", @@ -47,6 +49,8 @@ "build": "craco build", "test": "craco test", "test:cart": "craco test src/kitUI/Cart --watchAll=false", + "test:cypress": "start-server-and-test start http://localhost:3000 cypress", + "cypress": "cypress open", "eject": "craco eject" }, "eslintConfig": { diff --git a/src/api/roles.ts b/src/api/roles.ts index 78f454e..6310a2a 100644 --- a/src/api/roles.ts +++ b/src/api/roles.ts @@ -21,7 +21,15 @@ export const MOCK_DATA_USERS = [ export type TMockData = typeof MOCK_DATA_USERS; -export type UsersType = { login: string; email: string; phoneNumber: string; isDeleted: boolean; createdAt: string }[]; +export type UserType = { + _id: string; + login: string; + email: string; + phoneNumber: string; + isDeleted: boolean; + createdAt: string; + updatedAt: string; +}; export const getRoles_mock = (): Promise => { return new Promise((resolve) => { diff --git a/src/assets/icons/check.svg b/src/assets/icons/check.svg new file mode 100644 index 0000000..55c02f0 --- /dev/null +++ b/src/assets/icons/check.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/icons/forward.svg b/src/assets/icons/forward.svg new file mode 100644 index 0000000..5ee1ea9 --- /dev/null +++ b/src/assets/icons/forward.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/package.svg b/src/assets/icons/package.svg new file mode 100644 index 0000000..06215bd --- /dev/null +++ b/src/assets/icons/package.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/transactions.svg b/src/assets/icons/transactions.svg new file mode 100644 index 0000000..4e12c2f --- /dev/null +++ b/src/assets/icons/transactions.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/user.svg b/src/assets/icons/user.svg new file mode 100644 index 0000000..d919ed6 --- /dev/null +++ b/src/assets/icons/user.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/hooks/useDiscounts.hook.ts b/src/hooks/useDiscounts.hook.ts deleted file mode 100644 index 6c30d09..0000000 --- a/src/hooks/useDiscounts.hook.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { authStore } from "@root/stores/auth"; -import { setDiscounts } from "@root/stores/discounts"; - -import type { GetDiscountResponse } from "@root/model/discount"; - -const makeRequest = authStore.getState().makeRequest; - -export const useDiscounts = () => { - const requestDiscounts = async () => { - const controller = new AbortController(); - - makeRequest({ - url: "https://admin.pena.digital/price/discounts", - method: "get", - useToken: true, - bearer: true, - signal: controller.signal, - }) - .then((result) => { - setDiscounts(result.Discounts); - }) - .catch((error) => { - console.log("Error fetching discounts", error); - }); - - return () => controller.abort(); - }; - - return { requestDiscounts }; -}; diff --git a/src/hooks/usePrivilegies.hook.ts b/src/hooks/usePrivilegies.hook.ts deleted file mode 100644 index 96dbb08..0000000 --- a/src/hooks/usePrivilegies.hook.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { useState, useEffect } from "react"; -import { authStore } from "@root/stores/auth"; - -import { resetPrivilegeArray } from "@root/stores/privilegesStore"; -import { exampleCartValues } from "@stores/mocks/exampleCartValues"; - -import type { RealPrivilege } from "@root/model/privilege"; - -export type Privilege = { - createdAt: string; - description: string; - isDeleted: boolean; - name: string; - price: number; - privilegeId: string; - serviceKey: string; - type: "count" | "day" | "mb"; - updatedAt: string; - value: string; - _id: string; -}; - -type SeverPrivilegiesResponse = { - templategen: RealPrivilege[]; -}; - -type UsePrivilegies = { - requestPrivilegies: () => Promise; - isError: boolean; - isLoading: boolean; - errorMessage: string; -}; - -const baseUrl = - process.env.NODE_ENV === "production" - ? "/strator" - : "https://admin.pena.digital/strator"; - -export const usePrivilegies = (): UsePrivilegies => { - const [privilegies, setPrivilegies] = useState([]); - const [isLoading, setIsLoading] = useState(false); - const [isError, setIsError] = useState(false); - const [errorMessage, setErrorMessage] = useState(""); - const { makeRequest } = authStore.getState(); - - useEffect(() => { - let extracted: RealPrivilege[] = []; - for (let serviceKey in privilegies) { - //Приходит объект. В его значениях массивы привилегий для разных сервисов. Высыпаем в общую кучу и обновляем стор - extracted = extracted.concat(privilegies[serviceKey]); - } - - let readyArray = extracted.map((privilege) => ({ - serviceKey: privilege.serviceKey, - privilegeId: privilege.privilegeId, - name: privilege.name, - description: privilege.description, - type: privilege.type, - price: privilege.price, - value: privilege.value, - id: privilege._id, - })); - - resetPrivilegeArray([...readyArray, ...exampleCartValues.privileges]); - }, [privilegies]); - - const requestPrivilegies = async () => { - setIsLoading(true); - - await makeRequest({ - url: baseUrl + "/privilege/service", - method: "get", - }) - .then(({ templategen }) => setPrivilegies(templategen)) - .catch(() => { - setIsError(true); - setErrorMessage("Ошибка при получении привилегий"); - }) - .finally(() => setIsLoading(false)); - }; - - return { - requestPrivilegies, - isError, - isLoading, - errorMessage, - }; -}; diff --git a/src/hooks/useTariffs.hook.ts b/src/hooks/useTariffs.hook.ts deleted file mode 100644 index a17e747..0000000 --- a/src/hooks/useTariffs.hook.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { useEffect, useState } from "react"; -import { Tariff, Tariff_BACKEND } from "@root/model/tariff"; -import { resetTariffsStore } from "@root/stores/tariffsStore"; -import { authStore } from "@root/stores/auth"; - -type UseGetTariffs = { - requestTariffs: (page?: number, tariffs?: Tariff_BACKEND[]) => Promise; - isLoading: boolean; -}; - -type GetTariffsResponse = { - totalPages: number; - tariffs: Tariff_BACKEND[]; -}; - -const baseUrl = - process.env.NODE_ENV === "production" - ? "/strator" - : "https://admin.pena.digital/strator"; - -export const useTariffs = (): UseGetTariffs => { - const [isLoading, setIsLoading] = useState(false); - const [tariffsList, setTariffsList] = useState([]); - const { makeRequest } = authStore.getState(); - - useEffect(() => { - const convertedTariffs: Record = {}; - - tariffsList - .filter(({ isDeleted }) => !isDeleted) - .forEach((tariff) => { - convertedTariffs[tariff._id] = { - id: tariff._id, - name: tariff.name, - isCustom: tariff.price ? true : false, - amount: tariff.privilegies[0].amount, - isFront: false, - privilegeId: tariff.privilegies[0].privilegeId, - price: tariff.privilegies[0].price, - isDeleted: tariff.isDeleted, - customPricePerUnit: tariff.price, - }; - }); - - resetTariffsStore(convertedTariffs); - }, [tariffsList]); - - const requestTariffs = async ( - page: number = 1, - existingTariffs: Tariff_BACKEND[] = [] - ): Promise => { - setIsLoading(true); - - try { - const { tariffs, totalPages } = await makeRequest< - never, - GetTariffsResponse - >({ - url: baseUrl + `/tariff/?page=${page}&limit=${100}`, - method: "get", - bearer: true, - }); - - if (page < totalPages) { - return requestTariffs(page + 1, [...existingTariffs, ...tariffs]); - } - - setTariffsList([...existingTariffs, ...tariffs]); - } catch { - throw new Error("Ошибка при получении тарифов"); - } finally { - setIsLoading(false); - } - }; - - return { requestTariffs, isLoading }; -}; diff --git a/src/index.tsx b/src/index.tsx index cb0597d..c7da5db 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -17,6 +17,7 @@ import Sections from "@pages/Sections"; import Dashboard from "@pages/dashboard"; import Error404 from "@pages/Error404"; import Users from "@pages/dashboard/Content/Users"; +import ModalUser from "@root/pages/dashboard/ModalUser"; import Entities from "@pages/dashboard/Content/Entities"; import Tariffs from "@pages/dashboard/Content/Tariffs"; import DiscountManagement from "@root/pages/dashboard/Content/DiscountManagement/DiscountManagement"; @@ -29,6 +30,7 @@ import "./index.css"; const componentsArray = [ ["/users", ], + ["/users/:userId", ], ["/entities", ], ["/tariffs", ], ["/discounts", ], diff --git a/src/kitUI/Cart/Cart.tsx b/src/kitUI/Cart/Cart.tsx index 15c488b..f7af09d 100644 --- a/src/kitUI/Cart/Cart.tsx +++ b/src/kitUI/Cart/Cart.tsx @@ -25,20 +25,19 @@ import { formatDiscountFactor, } from "./calc"; -import { AnyDiscount, CartItemTotal } from "@root/model/cart"; +import { CartItemTotal } from "@root/model/cart"; import { Privilege } from "@root/model/tariff"; -import { useDiscountStore, setDiscounts } from "@root/stores/discounts"; import { useCartStore } from "@root/stores/cart"; import { findPrivilegeById } from "@root/stores/privilegesStore"; import { testUser } from "@root/stores/mocks/user"; import { useTariffStore } from "@root/stores/tariffsStore"; import { Discount } from "@root/model/discount"; -import { authStore } from "@root/stores/auth"; +import { useDiscountStore } from "@root/stores/discounts"; +import { requestPrivilegies } from "@root/services/privilegies.service"; +import { requestDiscounts } from "@root/services/discounts.service"; interface Props { - requestPrivilegies: () => Promise; - requestDiscounts: () => Promise<() => void>; selectedTariffs: GridSelectionModel; } @@ -58,19 +57,13 @@ interface MergedTariff { isFront: boolean; } -export default function Cart({ - requestPrivilegies, - requestDiscounts, - selectedTariffs, -}: Props) { +export default function Cart({ selectedTariffs }: Props) { let cartTariffs = Object.values(useTariffStore().tariffs); - // const discounts = useDiscountStore((store) => store.discounts); - const [discounts, setDiscounts] = useState([]); + const discounts = useDiscountStore((store) => store.discounts); const cartTotal = useCartStore((state) => state.cartTotal); const setCartTotal = useCartStore((store) => store.setCartTotal); const [couponField, setCouponField] = useState(""); const [loyaltyField, setLoyaltyField] = useState(""); - const makeRequest = authStore.getState().makeRequest; const [errorMessage, setErrorMessage] = useState(null); const [isNonCommercial, setIsNonCommercial] = useState(false); @@ -157,17 +150,6 @@ export default function Cart({ await requestPrivilegies(); await requestDiscounts(); - //рассчитать - const dis = await makeRequest({ - url: "https://admin.pena.digital/price/discounts", - method: "get", - useToken: true, - bearer: true, - }); - console.log(dis); - // @ts-ignore - setDiscounts(dis.Discounts); - const cartItems = cartTariffs .filter((tariff) => selectedTariffs.includes(tariff.id)) .map((tariff) => createCartItem(tariff)); @@ -178,15 +160,11 @@ export default function Cart({ if (!isFinite(loyaltyValue)) loyaltyValue = 0; - const activeDiscounts = discounts.filter( - (discount) => !discount.Deprecated - ); - const cartData = calcCartData({ user: testUser, purchasesAmount: loyaltyValue, cartItems, - discounts: activeDiscounts, + discounts, isNonCommercial, coupon: couponField, }); diff --git a/src/kitUI/Cart/calc.ts b/src/kitUI/Cart/calc.ts index b693d72..0904eb8 100644 --- a/src/kitUI/Cart/calc.ts +++ b/src/kitUI/Cart/calc.ts @@ -1,14 +1,6 @@ import { - CartItem, - AnyDiscount, - CartTotal, - CartItemTotal, - PrivilegeDiscount, - CartPurchasesAmountDiscount, - PurchasesAmountDiscount, - ServiceToPriceMap, - ServiceDiscount, - UserDiscount, + CartItem, CartTotal, + CartItemTotal, ServiceToPriceMap } from "@root/model/cart"; import { Discount } from "@root/model/discount"; import { User } from "../../model/user"; diff --git a/src/kitUI/outlinedInput.tsx b/src/kitUI/outlinedInput.tsx index 06b15ff..bcbd380 100644 --- a/src/kitUI/outlinedInput.tsx +++ b/src/kitUI/outlinedInput.tsx @@ -1,15 +1,18 @@ import { styled } from "@mui/material/styles"; -import { TextField} from "@mui/material"; +import { TextField } from "@mui/material"; export default styled(TextField)(({ theme }) => ({ + color: theme.palette.grayLight.main, + "& .MuiInputLabel-root": { color: theme.palette.grayLight.main, - "& .MuiInputLabel-root": { - color: theme.palette.grayLight.main, - }, - "& .MuiFilledInput-root": { - border: theme.palette.grayLight.main+" 1px solid", - borderRadius: "0", - backgroundColor: theme.palette.hover.main, - color: theme.palette.grayLight.main, - } + }, + "& .MuiFilledInput-root": { + border: theme.palette.grayLight.main + " 1px solid", + borderRadius: "0", + backgroundColor: theme.palette.hover.main, + color: theme.palette.grayLight.main, + }, -})); \ No newline at end of file + "& .MuiFilledInput-root.Mui-error": { + fontSize: "8px", + }, +})); diff --git a/src/model/cart.ts b/src/model/cart.ts index 99e8849..50c3820 100644 --- a/src/model/cart.ts +++ b/src/model/cart.ts @@ -1,105 +1,6 @@ import { ServiceType, Privilege, Tariff } from "./tariff"; import { Discount } from "@root/model/discount"; -interface DiscountBase { - _id: string; - name: string; - description: string; - /** Этап применения скидки */ - layer?: number; - disabled?: boolean; -} - -export interface PurchasesAmountDiscount extends DiscountBase { - conditionType: "purchasesAmount"; - condition: { - purchasesAmount: number; - }; - /** Множитель, на который умножается сумма при применении скидки */ - factor: number; -} - -export interface CartPurchasesAmountDiscount extends DiscountBase { - conditionType: "cartPurchasesAmount"; - condition: { - cartPurchasesAmount: number; - }; - /** Множитель, на который умножается сумма при применении скидки */ - factor: number; -} - -export interface PrivilegeDiscount extends DiscountBase { - conditionType: "privilege"; - condition: { - privilege: { - id: string; - /** Скидка применяется, если значение больше или равно этому значению */ - value: number; - }; - }; - target: { - products: Array<{ - privilegeId: string; - /** Множитель, на который умножается сумма при применении скидки */ - factor: number; - }>; - }; -} - -export interface ServiceDiscount extends DiscountBase { - conditionType: "service"; - condition: { - service: { - id: ServiceType; - /** Скидка применяется, если значение больше или равно этому значению */ - value: number; - }; - }; - target: { - service: ServiceType; - /** Множитель, на который умножается сумма при применении скидки */ - factor: number; - }; -} - -export interface UserTypeDiscount extends DiscountBase { - conditionType: "userType"; - condition: { - userType: string; - }; - target: { - IsAllProducts: boolean; - /** Множитель, на который умножается сумма при применении скидки */ - factor: number; - }; - overwhelm: boolean; -} - -export interface UserDiscount extends DiscountBase { - conditionType: "user"; - condition: { - coupon: string; - user: string; - }; - target: { - products: Array<{ - privilegeId: string; - /** Множитель, на который умножается сумма при применении скидки */ - factor: number; - }>; - }; - overwhelm: boolean; -} - -export type AnyDiscount = - | PurchasesAmountDiscount - | CartPurchasesAmountDiscount - | PrivilegeDiscount - | ServiceDiscount - | UserTypeDiscount - | UserDiscount; - -export type DiscountConditionType = AnyDiscount["conditionType"]; export interface Promocode { id: string; diff --git a/src/pages/Authorization/signin.tsx b/src/pages/Authorization/signin.tsx index 5401d41..f350533 100644 --- a/src/pages/Authorization/signin.tsx +++ b/src/pages/Authorization/signin.tsx @@ -19,11 +19,13 @@ function validate(values: Values) { const errors = {} as any; if (!values.email) { - errors.email = "Required"; + errors.email = "Обязательное поле"; + } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(values.email)) { + errors.email = "Неверный формат эл. почты"; } if (!values.password) { - errors.password = "Required"; + errors.password = "Введите пароль"; } if (values.password && !/^[\S]{8,25}$/i.test(values.password)) { @@ -107,11 +109,34 @@ const SigninForm = () => { *": { marginRight: "10px" } }}> - + + {props.touched.email && props.errors.email} + + } + /> *": { marginRight: "10px" } }}> - + + {props.touched.password && props.errors.password} + + } + /> = {}; + + if (!values.email) { + errors.email = "Обязательное поле"; + } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(values.email)) { + errors.email = "Неверный формат эл. почты"; + } + + if (!values.password) { + errors.password = "Обязательное поле"; + } else if (!/^[\S]{8,25}$/i.test(values.password)) { + errors.password = "Неверный пароль"; + } + if (values.password !== values.repeatPassword) { + errors.repeatPassword = "Пароли не совпадают"; + } + + return errors; } + const SignUp = () => { - const navigate = useNavigate(); - const theme = useTheme(); - const { makeRequest } = authStore(); + const navigate = useNavigate(); + const theme = useTheme(); + const { makeRequest } = authStore(); + const { enqueueSnackbar } = useSnackbar(); - return ( - { + formikHelpers.setSubmitting(true); + makeRequest({ + url: "https://admin.pena.digital/auth/register", + body: { + login: values.email, + email: values.email, + password: values.repeatPassword, + phoneNumber: "--", + }, + useToken: false, + }) + .then((e) => { + navigate("/users"); + }) + .catch((e) => { + console.log(e); + enqueueSnackbar( + e.response && e.response.data && e.response.data.message ? e.response.data.message : `Unknown error`, + { variant: "error" } // Устанавливаем вариант уведомления на "error" + ); + }) + .finally(() => { + formikHelpers.setSubmitting(false); + }); + }} + > + {(props) => ( +
+ { - formikHelpers.setSubmitting(true); - makeRequest({ - url: "https://admin.pena.digital/auth/register", - body: { - login: values.email, - email: values.email, - password: values.repeatPassword, - phoneNumber: "--", - }, - useToken: false, - }) - .then((e) => { - navigate("/users"); - }) - .catch((e) => { - console.log(e); - enqueueSnackbar( - e.response && e.response.data && e.response.data.message ? e.response.data.message : `Unknown error` - ); - }).finally(() => { - formikHelpers.setSubmitting(false); - }); - }} - > - {props => - - - *": { - marginTop: "15px", - }, - }} - > - - Новый аккаунт - - + > + *": { + marginTop: "15px", + }, + }} + > + + Новый аккаунт + + - - - Добро пожаловать - - - Мы рады что вы выбрали нас! - - - *": { marginRight: "10px" } }}> - - - - *": { marginRight: "10px" } }}> - - - - *": { marginRight: "10px" } }}> - - - - - - У меня уже есть аккаунт - - - - - } -
- ); + + + Добро пожаловать + + + Мы рады что вы выбрали нас! + + + *": { marginRight: "10px" } }}> + + + {props.touched.email && props.errors.email} + + } + /> + + *": { marginRight: "10px" } }}> + + + {props.touched.password && props.errors.password} + + } + /> + + *": { marginRight: "10px" } }}> + + + {props.touched.repeatPassword && props.errors.repeatPassword} + + } + /> + + + + У меня уже есть аккаунт + +
+ + + )} + + ); }; -export default SignUp; \ No newline at end of file +export default SignUp; diff --git a/src/pages/Setting/ListPrivilegie.tsx b/src/pages/Setting/ListPrivilegie.tsx index 067a3b7..9132ed3 100644 --- a/src/pages/Setting/ListPrivilegie.tsx +++ b/src/pages/Setting/ListPrivilegie.tsx @@ -1,16 +1,33 @@ -import { Typography } from "@mui/material"; -import { СardPrivilegie } from "./CardPrivilegie"; +import { useEffect } from "react"; + import { usePrivilegeStore } from "@root/stores/privilegesStore"; +import { requestPrivilegies } from "@root/services/privilegies.service"; + +import { СardPrivilegie } from "./CardPrivilegie"; export default function ListPrivilegie() { - const privileges = usePrivilegeStore().privileges; + const privileges = usePrivilegeStore((state) => state.privileges); + useEffect(() => { + requestPrivilegies(); + }, []); return ( <> - {privileges.map(({ name, type, price, description, value, privilegeId, serviceKey, id, amount }) => ( + {privileges.map( + ({ + name, + type, + price, + description, + value, + privilegeId, + serviceKey, + id, + amount, + }) => ( <СardPrivilegie - key={id} + key={privilegeId} name={name} type={type} amount={1} @@ -20,8 +37,8 @@ export default function ListPrivilegie() { serviceKey={serviceKey} description={description} /> - )) - } + ) + )} ); } diff --git a/src/pages/dashboard/Content/DiscountManagement/ControlPanel.tsx b/src/pages/dashboard/Content/DiscountManagement/ControlPanel.tsx index 40edca4..69fc5e7 100644 --- a/src/pages/dashboard/Content/DiscountManagement/ControlPanel.tsx +++ b/src/pages/dashboard/Content/DiscountManagement/ControlPanel.tsx @@ -1,47 +1,51 @@ -import { Box, Button, IconButton, useTheme } from "@mui/material"; -import { DataGrid, GridColDef, GridRowsProp, GridToolbar } from "@mui/x-data-grid"; -import { formatDiscountFactor } from "@root/kitUI/Cart/calc"; -import { openEditDiscountDialog, setDiscounts, setSelectedDiscountIds, updateDiscount, useDiscountStore } from "@root/stores/discounts"; +import { enqueueSnackbar } from "notistack"; +import { GridSelectionModel } from "@mui/x-data-grid"; +import { Box, Button } from "@mui/material"; + import { changeDiscount } from "@root/api/discounts"; import { findDiscountsById } from "@root/stores/discounts"; -import { GridSelectionModel, GridRowId } from "@mui/x-data-grid"; -import { enqueueSnackbar } from "notistack"; +import { requestDiscounts } from "@root/services/discounts.service"; interface Props { - selectedRows: GridSelectionModel + selectedRows: GridSelectionModel; } -export default function DiscountDataGrid({selectedRows}:Props) { +export default function DiscountDataGrid({ selectedRows }: Props) { + const changeData = async (isActive: boolean) => { + let done = 0; + let fatal = 0; -const changeData = (isActive:boolean) => { - let done = 0 - let fatal = 0 - selectedRows.forEach((id:GridRowId) => { - const discount = findDiscountsById(String(id)) - if (discount) { - discount.Deprecated = isActive - changeDiscount(String(id), discount) - .then(() => { - done += 1 - }) - .catch(() => { - fatal += 1 - }) - .finally(() => { - if (done) enqueueSnackbar("Успешно изменён статус " + done + " скидок") - if (fatal) enqueueSnackbar(fatal + " скидок не изменили статус") - }) - } else { - enqueueSnackbar("Скидка не найдена") - } - }) - -} + for (const id of selectedRows) { + const discount = findDiscountsById(String(id)); - return ( - - - - - ); + if (!discount) { + return enqueueSnackbar("Скидка не найдена"); + } + + try { + await changeDiscount(String(id), { ...discount, Deprecated: isActive }); + + done += 1; + } catch { + fatal += 1; + } + } + + await requestDiscounts(); + + if (done) { + enqueueSnackbar("Успешно изменён статус " + done + " скидок"); + } + + if (fatal) { + enqueueSnackbar(fatal + " скидок не изменили статус"); + } + }; + + return ( + + + + + ); } diff --git a/src/pages/dashboard/Content/DiscountManagement/DiscountDataGrid.tsx b/src/pages/dashboard/Content/DiscountManagement/DiscountDataGrid.tsx index 4442b89..5c63ce0 100644 --- a/src/pages/dashboard/Content/DiscountManagement/DiscountDataGrid.tsx +++ b/src/pages/dashboard/Content/DiscountManagement/DiscountDataGrid.tsx @@ -17,7 +17,7 @@ import DeleteIcon from "@mui/icons-material/Delete"; import EditIcon from "@mui/icons-material/Edit"; import { deleteDiscount } from "@root/api/discounts"; import { GridSelectionModel } from "@mui/x-data-grid"; -import { useDiscounts } from "@root/hooks/useDiscounts.hook"; +import { requestDiscounts } from "@root/services/discounts.service"; import AutorenewIcon from "@mui/icons-material/Autorenew"; const columns: GridColDef[] = [ @@ -119,14 +119,13 @@ export default function DiscountDataGrid({ selectedRowsHC }: Props) { ); const realDiscounts = useDiscountStore((state) => state.discounts); const editDiscountId = useDiscountStore((state) => state.editDiscountId); - const { requestDiscounts } = useDiscounts(); useEffect(() => { requestDiscounts(); }, []); const rowBackDicounts: GridRowsProp = realDiscounts - .filter((e) => e.Layer > 0) + .filter(({ Layer }) => Layer > 0) .map((discount) => { console.log( discount.Condition[ diff --git a/src/pages/dashboard/Content/ServiceUsersDG.tsx b/src/pages/dashboard/Content/ServiceUsersDG.tsx index be71bc2..c851255 100644 --- a/src/pages/dashboard/Content/ServiceUsersDG.tsx +++ b/src/pages/dashboard/Content/ServiceUsersDG.tsx @@ -1,9 +1,10 @@ import { GridColDef, GridSelectionModel, GridToolbar } from "@mui/x-data-grid"; import { Skeleton } from "@mui/material"; +import { useNavigate } from "react-router-dom"; import DataGrid from "@kitUI/datagrid"; -import type { UsersType } from "@root/api/roles"; +import type { UserType } from "@root/api/roles"; const columns: GridColDef[] = [ { field: "login", headerName: "Логин", width: 100 }, @@ -15,14 +16,17 @@ const columns: GridColDef[] = [ interface Props { handleSelectionChange: (selectionModel: GridSelectionModel) => void; - users: any + users: UserType[]; } -export default function ServiceUsersDG({ handleSelectionChange, users }: Props) { - if (!users) { - return Loading...; - } - const gridData = users.users.map((user:any) => ({ +export default function ServiceUsersDG({ + handleSelectionChange, + users = [], +}: Props) { + const navigate = useNavigate(); + + const gridData = users.map((user) => ({ + id: user._id, login: user.login, email: user.email, phoneNumber: user.phoneNumber, @@ -31,14 +35,21 @@ export default function ServiceUsersDG({ handleSelectionChange, users }: Props) })); return ( - users.login} - checkboxSelection={true} - rows={gridData} - columns={columns} - components={{ Toolbar: GridToolbar }} - onSelectionModelChange={handleSelectionChange} - /> + <> + {users.length ? ( + users.login} + checkboxSelection={true} + rows={gridData} + columns={columns} + components={{ Toolbar: GridToolbar }} + onSelectionModelChange={handleSelectionChange} + onRowClick={({ row }) => navigate(row.id)} + /> + ) : ( + Loading... + )} + ); } diff --git a/src/pages/dashboard/Content/Tariffs/CreateTariff.tsx b/src/pages/dashboard/Content/Tariffs/CreateTariff.tsx index 858f6a0..e30fb15 100644 --- a/src/pages/dashboard/Content/Tariffs/CreateTariff.tsx +++ b/src/pages/dashboard/Content/Tariffs/CreateTariff.tsx @@ -1,31 +1,15 @@ import { useState } from "react"; -import { - Typography, - Container, - Button, - Select, - MenuItem, - FormControl, - InputLabel, - useTheme, - Box, -} from "@mui/material"; +import { Typography, Container, Button, Select, MenuItem, FormControl, InputLabel, useTheme, Box } from "@mui/material"; import { enqueueSnackbar } from "notistack"; import { CustomTextField } from "@root/kitUI/CustomTextField"; +import { requestTariffs } from "@root/services/tariffs.service"; import { authStore } from "@root/stores/auth"; -import { - findPrivilegeById, - usePrivilegeStore, -} from "@root/stores/privilegesStore"; +import { findPrivilegeById, usePrivilegeStore } from "@root/stores/privilegesStore"; import type { Privilege_BACKEND } from "@root/model/tariff"; -type CreateTariffProps = { - requestTariffs: () => Promise; -}; - type CreateTariffBackendRequest = { name: string; price: number; @@ -33,12 +17,9 @@ type CreateTariffBackendRequest = { privilegies: Omit[]; }; -const baseUrl = - process.env.NODE_ENV === "production" - ? "/strator" - : "https://admin.pena.digital/strator"; +const baseUrl = process.env.NODE_ENV === "production" ? "/strator" : "https://admin.pena.digital/strator"; -export default function CreateTariff({ requestTariffs }: CreateTariffProps) { +export default function CreateTariff() { const { makeRequest } = authStore(); const theme = useTheme(); @@ -173,7 +154,11 @@ export default function CreateTariff({ requestTariffs }: CreateTariffProps) { inputProps={{ sx: { pt: "12px" } }} > {privileges.map((privilege) => ( - + {privilege.description} ))} @@ -221,6 +206,8 @@ export default function CreateTariff({ requestTariffs }: CreateTariffProps) { type="number" /> @@ -153,9 +144,8 @@ export default function TariffsDG({ closeDeleteModal(); }} selectedTariffs={selectedTariffs} - requestTariffs={requestTariffs} /> - + ); } diff --git a/src/pages/dashboard/Content/Users.tsx b/src/pages/dashboard/Content/Users.tsx index 3aba3a1..bfef0c0 100644 --- a/src/pages/dashboard/Content/Users.tsx +++ b/src/pages/dashboard/Content/Users.tsx @@ -30,7 +30,12 @@ import { getRoles_mock, TMockData } from "../../../api/roles"; import theme from "../../../theme"; -import type { UsersType } from "../../../api/roles"; +import type { UserType } from "../../../api/roles"; + +type RegisteredUsersResponse = { + tatalPages: number; + users: UserType[]; +}; const baseUrl = process.env.NODE_ENV === "production" ? "" : "https://admin.pena.digital"; @@ -85,8 +90,8 @@ const Users: React.FC = () => { handleChangeData(); const [roles, setRoles] = React.useState([]); - const [users, setUsers] = React.useState(); - const [manager, setManager] = React.useState(); + const [users, setUsers] = React.useState([]); + const [manager, setManager] = React.useState([]); useEffect(() => { async function axiosRoles() { @@ -103,12 +108,12 @@ const Users: React.FC = () => { } async function gettingRegisteredUsers() { try { - const usersResponse = await makeRequest({ + const { users } = await makeRequest({ method: "get", url: baseUrl + "/user/", }); - setUsers(usersResponse); + setUsers(users); } catch (error) { console.error("Ошибка при получении пользователей!"); } @@ -116,12 +121,12 @@ const Users: React.FC = () => { async function gettingListManagers() { try { - const managersResponse = await makeRequest({ + const { users } = await makeRequest({ method: "get", url: baseUrl + "/user/", }); - setManager(managersResponse); + setManager(users); } catch (error) { console.error("Ошибка при получении менеджеров!"); } diff --git a/src/pages/dashboard/ModalUser/PurchaseTab.tsx b/src/pages/dashboard/ModalUser/PurchaseTab.tsx new file mode 100644 index 0000000..dbc87cf --- /dev/null +++ b/src/pages/dashboard/ModalUser/PurchaseTab.tsx @@ -0,0 +1,241 @@ +import { useEffect, useRef, useState } from "react"; +import { Box, useTheme, useMediaQuery } from "@mui/material"; +import { DataGrid } from "@mui/x-data-grid"; + +import { scrollBlock } from "@root/utils/scrollBlock"; + +import forwardIcon from "@root/assets/icons/forward.svg"; + +import type { ChangeEvent } from "react"; +import type { GridColDef } from "@mui/x-data-grid"; + +const COLUMNS: GridColDef[] = [ + { + field: "date", + headerName: "Дата", + minWidth: 130, + maxWidth: 200, + flex: 1, + sortable: false, + }, + { + field: "time", + headerName: "Время", + minWidth: 90, + maxWidth: 180, + flex: 1, + sortable: false, + }, + { + field: "product", + headerName: "Товар", + minWidth: 200, + maxWidth: 280, + flex: 1, + sortable: false, + }, + { + field: "amount", + headerName: "Кол-во", + minWidth: 70, + maxWidth: 70, + flex: 1, + sortable: false, + }, +]; + +const ROWS = [ + { + id: "row_1", + date: "19.02.2023", + time: "17:01", + product: "Шаблонизатор", + amount: "1 шт.", + }, + { + id: "row_2", + date: "28.02.2023", + time: "10:43", + product: "Шаблонизатор", + amount: "1 шт.", + }, + { + id: "row_3", + date: "04.03.2023", + time: "21:09", + product: "Сокращатель ссылок", + amount: "2 шт.", + }, +]; + +export const PurchaseTab = () => { + const [canScrollToRight, setCanScrollToRight] = useState(true); + const [canScrollToLeft, setCanScrollToLeft] = useState(false); + const theme = useTheme(); + const smallScreen = useMediaQuery(theme.breakpoints.down(830)); + const gridContainer = useRef(null); + + useEffect(() => { + const handleScroll = (nativeEvent: unknown) => { + const { target } = nativeEvent as ChangeEvent; + + if (target.scrollLeft > 0) { + setCanScrollToLeft(true); + } else { + setCanScrollToLeft(false); + } + + if (target.clientWidth + target.scrollLeft >= target.scrollWidth - 1) { + setCanScrollToRight(false); + } else { + setCanScrollToRight(true); + } + }; + + const addScrollEvent = () => { + const grid = gridContainer.current?.querySelector( + ".MuiDataGrid-virtualScroller" + ); + + if (grid) { + grid.addEventListener("scroll", handleScroll); + + return; + } + + setTimeout(addScrollEvent, 100); + }; + + addScrollEvent(); + + return () => { + const grid = gridContainer.current?.querySelector( + ".MuiDataGrid-virtualScroller" + ); + + grid?.removeEventListener("scroll", handleScroll); + }; + }, []); + + const scrollDataGrid = (toStart = false) => { + const grid = gridContainer.current?.querySelector( + ".MuiDataGrid-virtualScroller" + ); + + if (grid) { + scrollBlock(grid, { left: toStart ? 0 : grid.scrollWidth }); + } + }; + + return ( + + + {smallScreen && ( + + {canScrollToLeft && ( + scrollDataGrid(true)} + > + forward + + )} + {canScrollToRight && ( + scrollDataGrid(false)} + > + forward + + )} + + )} + + ); +}; diff --git a/src/pages/dashboard/ModalUser/TransactionsTab.tsx b/src/pages/dashboard/ModalUser/TransactionsTab.tsx new file mode 100644 index 0000000..75283d7 --- /dev/null +++ b/src/pages/dashboard/ModalUser/TransactionsTab.tsx @@ -0,0 +1,252 @@ +import { useEffect, useRef, useState } from "react"; +import { Typography, Box, useTheme, useMediaQuery } from "@mui/material"; +import { DataGrid } from "@mui/x-data-grid"; + +import { scrollBlock } from "@root/utils/scrollBlock"; + +import forwardIcon from "@root/assets/icons/forward.svg"; + +import type { ChangeEvent } from "react"; +import type { GridColDef } from "@mui/x-data-grid"; + +const COLUMNS: GridColDef[] = [ + { + field: "date", + headerName: "Дата", + width: 130, + sortable: false, + }, + { + field: "time", + headerName: "Время", + width: 90, + sortable: false, + }, + { + field: "amount", + headerName: "Сумма", + width: 140, + sortable: false, + }, + { + field: "email", + headerName: "Email", + width: 280, + sortable: false, + }, + { + field: "status", + headerName: "Статус", + width: 100, + sortable: false, + renderCell: ({ value }) => ( + + {value ? "accepted" : "timeout"} + + ), + }, +]; + +const ROWS = [ + { + id: "row_1", + date: "19.02.2023", + time: "17:01", + amount: "2 065 руб.", + email: "emailexample@gmail.com", + status: true, + }, + { + id: "row_2", + date: "28.02.2023", + time: "10:43", + amount: "21 250 руб.", + email: "verylongemailexample@gmail.com", + status: true, + }, + { + id: "row_3", + date: "04.03.2023", + time: "21:09", + amount: "108 065 руб.", + email: "emailexample@gmail.com", + status: false, + }, +]; + +export const TransactionsTab = () => { + const [canScrollToRight, setCanScrollToRight] = useState(true); + const [canScrollToLeft, setCanScrollToLeft] = useState(false); + const theme = useTheme(); + const smallScreen = useMediaQuery(theme.breakpoints.down(1070)); + const gridContainer = useRef(null); + + useEffect(() => { + const handleScroll = (nativeEvent: unknown) => { + const { target } = nativeEvent as ChangeEvent; + + if (target.scrollLeft > 0) { + setCanScrollToLeft(true); + } else { + setCanScrollToLeft(false); + } + + if (target.clientWidth + target.scrollLeft >= target.scrollWidth - 1) { + setCanScrollToRight(false); + } else { + setCanScrollToRight(true); + } + }; + + const addScrollEvent = () => { + const grid = gridContainer.current?.querySelector( + ".MuiDataGrid-virtualScroller" + ); + + if (grid) { + grid.addEventListener("scroll", handleScroll); + + return; + } + + setTimeout(addScrollEvent, 100); + }; + + addScrollEvent(); + + return () => { + const grid = gridContainer.current?.querySelector( + ".MuiDataGrid-virtualScroller" + ); + + grid?.removeEventListener("scroll", handleScroll); + }; + }, []); + + const scrollDataGrid = (toStart = false) => { + const grid = gridContainer.current?.querySelector( + ".MuiDataGrid-virtualScroller" + ); + + if (grid) { + scrollBlock(grid, { left: toStart ? 0 : grid.scrollWidth }); + } + }; + + return ( + + + {smallScreen && ( + + {canScrollToLeft && ( + scrollDataGrid(true)} + > + forward + + )} + {canScrollToRight && ( + scrollDataGrid(false)} + > + forward + + )} + + )} + + ); +}; diff --git a/src/pages/dashboard/ModalUser/UserTab.tsx b/src/pages/dashboard/ModalUser/UserTab.tsx new file mode 100644 index 0000000..391f2c0 --- /dev/null +++ b/src/pages/dashboard/ModalUser/UserTab.tsx @@ -0,0 +1,66 @@ +import { Box, Typography, useTheme, useMediaQuery } from "@mui/material"; + +export const UserTab = () => { + const theme = useTheme(); + const mobile = useMediaQuery(theme.breakpoints.down(700)); + + return ( + + + + ID + + {" "} + 2810 + + + + Дата регистрации + + 17.02.2023 + + + + Email + + emailexamle@gmail.com + + + + Телефон + + +7 123 456 78 90 + + + + Тип: + + НКО + + + + + + ФИО: + + Куликов Геннадий Викторович + + + + + Внутренний кошелек + + + 2 096 руб. + + + + + ); +}; diff --git a/src/pages/dashboard/ModalUser/VerificationTab.tsx b/src/pages/dashboard/ModalUser/VerificationTab.tsx new file mode 100644 index 0000000..42aede1 --- /dev/null +++ b/src/pages/dashboard/ModalUser/VerificationTab.tsx @@ -0,0 +1,155 @@ +import { useState, useEffect } from "react"; +import { useParams } from "react-router-dom"; +import { Box, Typography, TextField, Button } from "@mui/material"; + +import { authStore } from "@root/stores/auth"; + +import type { ChangeEvent } from "react"; + +type File = { + name: "inn" | "rule" | "egrule" | "certificate"; + url: string; +}; + +type Verification = { + _id: string; + accepted: boolean; + status: "org" | "nko"; + updated_at: string; + comment: string; + files: File[]; +}; + +type PatchVerificationBody = { + id: string; + status: "org" | "nko"; + comment: string; + accepted: boolean; +}; + +const baseUrl = + process.env.NODE_ENV === "production" ? "" : "https://hub.pena.digital"; + +export const VerificationTab = () => { + const [user, setUser] = useState(null); + const [comment, setComment] = useState(""); + const { userId } = useParams(); + const { makeRequest } = authStore(); + + const requestVefification = async () => + makeRequest({ + method: "get", + url: baseUrl + `/verification/verification/${userId}`, + }).then((verification) => { + setUser(verification); + setComment(verification.comment); + }); + + useEffect(() => { + requestVefification(); + }, []); + + const verify = async (accepted: boolean) => { + if (!user) { + return; + } + + try { + await makeRequest({ + method: "patch", + useToken: true, + url: baseUrl + `/verification/verification`, + body: { + accepted, + comment, + id: user._id, + status: user.status, + }, + }); + + await requestVefification(); + } catch {} + }; + + return ( + + + {user?.accepted ? "Верификация пройдена" : "Не верифицирован"} + + {user?.files?.map(({ name, url }, index) => ( + + + {index + 1}.{" "} + {name === "inn" + ? "Скан ИНН организации (выписка из ЕГЮРЛ)" + : name === "rule" + ? "Устав организации" + : name === "certificate" + ? "Свидетельство о регистрации НКО" + : `Скан документа ${index + 1}`} + + + + {url.split("/").pop()?.split(".")?.[0]} + + + + ))} + {user?.comment && ( + + + Комментарий: + + {user.comment} + + )} + ) => + setComment(event.target.value) + } + /> + + + + + + ); +}; diff --git a/src/pages/dashboard/ModalUser/index.tsx b/src/pages/dashboard/ModalUser/index.tsx index eba80ff..8e4effb 100644 --- a/src/pages/dashboard/ModalUser/index.tsx +++ b/src/pages/dashboard/ModalUser/index.tsx @@ -1,183 +1,190 @@ -import * as React from "react"; -import { useLinkClickHandler } from "react-router-dom"; -import { Box, Modal, Fade, Backdrop, Typography } from "@mui/material"; -import Tabs from "@mui/material/Tabs"; -import Tab from "@mui/material/Tab"; -import { DataGrid, GridColDef } from '@mui/x-data-grid'; -import theme from "../../../theme"; +import { useState } from "react"; +import { useLinkClickHandler } from "react-router-dom"; +import { + Box, + Modal, + Fade, + Backdrop, + Typography, + Tabs, + Tab, + useTheme, + useMediaQuery, +} from "@mui/material"; +import { UserTab } from "./UserTab"; +import { PurchaseTab } from "./PurchaseTab"; +import { TransactionsTab } from "./TransactionsTab"; +import { VerificationTab } from "./VerificationTab"; -export interface MWProps { - open: boolean -} +import { ReactComponent as UserIcon } from "@root/assets/icons/user.svg"; +import { ReactComponent as PackageIcon } from "@root/assets/icons/package.svg"; +import { ReactComponent as TransactionsIcon } from "@root/assets/icons/transactions.svg"; +import { ReactComponent as CheckIcon } from "@root/assets/icons/check.svg"; -const columns: GridColDef[] = [ - { - field: 'id', - headerName: 'ID', - width: 30, - sortable: false, +import forwardIcon from "@root/assets/icons/forward.svg"; + +import type { SyntheticEvent } from "react"; + +const TABS = [ + { name: "Пользователь", icon: UserIcon, activeStyles: { fill: "#7E2AEA" } }, + { + name: "Покупка товаров и услуг", + icon: PackageIcon, + activeStyles: { stroke: "#7E2AEA" }, }, { - field: 'dateTime', - headerName: 'Дата / время', - width: 150, - sortable: false, - }, - { - field: 'email', - headerName: 'Почта', - width: 110, - sortable: false, - },{ - field: 'summa', - headerName: 'Сумма', - type: 'number', - width: 110, - sortable: false, - }, - { - field: 'idLong', - headerName: 'ID long', - type: 'number', - width: 110, - sortable: false, - }, - { - field: 'paymentStatus', - headerName: 'Статус платежа', - width: 160, - sortable: false, + name: "Транзакции", + icon: TransactionsIcon, + activeStyles: { stroke: "#7E2AEA" }, }, + { name: "Верификация", icon: CheckIcon, activeStyles: { stroke: "#7E2AEA" } }, ]; -const rows = [ - { id: 1, dateTime: '22.09.22 12:15', email: 'asd@mail.ru', summa: 100500, idLong: 123, paymentStatus: "В обработке" }, - { id: 1, dateTime: '22.09.22 12:15', email: 'asd@mail.ru', summa: 100500, idLong: 123, paymentStatus: "В обработке" }, - { id: 1, dateTime: '22.09.22 12:15', email: 'asd@mail.ru', summa: 100500, idLong: 123, paymentStatus: "В обработке" }, - { id: 1, dateTime: '22.09.22 12:15', email: 'asd@mail.ru', summa: 100500, idLong: 123, paymentStatus: "В обработке" }, - { id: 1, dateTime: '22.09.22 12:15', email: 'asd@mail.ru', summa: 100500, idLong: 123, paymentStatus: "В обработке" }, -]; +const ModalUser = () => { + const [value, setValue] = useState(0); + const [openNavigation, setOpenNavigation] = useState(false); + const theme = useTheme(); + const tablet = useMediaQuery(theme.breakpoints.down(1070)); + const mobile = useMediaQuery(theme.breakpoints.down(700)); -const ModalUser = ({open}: MWProps ) => { - const [value, setValue] = React.useState(0); - - const handleChange = (event: React.SyntheticEvent, newValue: number) => { - setValue(newValue); - }; - return ( - + <> - - - + + + Пользователь сервиса - - - + - - - - - { value == 0 && ( - - Id: 1 - Email: 2 - Номер телефона: 3 - - ) } - - { value == 1 && ( - - setOpenNavigation((isOpened) => !isOpened)} /> - - ) } + )} + + setValue(newValue) + } + aria-label="Vertical tabs example" + sx={{ + padding: mobile ? "16px" : "10px", + width: "100%", + }} + TabIndicatorProps={{ style: { background: "transparent" } }} + > + {TABS.map(({ name, icon: Icon, activeStyles }) => ( + } + iconPosition="start" + key={name} + label={mobile ? (openNavigation ? name : "") : name} + sx={{ + justifyContent: "flex-start", + textTransform: "inherit", + minHeight: "auto", + minWidth: "auto", + fontSize: "15px", + padding: mobile ? "9px" : "15px", + marginBottom: mobile ? "15px" : "5px", + color: theme.palette.common.black, + whiteSpace: "nowrap", + lineHeight: "18px", + transition: ".2s", + "&.MuiButtonBase-root.Mui-selected": { + borderRadius: "12px", + color: "#7E2AEA", + background: "rgba(126, 42, 234, 0.07)", + "& svg": activeStyles, + }, + }} + /> + ))} + + + + {value === 0 && } + {value === 1 && } + {value === 2 && } + {value === 3 && } + - + ); -} - +}; export default ModalUser; diff --git a/src/pages/dashboard/index.tsx b/src/pages/dashboard/index.tsx index bcfc4a3..ad783a2 100644 --- a/src/pages/dashboard/index.tsx +++ b/src/pages/dashboard/index.tsx @@ -59,7 +59,6 @@ export default () => { - ); diff --git a/src/services/discounts.service.ts b/src/services/discounts.service.ts new file mode 100644 index 0000000..ed2d609 --- /dev/null +++ b/src/services/discounts.service.ts @@ -0,0 +1,32 @@ +import { setDiscounts } from "@root/stores/discounts"; +import { authStore } from "@root/stores/auth"; + +import type { GetDiscountResponse, Discount } from "@root/model/discount"; + +const baseUrl = + process.env.NODE_ENV === "production" + ? "/price" + : "https://admin.pena.digital/price"; + +const { makeRequest } = authStore.getState(); + +const filterDiscounts = (discounts: Discount[]) => { + const activeDiscounts = discounts.filter((discount) => !discount.Deprecated); + + setDiscounts(activeDiscounts); +}; + +export const requestDiscounts = async (): Promise => { + try { + const { Discounts } = await makeRequest({ + url: baseUrl + "/discounts", + method: "get", + useToken: true, + bearer: true, + }); + + filterDiscounts(Discounts); + } catch { + throw new Error("Ошибка при получении скидок"); + } +}; diff --git a/src/services/privilegies.service.ts b/src/services/privilegies.service.ts new file mode 100644 index 0000000..63eedd2 --- /dev/null +++ b/src/services/privilegies.service.ts @@ -0,0 +1,63 @@ +import { authStore } from "@root/stores/auth"; + +import { resetPrivilegeArray } from "@root/stores/privilegesStore"; +import { exampleCartValues } from "@stores/mocks/exampleCartValues"; + +import type { RealPrivilege } from "@root/model/privilege"; + +export type Privilege = { + createdAt: string; + description: string; + isDeleted: boolean; + name: string; + price: number; + privilegeId: string; + serviceKey: string; + type: "count" | "day" | "mb"; + updatedAt: string; + value: string; + _id: string; +}; + +type SeverPrivilegiesResponse = { + templategen: RealPrivilege[]; +}; + +const baseUrl = + process.env.NODE_ENV === "production" + ? "/strator" + : "https://admin.pena.digital/strator"; + +const { makeRequest } = authStore.getState(); + +const mutatePrivilegies = (privilegies: RealPrivilege[]) => { + let extracted: RealPrivilege[] = []; + for (let serviceKey in privilegies) { + //Приходит объект. В его значениях массивы привилегий для разных сервисов. Высыпаем в общую кучу и обновляем стор + extracted = extracted.concat(privilegies[serviceKey]); + } + + let readyArray = extracted.map((privilege) => ({ + serviceKey: privilege.serviceKey, + privilegeId: privilege.privilegeId, + name: privilege.name, + description: privilege.description, + type: privilege.type, + price: privilege.price, + value: privilege.value, + id: privilege._id, + })); + + resetPrivilegeArray([...readyArray, ...exampleCartValues.privileges]); +}; + +export const requestPrivilegies = async () => { + await makeRequest({ + url: baseUrl + "/privilege/service", + method: "get", + }) + .then(({ templategen }) => mutatePrivilegies(templategen)) + .catch(() => { + console.log("Ошибка при получении привилегий"); + }); +}; diff --git a/src/services/tariffs.service.ts b/src/services/tariffs.service.ts new file mode 100644 index 0000000..d91f0cd --- /dev/null +++ b/src/services/tariffs.service.ts @@ -0,0 +1,62 @@ +import { resetTariffsStore } from "@root/stores/tariffsStore"; +import { authStore } from "@root/stores/auth"; + +import type { Tariff, Tariff_BACKEND } from "@root/model/tariff"; + +type GetTariffsResponse = { + totalPages: number; + tariffs: Tariff_BACKEND[]; +}; + +const baseUrl = + process.env.NODE_ENV === "production" + ? "/strator" + : "https://admin.pena.digital/strator"; + +const { makeRequest } = authStore.getState(); + +const mutateTariffs = (tariffs: Tariff_BACKEND[]) => { + const convertedTariffs: Record = {}; + + tariffs + .filter(({ isDeleted }) => !isDeleted) + .forEach((tariff) => { + convertedTariffs[tariff._id] = { + id: tariff._id, + name: tariff.name, + isCustom: tariff.price ? true : false, + amount: tariff.privilegies[0].amount, + isFront: false, + privilegeId: tariff.privilegies[0].privilegeId, + price: tariff.privilegies[0].price, + isDeleted: tariff.isDeleted, + customPricePerUnit: tariff.price, + }; + }); + + resetTariffsStore(convertedTariffs); +}; + +export const requestTariffs = async ( + page: number = 1, + existingTariffs: Tariff_BACKEND[] = [] +): Promise => { + try { + const { tariffs, totalPages } = await makeRequest< + never, + GetTariffsResponse + >({ + url: baseUrl + `/tariff/?page=${page}&limit=${100}`, + method: "get", + bearer: true, + }); + + if (page < totalPages) { + return requestTariffs(page + 1, [...existingTariffs, ...tariffs]); + } + + mutateTariffs([...existingTariffs, ...tariffs]); + } catch { + throw new Error("Ошибка при получении тарифов"); + } +}; diff --git a/src/stores/discounts.ts b/src/stores/discounts.ts index cf52de8..97b775f 100644 --- a/src/stores/discounts.ts +++ b/src/stores/discounts.ts @@ -1,8 +1,6 @@ import { GridSelectionModel } from "@mui/x-data-grid"; -import { AnyDiscount } from "@root/model/cart"; import { create } from "zustand"; import { devtools } from "zustand/middleware"; -import { exampleCartValues } from "./mocks/exampleCartValues"; import { Discount } from "@root/model/discount"; import { produce } from "immer"; @@ -49,58 +47,3 @@ export const setSelectedDiscountIds = (selectedDiscountIds: DiscountStore["selec export const openEditDiscountDialog = (editDiscountId: DiscountStore["editDiscountId"]) => useDiscountStore.setState({ editDiscountId }); export const closeEditDiscountDialog = () => useDiscountStore.setState({ editDiscountId: null }); - -/** @deprecated */ -interface MockDiscountStore { - discounts: AnyDiscount[]; - selectedDiscountIds: GridSelectionModel, -} - -/** @deprecated */ -export const useMockDiscountStore = create()( - devtools( - (set, get) => ({ - discounts: exampleCartValues.discounts, - selectedDiscountIds: [], - }), - { - name: "Discount store" - } - ) -); - -/** @deprecated */ -export const addMockDiscounts = (newDiscounts: AnyDiscount[]) => useMockDiscountStore.setState(state => ({ discounts: [...state.discounts, ...newDiscounts] })); - -/** @deprecated */ -export const setMockSelectedDiscountIds = (selectedDiscountIds: MockDiscountStore["selectedDiscountIds"]) => useMockDiscountStore.setState({ selectedDiscountIds }); - -/** @deprecated */ -export const activateMockDiscounts = () => useMockDiscountStore.setState(state => { - const discounts: AnyDiscount[] = []; - state.discounts.forEach(discount => { - if (!state.selectedDiscountIds.includes(discount._id)) return discounts.push(discount); - - discounts.push({ - ...discount, - disabled: false, - }); - }); - - return { discounts }; -}); - -/** @deprecated */ -export const deactivateMockDiscounts = () => useMockDiscountStore.setState(state => { - const discounts: AnyDiscount[] = []; - state.discounts.forEach(discount => { - if (!state.selectedDiscountIds.includes(discount._id)) return discounts.push(discount); - - discounts.push({ - ...discount, - disabled: true, - }); - }); - - return { discounts }; -}); diff --git a/src/stores/mocks/exampleCartValues.ts b/src/stores/mocks/exampleCartValues.ts index dcd7298..6aae34b 100644 --- a/src/stores/mocks/exampleCartValues.ts +++ b/src/stores/mocks/exampleCartValues.ts @@ -1,7 +1,8 @@ -import { AnyDiscount } from "@root/model/cart"; -import { Privilege } from "@root/model/tariff"; +// @ts-nocheck import { User } from "../../model/user"; + +/** @deprecated */ export type TestCase = { input: { UserInformation: User; @@ -17,12 +18,14 @@ export type TestCase = { }; }; +/** @deprecated */ type ExampleCartValues = { privileges: Privilege[]; discounts: AnyDiscount[]; testCases: TestCase[]; }; +/** @deprecated */ export const exampleCartValues: ExampleCartValues = { privileges: [ { diff --git a/src/theme.ts b/src/theme.ts index 10c4292..f4f56ca 100644 --- a/src/theme.ts +++ b/src/theme.ts @@ -1,4 +1,3 @@ -import { Theme } from "@mui/material/styles"; import { createTheme, PaletteColorOptions, ThemeOptions } from "@mui/material"; import { deepmerge } from "@mui/utils"; //import { createTheme } from "./types"; @@ -19,6 +18,14 @@ declare module "@mui/material/styles" { primary: { main: string; }; + common: { + black: string; + white: string; + }; + background: { + default: string; + paper: string; + }; secondary: { main: string; }; diff --git a/src/utils/scrollBlock.ts b/src/utils/scrollBlock.ts new file mode 100644 index 0000000..2fd6b86 --- /dev/null +++ b/src/utils/scrollBlock.ts @@ -0,0 +1,10 @@ +type Coordinates = { + top?: number; + left?: number; +}; + +export const scrollBlock = ( + block: Element, + coordinates: Coordinates, + smooth = true +) => block.scroll({ ...coordinates, behavior: smooth ? "smooth" : "auto" }); diff --git a/tsconfig.json b/tsconfig.json index 8680d72..64018cf 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,11 +2,7 @@ "extends": "./tsconfig.extend.json", "compilerOptions": { "target": "es5", - "lib": [ - "dom", - "dom.iterable", - "esnext" - ], + "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, "esModuleInterop": true, @@ -19,9 +15,10 @@ "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, - "jsx": "react-jsx" + "jsx": "react-jsx", + "types": ["node"], }, - "include": [ - "src" - ] + "include": ["src", "**/*.ts"] } + + diff --git a/yarn.lock b/yarn.lock index b6a4387..a442af0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1081,6 +1081,11 @@ resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@colors/colors@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" + integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== + "@craco/craco@^5.5.0": version "5.9.0" resolved "https://registry.npmjs.org/@craco/craco/-/craco-5.9.0.tgz" @@ -1201,6 +1206,38 @@ resolved "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.1.1.tgz" integrity sha512-jwx+WCqszn53YHOfvFMJJRd/B2GqkCBt+1MJSG6o5/s8+ytHMvDZXsJgUEWLk12UnLd7HYKac4BYU5i/Ron1Cw== +"@cypress/request@^2.88.11": + version "2.88.11" + resolved "https://registry.yarnpkg.com/@cypress/request/-/request-2.88.11.tgz#5a4c7399bc2d7e7ed56e92ce5acb620c8b187047" + integrity sha512-M83/wfQ1EkspjkE2lNWNV5ui2Cv7UCv1swW1DqljahbzLVWltcsexQh8jYtuS/vzFXP+HySntGM83ZXA9fn17w== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + http-signature "~1.3.6" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + performance-now "^2.1.0" + qs "~6.10.3" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^8.3.2" + +"@cypress/xvfb@^1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@cypress/xvfb/-/xvfb-1.2.4.tgz#2daf42e8275b39f4aa53c14214e557bd14e7748a" + integrity sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q== + dependencies: + debug "^3.1.0" + lodash.once "^4.1.1" + "@date-io/core@1.x": version "1.3.13" resolved "https://registry.npmjs.org/@date-io/core/-/core-1.3.13.tgz" @@ -1396,6 +1433,18 @@ lodash.isundefined "^3.0.1" lodash.uniq "^4.5.0" +"@hapi/hoek@^9.0.0": + version "9.3.0" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" + integrity sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ== + +"@hapi/topo@^5.0.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.1.0.tgz#dc448e332c6c6e37a4dc02fd84ba8d44b9afb012" + integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg== + dependencies: + "@hapi/hoek" "^9.0.0" + "@humanwhocodes/config-array@^0.11.8": version "0.11.8" resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz" @@ -2007,6 +2056,23 @@ resolved "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz" integrity sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg== +"@sideway/address@^4.1.3": + version "4.1.4" + resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0" + integrity sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw== + dependencies: + "@hapi/hoek" "^9.0.0" + +"@sideway/formula@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.1.tgz#80fcbcbaf7ce031e0ef2dd29b1bfc7c3f583611f" + integrity sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg== + +"@sideway/pinpoint@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" + integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== + "@sinclair/typebox@^0.24.1": version "0.24.51" resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz" @@ -2406,6 +2472,11 @@ resolved "https://registry.npmjs.org/@types/node/-/node-14.18.36.tgz" integrity sha512-FXKWbsJ6a1hIrRxv+FoukuHnGTgEzKYGi7kilfMae96AL9UNkPFNWJEEYWzdRI9ooIkbr4AKldyuSTLql06vLQ== +"@types/node@^14.14.31": + version "14.18.53" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.53.tgz#42855629b8773535ab868238718745bf56c56219" + integrity sha512-soGmOpVBUq+gaBMwom1M+krC/NNbWlosh4AtGA03SyWNDiqSKtwp7OulO1M6+mg8YkHMvJ/y0AkCeO8d1hNb7A== + "@types/parse-json@^4.0.0": version "4.0.0" resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz" @@ -2520,6 +2591,16 @@ "@types/mime" "*" "@types/node" "*" +"@types/sinonjs__fake-timers@8.1.1": + version "8.1.1" + resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz#b49c2c70150141a15e0fa7e79cf1f92a72934ce3" + integrity sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g== + +"@types/sizzle@^2.3.2": + version "2.3.3" + resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.3.tgz#ff5e2f1902969d305225a047c8a0fd5c915cebef" + integrity sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ== + "@types/sockjs@^0.3.33": version "0.3.33" resolved "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz" @@ -2615,6 +2696,13 @@ dependencies: "@types/yargs-parser" "*" +"@types/yauzl@^2.9.1": + version "2.10.0" + resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.0.tgz#b3248295276cf8c6f153ebe6a9aba0c988cb2599" + integrity sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw== + dependencies: + "@types/node" "*" + "@typescript-eslint/eslint-plugin@^5.5.0": version "5.53.0" resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.53.0.tgz" @@ -3062,6 +3150,14 @@ agent-base@6: dependencies: debug "4" +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + ajv-errors@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz" @@ -3113,7 +3209,12 @@ ansi-colors@^1.0.1: dependencies: ansi-wrap "^0.1.0" -ansi-escapes@^4.2.1, ansi-escapes@^4.3.1: +ansi-colors@^4.1.1: + version "4.1.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" + integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== + +ansi-escapes@^4.2.1, ansi-escapes@^4.3.0, ansi-escapes@^4.3.1: version "4.3.2" resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== @@ -3180,6 +3281,11 @@ aproba@^1.1.1: resolved "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== +arch@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" + integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== + archiver-utils@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz" @@ -3336,6 +3442,18 @@ asn1.js@^5.2.0: minimalistic-assert "^1.0.0" safer-buffer "^2.1.0" +asn1@~0.2.3: + version "0.2.6" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== + assert@^1.1.1: version "1.5.0" resolved "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz" @@ -3354,12 +3472,17 @@ ast-types-flow@^0.0.7: resolved "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz" integrity sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag== +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + async-each@^1.0.1: version "1.0.6" resolved "https://registry.npmjs.org/async-each/-/async-each-1.0.6.tgz" integrity sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg== -async@^3.2.3: +async@^3.2.0, async@^3.2.3: version "3.2.4" resolved "https://registry.npmjs.org/async/-/async-3.2.4.tgz" integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== @@ -3396,11 +3519,29 @@ available-typed-arrays@^1.0.5: resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== + +aws4@^1.8.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3" + integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg== + axe-core@^4.6.2: version "4.6.3" resolved "https://registry.npmjs.org/axe-core/-/axe-core-4.6.3.tgz" integrity sha512-/BQzOX780JhsxDnPpH4ZiyrJAzcd8AfzFPkv+89veFSr1rcMjuq2JDCwypKaPeB6ljHp9KjXhPpjgCvQlWYuqg== +axios@^0.27.2: + version "0.27.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" + integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== + dependencies: + follow-redirects "^1.14.9" + form-data "^4.0.0" + axios@^1.3.4: version "1.3.4" resolved "https://registry.npmjs.org/axios/-/axios-1.3.4.tgz" @@ -3597,6 +3738,13 @@ batch@0.6.1: resolved "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz" integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== + dependencies: + tweetnacl "^0.14.3" + bfj@^7.0.2: version "7.0.2" resolved "https://registry.npmjs.org/bfj/-/bfj-7.0.2.tgz" @@ -3651,7 +3799,12 @@ bl@^4.0.3: inherits "^2.0.4" readable-stream "^3.4.0" -bluebird@^3.5.5: +blob-util@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/blob-util/-/blob-util-2.0.2.tgz#3b4e3c281111bb7f11128518006cdc60b403a1eb" + integrity sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ== + +bluebird@3.7.2, bluebird@^3.5.5, bluebird@^3.7.2: version "3.7.2" resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== @@ -3830,7 +3983,7 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" -buffer-crc32@^0.2.1, buffer-crc32@^0.2.13: +buffer-crc32@^0.2.1, buffer-crc32@^0.2.13, buffer-crc32@~0.2.3: version "0.2.13" resolved "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz" integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== @@ -3859,7 +4012,7 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" -buffer@^5.5.0: +buffer@^5.5.0, buffer@^5.6.0: version "5.7.1" resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== @@ -3928,6 +4081,11 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" +cachedir@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8" + integrity sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw== + call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" @@ -3989,6 +4147,11 @@ case-sensitive-paths-webpack-plugin@^2.4.0: resolved "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz" integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw== +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== + chainsaw@~0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz" @@ -4038,6 +4201,11 @@ char-regex@^2.0.0: resolved "https://registry.npmjs.org/char-regex/-/char-regex-2.0.1.tgz" integrity sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw== +check-more-types@2.24.0, check-more-types@^2.24.0: + version "2.24.0" + resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600" + integrity sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA== + check-types@^11.1.1: version "11.2.2" resolved "https://registry.npmjs.org/check-types/-/check-types-11.2.2.tgz" @@ -4122,6 +4290,35 @@ clean-css@^5.2.2: dependencies: source-map "~0.6.0" +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-table3@~0.6.1: + version "0.6.3" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.3.tgz#61ab765aac156b52f222954ffc607a6f01dbeeb2" + integrity sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg== + dependencies: + string-width "^4.2.0" + optionalDependencies: + "@colors/colors" "1.5.0" + +cli-truncate@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" + integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== + dependencies: + slice-ansi "^3.0.0" + string-width "^4.2.0" + cliui@^7.0.2: version "7.0.4" resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" @@ -4221,7 +4418,12 @@ colorette@^2.0.10: resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz" integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== -combined-stream@^1.0.8: +colorette@^2.0.16: + version "2.0.20" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== + +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -4233,6 +4435,11 @@ commander@^2.20.0: resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== +commander@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + commander@^7.2.0: version "7.2.0" resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz" @@ -4394,6 +4601,11 @@ core-js@^3.19.2: resolved "https://registry.npmjs.org/core-js/-/core-js-3.28.0.tgz" integrity sha512-GiZn9D4Z/rSYvTeg1ljAIsEqFm0LaN9gVtwDCrKL80zHtS31p9BAjmTxVqTQDMpwlMolJZOFntUG2uwyj7DAqw== +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== + core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz" @@ -4734,11 +4946,66 @@ cyclist@^1.0.1: resolved "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz" integrity sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A== +cypress@^12.17.2: + version "12.17.2" + resolved "https://registry.yarnpkg.com/cypress/-/cypress-12.17.2.tgz#040ac55de1e811f6e037d231a2869d5ab8c29c85" + integrity sha512-hxWAaWbqQBzzMuadSGSuQg5PDvIGOovm6xm0hIfpCVcORsCAj/gF2p0EvfnJ4f+jK2PCiDgP6D2eeE9/FK4Mjg== + dependencies: + "@cypress/request" "^2.88.11" + "@cypress/xvfb" "^1.2.4" + "@types/node" "^14.14.31" + "@types/sinonjs__fake-timers" "8.1.1" + "@types/sizzle" "^2.3.2" + arch "^2.2.0" + blob-util "^2.0.2" + bluebird "^3.7.2" + buffer "^5.6.0" + cachedir "^2.3.0" + chalk "^4.1.0" + check-more-types "^2.24.0" + cli-cursor "^3.1.0" + cli-table3 "~0.6.1" + commander "^6.2.1" + common-tags "^1.8.0" + dayjs "^1.10.4" + debug "^4.3.4" + enquirer "^2.3.6" + eventemitter2 "6.4.7" + execa "4.1.0" + executable "^4.1.1" + extract-zip "2.0.1" + figures "^3.2.0" + fs-extra "^9.1.0" + getos "^3.2.1" + is-ci "^3.0.0" + is-installed-globally "~0.4.0" + lazy-ass "^1.6.0" + listr2 "^3.8.3" + lodash "^4.17.21" + log-symbols "^4.0.0" + minimist "^1.2.8" + ospath "^1.2.2" + pretty-bytes "^5.6.0" + proxy-from-env "1.0.0" + request-progress "^3.0.0" + semver "^7.5.3" + supports-color "^8.1.1" + tmp "~0.2.1" + untildify "^4.0.0" + yauzl "^2.10.0" + damerau-levenshtein@^1.0.8: version "1.0.8" resolved "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz" integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== + dependencies: + assert-plus "^1.0.0" + data-urls@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz" @@ -4748,6 +5015,11 @@ data-urls@^2.0.0: whatwg-mimetype "^2.3.0" whatwg-url "^8.0.0" +dayjs@^1.10.4: + version "1.11.9" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.9.tgz#9ca491933fadd0a60a2c19f6c237c03517d71d1a" + integrity sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA== + dayjs@^1.11.5, dayjs@^1.8.34: version "1.11.7" resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz" @@ -4760,14 +5032,14 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0: dependencies: ms "2.0.0" -debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: +debug@4, debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" -debug@^3.2.7: +debug@^3.1.0, debug@^3.2.7: version "3.2.7" resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== @@ -5099,7 +5371,7 @@ duplexer2@~0.1.4: dependencies: readable-stream "^2.0.2" -duplexer@^0.1.2: +duplexer@^0.1.2, duplexer@~0.1.1: version "0.1.2" resolved "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== @@ -5114,6 +5386,14 @@ duplexify@^3.4.2, duplexify@^3.6.0: readable-stream "^2.0.0" stream-shift "^1.0.0" +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" @@ -5205,6 +5485,13 @@ enhanced-resolve@^5.10.0: graceful-fs "^4.2.4" tapable "^2.2.0" +enquirer@^2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" + entities@^2.0.0: version "2.2.0" resolved "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz" @@ -5639,6 +5926,24 @@ etag@~1.8.1: resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== +event-stream@=3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" + integrity sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g== + dependencies: + duplexer "~0.1.1" + from "~0" + map-stream "~0.1.0" + pause-stream "0.0.11" + split "0.3" + stream-combiner "~0.0.4" + through "~2.3.1" + +eventemitter2@6.4.7: + version "6.4.7" + resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.7.tgz#a7f6c4d7abf28a14c1ef3442f21cb306a054271d" + integrity sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg== + eventemitter3@^4.0.0: version "4.0.7" resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" @@ -5672,7 +5977,22 @@ exceljs@^4.3.0: unzipper "^0.10.11" uuid "^8.3.0" -execa@^5.0.0: +execa@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" + integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + +execa@5.1.1, execa@^5.0.0: version "5.1.1" resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== @@ -5687,6 +6007,13 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" +executable@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c" + integrity sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg== + dependencies: + pify "^2.2.0" + exit@^0.1.2: version "0.1.2" resolved "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz" @@ -5778,6 +6105,11 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + extglob@^2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz" @@ -5792,6 +6124,27 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" +extract-zip@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a" + integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg== + dependencies: + debug "^4.1.1" + get-stream "^5.1.0" + yauzl "^2.10.0" + optionalDependencies: + "@types/yauzl" "^2.9.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== + +extsprintf@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== + fast-csv@^4.3.1: version "4.3.6" resolved "https://registry.npmjs.org/fast-csv/-/fast-csv-4.3.6.tgz" @@ -5860,11 +6213,25 @@ fbjs@^0.8.9: setimmediate "^1.0.5" ua-parser-js "^0.7.30" +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g== + dependencies: + pend "~1.2.0" + figgy-pudding@^3.5.1: version "3.5.2" resolved "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz" integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== +figures@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== + dependencies: + escape-string-regexp "^1.0.5" + file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" @@ -5994,7 +6361,7 @@ flush-write-stream@^1.0.0: inherits "^2.0.3" readable-stream "^2.3.6" -follow-redirects@^1.0.0, follow-redirects@^1.15.0: +follow-redirects@^1.0.0, follow-redirects@^1.14.9, follow-redirects@^1.15.0: version "1.15.2" resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz" integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== @@ -6011,6 +6378,11 @@ for-in@^1.0.2: resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz" integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== + fork-ts-checker-webpack-plugin@^6.5.0: version "6.5.2" resolved "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.2.tgz" @@ -6048,6 +6420,15 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + formik@^2.2.9: version "2.2.9" resolved "https://registry.npmjs.org/formik/-/formik-2.2.9.tgz" @@ -6091,6 +6472,11 @@ from2@^2.1.0: inherits "^2.0.1" readable-stream "^2.0.0" +from@~0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" + integrity sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g== + fs-constants@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz" @@ -6105,7 +6491,7 @@ fs-extra@^10.0.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@^9.0.0, fs-extra@^9.0.1: +fs-extra@^9.0.0, fs-extra@^9.0.1, fs-extra@^9.1.0: version "9.1.0" resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== @@ -6207,6 +6593,13 @@ get-package-type@^0.1.0: resolved "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== +get-stream@^5.0.0, get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + get-stream@^6.0.0: version "6.0.1" resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" @@ -6225,6 +6618,20 @@ get-value@^2.0.3, get-value@^2.0.6: resolved "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz" integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== +getos@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/getos/-/getos-3.2.1.tgz#0134d1f4e00eb46144c5a9c0ac4dc087cbb27dc5" + integrity sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q== + dependencies: + async "^3.2.0" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== + dependencies: + assert-plus "^1.0.0" + glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz" @@ -6264,6 +6671,13 @@ glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" +global-dirs@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.1.tgz#0c488971f066baceda21447aecb1a8b911d22485" + integrity sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA== + dependencies: + ini "2.0.0" + global-modules@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz" @@ -6602,6 +7016,15 @@ http-proxy@^1.18.1: follow-redirects "^1.0.0" requires-port "^1.0.0" +http-signature@~1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.3.6.tgz#cb6fbfdf86d1c974f343be94e87f7fc128662cf9" + integrity sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw== + dependencies: + assert-plus "^1.0.0" + jsprim "^2.0.2" + sshpk "^1.14.1" + https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz" @@ -6615,6 +7038,11 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== + human-signals@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" @@ -6735,6 +7163,11 @@ inherits@2.0.3: resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== +ini@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" + integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== + ini@^1.3.5: version "1.3.8" resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" @@ -6834,6 +7267,13 @@ is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== +is-ci@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" + integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ== + dependencies: + ci-info "^3.2.0" + is-core-module@^2.11.0, is-core-module@^2.9.0: version "2.11.0" resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz" @@ -6926,6 +7366,14 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-installed-globally@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" + integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== + dependencies: + global-dirs "^3.0.0" + is-path-inside "^3.0.2" + is-map@^2.0.1, is-map@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz" @@ -6965,7 +7413,7 @@ is-obj@^1.0.1: resolved "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz" integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg== -is-path-inside@^3.0.3: +is-path-inside@^3.0.2, is-path-inside@^3.0.3: version "3.0.3" resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== @@ -7052,11 +7500,16 @@ is-typed-array@^1.1.10, is-typed-array@^1.1.9: gopd "^1.0.1" has-tostringtag "^1.0.0" -is-typedarray@^1.0.0: +is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + is-weakmap@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz" @@ -7129,6 +7582,11 @@ isomorphic-fetch@^2.1.1: node-fetch "^1.0.1" whatwg-fetch ">=0.10.0" +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== + istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: version "3.2.0" resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz" @@ -7715,6 +8173,17 @@ jest@^27.4.3: import-local "^3.0.2" jest-cli "^27.5.1" +joi@^17.7.0: + version "17.9.2" + resolved "https://registry.yarnpkg.com/joi/-/joi-17.9.2.tgz#8b2e4724188369f55451aebd1d0b1d9482470690" + integrity sha512-Itk/r+V4Dx0V3c7RLFdRh12IOjySm2/WGPMubBT92cQvRfYZhPM2W0hZlctjj72iES8jsRCwp7S/cRmWBnJ4nw== + dependencies: + "@hapi/hoek" "^9.0.0" + "@hapi/topo" "^5.0.0" + "@sideway/address" "^4.1.3" + "@sideway/formula" "^3.0.1" + "@sideway/pinpoint" "^2.0.0" + js-sdsl@^4.1.4: version "4.3.0" resolved "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz" @@ -7740,6 +8209,11 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== + jsdom@^16.6.0: version "16.7.0" resolved "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz" @@ -7803,7 +8277,7 @@ json-schema-traverse@^1.0.0: resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== -json-schema@^0.4.0: +json-schema@0.4.0, json-schema@^0.4.0: version "0.4.0" resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz" integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== @@ -7813,6 +8287,11 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== + json5@^1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz" @@ -7839,6 +8318,16 @@ jsonpointer@^5.0.0: resolved "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz" integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== +jsprim@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-2.0.2.tgz#77ca23dbcd4135cd364800d22ff82c2185803d4d" + integrity sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ== + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.4.0" + verror "1.10.0" + "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.3: version "3.3.3" resolved "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz" @@ -7903,6 +8392,11 @@ language-tags@=1.0.5: dependencies: language-subtag-registry "~0.3.2" +lazy-ass@1.6.0, lazy-ass@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513" + integrity sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw== + lazystream@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz" @@ -7953,6 +8447,20 @@ listenercount@~1.0.1: resolved "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz" integrity sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ== +listr2@^3.8.3: + version "3.14.0" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.14.0.tgz#23101cc62e1375fd5836b248276d1d2b51fdbe9e" + integrity sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g== + dependencies: + cli-truncate "^2.1.0" + colorette "^2.0.16" + log-update "^4.0.0" + p-map "^4.0.0" + rfdc "^1.3.0" + rxjs "^7.5.1" + through "^2.3.8" + wrap-ansi "^7.0.0" + loader-runner@^2.4.0: version "2.4.0" resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz" @@ -8083,6 +8591,11 @@ lodash.merge@^4.6.2: resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash.once@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== + lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz" @@ -8103,6 +8616,24 @@ lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7. resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +log-symbols@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +log-update@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" + integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== + dependencies: + ansi-escapes "^4.3.0" + cli-cursor "^3.1.0" + slice-ansi "^4.0.0" + wrap-ansi "^6.2.0" + loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" @@ -8175,6 +8706,11 @@ map-cache@^0.2.2: resolved "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz" integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== +map-stream@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" + integrity sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g== + map-visit@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz" @@ -8289,7 +8825,7 @@ mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: +mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -8342,7 +8878,7 @@ minimatch@^5.0.1, minimatch@^5.1.0: dependencies: brace-expansion "^2.0.1" -minimist@^1.2.0, minimist@^1.2.6: +minimist@^1.2.0, minimist@^1.2.6, minimist@^1.2.7, minimist@^1.2.8: version "1.2.8" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== @@ -8560,7 +9096,7 @@ notistack@^3.0.1: clsx "^1.1.0" goober "^2.0.33" -npm-run-path@^4.0.1: +npm-run-path@^4.0.0, npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== @@ -8726,7 +9262,7 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" -onetime@^5.1.2: +onetime@^5.1.0, onetime@^5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== @@ -8771,6 +9307,11 @@ os-browserify@^0.3.0: resolved "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz" integrity sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A== +ospath@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/ospath/-/ospath-1.2.2.tgz#1276639774a3f8ef2572f7fe4280e0ea4550c07b" + integrity sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA== + p-limit@^2.0.0, p-limit@^2.2.0: version "2.3.0" resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" @@ -8806,6 +9347,13 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + p-retry@^4.5.0: version "4.6.2" resolved "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz" @@ -8945,6 +9493,13 @@ path@^0.12.7: process "^0.11.1" util "^0.10.3" +pause-stream@0.0.11: + version "0.0.11" + resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" + integrity sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A== + dependencies: + through "~2.3" + pbkdf2@^3.0.3: version "3.1.2" resolved "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz" @@ -8956,6 +9511,11 @@ pbkdf2@^3.0.3: safe-buffer "^5.0.1" sha.js "^2.4.8" +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== + performance-now@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz" @@ -8976,7 +9536,7 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3, picomatc resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -pify@^2.3.0: +pify@^2.2.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== @@ -9589,7 +10149,7 @@ prelude-ls@~1.1.2: resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz" integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== -pretty-bytes@^5.3.0, pretty-bytes@^5.4.1: +pretty-bytes@^5.3.0, pretty-bytes@^5.4.1, pretty-bytes@^5.6.0: version "5.6.0" resolved "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz" integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== @@ -9684,6 +10244,11 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" +proxy-from-env@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee" + integrity sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A== + proxy-from-env@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz" @@ -9694,7 +10259,14 @@ prr@~1.0.1: resolved "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz" integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== -psl@^1.1.33: +ps-tree@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.2.0.tgz#5e7425b89508736cdd4f2224d028f7bb3f722ebd" + integrity sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA== + dependencies: + event-stream "=3.3.4" + +psl@^1.1.28, psl@^1.1.33: version "1.9.0" resolved "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz" integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== @@ -9763,6 +10335,13 @@ qs@6.11.0: dependencies: side-channel "^1.0.4" +qs@~6.10.3: + version "6.10.5" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.5.tgz#974715920a80ff6a262264acd2c7e6c2a53282b4" + integrity sha512-O5RlPh0VFtR78y79rgcgKK4wbAI0C5zGVLztOIdpWX6ep368q5Hv6XRxDvXuZ9q3C6v+e3n8UfZZJw7IIG27eQ== + dependencies: + side-channel "^1.0.4" + querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz" @@ -10209,6 +10788,13 @@ replace-ext@^1.0.0: resolved "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz" integrity sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw== +request-progress@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-3.0.0.tgz#4ca754081c7fec63f505e4faa825aa06cd669dbe" + integrity sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg== + dependencies: + throttleit "^1.0.0" + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" @@ -10285,6 +10871,14 @@ resolve@^2.0.0-next.4: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + ret@~0.1.10: version "0.1.15" resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz" @@ -10300,6 +10894,11 @@ reusify@^1.0.4: resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== +rfdc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + rifm@^0.12.1: version "0.12.1" resolved "https://registry.npmjs.org/rifm/-/rifm-0.12.1.tgz" @@ -10380,6 +10979,13 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" +rxjs@^7.5.1, rxjs@^7.8.0: + version "7.8.1" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== + dependencies: + tslib "^2.1.0" + safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" @@ -10406,7 +11012,7 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.1.0: +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -10518,6 +11124,13 @@ semver@^7.3.2, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8: dependencies: lru-cache "^6.0.0" +semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + send@0.18.0: version "0.18.0" resolved "https://registry.npmjs.org/send/-/send-0.18.0.tgz" @@ -10658,6 +11271,24 @@ slash@^4.0.0: resolved "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz" integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== +slice-ansi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" + integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz" @@ -10797,11 +11428,33 @@ split-string@^3.0.1, split-string@^3.0.2: dependencies: extend-shallow "^3.0.0" +split@0.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" + integrity sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA== + dependencies: + through "2" + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== +sshpk@^1.14.1: + version "1.17.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" + integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + ssri@^6.0.1: version "6.0.2" resolved "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz" @@ -10826,6 +11479,20 @@ stackframe@^1.3.4: resolved "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz" integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw== +start-server-and-test@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/start-server-and-test/-/start-server-and-test-2.0.0.tgz#0644809d63036a8a001efb70582f3e37ebfdd33d" + integrity sha512-UqKLw0mJbfrsG1jcRLTUlvuRi9sjNuUiDOLI42r7R5fA9dsFoywAy9DoLXNYys9B886E4RCKb+qM1Gzu96h7DQ== + dependencies: + arg "^5.0.2" + bluebird "3.7.2" + check-more-types "2.24.0" + debug "4.3.4" + execa "5.1.1" + lazy-ass "1.6.0" + ps-tree "1.2.0" + wait-on "7.0.1" + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz" @@ -10859,6 +11526,13 @@ stream-browserify@^2.0.1: inherits "~2.0.1" readable-stream "^2.0.2" +stream-combiner@~0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" + integrity sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw== + dependencies: + duplexer "~0.1.1" + stream-each@^1.1.0: version "1.2.3" resolved "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz" @@ -11062,7 +11736,7 @@ supports-color@^7.0.0, supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -supports-color@^8.0.0: +supports-color@^8.0.0, supports-color@^8.1.1: version "8.1.1" resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== @@ -11261,6 +11935,11 @@ throat@^6.0.1: resolved "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz" integrity sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ== +throttleit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c" + integrity sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g== + through2@^2.0.0: version "2.0.5" resolved "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz" @@ -11269,6 +11948,11 @@ through2@^2.0.0: readable-stream "~2.3.6" xtend "~4.0.1" +through@2, through@^2.3.8, through@~2.3, through@~2.3.1: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + thunky@^1.0.2: version "1.1.0" resolved "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz" @@ -11286,7 +11970,7 @@ tiny-warning@^1.0.2: resolved "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== -tmp@^0.2.0: +tmp@^0.2.0, tmp@~0.2.1: version "0.2.1" resolved "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz" integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== @@ -11355,6 +12039,14 @@ tough-cookie@^4.0.0: universalify "^0.2.0" url-parse "^1.5.3" +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + tr46@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz" @@ -11399,6 +12091,11 @@ tslib@^2.0.3: resolved "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz" integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== +tslib@^2.1.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3" + integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA== + tsutils@^3.21.0: version "3.21.0" resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" @@ -11411,6 +12108,18 @@ tty-browserify@0.0.0: resolved "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz" integrity sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw== +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" @@ -11576,6 +12285,11 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" +untildify@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" + integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== + unzipper@^0.10.11: version "0.10.11" resolved "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz" @@ -11708,6 +12422,15 @@ vary@~1.1.2: resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + vinyl-sourcemaps-apply@^0.2.1: version "0.2.1" resolved "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz" @@ -11746,6 +12469,17 @@ w3c-xmlserializer@^2.0.0: dependencies: xml-name-validator "^3.0.0" +wait-on@7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-7.0.1.tgz#5cff9f8427e94f4deacbc2762e6b0a489b19eae9" + integrity sha512-9AnJE9qTjRQOlTZIldAaf/da2eW0eSRSgcqq85mXQja/DW3MriHxkpODDSUEg+Gri/rKEcXUZHe+cevvYItaog== + dependencies: + axios "^0.27.2" + joi "^17.7.0" + lodash "^4.17.21" + minimist "^1.2.7" + rxjs "^7.8.0" + walker@^1.0.7: version "1.0.8" resolved "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz" @@ -12224,6 +12958,15 @@ worker-farm@^1.7.0: dependencies: errno "~0.1.7" +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" @@ -12316,6 +13059,14 @@ yargs@^16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" +yauzl@^2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g== + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" + yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz"