diff --git a/.github/workflows/test-mobile-e2e.yml b/.github/workflows/test-mobile-e2e.yml index 7cb8c795c652..257c47d70e5d 100644 --- a/.github/workflows/test-mobile-e2e.yml +++ b/.github/workflows/test-mobile-e2e.yml @@ -65,10 +65,14 @@ jobs: key: ${{ runner.os }}-pods-${{ hashFiles('apps/ledger-live-mobile/ios/Podfile.lock') }} - name: install dependencies run: | - pnpm i --filter="live-mobile..." --filter="ledger-live" --no-frozen-lockfile --unsafe-perm + pnpm i --filter="live-mobile..." --filter="ledger-live" --filter="dummy-*" --no-frozen-lockfile --unsafe-perm - name: Build dependencies run: | pnpm build:llm:deps + - name: Build Dummy Live SDK and Dummy Wallet API apps for testing + run: | + pnpm test-utils dummy-apps:build + shell: bash - name: Create iOS simulator id: simulator run: | diff --git a/apps/ledger-live-desktop/package.json b/apps/ledger-live-desktop/package.json index eaf4899835f8..6f6657627dd7 100644 --- a/apps/ledger-live-desktop/package.json +++ b/apps/ledger-live-desktop/package.json @@ -20,7 +20,6 @@ "build": "cross-env CSC_IDENTITY_AUTO_DISCOVERY=false STAGING=1 node ./tools/dist --nosign -v", "build:js": "cross-env NODE_ENV=production node ./tools/main.js build", "build:testing": "cross-env NODE_ENV=production TESTING=1 node ./tools/main.js build", - "build:dummy-apps": "pnpm --filter='dummy-wallet-app' --filter='dummy-live-app' build", "lint": "eslint src static tools tests --ext .js,.jsx,.json,.ts,.tsx --cache", "lint:fix": "eslint src tools static tests --ext .js,.jsx,.json,.ts,.tsx --fix", "prettier": "prettier --write \"{src,tools,tests}/**/*.{js,jsx,json,ts,tsx}\"", @@ -152,6 +151,7 @@ "@babel/preset-typescript": "^7.15.0", "@electron/notarize": "^2.0.0", "@ledgerhq/react-devtools": "workspace:^", + "@ledgerhq/test-utils": "workspace:^", "@octokit/rest": "^18.12.0", "@playwright/test": "^1.34.3", "@sentry/cli": "^2.13.0", diff --git a/apps/ledger-live-desktop/tests/specs/services/buy.smoke.spec.ts b/apps/ledger-live-desktop/tests/specs/services/buy.smoke.spec.ts index 65fc15db4402..4ed8f71ffec5 100644 --- a/apps/ledger-live-desktop/tests/specs/services/buy.smoke.spec.ts +++ b/apps/ledger-live-desktop/tests/specs/services/buy.smoke.spec.ts @@ -1,6 +1,5 @@ import test from "../../fixtures/common"; import { expect } from "@playwright/test"; -import * as server from "../../utils/serve-dummy-app"; import { Layout } from "../../models/Layout"; import { DiscoverPage } from "../../models/DiscoverPage"; import { PortfolioPage } from "../../models/PortfolioPage"; @@ -9,6 +8,7 @@ import { AccountsPage } from "../../models/AccountsPage"; import { AccountPage } from "../../models/AccountPage"; import { SettingsPage } from "../../models/SettingsPage"; import { MarketPage } from "../../models/MarketPage"; +import { getLiveAppManifest, startDummyServer, stopDummyServer } from "@ledgerhq/test-utils"; test.use({ userdata: "1AccountBTC1AccountETH", @@ -26,14 +26,14 @@ let continueTest = false; test.beforeAll(async ({ request }) => { // Check that dummy app in tests/utils/dummy-ptx-app has been started successfully try { - const port = await server.start("dummy-ptx-app/public"); + const port = await startDummyServer("dummy-ptx-app/public"); const url = `http://localhost:${port}`; const response = await request.get(url); if (response.ok() && port) { continueTest = true; console.info(`========> Dummy test app successfully running on port ${port}! <=========`); process.env.MOCK_REMOTE_LIVE_MANIFEST = JSON.stringify( - server.liveAppManifest({ + getLiveAppManifest({ id: "multibuy", url, name: "Dummy Buy / Sell App", @@ -64,8 +64,8 @@ test.beforeAll(async ({ request }) => { } }); -test.afterAll(() => { - server.stop(); +test.afterAll(async () => { + await stopDummyServer(); console.info(`========> Dummy test app stopped <=========`); delete process.env.MOCK_REMOTE_LIVE_MANIFEST; }); diff --git a/apps/ledger-live-desktop/tests/specs/services/discover.smoke.spec.ts b/apps/ledger-live-desktop/tests/specs/services/discover.smoke.spec.ts index e62833046bd8..a398e1f462bf 100644 --- a/apps/ledger-live-desktop/tests/specs/services/discover.smoke.spec.ts +++ b/apps/ledger-live-desktop/tests/specs/services/discover.smoke.spec.ts @@ -5,7 +5,7 @@ import { Layout } from "../../models/Layout"; import { Drawer } from "../../models/Drawer"; import { Modal } from "../../models/Modal"; import { DeviceAction } from "../../models/DeviceAction"; -import * as server from "../../utils/serve-dummy-app"; +import { startDummyServer, getLiveAppManifest, stopDummyServer } from "@ledgerhq/test-utils"; test.use({ userdata: "1AccountBTC1AccountETH" }); @@ -14,14 +14,14 @@ let continueTest = false; test.beforeAll(async ({ request }) => { // Check that dummy app in tests/utils/dummy-app-build has been started successfully try { - const port = await server.start("dummy-live-app/build"); + const port = await startDummyServer("dummy-live-app/build"); const url = `http://localhost:${port}`; const response = await request.get(url); if (response.ok()) { continueTest = true; console.info(`========> Dummy test app successfully running on port ${port}! <=========`); process.env.MOCK_REMOTE_LIVE_MANIFEST = JSON.stringify( - server.liveAppManifest({ + getLiveAppManifest({ id: "dummy-live-app", url, permissions: [{ method: "*" }], @@ -44,8 +44,8 @@ test.beforeAll(async ({ request }) => { } }); -test.afterAll(() => { - server.stop(); +test.afterAll(async () => { + await stopDummyServer(); console.info(`========> Dummy test app stopped <=========`); delete process.env.MOCK_REMOTE_LIVE_MANIFEST; }); diff --git a/apps/ledger-live-desktop/tests/specs/services/wallet-api.smoke.spec.ts b/apps/ledger-live-desktop/tests/specs/services/wallet-api.smoke.spec.ts index 7871d96b4faa..e9b772b39183 100644 --- a/apps/ledger-live-desktop/tests/specs/services/wallet-api.smoke.spec.ts +++ b/apps/ledger-live-desktop/tests/specs/services/wallet-api.smoke.spec.ts @@ -5,7 +5,7 @@ import { Layout } from "../../models/Layout"; import { Drawer } from "../../models/Drawer"; import { Modal } from "../../models/Modal"; import { DeviceAction } from "../../models/DeviceAction"; -import * as server from "../../utils/serve-dummy-app"; +import { startDummyServer, getLiveAppManifest, stopDummyServer } from "@ledgerhq/test-utils"; import { randomUUID } from "crypto"; test.use({ userdata: "1AccountBTC1AccountETH" }); @@ -15,7 +15,7 @@ let continueTest = false; test.beforeAll(async ({ request }) => { // Check that dummy app in tests/utils/dummy-app-build has been started successfully try { - const port = await server.start("dummy-wallet-app/build"); + const port = await startDummyServer("dummy-wallet-app/build"); const url = `http://localhost:${port}`; const response = await request.get(url); if (response.ok()) { @@ -24,7 +24,7 @@ test.beforeAll(async ({ request }) => { `========> Dummy Wallet API app successfully running on port ${port}! <=========`, ); process.env.MOCK_REMOTE_LIVE_MANIFEST = JSON.stringify( - server.liveAppManifest({ + getLiveAppManifest({ id: "dummy-live-app", url, name: "Dummy Wallet API Live App", @@ -48,8 +48,8 @@ test.beforeAll(async ({ request }) => { } }); -test.afterAll(() => { - server.stop(); +test.afterAll(async () => { + await stopDummyServer(); console.info(`========> Dummy Wallet API app stopped <=========`); delete process.env.MOCK_REMOTE_LIVE_MANIFEST; }); @@ -70,7 +70,7 @@ test("Wallet API methods", async ({ page }) => { await drawer.waitForDrawerToDisappear(); const id = randomUUID(); - const resPromise = discoverPage.send({ + const response = discoverPage.send({ jsonrpc: "2.0", id, method: "account.request", @@ -82,9 +82,7 @@ test("Wallet API methods", async ({ page }) => { await drawer.selectCurrency("bitcoin"); await drawer.selectAccount("bitcoin"); - const res = await resPromise; - - expect(res).toStrictEqual({ + await expect(response).resolves.toMatchObject({ jsonrpc: "2.0", id, result: { @@ -94,7 +92,7 @@ test("Wallet API methods", async ({ page }) => { balance: "35688397", blockHeight: 194870, currency: "bitcoin", - lastSyncDate: "2020-03-14T13:34:42.000Z", + // lastSyncDate: "2020-03-14T13:34:42.000Z", TODO: make sure the sync date doesn't change name: "Bitcoin 1 (legacy)", spendableBalance: "35688397", }, @@ -104,7 +102,7 @@ test("Wallet API methods", async ({ page }) => { await test.step("account.receive", async () => { const id = randomUUID(); - const resPromise = discoverPage.send({ + const response = discoverPage.send({ jsonrpc: "2.0", id, method: "account.receive", @@ -116,9 +114,7 @@ test("Wallet API methods", async ({ page }) => { await deviceAction.openApp(); await modal.waitForModalToDisappear(); - const res = await resPromise; - - expect(res).toStrictEqual({ + await expect(response).resolves.toStrictEqual({ jsonrpc: "2.0", id, result: { diff --git a/apps/ledger-live-desktop/tests/utils/dummy-wallet-app/README.md b/apps/ledger-live-desktop/tests/utils/dummy-wallet-app/README.md deleted file mode 100644 index 438d6b901400..000000000000 --- a/apps/ledger-live-desktop/tests/utils/dummy-wallet-app/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Ledger Live Dummy Wallet App - -The purpose of this app is to allow automated front end testing of Ledger Live Wallet apps, and verify that Ledger Live correctly: - -- handles the rendering of external Live Apps -- handles calls of the Live SDK from external Live apps - -The app is a simple [Create React App](https://github.com/facebook/create-react-app) which uses the [Ledger Live App SDK](https://www.npmjs.com/package/@ledgerhq/live-app-sdk). It has some buttons that have hardcoded responses that can be triggered from the playwright tests, thus allowing us to check the UI. This means the app isn't suitable for manual testing or full E2E testing since it is not dynamic, and does not make calls to external services or the Nano itself. - -## How to run locally for development - -Run `pnpm --filter="dummy-wallet-app" start`. - -## Quick script to build the app from scratch - -To use the Dummy app in the Playwright tests, you must install and build the dependencies and source code for the dummy app. To do this run the following from the root folder of this monorepo: - -`pnpm clean && pnpm --filter="dummy-wallet-app" i && pnpm --filter="dummy-wallet-app" build` - -Then run `pnpm --filter="dummy-wallet-app" serve` diff --git a/apps/ledger-live-desktop/tests/utils/dummy-wallet-app/public/index.html b/apps/ledger-live-desktop/tests/utils/dummy-wallet-app/public/index.html deleted file mode 100644 index fc371124727b..000000000000 --- a/apps/ledger-live-desktop/tests/utils/dummy-wallet-app/public/index.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - Ledger Live App - - - - -
- - - diff --git a/apps/ledger-live-desktop/tests/utils/dummy-wallet-app/src/App.tsx b/apps/ledger-live-desktop/tests/utils/dummy-wallet-app/src/App.tsx deleted file mode 100644 index e54c6b5bdacc..000000000000 --- a/apps/ledger-live-desktop/tests/utils/dummy-wallet-app/src/App.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import React, { useCallback, useEffect, useRef } from "react"; -import { WindowMessageTransport, RpcResponse } from "@ledgerhq/wallet-api-client"; -import "./App.css"; - -type PendingRequests = Record void>; - -function useE2EInjection() { - const queue = useRef({}); - const transport = useRef(new WindowMessageTransport()); - - const send = useCallback(jsonStr => { - const { id } = JSON.parse(jsonStr); - - return new Promise(resolve => { - queue.current[id] = resolve; - transport.current.send(jsonStr); - }); - }, []); - - useEffect(() => { - transport.current.connect(); - transport.current.onMessage = (msgStr: string) => { - const msg = JSON.parse(msgStr); - if (!msg.id) return; - - const resolve = queue.current[msg.id]; - if (!resolve) return; - - resolve(msg); - delete queue.current[msg.id]; - }; - - window.ledger = { - // to avoid overriding other fields - ...window.ledger, - e2e: { - ...window.ledger?.e2e, - walletApi: { - send, - }, - }, - }; - }, [send]); -} - -function getQueryParams(params: URLSearchParams) { - const paramList = []; - - for (const [key, value] of params.entries()) { - paramList.push(
  • {`${key}: ${value}`}
  • ); - } - - return paramList; -} - -const App = () => { - useE2EInjection(); - - const searchParams = new URLSearchParams(window.location.search); - - return ( -
    -
    -
    - logo - dummy -
    -

    Ledger Live Dummy Wallet API App

    -

    App for testing the Ledger Live Wallet API manually and in Automated tests

    -
    - Query Params for web app: -
      {searchParams && getQueryParams(searchParams)}
    -
    -
    -
    - ); -}; - -export default App; diff --git a/apps/ledger-live-mobile/.env.mock b/apps/ledger-live-mobile/.env.mock index eab20879f8cc..cffe417dc17e 100644 --- a/apps/ledger-live-mobile/.env.mock +++ b/apps/ledger-live-mobile/.env.mock @@ -10,4 +10,5 @@ BRAZE_IOS_API_KEY="e0a7dfaf-fc30-48f6-b998-01dbebbb73a4" BRAZE_CUSTOM_ENDPOINT="sdk.fra-02.braze.eu" FEATURE_FLAGS={"syncOnboarding":{"enabled":false},"llmNewDeviceSelection":{"enabled":false},"protectServicesMobile":{"enabled":false},"brazePushNotifications":{"enabled":false}} # Fix random iOS app crash https://github.com/wix/Detox/pull/3135 -SIMCTL_CHILD_NSZombieEnabled=YES \ No newline at end of file +SIMCTL_CHILD_NSZombieEnabled=YES +MOCK_REMOTE_LIVE_MANIFEST=[{"name":"Dummy Wallet API Live App","homepageUrl":"https://developers.ledger.com/","icon":"","platforms":["ios","android","desktop"],"apiVersion":"2.0.0","manifestVersion":"1","branch":"stable","categories":["tools"],"currencies":"*","content":{"shortDescription":{"en":"App to test the Wallet API"},"description":{"en":"App to test the Wallet API with Playwright"}},"permissions":["account.list","account.receive","account.request","currency.list","device.close","device.exchange","device.transport","message.sign","transaction.sign","transaction.signAndBroadcast","storage.set","storage.get","bitcoin.getXPub","wallet.capabilities","wallet.userId","wallet.info"],"domains":["http://*"],"visibility":"complete","id":"dummy-live-app","url":"http://localhost:52619"}] \ No newline at end of file diff --git a/apps/ledger-live-mobile/android/app/src/debug/res/xml/network_security_config.xml b/apps/ledger-live-mobile/android/app/src/debug/res/xml/network_security_config.xml index 2439f15c2cb7..99bee9f07783 100644 --- a/apps/ledger-live-mobile/android/app/src/debug/res/xml/network_security_config.xml +++ b/apps/ledger-live-mobile/android/app/src/debug/res/xml/network_security_config.xml @@ -1,4 +1,8 @@ + + 10.0.2.2 + localhost + diff --git a/apps/ledger-live-mobile/detox.config.js b/apps/ledger-live-mobile/detox.config.js index 2d5a0bc6e114..690abc01fec7 100644 --- a/apps/ledger-live-mobile/detox.config.js +++ b/apps/ledger-live-mobile/detox.config.js @@ -30,28 +30,24 @@ module.exports = { "ios.debug": { type: "ios.app", build: `export ENVFILE=.env.mock && xcodebuild ARCHS=${iosArch} ONLY_ACTIVE_ARCH=no -workspace ios/ledgerlivemobile.xcworkspace -scheme ledgerlivemobile -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build`, - binaryPath: - "ios/build/Build/Products/Debug-iphonesimulator/ledgerlivemobile.app", + binaryPath: "ios/build/Build/Products/Debug-iphonesimulator/ledgerlivemobile.app", }, "ios.staging": { type: "ios.app", build: `export ENVFILE=.env.mock && xcodebuild ARCHS=${iosArch} ONLY_ACTIVE_ARCH=no -workspace ios/ledgerlivemobile.xcworkspace -scheme ledgerlivemobile -configuration Staging -sdk iphonesimulator -derivedDataPath ios/build`, - binaryPath: - "ios/build/Build/Products/Staging-iphonesimulator/ledgerlivemobile.app", + binaryPath: "ios/build/Build/Products/Staging-iphonesimulator/ledgerlivemobile.app", }, "ios.release": { type: "ios.app", build: `export ENVFILE=.env.mock && xcodebuild ARCHS=${iosArch} ONLY_ACTIVE_ARCH=no -workspace ios/ledgerlivemobile.xcworkspace -scheme ledgerlivemobile -configuration Release -sdk iphonesimulator -derivedDataPath ios/build`, - binaryPath: - "ios/build/Build/Products/Release-iphonesimulator/ledgerlivemobile.app", + binaryPath: "ios/build/Build/Products/Release-iphonesimulator/ledgerlivemobile.app", }, "android.debug": { type: "android.apk", build: "cd android && ENVFILE=.env.mock ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && cd ..", binaryPath: `android/app/build/outputs/apk/debug/app-${androidArch}-debug.apk`, - testBinaryPath: - "android/app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk", + testBinaryPath: "android/app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk", }, "android.release": { type: "android.apk", diff --git a/apps/ledger-live-mobile/e2e/bridge/client.ts b/apps/ledger-live-mobile/e2e/bridge/client.ts index 86e216ab4896..a06ebe963237 100644 --- a/apps/ledger-live-mobile/e2e/bridge/client.ts +++ b/apps/ledger-live-mobile/e2e/bridge/client.ts @@ -9,6 +9,15 @@ import { acceptGeneralTermsLastVersion } from "../../src/logic/terms"; import accountModel from "../../src/logic/accountModel"; import { navigate } from "../../src/rootnavigation"; +type ClientData = + | { + type: DescriptorEventType; + payload: { id: string; name: string; serviceUUID: string }; + } + | { type: "open" }; + +export const e2eBridgeClient = new Subject(); + let ws: WebSocket; export function init(port = 8099) { @@ -26,11 +35,8 @@ export function init(port = 8099) { ws.onmessage = onMessage; } -async function onMessage(event: { data: unknown }) { - invariant( - typeof event.data === "string", - "[E2E Bridge Client]: Message data must be string", - ); +function onMessage(event: { data: unknown }) { + invariant(typeof event.data === "string", "[E2E Bridge Client]: Message data must be string"); const msg = JSON.parse(event.data); invariant(msg.type, "[E2E Bridge Client]: type is missing"); @@ -40,7 +46,7 @@ async function onMessage(event: { data: unknown }) { switch (msg.type) { case "add": case "open": - e2eBridgeSubject.next(msg); + e2eBridgeClient.next(msg); break; case "setGlobals": Object.entries(msg.payload).forEach(([k, v]) => { @@ -67,14 +73,14 @@ async function onMessage(event: { data: unknown }) { } } -type SubjectData = - | { - type: DescriptorEventType; - payload: { id: string; name: string; serviceUUID: string }; - } - | { type: "open" }; - -export const e2eBridgeSubject = new Subject(); +export function sendWalletAPIResponse(payload: Record) { + ws.send( + JSON.stringify({ + type: "walletAPIResponse", + payload, + }), + ); +} function log(message: string) { // eslint-disable-next-line no-console diff --git a/apps/ledger-live-mobile/e2e/bridge/server.ts b/apps/ledger-live-mobile/e2e/bridge/server.ts index ea52acb4a917..5136909be7cb 100644 --- a/apps/ledger-live-mobile/e2e/bridge/server.ts +++ b/apps/ledger-live-mobile/e2e/bridge/server.ts @@ -2,6 +2,14 @@ import { Server } from "ws"; import path from "path"; import fs from "fs"; import { NavigatorName } from "../../src/const"; +import { Subject } from "rxjs"; + +type ServerData = { + type: "walletAPIResponse"; + payload: string; +}; + +export const e2eBridgeServer = new Subject(); let wss: Server; @@ -70,10 +78,13 @@ export function open() { } function onMessage(messageStr: string) { - const msg = JSON.parse(messageStr); + const msg: ServerData = JSON.parse(messageStr); log(`Message\n${JSON.stringify(msg, null, 2)}`); switch (msg.type) { + case "walletAPIResponse": + e2eBridgeServer.next(msg); + break; default: break; } diff --git a/apps/ledger-live-mobile/e2e/helpers.ts b/apps/ledger-live-mobile/e2e/helpers.ts index 18123155e171..e9474b02c7db 100644 --- a/apps/ledger-live-mobile/e2e/helpers.ts +++ b/apps/ledger-live-mobile/e2e/helpers.ts @@ -96,6 +96,6 @@ export async function openDeeplink(link?: string) { await device.openURL({ url: BASE_DEEPLINK + link }); } -export async function isAndroid() { +export function isAndroid() { return device.getPlatform() === "android"; } diff --git a/apps/ledger-live-mobile/e2e/models/discovery/discoveryPage.ts b/apps/ledger-live-mobile/e2e/models/discovery/discoveryPage.ts index 5824396cc395..5bb2ed93677a 100644 --- a/apps/ledger-live-mobile/e2e/models/discovery/discoveryPage.ts +++ b/apps/ledger-live-mobile/e2e/models/discovery/discoveryPage.ts @@ -4,7 +4,7 @@ import { expect } from "detox"; const baseLink = "discover/"; export default class DiscoveryPage { - getDicoveryBanner = () => getElementById("discover-banner"); + getDiscoveryBanner = () => getElementById("discover-banner"); waitForSelectCrypto = () => waitForElementByText("Select crypto"); async openViaDeeplink(discoverApps = "") { @@ -12,6 +12,6 @@ export default class DiscoveryPage { } async expectDiscoveryPage() { - await expect(this.getDicoveryBanner()).toBeVisible(); + await expect(this.getDiscoveryBanner()).toBeVisible(); } } diff --git a/apps/ledger-live-mobile/e2e/models/liveApps/cryptoDrawer.ts b/apps/ledger-live-mobile/e2e/models/liveApps/cryptoDrawer.ts new file mode 100644 index 000000000000..e9e78d5e9ec5 --- /dev/null +++ b/apps/ledger-live-mobile/e2e/models/liveApps/cryptoDrawer.ts @@ -0,0 +1,11 @@ +import { tapByText } from "../../helpers"; + +export default class CryptoDrawer { + selectCurrencyFromDrawer(currencyName: string) { + return tapByText(currencyName); + } + + selectAccountFromDrawer(accountName: string) { + return tapByText(accountName); + } +} diff --git a/apps/ledger-live-mobile/e2e/models/liveApps/liveAppWebview.ts b/apps/ledger-live-mobile/e2e/models/liveApps/liveAppWebview.ts new file mode 100644 index 000000000000..28614ffb24ba --- /dev/null +++ b/apps/ledger-live-mobile/e2e/models/liveApps/liveAppWebview.ts @@ -0,0 +1,53 @@ +import { randomUUID } from "crypto"; +import { web, by } from "detox"; +import { e2eBridgeServer } from "../../bridge/server"; +import { first, filter, map } from "rxjs/operators"; +import { startDummyServer } from "@ledgerhq/test-utils"; + +export default class LiveAppWebview { + async startLiveApp(liveAppDirectory: string, liveAppPort = 3000) { + try { + const port = await startDummyServer(`${liveAppDirectory}/build`, liveAppPort); + + const url = `http://localhost:${port}`; + const response = await fetch(url); + if (response.ok) { + // eslint-disable-next-line no-console + console.info( + `========> Dummy Wallet API app successfully running on port ${port}! <=========`, + ); + return true; + } else { + throw new Error("Ping response != 200, got: " + response.status); + } + } catch (error) { + console.warn(`========> Dummy test app not running! <=========`); + console.error(error); + return false; + } + } + + async send(params: Record) { + const webview = web.element(by.web.id("root")); + const id = randomUUID(); + const json = JSON.stringify({ + id, + jsonrpc: "2.0", + ...params, + }); + + await webview.runScript(`function sendWalletAPIRequestFromLiveApp(webviewElement) { + window.ledger.e2e.walletApi.send('${json}'); + }`); + + const response = e2eBridgeServer + .pipe( + filter(msg => msg.type === "walletAPIResponse"), + first(), + map(msg => msg.payload), + ) + .toPromise(); + + return { id, response }; + } +} diff --git a/apps/ledger-live-mobile/e2e/specs/deeplinks.spec.ts b/apps/ledger-live-mobile/e2e/specs/deeplinks.spec.ts index 21aa22b05d6d..c3d1e6b325cb 100644 --- a/apps/ledger-live-mobile/e2e/specs/deeplinks.spec.ts +++ b/apps/ledger-live-mobile/e2e/specs/deeplinks.spec.ts @@ -97,7 +97,7 @@ describe("DeepLinks Tests", () => { }); it("should open Discover page and Mercuryo", async () => { - if (!(await isAndroid())) return; + if (!isAndroid()) return; await discoveryPage.openViaDeeplink(); await discoveryPage.expectDiscoveryPage(); await discoveryPage.openViaDeeplink(mercuryoDL.name); diff --git a/apps/ledger-live-mobile/e2e/specs/wallet-api.spec.ts b/apps/ledger-live-mobile/e2e/specs/wallet-api.spec.ts new file mode 100644 index 000000000000..03488211aa54 --- /dev/null +++ b/apps/ledger-live-mobile/e2e/specs/wallet-api.spec.ts @@ -0,0 +1,84 @@ +import { by, device, web } from "detox"; // this is because we need to use both the jest expect and the detox.expect version, which has some different assertions +import { loadConfig } from "../bridge/server"; +import { isAndroid } from "../helpers"; +import PortfolioPage from "../models/wallet/portfolioPage"; +import DiscoveryPage from "../models/discovery/discoveryPage"; +import LiveAppWebview from "../models/liveApps/liveAppWebview"; +import CryptoDrawer from "../models/liveApps/cryptoDrawer"; +import { stopDummyServer } from "@ledgerhq/test-utils"; + +let portfolioPage: PortfolioPage; +let discoverPage: DiscoveryPage; +let liveAppWebview: LiveAppWebview; +let cryptoDrawer: CryptoDrawer; + +let continueTest: boolean; + +describe("Wallet API methods", () => { + beforeAll(async () => { + portfolioPage = new PortfolioPage(); + discoverPage = new DiscoveryPage(); + liveAppWebview = new LiveAppWebview(); + cryptoDrawer = new CryptoDrawer(); + + await device.reverseTcpPort(52619); // To allow the android emulator to access the dummy app + // Check that dummy app in tests/utils/dummy-app-build has been started successfully + + continueTest = await liveAppWebview.startLiveApp("dummy-wallet-app", 52619); + + if (!continueTest || !isAndroid()) { + console.warn("Stopping Wallet API test setup"); + return; // need to make this a proper ignore/jest warning + } + + loadConfig("1AccountBTC1AccountETHReadOnlyFalse", true); + + // start navigation + await portfolioPage.waitForPortfolioPageToLoad(); + await discoverPage.openViaDeeplink("dummy-live-app"); + + const title = await web.element(by.web.id("image-container")).getTitle(); + expect(title).toBe("Dummy Wallet API App"); + + const url = await web.element(by.web.id("param-container")).getCurrentUrl(); + expect(url).toBe("http://localhost:52619/?theme=light&lang=en&name=Dummy+Wallet+API+Live+App"); + }); + + afterAll(async () => { + await stopDummyServer(); + }); + + it("account.request", async () => { + if (!continueTest || !isAndroid()) { + console.warn("Stopping Wallet API test"); + return; // need to make this a proper ignore/jest warning + } + + const { id, response } = await liveAppWebview.send({ + method: "account.request", + params: { + currencyIds: ["ethereum", "bitcoin"], + }, + }); + + await cryptoDrawer.selectCurrencyFromDrawer("Bitcoin"); + await cryptoDrawer.selectAccountFromDrawer("Bitcoin 1 (legacy)"); + + await expect(response).resolves.toMatchObject({ + jsonrpc: "2.0", + id, + result: { + rawAccount: { + id: "2d23ca2a-069e-579f-b13d-05bc706c7583", + address: "1xeyL26EKAAR3pStd7wEveajk4MQcrYezeJ", + balance: "35688397", + blockHeight: 194870, + currency: "bitcoin", + // lastSyncDate: "2020-03-14T13:34:42.000Z", + name: "Bitcoin 1 (legacy)", + spendableBalance: "35688397", + }, + }, + }); + }); +}); diff --git a/apps/ledger-live-mobile/package.json b/apps/ledger-live-mobile/package.json index d3220338d628..893024406e13 100644 --- a/apps/ledger-live-mobile/package.json +++ b/apps/ledger-live-mobile/package.json @@ -208,6 +208,7 @@ "@babel/preset-react": "^7.13.13", "@babel/runtime": "^7.12.5", "@jest/reporters": "^29.3.1", + "@ledgerhq/test-utils": "workspace:^", "@react-native-community/cli": "^7.0.1", "@react-native-community/cli-platform-android": "^7.0.1", "@react-native-community/cli-platform-ios": "^7.0.1", diff --git a/apps/ledger-live-mobile/src/components/Web3AppWebview/PlatformAPIWebview.tsx b/apps/ledger-live-mobile/src/components/Web3AppWebview/PlatformAPIWebview.tsx index 69a633e13466..c30255d56d88 100644 --- a/apps/ledger-live-mobile/src/components/Web3AppWebview/PlatformAPIWebview.tsx +++ b/apps/ledger-live-mobile/src/components/Web3AppWebview/PlatformAPIWebview.tsx @@ -57,20 +57,15 @@ function renderLoading() { } export const PlatformAPIWebview = forwardRef( ({ manifest, inputs = {}, onStateChange }, ref) => { - const { webviewProps, webviewState, webviewRef } = useWebviewState( + const { webviewProps, webviewRef } = useWebviewState( { manifest, inputs, }, ref, + onStateChange, ); - useEffect(() => { - if (onStateChange) { - onStateChange(webviewState); - } - }, [webviewState, onStateChange]); - const accounts = useSelector(flattenAccountsSelector); const navigation = useNavigation< diff --git a/apps/ledger-live-mobile/src/components/Web3AppWebview/WalletAPIWebview.tsx b/apps/ledger-live-mobile/src/components/Web3AppWebview/WalletAPIWebview.tsx index d3d32d927eaa..ad2f893412a9 100644 --- a/apps/ledger-live-mobile/src/components/Web3AppWebview/WalletAPIWebview.tsx +++ b/apps/ledger-live-mobile/src/components/Web3AppWebview/WalletAPIWebview.tsx @@ -1,330 +1,19 @@ -import React, { useState, useCallback, useEffect, useMemo, RefObject, forwardRef } from "react"; -import { useSelector } from "react-redux"; +import React, { forwardRef } from "react"; import { ActivityIndicator, StyleSheet, View } from "react-native"; -import VersionNumber from "react-native-version-number"; import { WebView as RNWebView } from "react-native-webview"; -import { useNavigation } from "@react-navigation/native"; -import { Operation, SignedOperation } from "@ledgerhq/types-live"; -import type { Transaction } from "@ledgerhq/live-common/generated/types"; -import { - safeGetRefValue, - ExchangeType, - UiHook, - useConfig, - useWalletAPIServer, -} from "@ledgerhq/live-common/wallet-api/react"; -import trackingWrapper from "@ledgerhq/live-common/wallet-api/tracking"; -import type { Device } from "@ledgerhq/live-common/hw/actions/types"; -import BigNumber from "bignumber.js"; -import { AppManifest } from "@ledgerhq/live-common/wallet-api/types"; -import { NavigatorName, ScreenName } from "../../const"; -import { flattenAccountsSelector } from "../../reducers/accounts"; -import { track } from "../../analytics/segment"; -import prepareSignTransaction from "./liveSDKLogic"; -import { StackNavigatorNavigation } from "../RootNavigator/types/helpers"; -import { BaseNavigatorStackParamList } from "../RootNavigator/types/BaseNavigator"; -import { analyticsEnabledSelector } from "../../reducers/settings"; -import getOrCreateUser from "../../user"; import { WebviewAPI, WebviewProps } from "./types"; -import { useWebviewState } from "./helpers"; -import deviceStorage from "../../logic/storeWrapper"; +import { useWebView } from "./helpers"; import { NetworkError } from "./NetworkError"; -const wallet = { - name: "ledger-live-mobile", - version: VersionNumber.appVersion, -}; -const tracking = trackingWrapper(track); - -function useUiHook(): Partial { - const navigation = useNavigation(); - const [device, setDevice] = useState(); - - return useMemo( - () => ({ - "account.request": ({ accounts$, currencies, onSuccess, onError }) => { - if (currencies.length === 1) { - navigation.navigate(NavigatorName.RequestAccount, { - screen: ScreenName.RequestAccountsSelectAccount, - params: { - accounts$, - currency: currencies[0], - allowAddAccount: true, - onSuccess, - onError, - }, - }); - } else { - navigation.navigate(NavigatorName.RequestAccount, { - screen: ScreenName.RequestAccountsSelectCrypto, - params: { - accounts$, - currencies, - allowAddAccount: true, - onSuccess, - onError, - }, - }); - } - }, - "account.receive": ({ - account, - parentAccount, - accountAddress, - onSuccess, - onCancel, - onError, - }) => { - navigation.navigate(ScreenName.VerifyAccount, { - account, - parentId: parentAccount ? parentAccount.id : undefined, - onSuccess: () => onSuccess(accountAddress), - onClose: onCancel, - onError, - }); - }, - "message.sign": ({ account, message, onSuccess, onError, onCancel }) => { - navigation.navigate(NavigatorName.SignMessage, { - screen: ScreenName.SignSummary, - params: { - message, - accountId: account.id, - onConfirmationHandler: onSuccess, - onFailHandler: onError, - }, - onClose: onCancel, - }); - }, - "storage.get": async ({ key, storeId }) => { - return (await deviceStorage.get(`${storeId}-${key}`)) as string; - }, - "storage.set": ({ key, value, storeId }) => { - deviceStorage.save(`${storeId}-${key}`, value); - }, - "transaction.sign": ({ - account, - parentAccount, - signFlowInfos: { liveTx }, - options, - onSuccess, - onError, - }) => { - const tx = prepareSignTransaction( - account, - parentAccount, - liveTx as Partial, - ); - - navigation.navigate(NavigatorName.SignTransaction, { - screen: ScreenName.SignTransactionSummary, - params: { - currentNavigation: ScreenName.SignTransactionSummary, - nextNavigation: ScreenName.SignTransactionSelectDevice, - transaction: tx as Transaction, - accountId: account.id, - parentId: parentAccount ? parentAccount.id : undefined, - appName: options?.hwAppId, - onSuccess: ({ - signedOperation, - transactionSignError, - }: { - signedOperation: SignedOperation; - transactionSignError: Error; - }) => { - if (transactionSignError) { - onError(transactionSignError); - } else { - onSuccess(signedOperation); - - const n = - navigation.getParent>() || - navigation; - n.pop(); - } - }, - onError, - }, - }); - }, - "device.transport": ({ appName, onSuccess, onCancel }) => { - navigation.navigate(ScreenName.DeviceConnect, { - appName, - onSuccess, - onClose: onCancel, - }); - }, - "exchange.start": ({ exchangeType, onSuccess, onCancel }) => { - navigation.navigate(NavigatorName.PlatformExchange, { - screen: ScreenName.PlatformStartExchange, - params: { - request: { - exchangeType: ExchangeType[exchangeType], - }, - onResult: (result: { - startExchangeResult?: string; - startExchangeError?: Error; - device?: Device; - }) => { - if (result.startExchangeError) { - onCancel(result.startExchangeError); - } - - if (result.startExchangeResult) { - setDevice(result.device); - onSuccess(result.startExchangeResult); - } - - const n = - navigation.getParent>() || - navigation; - n.pop(); - }, - }, - }); - }, - "exchange.complete": ({ exchangeParams, onSuccess, onCancel }) => { - navigation.navigate(NavigatorName.PlatformExchange, { - screen: ScreenName.PlatformCompleteExchange, - params: { - request: { - exchangeType: exchangeParams.exchangeType, - provider: exchangeParams.provider, - exchange: exchangeParams.exchange, - transaction: exchangeParams.transaction as Transaction, - binaryPayload: exchangeParams.binaryPayload, - signature: exchangeParams.signature, - feesStrategy: exchangeParams.feesStrategy, - }, - device, - onResult: (result: { operation?: Operation; error?: Error }) => { - if (result.error) { - onCancel(result.error); - } - if (result.operation) { - onSuccess(result.operation.id); - } - setDevice(undefined); - const n = - navigation.getParent>() || - navigation; - n.pop(); - }, - }, - }); - }, - }), - [navigation, device], - ); -} - -const useGetUserId = () => { - const [userId, setUserId] = useState(""); - - useEffect(() => { - let mounted = true; - getOrCreateUser().then(({ user }) => { - if (mounted) setUserId(user.id); - }); - return () => { - mounted = false; - }; - }, []); - - return userId; -}; - -function useWebView( - { manifest }: Pick, - webviewRef: RefObject, -) { - const accounts = useSelector(flattenAccountsSelector); - - const uiHook = useUiHook(); - const analyticsEnabled = useSelector(analyticsEnabledSelector); - const userId = useGetUserId(); - const config = useConfig({ - appId: manifest.id, - userId, - tracking: analyticsEnabled, - wallet, - }); - - const webviewHook = useMemo(() => { - return { - reload: () => { - const webview = safeGetRefValue(webviewRef); - - webview.reload(); - }, - // TODO: wallet-api-server lifecycle is not perfect and will try to send messages before a ref is available. Some additional thinkering is needed here. - postMessage: (message: string) => { - try { - const webview = safeGetRefValue(webviewRef); - - webview.postMessage(message); - } catch (error) { - console.warn( - "wallet-api-server tried to send a message while the webview was not yet initialized.", - ); - } - }, - }; - }, [webviewRef]); - - const { onMessage: onMessageRaw, onLoadError } = useWalletAPIServer({ - manifest: manifest as AppManifest, - accounts, - tracking, - config, - webviewHook, - uiHook, - }); - - const onMessage = useCallback( - e => { - if (e.nativeEvent?.data) { - onMessageRaw(e.nativeEvent.data); - } - }, - [onMessageRaw], - ); - - return { - onLoadError, - onMessage, - }; -} - -function renderLoading() { - return ( - - - - ); -} - export const WalletAPIWebview = forwardRef( ({ manifest, inputs = {}, onStateChange, allowsBackForwardNavigationGestures = true }, ref) => { - const { webviewProps, webviewState, webviewRef } = useWebviewState( - { - manifest: manifest as AppManifest, - inputs, - }, - ref, - ); - - useEffect(() => { - if (onStateChange) { - onStateChange(webviewState); - } - }, [webviewState, onStateChange]); - - const { onMessage, onLoadError } = useWebView( + const { onMessage, onLoadError, webviewProps, webviewRef } = useWebView( { manifest, inputs, }, - webviewRef, + ref, + onStateChange, ); return ( @@ -346,6 +35,7 @@ export const WalletAPIWebview = forwardRef( scrollEnabled={true} style={styles.webview} renderError={() => webviewRef.current?.reload()} />} + testID="wallet-api-webview" {...webviewProps} /> ); @@ -354,6 +44,14 @@ export const WalletAPIWebview = forwardRef( WalletAPIWebview.displayName = "WalletAPIWebview"; +function renderLoading() { + return ( + + + + ); +} + const styles = StyleSheet.create({ root: { flex: 1, diff --git a/apps/ledger-live-mobile/src/components/Web3AppWebview/helpers.ts b/apps/ledger-live-mobile/src/components/Web3AppWebview/helpers.ts index a6ffdc6137bd..84e8c29a3387 100644 --- a/apps/ledger-live-mobile/src/components/Web3AppWebview/helpers.ts +++ b/apps/ledger-live-mobile/src/components/Web3AppWebview/helpers.ts @@ -1,10 +1,119 @@ import { AppManifest } from "@ledgerhq/live-common/wallet-api/types"; import { addParamsToURL, getClientHeaders } from "@ledgerhq/live-common/wallet-api/helpers"; -import { safeGetRefValue } from "@ledgerhq/live-common/wallet-api/react"; +import { + safeGetRefValue, + ExchangeType, + UiHook, + useConfig, + useWalletAPIServer, +} from "@ledgerhq/live-common/wallet-api/react"; +import { Operation, SignedOperation } from "@ledgerhq/types-live"; +import type { Transaction } from "@ledgerhq/live-common/generated/types"; +import trackingWrapper from "@ledgerhq/live-common/wallet-api/tracking"; +import type { Device } from "@ledgerhq/live-common/hw/actions/types"; +import BigNumber from "bignumber.js"; +import { useSelector } from "react-redux"; import { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react"; import { WebViewProps, WebView } from "react-native-webview"; +import VersionNumber from "react-native-version-number"; import { useTheme } from "styled-components/native"; -import { WebviewAPI, WebviewState } from "./types"; +import { useNavigation } from "@react-navigation/native"; +import { NavigatorName, ScreenName } from "../../const"; +import { flattenAccountsSelector } from "../../reducers/accounts"; +import { WebviewAPI, WebviewProps, WebviewState } from "./types"; +import prepareSignTransaction from "./liveSDKLogic"; +import { StackNavigatorNavigation } from "../RootNavigator/types/helpers"; +import { BaseNavigatorStackParamList } from "../RootNavigator/types/BaseNavigator"; +import { analyticsEnabledSelector } from "../../reducers/settings"; +import deviceStorage from "../../logic/storeWrapper"; +import { track } from "../../analytics/segment"; +import getOrCreateUser from "../../user"; +import * as bridge from "../../../e2e/bridge/client"; +import Config from "react-native-config"; + +export function useWebView( + { manifest, inputs }: Pick, + ref: React.ForwardedRef, + onStateChange: WebviewProps["onStateChange"], +) { + const { webviewProps, webviewRef } = useWebviewState( + { + manifest: manifest as AppManifest, + inputs, + }, + ref, + onStateChange, + ); + + const accounts = useSelector(flattenAccountsSelector); + + const uiHook = useUiHook(); + const analyticsEnabled = useSelector(analyticsEnabledSelector); + const userId = useGetUserId(); + const config = useConfig({ + appId: manifest.id, + userId, + tracking: analyticsEnabled, + wallet, + }); + + const webviewHook = useMemo(() => { + return { + reload: () => { + const webview = safeGetRefValue(webviewRef); + + webview.reload(); + }, + // TODO: wallet-api-server lifecycle is not perfect and will try to send messages before a ref is available. Some additional thinkering is needed here. + postMessage: (message: string) => { + try { + const webview = safeGetRefValue(webviewRef); + + webview.postMessage(message); + } catch (error) { + console.warn( + "wallet-api-server tried to send a message while the webview was not yet initialized.", + ); + } + }, + }; + }, [webviewRef]); + + const { onMessage: onMessageRaw, onLoadError } = useWalletAPIServer({ + manifest: manifest as AppManifest, + accounts, + tracking, + config, + webviewHook, + uiHook, + }); + + const onMessage = useCallback( + e => { + if (e.nativeEvent?.data) { + try { + const msg = JSON.parse(e.nativeEvent.data); + + if (Config.MOCK && msg.type === "e2eTest") { + bridge.sendWalletAPIResponse(msg.payload); + } else { + onMessageRaw(e.nativeEvent.data); + } + } catch { + onMessageRaw(e.nativeEvent.data); + } + } + }, + [onMessageRaw], + ); + + return { + onLoadError, + onMessage, + webviewProps, + webviewRef, + }; +} export const initialWebviewState: WebviewState = { url: "", @@ -14,14 +123,10 @@ export const initialWebviewState: WebviewState = { loading: false, }; -type useWebviewStateParams = { - manifest: AppManifest; - inputs?: Record; -}; - export function useWebviewState( - params: useWebviewStateParams, + params: Pick, WebviewAPIRef: React.ForwardedRef, + onStateChange: WebviewProps["onStateChange"], ) { const webviewRef = useRef(null); const { manifest, inputs } = params; @@ -126,6 +231,12 @@ export function useWebviewState( [], ); + useEffect(() => { + if (onStateChange) { + onStateChange(state); + } + }, [state, onStateChange]); + const props: Partial = useMemo( () => ({ onLoad, @@ -138,8 +249,211 @@ export function useWebviewState( ); return { - webviewState: state, webviewProps: props, webviewRef, }; } + +function useUiHook(): Partial { + const navigation = useNavigation(); + const [device, setDevice] = useState(); + + return useMemo( + () => ({ + "account.request": ({ accounts$, currencies, onSuccess, onError }) => { + if (currencies.length === 1) { + navigation.navigate(NavigatorName.RequestAccount, { + screen: ScreenName.RequestAccountsSelectAccount, + params: { + accounts$, + currency: currencies[0], + allowAddAccount: true, + onSuccess, + onError, + }, + }); + } else { + navigation.navigate(NavigatorName.RequestAccount, { + screen: ScreenName.RequestAccountsSelectCrypto, + params: { + accounts$, + currencies, + allowAddAccount: true, + onSuccess, + onError, + }, + }); + } + }, + "account.receive": ({ + account, + parentAccount, + accountAddress, + onSuccess, + onCancel, + onError, + }) => { + navigation.navigate(ScreenName.VerifyAccount, { + account, + parentId: parentAccount ? parentAccount.id : undefined, + onSuccess: () => onSuccess(accountAddress), + onClose: onCancel, + onError, + }); + }, + "message.sign": ({ account, message, onSuccess, onError, onCancel }) => { + navigation.navigate(NavigatorName.SignMessage, { + screen: ScreenName.SignSummary, + params: { + message, + accountId: account.id, + onConfirmationHandler: onSuccess, + onFailHandler: onError, + }, + onClose: onCancel, + }); + }, + "storage.get": async ({ key, storeId }) => { + return (await deviceStorage.get(`${storeId}-${key}`)) as string; + }, + "storage.set": ({ key, value, storeId }) => { + deviceStorage.save(`${storeId}-${key}`, value); + }, + "transaction.sign": ({ + account, + parentAccount, + signFlowInfos: { liveTx }, + options, + onSuccess, + onError, + }) => { + const tx = prepareSignTransaction( + account, + parentAccount, + liveTx as Partial, + ); + + navigation.navigate(NavigatorName.SignTransaction, { + screen: ScreenName.SignTransactionSummary, + params: { + currentNavigation: ScreenName.SignTransactionSummary, + nextNavigation: ScreenName.SignTransactionSelectDevice, + transaction: tx as Transaction, + accountId: account.id, + parentId: parentAccount ? parentAccount.id : undefined, + appName: options?.hwAppId, + onSuccess: ({ + signedOperation, + transactionSignError, + }: { + signedOperation: SignedOperation; + transactionSignError: Error; + }) => { + if (transactionSignError) { + onError(transactionSignError); + } else { + onSuccess(signedOperation); + + const n = + navigation.getParent>() || + navigation; + n.pop(); + } + }, + onError, + }, + }); + }, + "device.transport": ({ appName, onSuccess, onCancel }) => { + navigation.navigate(ScreenName.DeviceConnect, { + appName, + onSuccess, + onClose: onCancel, + }); + }, + "exchange.start": ({ exchangeType, onSuccess, onCancel }) => { + navigation.navigate(NavigatorName.PlatformExchange, { + screen: ScreenName.PlatformStartExchange, + params: { + request: { + exchangeType: ExchangeType[exchangeType], + }, + onResult: (result: { + startExchangeResult?: string; + startExchangeError?: Error; + device?: Device; + }) => { + if (result.startExchangeError) { + onCancel(result.startExchangeError); + } + + if (result.startExchangeResult) { + setDevice(result.device); + onSuccess(result.startExchangeResult); + } + + const n = + navigation.getParent>() || + navigation; + n.pop(); + }, + }, + }); + }, + "exchange.complete": ({ exchangeParams, onSuccess, onCancel }) => { + navigation.navigate(NavigatorName.PlatformExchange, { + screen: ScreenName.PlatformCompleteExchange, + params: { + request: { + exchangeType: exchangeParams.exchangeType, + provider: exchangeParams.provider, + exchange: exchangeParams.exchange, + transaction: exchangeParams.transaction as Transaction, + binaryPayload: exchangeParams.binaryPayload, + signature: exchangeParams.signature, + feesStrategy: exchangeParams.feesStrategy, + }, + device, + onResult: (result: { operation?: Operation; error?: Error }) => { + if (result.error) { + onCancel(result.error); + } + if (result.operation) { + onSuccess(result.operation.id); + } + setDevice(undefined); + const n = + navigation.getParent>() || + navigation; + n.pop(); + }, + }, + }); + }, + }), + [navigation, device], + ); +} + +const wallet = { + name: "ledger-live-mobile", + version: VersionNumber.appVersion, +}; + +const tracking = trackingWrapper(track); + +function useGetUserId() { + const [userId, setUserId] = useState(""); + + useEffect(() => { + let mounted = true; + getOrCreateUser().then(({ user }) => { + if (mounted) setUserId(user.id); + }); + return () => { + mounted = false; + }; + }, []); + + return userId; +} diff --git a/apps/ledger-live-mobile/src/components/Web3AppWebview/types.ts b/apps/ledger-live-mobile/src/components/Web3AppWebview/types.ts index a2bac7d9715f..fc8757e48d9e 100644 --- a/apps/ledger-live-mobile/src/components/Web3AppWebview/types.ts +++ b/apps/ledger-live-mobile/src/components/Web3AppWebview/types.ts @@ -1,4 +1,5 @@ import { LiveAppManifest } from "@ledgerhq/live-common/platform/types"; +import WebView from "react-native-webview"; export type WebviewProps = { manifest: LiveAppManifest; @@ -15,9 +16,6 @@ export type WebviewState = { loading: boolean; }; -export type WebviewAPI = { - reload: () => void; - goBack: () => void; - goForward: () => void; +export type WebviewAPI = Pick & { loadURL: (url: string) => void; }; diff --git a/apps/ledger-live-mobile/src/react-native-hw-transport-ble/makeMock.ts b/apps/ledger-live-mobile/src/react-native-hw-transport-ble/makeMock.ts index d5a641cbb22d..56f1f3c294ea 100644 --- a/apps/ledger-live-mobile/src/react-native-hw-transport-ble/makeMock.ts +++ b/apps/ledger-live-mobile/src/react-native-hw-transport-ble/makeMock.ts @@ -6,7 +6,7 @@ import type { Observer as TransportObserver, DescriptorEvent } from "@ledgerhq/h import { HwTransportError } from "@ledgerhq/errors"; import type { ApduMock } from "../logic/createAPDUMock"; import { hookRejections } from "../logic/debugReject"; -import { e2eBridgeSubject } from "../../e2e/bridge/client"; +import { e2eBridgeClient } from "../../e2e/bridge/client"; export type DeviceMock = { id: string; @@ -39,7 +39,7 @@ export default (opts: Opts) => { static setLogLevel = (_param: string) => {}; static listen(observer: TransportObserver, HwTransportError>) { - return e2eBridgeSubject + return e2eBridgeClient .pipe( filter(msg => msg.type === "add"), take(3), @@ -59,7 +59,7 @@ export default (opts: Opts) => { } static async open(device: string | Device) { - await e2eBridgeSubject + await e2eBridgeClient .pipe( filter(msg => msg.type === "open"), first(), diff --git a/libs/evm-tools/jest.config.js b/libs/evm-tools/jest.config.js index 8cb28be91f4c..1ddfbbd4db45 100644 --- a/libs/evm-tools/jest.config.js +++ b/libs/evm-tools/jest.config.js @@ -1,13 +1,10 @@ /** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */ module.exports = { preset: "ts-jest", - transform: { - ".(test|spec).[jt]sx?$": [ - "ts-jest", - { - tsconfig: "./src/__tests__/tsconfig.json", - }, - ], + globals: { + "ts-jest": { + tsconfig: "./src/__tests__/tsconfig.json", + }, }, testEnvironment: "node", coverageDirectory: "./coverage/", diff --git a/libs/evm-tools/package.json b/libs/evm-tools/package.json index f14fb2942ae6..19cca51e7bce 100644 --- a/libs/evm-tools/package.json +++ b/libs/evm-tools/package.json @@ -56,8 +56,8 @@ "@types/crypto-js": "^4.1.1", "@types/jest": "^28.1.8", "@types/node": "^18.15.7", - "jest": "^29.6.0", - "ts-jest": "^29.1.1" + "jest": "^28.1.3", + "ts-jest": "^28.0.8" }, "scripts": { "clean": "rimraf lib lib-es", diff --git a/libs/test-utils/.gitignore b/libs/test-utils/.gitignore new file mode 100644 index 000000000000..e8647040a160 --- /dev/null +++ b/libs/test-utils/.gitignore @@ -0,0 +1 @@ +**/build/ \ No newline at end of file diff --git a/apps/ledger-live-desktop/tests/utils/dummy-live-app/CHANGELOG.md b/libs/test-utils/dummy-live-app/CHANGELOG.md similarity index 100% rename from apps/ledger-live-desktop/tests/utils/dummy-live-app/CHANGELOG.md rename to libs/test-utils/dummy-live-app/CHANGELOG.md diff --git a/apps/ledger-live-desktop/tests/utils/dummy-live-app/README.md b/libs/test-utils/dummy-live-app/README.md similarity index 76% rename from apps/ledger-live-desktop/tests/utils/dummy-live-app/README.md rename to libs/test-utils/dummy-live-app/README.md index ceae3937e89d..8d1699a52327 100644 --- a/apps/ledger-live-desktop/tests/utils/dummy-live-app/README.md +++ b/libs/test-utils/dummy-live-app/README.md @@ -1,6 +1,7 @@ # Ledger Live Dummy Platform App The purpose of this app is to allow automated front end testing of Ledger Live Platform apps, and verify that Ledger Live correctly: + - handles the rendering of external Live Apps - handles calls of the Live SDK from external Live apps @@ -8,12 +9,10 @@ The app is a simple [Create React App](https://github.com/facebook/create-react- ## How to run locally for development -Run `pnpm --filter="dummy-live-app" start`. +Run `pnpm --filter="dummy-*" install` and `pnpm test-utils:dummy-live-app start` ## Quick script to build the app from scratch To use the Dummy app in the Playwright tests, you must install and build the dependencies and source code for the dummy app. To do this run the following from the root folder of this monorepo: -`pnpm clean && pnpm --filter="dummy-live-app" i && pnpm --filter="dummy-live-app" build` - -Then run `pnpm --filter="dummy-live-app" serve` +`pnpm test-utils:dummy-live-app i` and `pnpm test-utils:dummy-live-app build`. You can then run the apps with `npx http-server` in the same folder as the apps. Alternatively this app is started automatically in the playwright tests. diff --git a/apps/ledger-live-desktop/tests/utils/dummy-live-app/package.json b/libs/test-utils/dummy-live-app/package.json similarity index 87% rename from apps/ledger-live-desktop/tests/utils/dummy-live-app/package.json rename to libs/test-utils/dummy-live-app/package.json index 267ec13bc8ab..9e44e20384eb 100644 --- a/apps/ledger-live-desktop/tests/utils/dummy-live-app/package.json +++ b/libs/test-utils/dummy-live-app/package.json @@ -14,9 +14,7 @@ }, "scripts": { "start": "cross-env DISABLE_ESLINT_PLUGIN=true react-scripts start", - "build": "cross-env DISABLE_ESLINT_PLUGIN=true react-scripts build", - "test": "cross-env DISABLE_ESLINT_PLUGIN=true react-scripts test", - "eject": "react-scripts eject" + "build": "cross-env DISABLE_ESLINT_PLUGIN=true react-scripts build" }, "browserslist": { "production": [ diff --git a/apps/ledger-live-desktop/tests/utils/dummy-live-app/public/index.html b/libs/test-utils/dummy-live-app/public/index.html similarity index 100% rename from apps/ledger-live-desktop/tests/utils/dummy-live-app/public/index.html rename to libs/test-utils/dummy-live-app/public/index.html diff --git a/apps/ledger-live-desktop/tests/utils/dummy-live-app/src/App.css b/libs/test-utils/dummy-live-app/src/App.css similarity index 100% rename from apps/ledger-live-desktop/tests/utils/dummy-live-app/src/App.css rename to libs/test-utils/dummy-live-app/src/App.css diff --git a/apps/ledger-live-desktop/tests/utils/dummy-live-app/src/App.tsx b/libs/test-utils/dummy-live-app/src/App.tsx similarity index 100% rename from apps/ledger-live-desktop/tests/utils/dummy-live-app/src/App.tsx rename to libs/test-utils/dummy-live-app/src/App.tsx diff --git a/apps/ledger-live-desktop/tests/utils/dummy-live-app/src/index.css b/libs/test-utils/dummy-live-app/src/index.css similarity index 100% rename from apps/ledger-live-desktop/tests/utils/dummy-live-app/src/index.css rename to libs/test-utils/dummy-live-app/src/index.css diff --git a/apps/ledger-live-desktop/tests/utils/dummy-live-app/src/index.tsx b/libs/test-utils/dummy-live-app/src/index.tsx similarity index 100% rename from apps/ledger-live-desktop/tests/utils/dummy-live-app/src/index.tsx rename to libs/test-utils/dummy-live-app/src/index.tsx diff --git a/apps/ledger-live-desktop/tests/utils/dummy-live-app/src/ledger-logo.png b/libs/test-utils/dummy-live-app/src/ledger-logo.png similarity index 100% rename from apps/ledger-live-desktop/tests/utils/dummy-live-app/src/ledger-logo.png rename to libs/test-utils/dummy-live-app/src/ledger-logo.png diff --git a/apps/ledger-live-desktop/tests/utils/dummy-live-app/src/react-app-env.d.ts b/libs/test-utils/dummy-live-app/src/react-app-env.d.ts similarity index 100% rename from apps/ledger-live-desktop/tests/utils/dummy-live-app/src/react-app-env.d.ts rename to libs/test-utils/dummy-live-app/src/react-app-env.d.ts diff --git a/apps/ledger-live-desktop/tests/utils/dummy-live-app/tsconfig.json b/libs/test-utils/dummy-live-app/tsconfig.json similarity index 100% rename from apps/ledger-live-desktop/tests/utils/dummy-live-app/tsconfig.json rename to libs/test-utils/dummy-live-app/tsconfig.json diff --git a/apps/ledger-live-desktop/tests/utils/dummy-ptx-app/README.md b/libs/test-utils/dummy-ptx-app/README.md similarity index 72% rename from apps/ledger-live-desktop/tests/utils/dummy-ptx-app/README.md rename to libs/test-utils/dummy-ptx-app/README.md index b83244920e18..7caeb907bbf7 100644 --- a/apps/ledger-live-desktop/tests/utils/dummy-ptx-app/README.md +++ b/libs/test-utils/dummy-ptx-app/README.md @@ -4,4 +4,4 @@ The purpose of this app is to allow automated front end testing of Ledger Live P ## How to run locally for development -Run `npx http-serve` in the same folder as the dummy-ptx-app +Run `pnpm test-utils dummy-apps:start-ptx-app` in the same folder as the dummy-ptx-app diff --git a/apps/ledger-live-desktop/tests/utils/dummy-ptx-app/public/index.html b/libs/test-utils/dummy-ptx-app/public/index.html similarity index 100% rename from apps/ledger-live-desktop/tests/utils/dummy-ptx-app/public/index.html rename to libs/test-utils/dummy-ptx-app/public/index.html diff --git a/apps/ledger-live-desktop/tests/utils/dummy-ptx-app/public/ledger-logo.png b/libs/test-utils/dummy-ptx-app/public/ledger-logo.png similarity index 100% rename from apps/ledger-live-desktop/tests/utils/dummy-ptx-app/public/ledger-logo.png rename to libs/test-utils/dummy-ptx-app/public/ledger-logo.png diff --git a/apps/ledger-live-desktop/tests/utils/dummy-wallet-app/CHANGELOG.md b/libs/test-utils/dummy-wallet-app/CHANGELOG.md similarity index 100% rename from apps/ledger-live-desktop/tests/utils/dummy-wallet-app/CHANGELOG.md rename to libs/test-utils/dummy-wallet-app/CHANGELOG.md diff --git a/libs/test-utils/dummy-wallet-app/README.md b/libs/test-utils/dummy-wallet-app/README.md new file mode 100644 index 000000000000..41c13e6765cd --- /dev/null +++ b/libs/test-utils/dummy-wallet-app/README.md @@ -0,0 +1,254 @@ +# Dummy Wallet API App + +The purpose of this app is to allow automated front end testing of Ledger Live's Wallet API server implementation, and verify that Ledger Live correctly: + +- handles the rendering of external Live Apps +- handles calls of the Wallet API client from external Live apps + +The app is a simple [Create React App](https://github.com/facebook/create-react-app) which uses the [Wallet API](https://www.npmjs.com/package/@ledgerhq/wallet-api). + +## Local Dummy App setup steps + +```sh +pnpm i +pnpm test-utils:dummy-wallet-app start # Start development server +``` + +## Serve production build + +```sh +### Setup + +pnpm i +pnpm test-utils:dummy-wallet-app build + +### Desktop +pnpm build:lld:deps +pnpm desktop build:testing +pnpm desktop test:playwright wallet-api.spec.ts + +### Mobie +pnpm mobile start + +### iOS +pnpm build:llm:deps +pnpm mobile e2e:build -c ios.sim.debug +pnpm mobile e2e:test -c ios.sim.debug apps/ledger-live-mobile/e2e/specs/wallet-api.spec.ts + +### Android +pnpm build:llm:deps +pnpm mobile e2e:build -c android.emu.debug +pnpm mobile e2e:test -c android.emu.debug apps/ledger-live-mobile/e2e/specs/wallet-api.spec.ts +``` + +# How does it work? + +## Desktop + +```mermaid +sequenceDiagram + participant T as Test (Playwright) + participant A as App (Electron) + participant W as WebView + + T->>A: await LiveApp.send + activate T + A->>W: await window.ledger.e2e.walletApi.send(request) + activate A + W-->>A: wallet-api request + activate W + A-->>A: UI Hook (e.g. Side drawer to select account etc.) + A-->>W: wallet-api response + deactivate W + W->>A: Promise + deactivate A + A->>T: Promise + deactivate T +``` + +- `LiveApp.send`: This method turns a JSON-RPC request object into JSON. Then, it calls injected method via [`webview.executeJavaScript`](https://www.electronjs.org/docs/latest/api/webview-tag#webviewexecutejavascriptcode-usergesture). It allows testing engineers to simply await for a response from Live's wallet server and `expect` against the response. +- `window.ledger.e2e.walletApi.send`: This is an injected method in Dummy App to send a request to the Wallet API server. It returns `Promise` which is saved in a queue on the Dummy app side. +- Ledger Live Desktop either responds immediately with a response to the Wallet API request from the Live app, or after we've done some actions on the native LLD side (for example select an account, or mock a nano action). With this response the queued promise on the Live side is fulfilled with the result of the Wallet API request. +- The `webview.executeJavascript` promise on the Playwright test side is then subsequently fulfilled with the result of the Wallet API request, and we can use this to assert the expected result. + +### Steps to write a test + +First we start the local Dummy app at port 3000 by default and check that it can be accessed. Then we load a manifest which corresponds to this live app into the `MOCK_REMOTE_LIVE_MANIFEST` environmental variable (make sure the URL of the live app matches that of the live app, typically `http://localhost:3000`). + +```typescript +import { getMockAppManifest } from "PATH/TO/utils/serve-dummy-app"; + +let continueTest = false; + +test.beforeAll(async () => { + continueTest = await LiveApp.start(request); +}); +``` + +Then in the test we first send the Wallet API method that we want from the live app, perform any actions in Ledger Live, receive the response in the Live app, and verify the response by fulfilling the promise we initiated in the first step: + +```typescript +const discoverPage = new DiscoverPage(page); + +await test.step("account.request", async () => { + // previous test steps.... + + // generate a random id + const id = randomUUID(); + + // send the account.request method. This send method gives us the Wallet API message id and a promise from the 'inject javascript' step that we will resolve later + const { id, response } = discoverPage.send({ + jsonrpc: "2.0", + id, + method: "account.request", + params: { + currencyIds: ["ethereum", "bitcoin"], + }, + }); + + // perform actions in Ledger Live to get the wallet API response + await drawer.selectCurrency("bitcoin"); + await drawer.selectAccount("bitcoin"); + + // verify the response is as expected. Be careful to only resolve this one all the required user actions are finished + await expect(res).resolves.toStrictEqual({ + jsonrpc: "2.0", + id, + result: { + rawAccount: { + id: "2d23ca2a-069e-579f-b13d-05bc706c7583", + // etc.. + }, + }, + }); +}); +``` + +## Mobile + +```mermaid +sequenceDiagram + participant T as Test (Jest) + participant A as App (React Native) + participant W as WebView (react-native-webview) + + T->>A: await LiveApp.send + activate T + A->>W: window.ledger.e2e.walletApi.send(request) + activate A + W-->>A: wallet-api request + activate W + A-->>A: UI Hook (e.g. Side drawer to select account etc.) + A-->>W: wallet-api response + deactivate W + W->>A: window.ReactNativeWebview.postMessage(response) + deactivate A + Note over A: onMessage + A->>T: bridge.sendWalletAPIResponse(response) + deactivate T +``` + +The mobile side works similarly to desktop but with a few key differences: + +- `LiveAppWebview.send`: The same as desktop but uses [`webview.runScript`](https://wix.github.io/Detox/docs/api/webviews/#runscriptscript) from detox instead. +- `window.ledger.e2e.walletApi.send`: This global method in the dummy app behaves differently on mobile. In desktop/playwright the JS injection `send` method in the live app returns the response to the test process, whereas the mobile/detox method doesn't return anything. To get around this the live app looks for `window.ReactNativeWebView` which is injected by the `react-native-webview` module, and then calls `window.ReactNativeWebView.postMessage` method to send the Wallet API response back to the LLM App runtime. This message will be caught with the `onMessage` handler passed to the LLM webview component. Then, the handler sends the request to the Test runtime via the E2E websocket bridge server. Finally the bridge server sends the response to the test via `e2eBridgeServer` RxJS subject. + +### Steps to write a test + +First we start the local Dummy app at port 52619 (hardcoded for now) which matches the live app manifest in `.env.mock`. In future we can make this dynamic by passing a manifest from the test to LLM Live app Provider via the E2E Bridge, but this way is simpler for initial tests. + +Then in the `beforeAll` we check that the server is running and then navigate to the live app. + +```typescript +import { getMockAppManifest } from "PATH/TO/utils/serve-dummy-app"; + +test.beforeAll(async () => { + try { + const port = await server.start("dummy-wallet-app/build"); + const url = `http://localhost:${port}`; + const response = await request.get(url); + if (response.ok()) { + continueTest = true; + console.info( + `========> Dummy Wallet API app successfully running on port ${port}! <=========`, + ); + process.env.MOCK_REMOTE_LIVE_MANIFEST = JSON.stringify( + server.liveAppManifest({ + id: "dummy-live-app", + url, + name: "Dummy Wallet API Live App", + apiVersion: "2.0.0", + content: { + shortDescription: { + en: "App to test the Wallet API", + }, + description: { + en: "App to test the Wallet API with Playwright", + }, + }, + }), + ); + } else { + throw new Error("Ping response != 200, got: " + response.status); + } + } catch (error) { + console.warn(`========> Dummy test app not running! <=========`); + console.error(error); + } + + if (!continueTest || !isAndroid()) { + console.warn("Stopping Wallet API test setup"); + return; // need to make this a proper ignore/jest warning + } + + // start navigation + portfolioPage = new PortfolioPage(); + discoverPage = new DiscoveryPage(); + liveAppWebview = new LiveAppWebview(); + cryptoDrawer = new CryptoDrawer(); + + loadConfig("1AccountBTC1AccountETHReadOnlyFalse", true); + + await portfolioPage.waitForPortfolioPageToLoad(); + await discoverPage.openViaDeeplink("dummy-live-app"); + + const title = await detox.web.element(detox.by.web.id("image-container")).getTitle(); + expect(title).toBe("Dummy Wallet API App"); +}); +``` + +Then in the test we first send the Wallet API method that we want from the live app, perform any actions in Ledger Live, receive the response in the Live app, and verify the response by fulfilling the promise we initiated in the first step: + +```typescript +it("account.request", async () => { + // send wallet API request for the webview to send to LLM + const { id, response } = await liveAppWebview.send({ + method: "account.request", + params: { + currencyIds: ["ethereum", "bitcoin"], + }, + }); + + // perform any required actions in LLM for the test + await cryptoDrawer.selectCurrencyFromDrawer("Bitcoin"); + await cryptoDrawer.selectAccountFromDrawer("Bitcoin 1 (legacy)"); + + // verify the response after the Wallet API response is received and all the test steps are finished + await expect(response).resolves.toMatchObject({ + jsonrpc: "2.0", + id, + result: { + rawAccount: { + id: "2d23ca2a-069e-579f-b13d-05bc706c7583", + address: "1xeyL26EKAAR3pStd7wEveajk4MQcrYezeJ", + }, + }, + }); +}); +``` + +## Dummy App + +The most important part of the dummy app is handled by `useE2EInjection()`, which injects the `window.ledger.e2e.walletApi.send()` method. This is the method that is used by the tests to simulate a user doing an action that requires a Wallet API response from Ledger Live. + +`useE2EInjection()` also initialises the Wallet API transports (like any live app needs to communicate with Ledger Live), and also has a 'pending request' queue that keeps track of the requests it has sent to the Wallet API, so we can send responses back to the test for assertion. diff --git a/apps/ledger-live-desktop/tests/utils/dummy-wallet-app/package.json b/libs/test-utils/dummy-wallet-app/package.json similarity index 89% rename from apps/ledger-live-desktop/tests/utils/dummy-wallet-app/package.json rename to libs/test-utils/dummy-wallet-app/package.json index 5c47631536fb..d0b56e62cf04 100644 --- a/apps/ledger-live-desktop/tests/utils/dummy-wallet-app/package.json +++ b/libs/test-utils/dummy-wallet-app/package.json @@ -20,9 +20,7 @@ }, "scripts": { "start": "cross-env DISABLE_ESLINT_PLUGIN=true react-scripts start", - "build": "cross-env DISABLE_ESLINT_PLUGIN=true react-scripts build", - "test": "cross-env DISABLE_ESLINT_PLUGIN=true react-scripts test", - "eject": "react-scripts eject" + "build": "cross-env DISABLE_ESLINT_PLUGIN=true react-scripts build" }, "browserslist": { "production": [ diff --git a/apps/ledger-live-desktop/tests/utils/dummy-wallet-app/public/dummy-icon.png b/libs/test-utils/dummy-wallet-app/public/dummy-icon.png similarity index 100% rename from apps/ledger-live-desktop/tests/utils/dummy-wallet-app/public/dummy-icon.png rename to libs/test-utils/dummy-wallet-app/public/dummy-icon.png diff --git a/libs/test-utils/dummy-wallet-app/public/index.html b/libs/test-utils/dummy-wallet-app/public/index.html new file mode 100644 index 000000000000..949dca9a1edf --- /dev/null +++ b/libs/test-utils/dummy-wallet-app/public/index.html @@ -0,0 +1,16 @@ + + + + + + + + + Dummy Wallet API App + + + + +
    + + diff --git a/apps/ledger-live-desktop/tests/utils/dummy-wallet-app/public/ledger-logo.png b/libs/test-utils/dummy-wallet-app/public/ledger-logo.png similarity index 100% rename from apps/ledger-live-desktop/tests/utils/dummy-wallet-app/public/ledger-logo.png rename to libs/test-utils/dummy-wallet-app/public/ledger-logo.png diff --git a/apps/ledger-live-desktop/tests/utils/dummy-wallet-app/src/App.css b/libs/test-utils/dummy-wallet-app/src/App.css similarity index 100% rename from apps/ledger-live-desktop/tests/utils/dummy-wallet-app/src/App.css rename to libs/test-utils/dummy-wallet-app/src/App.css diff --git a/libs/test-utils/dummy-wallet-app/src/App.tsx b/libs/test-utils/dummy-wallet-app/src/App.tsx new file mode 100644 index 000000000000..1e90312e9163 --- /dev/null +++ b/libs/test-utils/dummy-wallet-app/src/App.tsx @@ -0,0 +1,33 @@ +import React, { useMemo } from "react"; +import { useE2EInjection } from "./hooks"; +import "./App.css"; + +export default function App() { + useE2EInjection(); + + const params = useMemo( + () => Array.from(new URLSearchParams(window.location.search).entries()), + [], + ); + + return ( +
    +
    +
    + logo + dummy +
    +

    Ledger Live Dummy Wallet API App

    +

    App for testing the Ledger Live Wallet API manually and in Automated tests

    +
    + Query Params for web app: +
      + {params.map(([key, value]) => ( +
    1. {`${key}: ${value}`}
    2. + ))} +
    +
    +
    +
    + ); +} diff --git a/libs/test-utils/dummy-wallet-app/src/hooks.ts b/libs/test-utils/dummy-wallet-app/src/hooks.ts new file mode 100644 index 000000000000..47be31ef0c9f --- /dev/null +++ b/libs/test-utils/dummy-wallet-app/src/hooks.ts @@ -0,0 +1,51 @@ +import { useCallback, useEffect, useRef } from "react"; +import { WindowMessageTransport, RpcResponse } from "@ledgerhq/wallet-api-client"; + +type PendingRequests = Record void>; + +export function useE2EInjection() { + const queue = useRef({}); + const transport = useRef(new WindowMessageTransport()); + + const send = useCallback(async jsonStr => { + const { id } = JSON.parse(jsonStr); + + const promise = new Promise(resolve => { + queue.current[id] = resolve; + transport.current.send(jsonStr); + }); + + // if mobile + if (window.ReactNativeWebView) { + const response = await promise; + window.ReactNativeWebView.postMessage(JSON.stringify({ type: "e2eTest", payload: response })); + } + + return promise; + }, []); + + useEffect(() => { + transport.current.connect(); + transport.current.onMessage = (msgStr: string) => { + const msg = JSON.parse(msgStr); + if (!msg.id) return; + + const resolve = queue.current[msg.id]; + if (!resolve) return; + + resolve(msg); + delete queue.current[msg.id]; + }; + + window.ledger = { + // to avoid overriding other fields + ...window.ledger, + e2e: { + ...window.ledger?.e2e, + walletApi: { + send, + }, + }, + }; + }, [send]); +} diff --git a/apps/ledger-live-desktop/tests/utils/dummy-wallet-app/src/index.css b/libs/test-utils/dummy-wallet-app/src/index.css similarity index 100% rename from apps/ledger-live-desktop/tests/utils/dummy-wallet-app/src/index.css rename to libs/test-utils/dummy-wallet-app/src/index.css diff --git a/apps/ledger-live-desktop/tests/utils/dummy-wallet-app/src/index.tsx b/libs/test-utils/dummy-wallet-app/src/index.tsx similarity index 100% rename from apps/ledger-live-desktop/tests/utils/dummy-wallet-app/src/index.tsx rename to libs/test-utils/dummy-wallet-app/src/index.tsx diff --git a/apps/ledger-live-desktop/tests/utils/dummy-wallet-app/src/react-app-env.d.ts b/libs/test-utils/dummy-wallet-app/src/react-app-env.d.ts similarity index 52% rename from apps/ledger-live-desktop/tests/utils/dummy-wallet-app/src/react-app-env.d.ts rename to libs/test-utils/dummy-wallet-app/src/react-app-env.d.ts index 0db73384d20e..5b6e0126b658 100644 --- a/apps/ledger-live-desktop/tests/utils/dummy-wallet-app/src/react-app-env.d.ts +++ b/libs/test-utils/dummy-wallet-app/src/react-app-env.d.ts @@ -4,8 +4,11 @@ interface Window { ledger: { e2e: { walletApi: { - send: (params: any) => void; + send: (params: unknown) => void; }; }; }; + ReactNativeWebView?: { + postMessage: (value: unknown) => void; + }; } diff --git a/apps/ledger-live-desktop/tests/utils/dummy-wallet-app/tsconfig.json b/libs/test-utils/dummy-wallet-app/tsconfig.json similarity index 100% rename from apps/ledger-live-desktop/tests/utils/dummy-wallet-app/tsconfig.json rename to libs/test-utils/dummy-wallet-app/tsconfig.json diff --git a/libs/test-utils/package.json b/libs/test-utils/package.json new file mode 100644 index 000000000000..ddf9a2fe4459 --- /dev/null +++ b/libs/test-utils/package.json @@ -0,0 +1,25 @@ +{ + "name": "@ledgerhq/test-utils", + "version": "0.0.1", + "private": true, + "description": "Dummy apps and utils for tests", + "keywords": [ + "Ledger" + ], + "main": "lib/index.js", + "module": "lib-es/index.js", + "types": "lib/index.d.ts", + "scripts": { + "clean": "rimraf lib lib-es", + "build": "tsc && tsc -m ES6 --outDir lib-es", + "dummy-apps:build": "pnpm --filter='dummy-*' build", + "dummy-apps:start-ptx-app": "cd dummy-ptx-app && npx http-server" + }, + "dependencies": { + "@ledgerhq/live-common": "workspace:^", + "serve-handler": "^6.1.3" + }, + "devDependencies": { + "@types/serve-handler": "^6.1.1" + } +} diff --git a/apps/ledger-live-desktop/tests/utils/serve-dummy-app.ts b/libs/test-utils/src/index.ts similarity index 60% rename from apps/ledger-live-desktop/tests/utils/serve-dummy-app.ts rename to libs/test-utils/src/index.ts index 86ffe60d15c4..7322eb70ed06 100644 --- a/apps/ledger-live-desktop/tests/utils/serve-dummy-app.ts +++ b/libs/test-utils/src/index.ts @@ -1,35 +1,39 @@ import handler from "serve-handler"; import http from "http"; +import net from "net"; import path from "path"; import { AppManifest } from "@ledgerhq/live-common/wallet-api/types"; let dummyAppPath: string; -export const server = http.createServer((request, response) => { - // You pass two more arguments for config and middleware - // More details here: https://github.com/vercel/serve-handler#options - handler(request, response, { - public: path.resolve(__dirname, dummyAppPath), - }); -}); +export const dummyAppServer: http.Server = http.createServer( + (request: http.IncomingMessage, response: http.ServerResponse) => { + // You pass two more arguments for config and middleware + // More details here: https://github.com/vercel/serve-handler#options + + handler(request, response, { + public: path.resolve(__dirname, "..", dummyAppPath), + }); + }, +); -export const start = (appPath: string, port = 0): Promise => { +export function startDummyServer(appPath: string, port = 0): Promise { dummyAppPath = appPath; return new Promise((resolve, reject) => { - server + dummyAppServer .listen(port, "localhost") .once("listening", () => { - resolve((server.address() as any).port as number); + resolve((dummyAppServer.address() as net.AddressInfo).port as number); }) - .once("error", error => { - server.close(); + .once("error", (error: unknown) => { + dummyAppServer.close(); reject(error); }); }); -}; +} -export const liveAppManifest = (params: Partial & Pick) => { +export function getLiveAppManifest(params: Partial & Pick) { const manifest = [ { name: "Generic Live App", @@ -74,6 +78,13 @@ export const liveAppManifest = (params: Partial & Pick server.close(); +export function stopDummyServer(): Promise { + dummyAppServer.close(); + return new Promise(resolve => { + dummyAppServer.on("close", () => { + resolve(); + }); + }); +} diff --git a/libs/test-utils/tsconfig.json b/libs/test-utils/tsconfig.json new file mode 100644 index 000000000000..094fd5f4da1d --- /dev/null +++ b/libs/test-utils/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base", + "compilerOptions": { + "declaration": true, + "outDir": "lib" + }, + "include": ["src/**/*"] +} diff --git a/package.json b/package.json index 317078a340bb..cdcbd49f9589 100644 --- a/package.json +++ b/package.json @@ -99,6 +99,9 @@ "ljs:types-cryptoassets": "pnpm --filter types-cryptoassets", "ljs:types-devices": "pnpm --filter types-devices", "ljs:types-live": "pnpm --filter types-live", + "test-utils": "pnpm --filter test-utils", + "test-utils:dummy-live-app": "pnpm --filter dummy-live-app", + "test-utils:dummy-wallet-app": "pnpm --filter dummy-wallet-app", "ui": "pnpm --filter ui", "ui:react": "pnpm --filter react-ui", "ui:native": "pnpm --filter native-ui", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 206724fd8a0d..3f7a4076615c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -531,6 +531,9 @@ importers: '@ledgerhq/react-devtools': specifier: workspace:^ version: link:../../tools/react-dev-tools + '@ledgerhq/test-utils': + specifier: workspace:^ + version: link:../../libs/test-utils '@octokit/rest': specifier: ^18.12.0 version: 18.12.0 @@ -724,86 +727,6 @@ importers: specifier: ^15.3.1 version: 15.4.1 - apps/ledger-live-desktop/tests/utils/dummy-live-app: - dependencies: - '@ledgerhq/live-app-sdk': - specifier: ^0.5.0 - version: 0.5.1 - '@types/jest': - specifier: ^27.0.1 - version: 27.5.1 - '@types/node': - specifier: ^16.7.13 - version: 16.11.12 - '@types/react': - specifier: ^17.0.53 - version: 17.0.53 - '@types/react-dom': - specifier: ^17.0.9 - version: 17.0.16(@types/react@17.0.53) - react: - specifier: ^17.0.2 - version: 17.0.2 - react-dom: - specifier: ^17.0.2 - version: 17.0.2(react@17.0.2) - react-scripts: - specifier: 5.0.0 - version: 5.0.0(react@17.0.2)(typescript@5.1.3) - devDependencies: - cross-env: - specifier: ^7.0.3 - version: 7.0.3 - - apps/ledger-live-desktop/tests/utils/dummy-wallet-app: - dependencies: - '@ledgerhq/hw-app-eth': - specifier: workspace:* - version: link:../../../../../libs/ledgerjs/packages/hw-app-eth - '@ledgerhq/hw-transport': - specifier: workspace:* - version: link:../../../../../libs/ledgerjs/packages/hw-transport - '@ledgerhq/live-common': - specifier: workspace:* - version: link:../../../../../libs/ledger-live-common - '@ledgerhq/wallet-api-client': - specifier: ^0.15.2 - version: 0.15.2 - '@ledgerhq/wallet-api-simulator': - specifier: ^0.12.5 - version: 0.12.5(react@17.0.2) - '@types/jest': - specifier: ^27.0.1 - version: 27.5.1 - '@types/node': - specifier: ^16.7.13 - version: 16.11.12 - '@types/react': - specifier: ^17.0.53 - version: 17.0.53 - '@types/react-dom': - specifier: ^17.0.9 - version: 17.0.16(@types/react@17.0.53) - bignumber.js: - specifier: ^9.1.0 - version: 9.1.0 - buffer: - specifier: ^6.0.3 - version: 6.0.3 - react: - specifier: ^17.0.2 - version: 17.0.2 - react-dom: - specifier: ^17.0.2 - version: 17.0.2(react@17.0.2) - react-scripts: - specifier: 5.0.0 - version: 5.0.0(react@17.0.2)(typescript@5.1.3) - devDependencies: - cross-env: - specifier: ^7.0.3 - version: 7.0.3 - apps/ledger-live-mobile: dependencies: '@azure/core-asynciterator-polyfill': @@ -1248,6 +1171,9 @@ importers: '@jest/reporters': specifier: ^29.3.1 version: 29.5.0(metro@0.76.0) + '@ledgerhq/test-utils': + specifier: workspace:^ + version: link:../../libs/test-utils '@react-native-community/cli': specifier: ^7.0.1 version: 7.0.4(@babel/core@7.21.0)(metro-resolver@0.76.0)(metro-transform-worker@0.76.0)(react-native@0.71.6) @@ -1868,11 +1794,11 @@ importers: specifier: ^18.15.7 version: 18.15.11 jest: - specifier: ^29.6.0 - version: 29.6.0(@types/node@18.15.11) + specifier: ^28.1.3 + version: 28.1.3(@types/node@18.15.11) ts-jest: - specifier: ^29.1.1 - version: 29.1.1(jest@29.6.0)(typescript@5.1.3) + specifier: ^28.0.8 + version: 28.0.8(jest@28.1.3)(typescript@5.1.3) libs/ledger-live-common: dependencies: @@ -4186,6 +4112,99 @@ importers: specifier: ^28.0.5 version: 28.0.8(jest@28.1.3)(typescript@5.1.3) + libs/test-utils: + dependencies: + '@ledgerhq/live-common': + specifier: workspace:^ + version: link:../ledger-live-common + serve-handler: + specifier: ^6.1.3 + version: 6.1.3 + devDependencies: + '@types/serve-handler': + specifier: ^6.1.1 + version: 6.1.1 + + libs/test-utils/dummy-live-app: + dependencies: + '@ledgerhq/live-app-sdk': + specifier: ^0.5.0 + version: 0.5.1 + '@types/jest': + specifier: ^27.0.1 + version: 27.5.1 + '@types/node': + specifier: ^16.7.13 + version: 16.11.12 + '@types/react': + specifier: ^17.0.53 + version: 17.0.53 + '@types/react-dom': + specifier: ^17.0.9 + version: 17.0.16(@types/react@17.0.53) + react: + specifier: ^17.0.2 + version: 17.0.2 + react-dom: + specifier: ^17.0.2 + version: 17.0.2(react@17.0.2) + react-scripts: + specifier: 5.0.0 + version: 5.0.0(react@17.0.2)(typescript@5.1.3) + devDependencies: + cross-env: + specifier: ^7.0.3 + version: 7.0.3 + + libs/test-utils/dummy-wallet-app: + dependencies: + '@ledgerhq/hw-app-eth': + specifier: workspace:* + version: link:../../ledgerjs/packages/hw-app-eth + '@ledgerhq/hw-transport': + specifier: workspace:* + version: link:../../ledgerjs/packages/hw-transport + '@ledgerhq/live-common': + specifier: workspace:* + version: link:../../ledger-live-common + '@ledgerhq/wallet-api-client': + specifier: ^0.15.2 + version: 0.15.2 + '@ledgerhq/wallet-api-simulator': + specifier: ^0.12.5 + version: 0.12.5(react@17.0.2) + '@types/jest': + specifier: ^27.0.1 + version: 27.5.1 + '@types/node': + specifier: ^16.7.13 + version: 16.11.12 + '@types/react': + specifier: ^17.0.53 + version: 17.0.53 + '@types/react-dom': + specifier: ^17.0.9 + version: 17.0.16(@types/react@17.0.53) + bignumber.js: + specifier: ^9.1.0 + version: 9.1.0 + buffer: + specifier: ^6.0.3 + version: 6.0.3 + react: + specifier: ^17.0.2 + version: 17.0.2 + react-dom: + specifier: ^17.0.2 + version: 17.0.2(react@17.0.2) + react-scripts: + specifier: 5.0.0 + version: 5.0.0(react@17.0.2)(typescript@5.1.3) + devDependencies: + cross-env: + specifier: ^7.0.3 + version: 7.0.3 + libs/ui: devDependencies: '@ledgerhq/crypto-icons-ui': @@ -5560,7 +5579,7 @@ packages: transitivePeerDependencies: - supports-color - /@babel/eslint-parser@7.18.9(@babel/core@7.21.0)(eslint@8.15.0): + /@babel/eslint-parser@7.18.9(@babel/core@7.21.0)(eslint@8.41.0): resolution: {integrity: sha512-KzSGpMBggz4fKbRbWLNyPVTuQr6cmCcBhOyXTw/fieOVaw5oYAwcAj4a7UKcDYCPxQq+CG1NCDZH9e2JTXquiQ==} engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} peerDependencies: @@ -5568,7 +5587,7 @@ packages: eslint: ^7.5.0 || ^8.0.0 dependencies: '@babel/core': 7.21.0 - eslint: 8.15.0 + eslint: 8.41.0 eslint-scope: 5.1.1 eslint-visitor-keys: 2.1.0 semver: 6.3.0 @@ -10392,14 +10411,14 @@ packages: postcss: 7.0.39 postcss-selector-parser: 6.0.10 - /@csstools/postcss-cascade-layers@1.0.5(postcss@8.4.13): + /@csstools/postcss-cascade-layers@1.0.5(postcss@8.4.21): resolution: {integrity: sha512-Id/9wBT7FkgFzdEpiEWrsVd4ltDxN0rI0QS0SChbeQiSuux3z21SJCRLu6h2cvCEUmaRi+VD0mHFj+GJD4GFnw==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - '@csstools/selector-specificity': 2.0.2(postcss-selector-parser@6.0.10)(postcss@8.4.13) - postcss: 8.4.13 + '@csstools/selector-specificity': 2.0.2(postcss-selector-parser@6.0.10)(postcss@8.4.21) + postcss: 8.4.21 postcss-selector-parser: 6.0.10 dev: false @@ -10413,14 +10432,14 @@ packages: postcss: 7.0.39 postcss-value-parser: 4.2.0 - /@csstools/postcss-color-function@1.1.1(postcss@8.4.13): + /@csstools/postcss-color-function@1.1.1(postcss@8.4.21): resolution: {integrity: sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.13) - postcss: 8.4.13 + '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.21) + postcss: 8.4.21 postcss-value-parser: 4.2.0 dev: false @@ -10433,13 +10452,13 @@ packages: postcss: 7.0.39 postcss-value-parser: 4.2.0 - /@csstools/postcss-font-format-keywords@1.0.1(postcss@8.4.13): + /@csstools/postcss-font-format-keywords@1.0.1(postcss@8.4.21): resolution: {integrity: sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-value-parser: 4.2.0 dev: false @@ -10452,13 +10471,13 @@ packages: postcss: 7.0.39 postcss-value-parser: 4.2.0 - /@csstools/postcss-hwb-function@1.0.2(postcss@8.4.13): + /@csstools/postcss-hwb-function@1.0.2(postcss@8.4.21): resolution: {integrity: sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-value-parser: 4.2.0 dev: false @@ -10472,14 +10491,14 @@ packages: postcss: 7.0.39 postcss-value-parser: 4.2.0 - /@csstools/postcss-ic-unit@1.0.1(postcss@8.4.13): + /@csstools/postcss-ic-unit@1.0.1(postcss@8.4.21): resolution: {integrity: sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.13) - postcss: 8.4.13 + '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.21) + postcss: 8.4.21 postcss-value-parser: 4.2.0 dev: false @@ -10493,14 +10512,14 @@ packages: postcss: 7.0.39 postcss-selector-parser: 6.0.10 - /@csstools/postcss-is-pseudo-class@2.0.7(postcss@8.4.13): + /@csstools/postcss-is-pseudo-class@2.0.7(postcss@8.4.21): resolution: {integrity: sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - '@csstools/selector-specificity': 2.0.2(postcss-selector-parser@6.0.10)(postcss@8.4.13) - postcss: 8.4.13 + '@csstools/selector-specificity': 2.0.2(postcss-selector-parser@6.0.10)(postcss@8.4.21) + postcss: 8.4.21 postcss-selector-parser: 6.0.10 dev: false @@ -10513,13 +10532,13 @@ packages: postcss: 7.0.39 postcss-value-parser: 4.2.0 - /@csstools/postcss-normalize-display-values@1.0.1(postcss@8.4.13): + /@csstools/postcss-normalize-display-values@1.0.1(postcss@8.4.21): resolution: {integrity: sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-value-parser: 4.2.0 dev: false @@ -10533,14 +10552,14 @@ packages: postcss: 7.0.39 postcss-value-parser: 4.2.0 - /@csstools/postcss-oklab-function@1.1.1(postcss@8.4.13): + /@csstools/postcss-oklab-function@1.1.1(postcss@8.4.21): resolution: {integrity: sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.13) - postcss: 8.4.13 + '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.21) + postcss: 8.4.21 postcss-value-parser: 4.2.0 dev: false @@ -10553,13 +10572,13 @@ packages: postcss: 7.0.39 postcss-value-parser: 4.2.0 - /@csstools/postcss-progressive-custom-properties@1.3.0(postcss@8.4.13): + /@csstools/postcss-progressive-custom-properties@1.3.0(postcss@8.4.21): resolution: {integrity: sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.3 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-value-parser: 4.2.0 dev: false @@ -10572,13 +10591,13 @@ packages: postcss: 7.0.39 postcss-value-parser: 4.2.0 - /@csstools/postcss-stepped-value-functions@1.0.1(postcss@8.4.13): + /@csstools/postcss-stepped-value-functions@1.0.1(postcss@8.4.21): resolution: {integrity: sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-value-parser: 4.2.0 dev: false @@ -10591,13 +10610,13 @@ packages: postcss: 7.0.39 postcss-value-parser: 4.2.0 - /@csstools/postcss-trigonometric-functions@1.0.2(postcss@8.4.13): + /@csstools/postcss-trigonometric-functions@1.0.2(postcss@8.4.21): resolution: {integrity: sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og==} engines: {node: ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-value-parser: 4.2.0 dev: false @@ -10609,13 +10628,13 @@ packages: dependencies: postcss: 7.0.39 - /@csstools/postcss-unset-value@1.0.2(postcss@8.4.13): + /@csstools/postcss-unset-value@1.0.2(postcss@8.4.21): resolution: {integrity: sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 dev: false /@csstools/selector-specificity@2.0.2(postcss-selector-parser@6.0.10)(postcss@7.0.39): @@ -10628,27 +10647,27 @@ packages: postcss: 7.0.39 postcss-selector-parser: 6.0.10 - /@csstools/selector-specificity@2.0.2(postcss-selector-parser@6.0.10)(postcss@8.4.13): + /@csstools/selector-specificity@2.0.2(postcss-selector-parser@6.0.10)(postcss@8.4.19): resolution: {integrity: sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 postcss-selector-parser: ^6.0.10 dependencies: - postcss: 8.4.13 + postcss: 8.4.19 postcss-selector-parser: 6.0.10 - dev: false + dev: true - /@csstools/selector-specificity@2.0.2(postcss-selector-parser@6.0.10)(postcss@8.4.19): + /@csstools/selector-specificity@2.0.2(postcss-selector-parser@6.0.10)(postcss@8.4.21): resolution: {integrity: sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 postcss-selector-parser: ^6.0.10 dependencies: - postcss: 8.4.19 + postcss: 8.4.21 postcss-selector-parser: 6.0.10 - dev: true + dev: false /@dabh/diagnostics@2.0.3: resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==} @@ -11068,6 +11087,7 @@ packages: cpu: [arm64] os: [android] requiresBuild: true + dev: true optional: true /@esbuild/android-arm64@0.17.5: @@ -11094,6 +11114,7 @@ packages: cpu: [arm] os: [android] requiresBuild: true + dev: true optional: true /@esbuild/android-arm@0.17.5: @@ -11120,6 +11141,7 @@ packages: cpu: [x64] os: [android] requiresBuild: true + dev: true optional: true /@esbuild/android-x64@0.17.5: @@ -11146,6 +11168,7 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true + dev: true optional: true /@esbuild/darwin-arm64@0.17.5: @@ -11172,6 +11195,7 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true + dev: true optional: true /@esbuild/darwin-x64@0.17.5: @@ -11198,6 +11222,7 @@ packages: cpu: [arm64] os: [freebsd] requiresBuild: true + dev: true optional: true /@esbuild/freebsd-arm64@0.17.5: @@ -11224,6 +11249,7 @@ packages: cpu: [x64] os: [freebsd] requiresBuild: true + dev: true optional: true /@esbuild/freebsd-x64@0.17.5: @@ -11250,6 +11276,7 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true + dev: true optional: true /@esbuild/linux-arm64@0.17.5: @@ -11276,6 +11303,7 @@ packages: cpu: [arm] os: [linux] requiresBuild: true + dev: true optional: true /@esbuild/linux-arm@0.17.5: @@ -11302,6 +11330,7 @@ packages: cpu: [ia32] os: [linux] requiresBuild: true + dev: true optional: true /@esbuild/linux-ia32@0.17.5: @@ -11337,6 +11366,7 @@ packages: cpu: [loong64] os: [linux] requiresBuild: true + dev: true optional: true /@esbuild/linux-loong64@0.17.5: @@ -11363,6 +11393,7 @@ packages: cpu: [mips64el] os: [linux] requiresBuild: true + dev: true optional: true /@esbuild/linux-mips64el@0.17.5: @@ -11389,6 +11420,7 @@ packages: cpu: [ppc64] os: [linux] requiresBuild: true + dev: true optional: true /@esbuild/linux-ppc64@0.17.5: @@ -11415,6 +11447,7 @@ packages: cpu: [riscv64] os: [linux] requiresBuild: true + dev: true optional: true /@esbuild/linux-riscv64@0.17.5: @@ -11441,6 +11474,7 @@ packages: cpu: [s390x] os: [linux] requiresBuild: true + dev: true optional: true /@esbuild/linux-s390x@0.17.5: @@ -11467,6 +11501,7 @@ packages: cpu: [x64] os: [linux] requiresBuild: true + dev: true optional: true /@esbuild/linux-x64@0.17.5: @@ -11493,6 +11528,7 @@ packages: cpu: [x64] os: [netbsd] requiresBuild: true + dev: true optional: true /@esbuild/netbsd-x64@0.17.5: @@ -11519,6 +11555,7 @@ packages: cpu: [x64] os: [openbsd] requiresBuild: true + dev: true optional: true /@esbuild/openbsd-x64@0.17.5: @@ -11545,6 +11582,7 @@ packages: cpu: [x64] os: [sunos] requiresBuild: true + dev: true optional: true /@esbuild/sunos-x64@0.17.5: @@ -11571,6 +11609,7 @@ packages: cpu: [arm64] os: [win32] requiresBuild: true + dev: true optional: true /@esbuild/win32-arm64@0.17.5: @@ -11597,6 +11636,7 @@ packages: cpu: [ia32] os: [win32] requiresBuild: true + dev: true optional: true /@esbuild/win32-ia32@0.17.5: @@ -11623,6 +11663,7 @@ packages: cpu: [x64] os: [win32] requiresBuild: true + dev: true optional: true /@esbuild/win32-x64@0.17.5: @@ -11634,16 +11675,6 @@ packages: dev: true optional: true - /@eslint-community/eslint-utils@4.4.0(eslint@8.15.0): - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - dependencies: - eslint: 8.15.0 - eslint-visitor-keys: 3.4.1 - dev: false - /@eslint-community/eslint-utils@4.4.0(eslint@8.41.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -11657,23 +11688,6 @@ packages: resolution: {integrity: sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - /@eslint/eslintrc@1.2.3: - resolution: {integrity: sha512-uGo44hIwoLGNyduRpjdEpovcbMdd+Nv7amtmJxnKmI8xj6yd5LncmSwDa5NgX/41lIFJtkjD6YdVfgEzPfJ5UA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - ajv: 6.12.6 - debug: 4.3.4 - espree: 9.5.2 - globals: 13.20.0 - ignore: 5.2.4 - import-fresh: 3.3.0 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - dev: false - /@eslint/eslintrc@2.0.3: resolution: {integrity: sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -13708,17 +13722,6 @@ packages: transitivePeerDependencies: - supports-color - /@humanwhocodes/config-array@0.9.5: - resolution: {integrity: sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==} - engines: {node: '>=10.10.0'} - dependencies: - '@humanwhocodes/object-schema': 1.2.1 - debug: 4.3.4 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - dev: false - /@humanwhocodes/module-importer@1.0.1: resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} @@ -13825,18 +13828,6 @@ packages: slash: 3.0.0 dev: true - /@jest/console@29.6.1: - resolution: {integrity: sha512-Aj772AYgwTSr5w8qnyoJ0eDYvN6bMsH3ORH1ivMotrInHLKdUz6BDlaEXHdM6kODaBIkNIyQGzsMvRdOv7VG7Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.6.1 - '@types/node': 18.16.19 - chalk: 4.1.2 - jest-message-util: 29.6.1 - jest-util: 29.6.1 - slash: 3.0.0 - dev: true - /@jest/core@24.9.0: resolution: {integrity: sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A==} engines: {node: '>= 6'} @@ -14141,49 +14132,6 @@ packages: - ts-node dev: true - /@jest/core@29.6.1: - resolution: {integrity: sha512-CcowHypRSm5oYQ1obz1wfvkjZZ2qoQlrKKvlfPwh5jUXVU12TWr2qMeH8chLMuTFzHh5a1g2yaqlqDICbr+ukQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/console': 29.6.1 - '@jest/reporters': 29.6.1 - '@jest/test-result': 29.6.1 - '@jest/transform': 29.6.1 - '@jest/types': 29.6.1 - '@types/node': 18.16.19 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - ci-info: 3.3.2 - exit: 0.1.2 - graceful-fs: 4.2.10 - jest-changed-files: 29.5.0 - jest-config: 29.6.1(@types/node@18.16.19) - jest-haste-map: 29.6.1 - jest-message-util: 29.6.1 - jest-regex-util: 29.4.3 - jest-resolve: 29.6.1 - jest-resolve-dependencies: 29.6.1 - jest-runner: 29.6.1 - jest-runtime: 29.6.1 - jest-snapshot: 29.6.1 - jest-util: 29.6.1 - jest-validate: 29.6.1 - jest-watcher: 29.6.1 - micromatch: 4.0.5 - pretty-format: 29.6.1 - slash: 3.0.0 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - metro - - supports-color - - ts-node - dev: true - /@jest/create-cache-key-function@29.5.0: resolution: {integrity: sha512-LIDZyZgnZss7uikvBKBB/USWwG+GO8+GnwRWT+YkCGDGsqLQlhm9BC3z6+7+eMs1kUlvXQIWEzBR8Q2Pnvx6lg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -14231,16 +14179,6 @@ packages: '@types/node': 18.16.19 jest-mock: 29.5.0 - /@jest/environment@29.6.1: - resolution: {integrity: sha512-RMMXx4ws+Gbvw3DfLSuo2cfQlK7IwGbpuEWXCqyYDcqYTI+9Ju3a5hDnXaxjNsa6uKh9PQF2v+qg+RLe63tz5A==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/fake-timers': 29.6.1 - '@jest/types': 29.6.1 - '@types/node': 18.16.19 - jest-mock: 29.6.1 - dev: true - /@jest/expect-utils@28.1.3: resolution: {integrity: sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} @@ -14255,13 +14193,6 @@ packages: jest-get-type: 29.4.3 dev: true - /@jest/expect-utils@29.6.1: - resolution: {integrity: sha512-o319vIf5pEMx0LmzSxxkYYxo4wrRLKHq9dP1yJU7FoPTB0LfAKSz8SWD6D/6U3v/O52t9cF5t+MeJiRsfk7zMw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - jest-get-type: 29.4.3 - dev: true - /@jest/expect@28.1.3: resolution: {integrity: sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} @@ -14284,17 +14215,6 @@ packages: - supports-color dev: true - /@jest/expect@29.6.1: - resolution: {integrity: sha512-N5xlPrAYaRNyFgVf2s9Uyyvr795jnB6rObuPx4QFvNJz8aAjpZUDfO4bh5G/xuplMID8PrnuF1+SfSyDxhsgYg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - expect: 29.6.1 - jest-snapshot: 29.6.1 - transitivePeerDependencies: - - metro - - supports-color - dev: true - /@jest/fake-timers@24.9.0: resolution: {integrity: sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==} engines: {node: '>= 6'} @@ -14340,18 +14260,6 @@ packages: jest-mock: 29.5.0 jest-util: 29.6.1 - /@jest/fake-timers@29.6.1: - resolution: {integrity: sha512-RdgHgbXyosCDMVYmj7lLpUwXA4c69vcNzhrt69dJJdf8azUrpRh3ckFCaTPNjsEeRi27Cig0oKDGxy5j7hOgHg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.6.1 - '@sinonjs/fake-timers': 10.2.0 - '@types/node': 18.16.19 - jest-message-util: 29.6.1 - jest-mock: 29.6.1 - jest-util: 29.6.1 - dev: true - /@jest/globals@27.5.1: resolution: {integrity: sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -14385,19 +14293,6 @@ packages: - supports-color dev: true - /@jest/globals@29.6.1: - resolution: {integrity: sha512-2VjpaGy78JY9n9370H8zGRCFbYVWwjY6RdDMhoJHa1sYfwe6XM/azGN0SjY8kk7BOZApIejQ1BFPyH7FPG0w3A==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/environment': 29.6.1 - '@jest/expect': 29.6.1 - '@jest/types': 29.6.1 - jest-mock: 29.6.1 - transitivePeerDependencies: - - metro - - supports-color - dev: true - /@jest/reporters@24.9.0: resolution: {integrity: sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw==} engines: {node: '>= 6'} @@ -14482,7 +14377,7 @@ packages: '@jest/test-result': 28.1.3 '@jest/transform': 28.1.3 '@jest/types': 28.1.3 - '@jridgewell/trace-mapping': 0.3.17 + '@jridgewell/trace-mapping': 0.3.18 '@types/node': 18.16.19 chalk: 4.1.2 collect-v8-coverage: 1.0.1 @@ -14521,7 +14416,7 @@ packages: '@jest/test-result': 28.1.3 '@jest/transform': 28.1.3(metro@0.76.0) '@jest/types': 28.1.3 - '@jridgewell/trace-mapping': 0.3.17 + '@jridgewell/trace-mapping': 0.3.18 '@types/node': 18.16.19 chalk: 4.1.2 collect-v8-coverage: 1.0.1 @@ -14584,44 +14479,6 @@ packages: - supports-color dev: true - /@jest/reporters@29.6.1: - resolution: {integrity: sha512-9zuaI9QKr9JnoZtFQlw4GREQbxgmNYXU6QuWtmuODvk5nvPUeBYapVR/VYMyi2WSx3jXTLJTJji8rN6+Cm4+FA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 29.6.1 - '@jest/test-result': 29.6.1 - '@jest/transform': 29.6.1 - '@jest/types': 29.6.1 - '@jridgewell/trace-mapping': 0.3.18 - '@types/node': 18.16.19 - chalk: 4.1.2 - collect-v8-coverage: 1.0.1 - exit: 0.1.2 - glob: 7.2.3 - graceful-fs: 4.2.10 - istanbul-lib-coverage: 3.2.0 - istanbul-lib-instrument: 5.2.0 - istanbul-lib-report: 3.0.0 - istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.1.4 - jest-message-util: 29.6.1 - jest-util: 29.6.1 - jest-worker: 29.6.1 - slash: 3.0.0 - string-length: 4.0.2 - strip-ansi: 6.0.1 - v8-to-istanbul: 9.0.1 - transitivePeerDependencies: - - metro - - supports-color - dev: true - /@jest/schemas@28.1.3: resolution: {integrity: sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} @@ -14660,15 +14517,6 @@ packages: /@jest/source-map@28.1.2: resolution: {integrity: sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jridgewell/trace-mapping': 0.3.17 - callsites: 3.1.0 - graceful-fs: 4.2.10 - dev: true - - /@jest/source-map@29.6.0: - resolution: {integrity: sha512-oA+I2SHHQGxDCZpbrsCQSoMLb3Bz547JnM+jUr9qEbuw0vQlWZfpPS7CO9J7XiwKicEz9OFn/IYoLkkiUD7bzA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jridgewell/trace-mapping': 0.3.18 callsites: 3.1.0 @@ -14712,16 +14560,6 @@ packages: collect-v8-coverage: 1.0.1 dev: true - /@jest/test-result@29.6.1: - resolution: {integrity: sha512-Ynr13ZRcpX6INak0TPUukU8GWRfm/vAytE3JbJNGAvINySWYdfE7dGZMbk36oVuK4CigpbhMn8eg1dixZ7ZJOw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/console': 29.6.1 - '@jest/types': 29.6.1 - '@types/istanbul-lib-coverage': 2.0.4 - collect-v8-coverage: 1.0.1 - dev: true - /@jest/test-sequencer@24.9.0: resolution: {integrity: sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A==} engines: {node: '>= 6'} @@ -14773,18 +14611,6 @@ packages: - metro dev: true - /@jest/test-sequencer@29.6.1: - resolution: {integrity: sha512-oBkC36PCDf/wb6dWeQIhaviU0l5u6VCsXa119yqdUosYAt7/FbQU2M2UoziO3igj/HBDEgp57ONQ3fm0v9uyyg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/test-result': 29.6.1 - graceful-fs: 4.2.10 - jest-haste-map: 29.6.1 - slash: 3.0.0 - transitivePeerDependencies: - - metro - dev: true - /@jest/transform@24.9.0: resolution: {integrity: sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ==} engines: {node: '>= 6'} @@ -14953,30 +14779,6 @@ packages: - supports-color dev: true - /@jest/transform@29.6.1: - resolution: {integrity: sha512-URnTneIU3ZjRSaf906cvf6Hpox3hIeJXRnz3VDSw5/X93gR8ycdfSIEy19FlVx8NFmpN7fe3Gb1xF+NjXaQLWg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@babel/core': 7.21.0 - '@jest/types': 29.6.1 - '@jridgewell/trace-mapping': 0.3.18 - babel-plugin-istanbul: 6.1.1 - chalk: 4.1.2 - convert-source-map: 2.0.0 - fast-json-stable-stringify: 2.1.0 - graceful-fs: 4.2.10 - jest-haste-map: 29.6.1 - jest-regex-util: 29.4.3 - jest-util: 29.6.1 - micromatch: 4.0.5 - pirates: 4.0.5 - slash: 3.0.0 - write-file-atomic: 4.0.2 - transitivePeerDependencies: - - metro - - supports-color - dev: true - /@jest/types@24.9.0: resolution: {integrity: sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==} engines: {node: '>= 6'} @@ -15051,7 +14853,7 @@ packages: dependencies: '@jridgewell/set-array': 1.1.1 '@jridgewell/sourcemap-codec': 1.4.14 - '@jridgewell/trace-mapping': 0.3.17 + '@jridgewell/trace-mapping': 0.3.18 /@jridgewell/resolve-uri@3.1.0: resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} @@ -15909,53 +15711,12 @@ packages: error-stack-parser: 2.0.7 find-up: 5.0.0 html-entities: 2.3.3 - loader-utils: 2.0.2 + loader-utils: 2.0.4 react-refresh: 0.11.0 schema-utils: 3.1.1 source-map: 0.7.4 - webpack: 5.76.1(metro@0.76.0) + webpack: 5.76.1 webpack-dev-server: 4.12.0(webpack@5.76.1) - dev: true - - /@pmmmwh/react-refresh-webpack-plugin@0.5.7(react-refresh@0.11.0)(webpack-dev-server@4.9.3)(webpack@5.72.1): - resolution: {integrity: sha512-bcKCAzF0DV2IIROp9ZHkRJa6O4jy7NlnHdWL3GmcUxYWNjLXkK5kfELELwEfSP5hXPfVL/qOGMAROuMQb9GG8Q==} - engines: {node: '>= 10.13'} - peerDependencies: - '@types/webpack': 4.x || 5.x - react-refresh: '>=0.10.0 <1.0.0' - sockjs-client: ^1.4.0 - type-fest: '>=0.17.0 <3.0.0' - webpack: '>=4.43.0 <6.0.0' - webpack-dev-server: 3.x || 4.x - webpack-hot-middleware: 2.x - webpack-plugin-serve: 0.x || 1.x - peerDependenciesMeta: - '@types/webpack': - optional: true - sockjs-client: - optional: true - type-fest: - optional: true - webpack-dev-server: - optional: true - webpack-hot-middleware: - optional: true - webpack-plugin-serve: - optional: true - dependencies: - ansi-html-community: 0.0.8 - common-path-prefix: 3.0.0 - core-js-pure: 3.22.5 - error-stack-parser: 2.0.7 - find-up: 5.0.0 - html-entities: 2.3.3 - loader-utils: 2.0.2 - react-refresh: 0.11.0 - schema-utils: 3.1.1 - source-map: 0.7.4 - webpack: 5.72.1 - webpack-dev-server: 4.9.3(webpack@5.72.1) - dev: false /@pmmmwh/react-refresh-webpack-plugin@0.5.7(react-refresh@0.11.0)(webpack@4.46.0): resolution: {integrity: sha512-bcKCAzF0DV2IIROp9ZHkRJa6O4jy7NlnHdWL3GmcUxYWNjLXkK5kfELELwEfSP5hXPfVL/qOGMAROuMQb9GG8Q==} @@ -15989,7 +15750,7 @@ packages: error-stack-parser: 2.0.7 find-up: 5.0.0 html-entities: 2.3.3 - loader-utils: 2.0.2 + loader-utils: 2.0.4 react-refresh: 0.11.0 schema-utils: 3.1.1 source-map: 0.7.4 @@ -19705,8 +19466,8 @@ packages: '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.21.0) '@babel/plugin-proposal-object-rest-spread': 7.20.7(@babel/core@7.21.0) '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.21.0) - '@babel/plugin-proposal-private-methods': 7.16.11(@babel/core@7.21.0) - '@babel/plugin-proposal-private-property-in-object': 7.16.7(@babel/core@7.21.0) + '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.21.0) + '@babel/plugin-proposal-private-property-in-object': 7.21.0(@babel/core@7.21.0) '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.21.0) '@babel/plugin-transform-arrow-functions': 7.20.7(@babel/core@7.21.0) '@babel/plugin-transform-block-scoping': 7.21.0(@babel/core@7.21.0) @@ -19776,8 +19537,8 @@ packages: '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.21.0) '@babel/plugin-proposal-object-rest-spread': 7.20.7(@babel/core@7.21.0) '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.21.0) - '@babel/plugin-proposal-private-methods': 7.16.11(@babel/core@7.21.0) - '@babel/plugin-proposal-private-property-in-object': 7.16.7(@babel/core@7.21.0) + '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.21.0) + '@babel/plugin-proposal-private-property-in-object': 7.21.0(@babel/core@7.21.0) '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.21.0) '@babel/plugin-transform-arrow-functions': 7.20.7(@babel/core@7.21.0) '@babel/plugin-transform-block-scoping': 7.21.0(@babel/core@7.21.0) @@ -20383,7 +20144,7 @@ packages: '@mdx-js/mdx': 1.6.22 '@types/lodash': 4.14.191 js-string-escape: 1.0.1 - loader-utils: 2.0.2 + loader-utils: 2.0.4 lodash: 4.17.21 prettier: 2.3.0 ts-dedent: 2.2.0 @@ -21435,12 +21196,12 @@ packages: dependencies: '@babel/core': 7.21.0 '@babel/plugin-transform-react-constant-elements': 7.17.6(@babel/core@7.21.0) - '@babel/preset-env': 7.17.10(@babel/core@7.21.0) + '@babel/preset-env': 7.21.4(@babel/core@7.21.0) '@babel/preset-react': 7.16.7(@babel/core@7.21.0) '@svgr/core': 5.5.0(@svgr/plugin-svgo@5.5.0) '@svgr/plugin-jsx': 5.5.0 '@svgr/plugin-svgo': 5.5.0 - loader-utils: 2.0.2 + loader-utils: 2.0.4 transitivePeerDependencies: - supports-color dev: false @@ -22740,7 +22501,7 @@ packages: /@types/serve-handler@6.1.1: resolution: {integrity: sha512-bIwSmD+OV8w0t2e7EWsuQYlGoS1o5aEdVktgkXaa43Zm0qVWi21xaSRb3DQA1UXD+DJ5bRq1Rgu14ZczB+CjIQ==} dependencies: - '@types/node': 17.0.32 + '@types/node': 18.16.19 dev: true /@types/serve-index@1.9.1: @@ -22991,34 +22752,6 @@ packages: transitivePeerDependencies: - supports-color - /@typescript-eslint/eslint-plugin@5.59.6(@typescript-eslint/parser@5.60.0)(eslint@8.15.0)(typescript@5.1.3): - resolution: {integrity: sha512-sXtOgJNEuRU5RLwPUb1jxtToZbgvq3M6FPpY4QENxoOggK+UpTxUBpj6tD8+Qh2g46Pi9We87E+eHnUw8YcGsw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - '@typescript-eslint/parser': ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@eslint-community/regexpp': 4.5.0 - '@typescript-eslint/parser': 5.60.0(eslint@8.15.0)(typescript@5.1.3) - '@typescript-eslint/scope-manager': 5.59.6 - '@typescript-eslint/type-utils': 5.59.6(eslint@8.15.0)(typescript@5.1.3) - '@typescript-eslint/utils': 5.59.6(eslint@8.15.0)(typescript@5.1.3) - debug: 4.3.4 - eslint: 8.15.0 - grapheme-splitter: 1.0.4 - ignore: 5.2.4 - natural-compare-lite: 1.4.0 - semver: 7.3.8 - tsutils: 3.21.0(typescript@5.1.3) - typescript: 5.1.3 - transitivePeerDependencies: - - supports-color - dev: false - /@typescript-eslint/eslint-plugin@5.59.6(@typescript-eslint/parser@5.60.0)(eslint@8.41.0)(typescript@5.1.3): resolution: {integrity: sha512-sXtOgJNEuRU5RLwPUb1jxtToZbgvq3M6FPpY4QENxoOggK+UpTxUBpj6tD8+Qh2g46Pi9We87E+eHnUw8YcGsw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -23045,7 +22778,6 @@ packages: typescript: 5.1.3 transitivePeerDependencies: - supports-color - dev: true /@typescript-eslint/experimental-utils@2.34.0(eslint@6.8.0)(typescript@5.1.3): resolution: {integrity: sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==} @@ -23062,7 +22794,7 @@ packages: - supports-color - typescript - /@typescript-eslint/experimental-utils@5.3.1(eslint@8.15.0)(typescript@5.1.3): + /@typescript-eslint/experimental-utils@5.3.1(eslint@8.41.0)(typescript@5.1.3): resolution: {integrity: sha512-RgFn5asjZ5daUhbK5Sp0peq0SSMytqcrkNfU4pnDma2D8P3ElZ6JbYjY8IMSFfZAJ0f3x3tnO3vXHweYg0g59w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -23072,9 +22804,9 @@ packages: '@typescript-eslint/scope-manager': 5.3.1 '@typescript-eslint/types': 5.3.1 '@typescript-eslint/typescript-estree': 5.3.1(typescript@5.1.3) - eslint: 8.15.0 + eslint: 8.41.0 eslint-scope: 5.1.1 - eslint-utils: 3.0.0(eslint@8.15.0) + eslint-utils: 3.0.0(eslint@8.41.0) transitivePeerDependencies: - supports-color - typescript @@ -23099,26 +22831,6 @@ packages: transitivePeerDependencies: - supports-color - /@typescript-eslint/parser@5.60.0(eslint@8.15.0)(typescript@5.1.3): - resolution: {integrity: sha512-jBONcBsDJ9UoTWrARkRRCgDz6wUggmH5RpQVlt7BimSwaTkTjwypGzKORXbR4/2Hqjk9hgwlon2rVQAjWNpkyQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/scope-manager': 5.60.0 - '@typescript-eslint/types': 5.60.0 - '@typescript-eslint/typescript-estree': 5.60.0(typescript@5.1.3) - debug: 4.3.4 - eslint: 8.15.0 - typescript: 5.1.3 - transitivePeerDependencies: - - supports-color - dev: false - /@typescript-eslint/parser@5.60.0(eslint@8.41.0)(typescript@5.1.3): resolution: {integrity: sha512-jBONcBsDJ9UoTWrARkRRCgDz6wUggmH5RpQVlt7BimSwaTkTjwypGzKORXbR4/2Hqjk9hgwlon2rVQAjWNpkyQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -23137,7 +22849,6 @@ packages: typescript: 5.1.3 transitivePeerDependencies: - supports-color - dev: true /@typescript-eslint/scope-manager@5.3.1: resolution: {integrity: sha512-XksFVBgAq0Y9H40BDbuPOTUIp7dn4u8oOuhcgGq7EoDP50eqcafkMVGrypyVGvDYHzjhdUCUwuwVUK4JhkMAMg==} @@ -23169,26 +22880,6 @@ packages: '@typescript-eslint/types': 5.60.0 '@typescript-eslint/visitor-keys': 5.60.0 - /@typescript-eslint/type-utils@5.59.6(eslint@8.15.0)(typescript@5.1.3): - resolution: {integrity: sha512-A4tms2Mp5yNvLDlySF+kAThV9VTBPCvGf0Rp8nl/eoDX9Okun8byTKoj3fJ52IJitjWOk0fKPNQhXEB++eNozQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: '*' - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/typescript-estree': 5.59.6(typescript@5.1.3) - '@typescript-eslint/utils': 5.59.6(eslint@8.15.0)(typescript@5.1.3) - debug: 4.3.4 - eslint: 8.15.0 - tsutils: 3.21.0(typescript@5.1.3) - typescript: 5.1.3 - transitivePeerDependencies: - - supports-color - dev: false - /@typescript-eslint/type-utils@5.59.6(eslint@8.41.0)(typescript@5.1.3): resolution: {integrity: sha512-A4tms2Mp5yNvLDlySF+kAThV9VTBPCvGf0Rp8nl/eoDX9Okun8byTKoj3fJ52IJitjWOk0fKPNQhXEB++eNozQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -23207,7 +22898,6 @@ packages: typescript: 5.1.3 transitivePeerDependencies: - supports-color - dev: true /@typescript-eslint/types@5.3.1: resolution: {integrity: sha512-bG7HeBLolxKHtdHG54Uac750eXuQQPpdJfCYuw4ZI3bZ7+GgKClMWM8jExBtp7NSP4m8PmLRM8+lhzkYnSmSxQ==} @@ -23343,31 +23033,11 @@ packages: '@typescript-eslint/typescript-estree': 5.57.0(typescript@5.1.3) eslint: 8.41.0 eslint-scope: 5.1.1 - semver: 7.3.8 - transitivePeerDependencies: - - supports-color - - typescript - dev: true - - /@typescript-eslint/utils@5.59.6(eslint@8.15.0)(typescript@5.1.3): - resolution: {integrity: sha512-vzaaD6EXbTS29cVH0JjXBdzMt6VBlv+hE31XktDRMX1j3462wZCJa7VzO2AxXEXcIl8GQqZPcOPuW/Z1tZVogg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.15.0) - '@types/json-schema': 7.0.11 - '@types/semver': 7.3.13 - '@typescript-eslint/scope-manager': 5.59.6 - '@typescript-eslint/types': 5.59.6 - '@typescript-eslint/typescript-estree': 5.59.6(typescript@5.1.3) - eslint: 8.15.0 - eslint-scope: 5.1.1 semver: 7.5.3 transitivePeerDependencies: - supports-color - typescript - dev: false + dev: true /@typescript-eslint/utils@5.59.6(eslint@8.41.0)(typescript@5.1.3): resolution: {integrity: sha512-vzaaD6EXbTS29cVH0JjXBdzMt6VBlv+hE31XktDRMX1j3462wZCJa7VzO2AxXEXcIl8GQqZPcOPuW/Z1tZVogg==} @@ -23387,7 +23057,6 @@ packages: transitivePeerDependencies: - supports-color - typescript - dev: true /@typescript-eslint/visitor-keys@5.3.1: resolution: {integrity: sha512-3cHUzUuVTuNHx0Gjjt5pEHa87+lzyqOiHXy/Gz+SJOCW1mpw9xQHIIEwnKn+Thph1mgWyZ90nboOcSuZr/jTTQ==} @@ -24126,6 +23795,7 @@ packages: acorn: ^8 dependencies: acorn: 8.7.1 + dev: true /acorn-import-assertions@1.8.0(acorn@8.8.2): resolution: {integrity: sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==} @@ -24133,7 +23803,6 @@ packages: acorn: ^8 dependencies: acorn: 8.8.2 - dev: true /acorn-jsx@5.3.2(acorn@7.4.1): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} @@ -24187,6 +23856,7 @@ packages: resolution: {integrity: sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==} engines: {node: '>=0.4.0'} hasBin: true + dev: true /acorn@8.8.2: resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} @@ -24218,7 +23888,7 @@ packages: resolution: {integrity: sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==} engines: {node: '>=8.9'} dependencies: - loader-utils: 2.0.2 + loader-utils: 2.0.4 regex-parser: 2.2.11 dev: false @@ -24564,7 +24234,7 @@ packages: minimatch: 3.1.2 read-config-file: 6.2.0 sanitize-filename: 1.6.3 - semver: 7.3.8 + semver: 7.5.3 tar: 6.1.11 temp-file: 3.4.0 transitivePeerDependencies: @@ -24982,7 +24652,7 @@ packages: postcss: 7.0.39 postcss-value-parser: 4.2.0 - /autoprefixer@10.4.8(postcss@8.4.13): + /autoprefixer@10.4.8(postcss@8.4.21): resolution: {integrity: sha512-75Jr6Q/XpTqEf6D2ltS5uMewJIx5irCU1oBYJrWjFenq/m12WRRrz6g15L1EIoYvPLXTbEry7rDOwrcYNj77xw==} engines: {node: ^10 || ^12 || >=14} hasBin: true @@ -24994,7 +24664,7 @@ packages: fraction.js: 4.2.0 normalize-range: 0.1.2 picocolors: 1.0.0 - postcss: 8.4.13 + postcss: 8.4.21 postcss-value-parser: 4.2.0 dev: false @@ -25294,25 +24964,6 @@ packages: - supports-color dev: true - /babel-jest@29.6.1(@babel/core@7.21.0): - resolution: {integrity: sha512-qu+3bdPEQC6KZSPz+4Fyjbga5OODNcp49j6GKzG1EKbkfyJBxEYGVUmVGpwCSeGouG52R4EgYMLb6p9YeEEQ4A==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.8.0 - dependencies: - '@babel/core': 7.21.0 - '@jest/transform': 29.6.1 - '@types/babel__core': 7.1.19 - babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.5.0(@babel/core@7.21.0) - chalk: 4.1.2 - graceful-fs: 4.2.10 - slash: 3.0.0 - transitivePeerDependencies: - - metro - - supports-color - dev: true - /babel-loader@8.1.0(@babel/core@7.9.0)(webpack@4.42.0): resolution: {integrity: sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==} engines: {node: '>= 6.9'} @@ -25356,6 +25007,7 @@ packages: make-dir: 3.1.0 schema-utils: 2.7.1 webpack: 5.72.1(esbuild@0.17.14) + dev: true /babel-loader@8.2.5(@babel/core@7.21.0)(webpack@5.76.1): resolution: {integrity: sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ==} @@ -25369,8 +25021,7 @@ packages: loader-utils: 2.0.2 make-dir: 3.1.0 schema-utils: 2.7.1 - webpack: 5.76.1(metro@0.76.0) - dev: true + webpack: 5.76.1 /babel-messages@6.23.0: resolution: {integrity: sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=} @@ -25478,16 +25129,6 @@ packages: '@types/babel__traverse': 7.17.1 dev: true - /babel-plugin-jest-hoist@29.5.0: - resolution: {integrity: sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@babel/template': 7.22.5 - '@babel/types': 7.22.5 - '@types/babel__core': 7.1.19 - '@types/babel__traverse': 7.17.1 - dev: true - /babel-plugin-macros@2.8.0: resolution: {integrity: sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==} dependencies: @@ -25881,17 +25522,6 @@ packages: babel-preset-current-node-syntax: 1.0.1(@babel/core@7.21.0) dev: true - /babel-preset-jest@29.5.0(@babel/core@7.21.0): - resolution: {integrity: sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.21.0 - babel-plugin-jest-hoist: 29.5.0 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.21.0) - dev: true - /babel-preset-react-app@10.0.1: resolution: {integrity: sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg==} dependencies: @@ -25899,14 +25529,14 @@ packages: '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.21.0) '@babel/plugin-proposal-decorators': 7.17.9(@babel/core@7.21.0) '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.21.0) - '@babel/plugin-proposal-numeric-separator': 7.16.7(@babel/core@7.21.0) + '@babel/plugin-proposal-numeric-separator': 7.18.6(@babel/core@7.21.0) '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.21.0) - '@babel/plugin-proposal-private-methods': 7.16.11(@babel/core@7.21.0) - '@babel/plugin-proposal-private-property-in-object': 7.16.7(@babel/core@7.21.0) + '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.21.0) + '@babel/plugin-proposal-private-property-in-object': 7.21.0(@babel/core@7.21.0) '@babel/plugin-transform-flow-strip-types': 7.16.7(@babel/core@7.21.0) '@babel/plugin-transform-react-display-name': 7.16.7(@babel/core@7.21.0) '@babel/plugin-transform-runtime': 7.17.10(@babel/core@7.21.0) - '@babel/preset-env': 7.17.10(@babel/core@7.21.0) + '@babel/preset-env': 7.21.4(@babel/core@7.21.0) '@babel/preset-react': 7.16.7(@babel/core@7.21.0) '@babel/preset-typescript': 7.16.7(@babel/core@7.21.0) '@babel/runtime': 7.20.13 @@ -26704,6 +26334,7 @@ packages: escalade: 3.1.1 node-releases: 2.0.10 picocolors: 1.0.0 + dev: true /browserslist@4.21.3: resolution: {integrity: sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==} @@ -26714,7 +26345,6 @@ packages: electron-to-chromium: 1.4.355 node-releases: 2.0.10 update-browserslist-db: 1.0.10(browserslist@4.21.3) - dev: true /browserslist@4.21.5: resolution: {integrity: sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==} @@ -28051,7 +27681,7 @@ packages: json-schema-typed: 7.0.3 onetime: 5.1.2 pkg-up: 3.1.0 - semver: 7.3.8 + semver: 7.5.3 dev: false /configstore@5.0.1: @@ -28101,9 +27731,8 @@ packages: engines: {node: '>=0.10.0'} /content-disposition@0.5.2: - resolution: {integrity: sha1-DPaLud318r55YcOoUXjLhdunjLQ=} + resolution: {integrity: sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==} engines: {node: '>= 0.6'} - dev: true /content-disposition@0.5.4: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} @@ -28685,14 +28314,14 @@ packages: postcss: 7.0.39 postcss-selector-parser: 6.0.10 - /css-blank-pseudo@3.0.3(postcss@8.4.13): + /css-blank-pseudo@3.0.3(postcss@8.4.21): resolution: {integrity: sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==} engines: {node: ^12 || ^14 || >=16} hasBin: true peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-selector-parser: 6.0.10 dev: false @@ -28741,14 +28370,14 @@ packages: postcss: 7.0.39 postcss-selector-parser: 6.0.10 - /css-has-pseudo@3.0.4(postcss@8.4.13): + /css-has-pseudo@3.0.4(postcss@8.4.21): resolution: {integrity: sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==} engines: {node: ^12 || ^14 || >=16} hasBin: true peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-selector-parser: 6.0.10 dev: false @@ -28808,7 +28437,7 @@ packages: webpack: ^4.27.0 || ^5.0.0 dependencies: icss-utils: 5.1.0(postcss@8.4.21) - loader-utils: 2.0.2 + loader-utils: 2.0.4 postcss: 8.4.21 postcss-modules-extract-imports: 3.0.0(postcss@8.4.21) postcss-modules-local-by-default: 4.0.0(postcss@8.4.21) @@ -28820,23 +28449,6 @@ packages: webpack: 5.76.1(metro@0.76.0) dev: true - /css-loader@6.7.1(webpack@5.72.1): - resolution: {integrity: sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw==} - engines: {node: '>= 12.13.0'} - peerDependencies: - webpack: ^5.0.0 - dependencies: - icss-utils: 5.1.0(postcss@8.4.21) - postcss: 8.4.21 - postcss-modules-extract-imports: 3.0.0(postcss@8.4.21) - postcss-modules-local-by-default: 4.0.0(postcss@8.4.21) - postcss-modules-scope: 3.0.0(postcss@8.4.21) - postcss-modules-values: 4.0.0(postcss@8.4.21) - postcss-value-parser: 4.2.0 - semver: 7.5.3 - webpack: 5.72.1 - dev: false - /css-loader@6.7.1(webpack@5.76.1): resolution: {integrity: sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw==} engines: {node: '>= 12.13.0'} @@ -28851,8 +28463,7 @@ packages: postcss-modules-values: 4.0.0(postcss@8.4.21) postcss-value-parser: 4.2.0 semver: 7.5.3 - webpack: 5.76.1(metro@0.76.0) - dev: true + webpack: 5.76.1 /css-minimizer-webpack-plugin@3.4.1(metro@0.76.0)(webpack@5.76.1): resolution: {integrity: sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==} @@ -28884,7 +28495,7 @@ packages: - metro dev: true - /css-minimizer-webpack-plugin@3.4.1(webpack@5.72.1): + /css-minimizer-webpack-plugin@3.4.1(webpack@5.76.1): resolution: {integrity: sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==} engines: {node: '>= 12.13.0'} peerDependencies: @@ -28909,7 +28520,7 @@ packages: schema-utils: 4.0.0 serialize-javascript: 6.0.0 source-map: 0.6.1 - webpack: 5.72.1 + webpack: 5.76.1 transitivePeerDependencies: - metro dev: false @@ -28930,14 +28541,14 @@ packages: dependencies: postcss: 7.0.39 - /css-prefers-color-scheme@6.0.3(postcss@8.4.13): + /css-prefers-color-scheme@6.0.3(postcss@8.4.21): resolution: {integrity: sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==} engines: {node: ^12 || ^14 || >=16} hasBin: true peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 dev: false /css-select-base-adapter@0.1.1: @@ -30516,11 +30127,6 @@ packages: resolution: {integrity: sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==} engines: {node: '>=12'} - /emittery@0.13.1: - resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} - engines: {node: '>=12'} - dev: true - /emittery@0.8.1: resolution: {integrity: sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==} engines: {node: '>=10'} @@ -30627,6 +30233,7 @@ packages: dependencies: graceful-fs: 4.2.10 tapable: 2.2.1 + dev: true /enquirer@2.3.6: resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} @@ -31284,6 +30891,7 @@ packages: '@esbuild/win32-arm64': 0.17.14 '@esbuild/win32-ia32': 0.17.14 '@esbuild/win32-x64': 0.17.14 + dev: true /esbuild@0.17.5: resolution: {integrity: sha512-Bu6WLCc9NMsNoMJUjGl3yBzTjVLXdysMltxQWiLAypP+/vQrf+3L1Xe8fCXzxaECus2cEJ9M7pk4yKatEwQMqQ==} @@ -31400,7 +31008,7 @@ packages: eslint-plugin-react-hooks: 1.7.0(eslint@6.8.0) typescript: 5.1.3 - /eslint-config-react-app@7.0.1(eslint@8.15.0)(jest@27.5.1)(typescript@5.1.3): + /eslint-config-react-app@7.0.1(eslint@8.41.0)(jest@27.5.1)(typescript@5.1.3): resolution: {integrity: sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==} engines: {node: '>=14.0.0'} peerDependencies: @@ -31411,20 +31019,20 @@ packages: optional: true dependencies: '@babel/core': 7.21.0 - '@babel/eslint-parser': 7.18.9(@babel/core@7.21.0)(eslint@8.15.0) + '@babel/eslint-parser': 7.18.9(@babel/core@7.21.0)(eslint@8.41.0) '@rushstack/eslint-patch': 1.1.4 - '@typescript-eslint/eslint-plugin': 5.59.6(@typescript-eslint/parser@5.60.0)(eslint@8.15.0)(typescript@5.1.3) - '@typescript-eslint/parser': 5.60.0(eslint@8.15.0)(typescript@5.1.3) + '@typescript-eslint/eslint-plugin': 5.59.6(@typescript-eslint/parser@5.60.0)(eslint@8.41.0)(typescript@5.1.3) + '@typescript-eslint/parser': 5.60.0(eslint@8.41.0)(typescript@5.1.3) babel-preset-react-app: 10.0.1 confusing-browser-globals: 1.0.11 - eslint: 8.15.0 - eslint-plugin-flowtype: 8.0.3(eslint@8.15.0) - eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.0)(eslint@8.15.0) - eslint-plugin-jest: 25.7.0(@typescript-eslint/eslint-plugin@5.59.6)(eslint@8.15.0)(jest@27.5.1)(typescript@5.1.3) - eslint-plugin-jsx-a11y: 6.7.1(eslint@8.15.0) - eslint-plugin-react: 7.32.2(eslint@8.15.0) - eslint-plugin-react-hooks: 4.6.0(eslint@8.15.0) - eslint-plugin-testing-library: 5.6.0(eslint@8.15.0)(typescript@5.1.3) + eslint: 8.41.0 + eslint-plugin-flowtype: 8.0.3(eslint@8.41.0) + eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.0)(eslint@8.41.0) + eslint-plugin-jest: 25.7.0(@typescript-eslint/eslint-plugin@5.59.6)(eslint@8.41.0)(jest@27.5.1)(typescript@5.1.3) + eslint-plugin-jsx-a11y: 6.7.1(eslint@8.41.0) + eslint-plugin-react: 7.32.2(eslint@8.41.0) + eslint-plugin-react-hooks: 4.6.0(eslint@8.41.0) + eslint-plugin-testing-library: 5.6.0(eslint@8.41.0)(typescript@5.1.3) typescript: 5.1.3 transitivePeerDependencies: - '@babel/plugin-syntax-flow' @@ -31542,35 +31150,6 @@ packages: - supports-color dev: true - /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-node@0.3.7)(eslint@8.15.0): - resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true - dependencies: - '@typescript-eslint/parser': 5.60.0(eslint@8.15.0)(typescript@5.1.3) - debug: 3.2.7 - eslint: 8.15.0 - eslint-import-resolver-node: 0.3.7 - transitivePeerDependencies: - - supports-color - dev: false - /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-node@0.3.7)(eslint@8.41.0): resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} engines: {node: '>=4'} @@ -31598,7 +31177,6 @@ packages: eslint-import-resolver-node: 0.3.7 transitivePeerDependencies: - supports-color - dev: true /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0): resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} @@ -31655,7 +31233,7 @@ packages: eslint: 6.8.0 lodash: 4.17.21 - /eslint-plugin-flowtype@8.0.3(eslint@8.15.0): + /eslint-plugin-flowtype@8.0.3(eslint@8.41.0): resolution: {integrity: sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -31663,7 +31241,7 @@ packages: '@babel/plugin-transform-react-jsx': ^7.14.9 eslint: ^8.1.0 dependencies: - eslint: 8.15.0 + eslint: 8.41.0 lodash: 4.17.21 string-natural-compare: 3.0.1 dev: false @@ -31738,39 +31316,6 @@ packages: - supports-color dev: true - /eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.60.0)(eslint@8.15.0): - resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - dependencies: - '@typescript-eslint/parser': 5.60.0(eslint@8.15.0)(typescript@5.1.3) - array-includes: 3.1.6 - array.prototype.flat: 1.3.1 - array.prototype.flatmap: 1.3.1 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 8.15.0 - eslint-import-resolver-node: 0.3.7 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-node@0.3.7)(eslint@8.15.0) - has: 1.0.3 - is-core-module: 2.11.0 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.values: 1.1.6 - resolve: 1.22.1 - semver: 6.3.0 - tsconfig-paths: 3.14.1 - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - dev: false - /eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.60.0)(eslint@8.41.0): resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==} engines: {node: '>=4'} @@ -31802,24 +31347,23 @@ packages: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - dev: true - /eslint-plugin-jest@25.7.0(@typescript-eslint/eslint-plugin@5.59.6)(eslint@8.15.0)(jest@27.5.1)(typescript@5.1.3): + /eslint-plugin-jest@25.7.0(@typescript-eslint/eslint-plugin@5.59.6)(eslint@8.41.0)(jest@27.5.1)(typescript@5.1.3): resolution: {integrity: sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} peerDependencies: '@typescript-eslint/eslint-plugin': ^4.0.0 || ^5.0.0 eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - jest: '*' + jest: ^27.0.0 peerDependenciesMeta: '@typescript-eslint/eslint-plugin': optional: true jest: optional: true dependencies: - '@typescript-eslint/eslint-plugin': 5.59.6(@typescript-eslint/parser@5.60.0)(eslint@8.15.0)(typescript@5.1.3) - '@typescript-eslint/experimental-utils': 5.3.1(eslint@8.15.0)(typescript@5.1.3) - eslint: 8.15.0 + '@typescript-eslint/eslint-plugin': 5.59.6(@typescript-eslint/parser@5.60.0)(eslint@8.41.0)(typescript@5.1.3) + '@typescript-eslint/experimental-utils': 5.3.1(eslint@8.41.0)(typescript@5.1.3) + eslint: 8.41.0 jest: 27.5.1 transitivePeerDependencies: - supports-color @@ -31873,31 +31417,6 @@ packages: has: 1.0.3 jsx-ast-utils: 2.4.1 - /eslint-plugin-jsx-a11y@6.7.1(eslint@8.15.0): - resolution: {integrity: sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==} - engines: {node: '>=4.0'} - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - dependencies: - '@babel/runtime': 7.20.13 - aria-query: 5.1.3 - array-includes: 3.1.6 - array.prototype.flatmap: 1.3.1 - ast-types-flow: 0.0.7 - axe-core: 4.7.2 - axobject-query: 3.1.1 - damerau-levenshtein: 1.0.8 - emoji-regex: 9.2.2 - eslint: 8.15.0 - has: 1.0.3 - jsx-ast-utils: 3.3.3 - language-tags: 1.0.5 - minimatch: 3.1.2 - object.entries: 1.1.6 - object.fromentries: 2.0.6 - semver: 6.3.0 - dev: false - /eslint-plugin-jsx-a11y@6.7.1(eslint@8.41.0): resolution: {integrity: sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==} engines: {node: '>=4.0'} @@ -31921,7 +31440,6 @@ packages: object.entries: 1.1.6 object.fromentries: 2.0.6 semver: 6.3.0 - dev: true /eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.8.0)(eslint@8.41.0)(prettier@2.8.3): resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} @@ -31948,15 +31466,6 @@ packages: dependencies: eslint: 6.8.0 - /eslint-plugin-react-hooks@4.6.0(eslint@8.15.0): - resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} - engines: {node: '>=10'} - peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - dependencies: - eslint: 8.15.0 - dev: false - /eslint-plugin-react-hooks@4.6.0(eslint@8.41.0): resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} engines: {node: '>=10'} @@ -31964,7 +31473,6 @@ packages: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 dependencies: eslint: 8.41.0 - dev: true /eslint-plugin-react@7.19.0(eslint@6.8.0): resolution: {integrity: sha512-SPT8j72CGuAP+JFbT0sJHOB80TX/pu44gQ4vXH/cq+hQTiY2PuZ6IHkqXJV6x1b28GDdo1lbInjKUrrdUf0LOQ==} @@ -31986,30 +31494,6 @@ packages: string.prototype.matchall: 4.0.8 xregexp: 4.4.1 - /eslint-plugin-react@7.32.2(eslint@8.15.0): - resolution: {integrity: sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==} - engines: {node: '>=4'} - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - dependencies: - array-includes: 3.1.6 - array.prototype.flatmap: 1.3.1 - array.prototype.tosorted: 1.1.1 - doctrine: 2.1.0 - eslint: 8.15.0 - estraverse: 5.3.0 - jsx-ast-utils: 3.3.3 - minimatch: 3.1.2 - object.entries: 1.1.6 - object.fromentries: 2.0.6 - object.hasown: 1.1.2 - object.values: 1.1.6 - prop-types: 15.8.1 - resolve: 2.0.0-next.4 - semver: 6.3.0 - string.prototype.matchall: 4.0.8 - dev: false - /eslint-plugin-react@7.32.2(eslint@8.41.0): resolution: {integrity: sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==} engines: {node: '>=4'} @@ -32032,16 +31516,15 @@ packages: resolve: 2.0.0-next.4 semver: 6.3.0 string.prototype.matchall: 4.0.8 - dev: true - /eslint-plugin-testing-library@5.6.0(eslint@8.15.0)(typescript@5.1.3): + /eslint-plugin-testing-library@5.6.0(eslint@8.41.0)(typescript@5.1.3): resolution: {integrity: sha512-y63TRzPhGCMNsnUwMGJU1MFWc/3GvYw+nzobp9QiyNTTKsgAt5RKAOT1I34+XqVBpX1lC8bScoOjCkP7iRv0Mw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0, npm: '>=6'} peerDependencies: eslint: ^7.5.0 || ^8.0.0 dependencies: - '@typescript-eslint/utils': 5.59.6(eslint@8.15.0)(typescript@5.1.3) - eslint: 8.15.0 + '@typescript-eslint/utils': 5.59.6(eslint@8.41.0)(typescript@5.1.3) + eslint: 8.41.0 transitivePeerDependencies: - supports-color - typescript @@ -32080,13 +31563,13 @@ packages: dependencies: eslint-visitor-keys: 1.3.0 - /eslint-utils@3.0.0(eslint@8.15.0): + /eslint-utils@3.0.0(eslint@8.41.0): resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} peerDependencies: eslint: '>=5' dependencies: - eslint: 8.15.0 + eslint: 8.41.0 eslint-visitor-keys: 2.1.0 dev: false @@ -32103,7 +31586,7 @@ packages: resolution: {integrity: sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - /eslint-webpack-plugin@3.2.0(eslint@8.15.0)(webpack@5.72.1): + /eslint-webpack-plugin@3.2.0(eslint@8.41.0)(webpack@5.76.1): resolution: {integrity: sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==} engines: {node: '>= 12.13.0'} peerDependencies: @@ -32111,12 +31594,12 @@ packages: webpack: ^5.0.0 dependencies: '@types/eslint': 8.4.2 - eslint: 8.15.0 + eslint: 8.41.0 jest-worker: 28.1.3 micromatch: 4.0.5 normalize-path: 3.0.0 schema-utils: 4.0.0 - webpack: 5.72.1 + webpack: 5.76.1 transitivePeerDependencies: - metro dev: false @@ -32166,50 +31649,6 @@ packages: transitivePeerDependencies: - supports-color - /eslint@8.15.0: - resolution: {integrity: sha512-GG5USZ1jhCu8HJkzGgeK8/+RGnHaNYZGrGDzUtigK3BsGESW/rs2az23XqE0WVwDxy1VRvvjSSGu5nB0Bu+6SA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - hasBin: true - dependencies: - '@eslint/eslintrc': 1.2.3 - '@humanwhocodes/config-array': 0.9.5 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.3 - debug: 4.3.4 - doctrine: 3.0.0 - escape-string-regexp: 4.0.0 - eslint-scope: 7.2.0 - eslint-utils: 3.0.0(eslint@8.15.0) - eslint-visitor-keys: 3.4.1 - espree: 9.5.2 - esquery: 1.5.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 - functional-red-black-tree: 1.0.1 - glob-parent: 6.0.2 - globals: 13.20.0 - ignore: 5.2.4 - import-fresh: 3.3.0 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - js-yaml: 4.1.0 - json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.1 - regexpp: 3.2.0 - strip-ansi: 6.0.1 - strip-json-comments: 3.1.1 - text-table: 0.2.0 - v8-compile-cache: 2.3.0 - transitivePeerDependencies: - - supports-color - dev: false - /eslint@8.41.0: resolution: {integrity: sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -32797,20 +32236,8 @@ packages: dependencies: '@jest/expect-utils': 29.5.0 jest-get-type: 29.4.3 - jest-matcher-utils: 29.5.0 - jest-message-util: 29.5.0 - jest-util: 29.6.1 - dev: true - - /expect@29.6.1: - resolution: {integrity: sha512-XEdDLonERCU1n9uR56/Stx9OqojaLAQtZf9PrCHH9Hl8YXiEIka3H4NXJ3NOIBmQJTg7+j7buh34PMHfJujc8g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/expect-utils': 29.6.1 - '@types/node': 18.16.19 - jest-get-type: 29.4.3 jest-matcher-utils: 29.6.1 - jest-message-util: 29.6.1 + jest-message-util: 29.5.0 jest-util: 29.6.1 dev: true @@ -33794,7 +33221,7 @@ packages: dev: false /fast-url-parser@1.1.3: - resolution: {integrity: sha1-9K8+qfNNiicc9YrSs3WfQx8LMY0=} + resolution: {integrity: sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==} dependencies: punycode: 1.4.1 @@ -33936,20 +33363,20 @@ packages: peerDependencies: webpack: ^4.0.0 || ^5.0.0 dependencies: - loader-utils: 2.0.2 + loader-utils: 2.0.4 schema-utils: 3.1.1 webpack: 4.42.1 dev: true - /file-loader@6.2.0(webpack@5.72.1): + /file-loader@6.2.0(webpack@5.76.1): resolution: {integrity: sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==} engines: {node: '>= 10.13.0'} peerDependencies: webpack: ^4.0.0 || ^5.0.0 dependencies: - loader-utils: 2.0.2 + loader-utils: 2.0.4 schema-utils: 3.1.1 - webpack: 5.72.1 + webpack: 5.76.1 dev: false /file-selector@0.6.0: @@ -34376,38 +33803,6 @@ packages: - supports-color dev: true - /fork-ts-checker-webpack-plugin@6.5.2(eslint@8.15.0)(typescript@5.1.3)(webpack@5.72.1): - resolution: {integrity: sha512-m5cUmF30xkZ7h4tWUgTAcEaKmUW7tfyUyTqNNOz7OxWJ0v1VWKTcOvH8FWHUwSjlW/356Ijc9vi3XfcPstpQKA==} - engines: {node: '>=10', yarn: '>=1.0.0'} - peerDependencies: - eslint: '>= 6' - typescript: '>= 2.7' - vue-template-compiler: '*' - webpack: '>= 4' - peerDependenciesMeta: - eslint: - optional: true - vue-template-compiler: - optional: true - dependencies: - '@babel/code-frame': 7.22.5 - '@types/json-schema': 7.0.11 - chalk: 4.1.2 - chokidar: 3.5.3 - cosmiconfig: 6.0.0 - deepmerge: 4.3.0 - eslint: 8.15.0 - fs-extra: 9.1.0 - glob: 7.2.3 - memfs: 3.4.6 - minimatch: 3.1.2 - schema-utils: 2.7.0 - semver: 7.5.3 - tapable: 1.1.3 - typescript: 5.1.3 - webpack: 5.72.1 - dev: false - /fork-ts-checker-webpack-plugin@6.5.2(eslint@8.41.0)(typescript@5.1.3)(webpack@4.42.1): resolution: {integrity: sha512-m5cUmF30xkZ7h4tWUgTAcEaKmUW7tfyUyTqNNOz7OxWJ0v1VWKTcOvH8FWHUwSjlW/356Ijc9vi3XfcPstpQKA==} engines: {node: '>=10', yarn: '>=1.0.0'} @@ -34470,7 +33865,6 @@ packages: tapable: 1.1.3 typescript: 5.1.3 webpack: 5.76.1(metro@0.76.0) - dev: true /form-data@2.3.3: resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} @@ -35878,20 +35272,6 @@ packages: webpack: 4.42.1 dev: true - /html-webpack-plugin@5.5.0(webpack@5.72.1): - resolution: {integrity: sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==} - engines: {node: '>=10.13.0'} - peerDependencies: - webpack: ^5.20.0 - dependencies: - '@types/html-minifier-terser': 6.1.0 - html-minifier-terser: 6.1.0 - lodash: 4.17.21 - pretty-error: 4.0.0 - tapable: 2.2.1 - webpack: 5.72.1 - dev: false - /html-webpack-plugin@5.5.0(webpack@5.76.1): resolution: {integrity: sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==} engines: {node: '>=10.13.0'} @@ -35903,8 +35283,7 @@ packages: lodash: 4.17.21 pretty-error: 4.0.0 tapable: 2.2.1 - webpack: 5.76.1(metro@0.76.0) - dev: true + webpack: 5.76.1 /htmlparser2@6.1.0: resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==} @@ -37270,14 +36649,6 @@ packages: p-limit: 3.1.0 dev: true - /jest-changed-files@29.5.0: - resolution: {integrity: sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - execa: 5.1.1 - p-limit: 3.1.0 - dev: true - /jest-circus@27.5.1: resolution: {integrity: sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -37362,35 +36733,6 @@ packages: - supports-color dev: true - /jest-circus@29.6.1: - resolution: {integrity: sha512-tPbYLEiBU4MYAL2XoZme/bgfUeotpDBd81lgHLCbDZZFaGmECk0b+/xejPFtmiBP87GgP/y4jplcRpbH+fgCzQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/environment': 29.6.1 - '@jest/expect': 29.6.1 - '@jest/test-result': 29.6.1 - '@jest/types': 29.6.1 - '@types/node': 18.16.19 - chalk: 4.1.2 - co: 4.6.0 - dedent: 0.7.0 - is-generator-fn: 2.1.0 - jest-each: 29.6.1 - jest-matcher-utils: 29.6.1 - jest-message-util: 29.6.1 - jest-runtime: 29.6.1 - jest-snapshot: 29.6.1 - jest-util: 29.6.1 - p-limit: 3.1.0 - pretty-format: 29.6.1 - pure-rand: 6.0.2 - slash: 3.0.0 - stack-utils: 2.0.5 - transitivePeerDependencies: - - metro - - supports-color - dev: true - /jest-cli@24.9.0: resolution: {integrity: sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg==} engines: {node: '>= 6'} @@ -37504,7 +36846,7 @@ packages: - ts-node dev: true - /jest-cli@28.1.3(@types/node@18.15.11)(ts-node@10.7.0): + /jest-cli@28.1.3(@types/node@18.15.11): resolution: {integrity: sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} hasBin: true @@ -37514,14 +36856,14 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 28.1.3(ts-node@10.7.0) + '@jest/core': 28.1.3 '@jest/test-result': 28.1.3 '@jest/types': 28.1.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.10 import-local: 3.1.0 - jest-config: 28.1.3(@types/node@18.15.11)(ts-node@10.7.0) + jest-config: 28.1.3(@types/node@18.15.11) jest-util: 28.1.3 jest-validate: 28.1.3 prompts: 2.4.2 @@ -37533,7 +36875,7 @@ packages: - ts-node dev: true - /jest-cli@28.1.3(@types/node@18.15.3)(ts-node@10.7.0): + /jest-cli@28.1.3(@types/node@18.15.11)(ts-node@10.7.0): resolution: {integrity: sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} hasBin: true @@ -37550,7 +36892,7 @@ packages: exit: 0.1.2 graceful-fs: 4.2.10 import-local: 3.1.0 - jest-config: 28.1.3(@types/node@18.15.3)(ts-node@10.7.0) + jest-config: 28.1.3(@types/node@18.15.11)(ts-node@10.7.0) jest-util: 28.1.3 jest-validate: 28.1.3 prompts: 2.4.2 @@ -37562,7 +36904,7 @@ packages: - ts-node dev: true - /jest-cli@28.1.3(@types/node@18.15.3)(ts-node@10.9.1): + /jest-cli@28.1.3(@types/node@18.15.3)(ts-node@10.7.0): resolution: {integrity: sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} hasBin: true @@ -37572,14 +36914,14 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 28.1.3(ts-node@10.9.1) + '@jest/core': 28.1.3(ts-node@10.7.0) '@jest/test-result': 28.1.3 '@jest/types': 28.1.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.10 import-local: 3.1.0 - jest-config: 28.1.3(@types/node@18.15.3)(ts-node@10.9.1) + jest-config: 28.1.3(@types/node@18.15.3)(ts-node@10.7.0) jest-util: 28.1.3 jest-validate: 28.1.3 prompts: 2.4.2 @@ -37591,7 +36933,7 @@ packages: - ts-node dev: true - /jest-cli@28.1.3(@types/node@18.15.7): + /jest-cli@28.1.3(@types/node@18.15.3)(ts-node@10.9.1): resolution: {integrity: sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} hasBin: true @@ -37601,14 +36943,14 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 28.1.3 + '@jest/core': 28.1.3(ts-node@10.9.1) '@jest/test-result': 28.1.3 '@jest/types': 28.1.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.10 import-local: 3.1.0 - jest-config: 28.1.3(@types/node@18.15.7) + jest-config: 28.1.3(@types/node@18.15.3)(ts-node@10.9.1) jest-util: 28.1.3 jest-validate: 28.1.3 prompts: 2.4.2 @@ -37620,7 +36962,7 @@ packages: - ts-node dev: true - /jest-cli@28.1.3(@types/node@20.2.5): + /jest-cli@28.1.3(@types/node@18.15.7): resolution: {integrity: sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} hasBin: true @@ -37637,7 +36979,7 @@ packages: exit: 0.1.2 graceful-fs: 4.2.10 import-local: 3.1.0 - jest-config: 28.1.3(@types/node@20.2.5) + jest-config: 28.1.3(@types/node@18.15.7) jest-util: 28.1.3 jest-validate: 28.1.3 prompts: 2.4.2 @@ -37649,7 +36991,7 @@ packages: - ts-node dev: true - /jest-cli@28.1.3(metro@0.76.0)(ts-node@10.9.1): + /jest-cli@28.1.3(@types/node@20.2.5): resolution: {integrity: sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} hasBin: true @@ -37659,14 +37001,14 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 28.1.3(metro@0.76.0)(ts-node@10.9.1) + '@jest/core': 28.1.3 '@jest/test-result': 28.1.3 '@jest/types': 28.1.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.10 import-local: 3.1.0 - jest-config: 28.1.3(metro@0.76.0)(ts-node@10.9.1) + jest-config: 28.1.3(@types/node@20.2.5) jest-util: 28.1.3 jest-validate: 28.1.3 prompts: 2.4.2 @@ -37678,9 +37020,9 @@ packages: - ts-node dev: true - /jest-cli@29.6.1(@types/node@18.15.11): - resolution: {integrity: sha512-607dSgTA4ODIN6go9w6xY3EYkyPFGicx51a69H7yfvt7lN53xNswEVLovq+E77VsTRi5fWprLH0yl4DJgE8Ing==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + /jest-cli@28.1.3(metro@0.76.0)(ts-node@10.9.1): + resolution: {integrity: sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} hasBin: true peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -37688,16 +37030,16 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 29.6.1 - '@jest/test-result': 29.6.1 - '@jest/types': 29.6.1 + '@jest/core': 28.1.3(metro@0.76.0)(ts-node@10.9.1) + '@jest/test-result': 28.1.3 + '@jest/types': 28.1.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.10 import-local: 3.1.0 - jest-config: 29.6.1(@types/node@18.15.11) - jest-util: 29.6.1 - jest-validate: 29.6.1 + jest-config: 28.1.3(metro@0.76.0)(ts-node@10.9.1) + jest-util: 28.1.3 + jest-validate: 28.1.3 prompts: 2.4.2 yargs: 17.5.1 transitivePeerDependencies: @@ -37854,6 +37196,46 @@ packages: - supports-color dev: true + /jest-config@28.1.3(@types/node@18.15.11): + resolution: {integrity: sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + dependencies: + '@babel/core': 7.21.0 + '@jest/test-sequencer': 28.1.3 + '@jest/types': 28.1.3 + '@types/node': 18.15.11 + babel-jest: 28.1.3(@babel/core@7.21.0) + chalk: 4.1.2 + ci-info: 3.3.2 + deepmerge: 4.3.0 + glob: 7.2.3 + graceful-fs: 4.2.10 + jest-circus: 28.1.3 + jest-environment-node: 28.1.3 + jest-get-type: 28.0.2 + jest-regex-util: 28.0.2 + jest-resolve: 28.1.3 + jest-runner: 28.1.3 + jest-util: 28.1.3 + jest-validate: 28.1.3 + micromatch: 4.0.5 + parse-json: 5.2.0 + pretty-format: 28.1.3 + slash: 3.0.0 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - metro + - supports-color + dev: true + /jest-config@28.1.3(@types/node@18.15.11)(ts-node@10.7.0): resolution: {integrity: sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} @@ -38260,86 +37642,6 @@ packages: - supports-color dev: true - /jest-config@29.6.1(@types/node@18.15.11): - resolution: {integrity: sha512-XdjYV2fy2xYixUiV2Wc54t3Z4oxYPAELUzWnV6+mcbq0rh742X2p52pii5A3oeRzYjLnQxCsZmp0qpI6klE2cQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@types/node': '*' - ts-node: '>=9.0.0' - peerDependenciesMeta: - '@types/node': - optional: true - ts-node: - optional: true - dependencies: - '@babel/core': 7.21.0 - '@jest/test-sequencer': 29.6.1 - '@jest/types': 29.6.1 - '@types/node': 18.15.11 - babel-jest: 29.6.1(@babel/core@7.21.0) - chalk: 4.1.2 - ci-info: 3.3.2 - deepmerge: 4.3.0 - glob: 7.2.3 - graceful-fs: 4.2.10 - jest-circus: 29.6.1 - jest-environment-node: 29.6.1 - jest-get-type: 29.4.3 - jest-regex-util: 29.4.3 - jest-resolve: 29.6.1 - jest-runner: 29.6.1 - jest-util: 29.6.1 - jest-validate: 29.6.1 - micromatch: 4.0.5 - parse-json: 5.2.0 - pretty-format: 29.6.1 - slash: 3.0.0 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - metro - - supports-color - dev: true - - /jest-config@29.6.1(@types/node@18.16.19): - resolution: {integrity: sha512-XdjYV2fy2xYixUiV2Wc54t3Z4oxYPAELUzWnV6+mcbq0rh742X2p52pii5A3oeRzYjLnQxCsZmp0qpI6klE2cQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@types/node': '*' - ts-node: '>=9.0.0' - peerDependenciesMeta: - '@types/node': - optional: true - ts-node: - optional: true - dependencies: - '@babel/core': 7.21.0 - '@jest/test-sequencer': 29.6.1 - '@jest/types': 29.6.1 - '@types/node': 18.16.19 - babel-jest: 29.6.1(@babel/core@7.21.0) - chalk: 4.1.2 - ci-info: 3.3.2 - deepmerge: 4.3.0 - glob: 7.2.3 - graceful-fs: 4.2.10 - jest-circus: 29.6.1 - jest-environment-node: 29.6.1 - jest-get-type: 29.4.3 - jest-regex-util: 29.4.3 - jest-resolve: 29.6.1 - jest-runner: 29.6.1 - jest-util: 29.6.1 - jest-validate: 29.6.1 - micromatch: 4.0.5 - parse-json: 5.2.0 - pretty-format: 29.6.1 - slash: 3.0.0 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - metro - - supports-color - dev: true - /jest-diff@24.9.0: resolution: {integrity: sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==} engines: {node: '>= 6'} @@ -38385,7 +37687,7 @@ packages: chalk: 4.1.2 diff-sequences: 29.4.3 jest-get-type: 29.4.3 - pretty-format: 29.5.0 + pretty-format: 29.6.1 dev: true /jest-diff@29.6.1: @@ -38418,13 +37720,6 @@ packages: detect-newline: 3.1.0 dev: true - /jest-docblock@29.4.3: - resolution: {integrity: sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - detect-newline: 3.1.0 - dev: true - /jest-each@24.9.0: resolution: {integrity: sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog==} engines: {node: '>= 6'} @@ -38459,17 +37754,6 @@ packages: pretty-format: 28.1.3 dev: true - /jest-each@29.6.1: - resolution: {integrity: sha512-n5eoj5eiTHpKQCAVcNTT7DRqeUmJ01hsAL0Q1SMiBHcBcvTKDELixQOGMCpqhbIuTcfC4kMfSnpmDqRgRJcLNQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.6.1 - chalk: 4.1.2 - jest-get-type: 29.4.3 - jest-util: 29.6.1 - pretty-format: 29.6.1 - dev: true - /jest-environment-jsdom-fourteen@1.0.1: resolution: {integrity: sha512-DojMX1sY+at5Ep+O9yME34CdidZnO3/zfPh8UW+918C5fIZET5vCjfkegixmsi7AtdYfkr4bPlIzmWnlvQkP7Q==} dependencies: @@ -38586,18 +37870,6 @@ packages: jest-mock: 29.5.0 jest-util: 29.5.0 - /jest-environment-node@29.6.1: - resolution: {integrity: sha512-ZNIfAiE+foBog24W+2caIldl4Irh8Lx1PUhg/GZ0odM1d/h2qORAsejiFc7zb+SEmYPn1yDZzEDSU5PmDkmVLQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/environment': 29.6.1 - '@jest/fake-timers': 29.6.1 - '@jest/types': 29.6.1 - '@types/node': 18.16.19 - jest-mock: 29.6.1 - jest-util: 29.6.1 - dev: true - /jest-file-snapshot@0.5.0: resolution: {integrity: sha512-A3cqn9RRB6yl/bMsN9+EiNU94JTptLmoFqmSfSeuku22UYotYF6C/Ntw7C2Kai0C7deirYfpDwRpdlyLhItvMQ==} dependencies: @@ -38796,28 +38068,7 @@ packages: graceful-fs: 4.2.10 jest-regex-util: 29.4.3 jest-util: 29.6.1 - jest-worker: 29.5.0(metro@0.76.0) - micromatch: 4.0.5 - walker: 1.0.8 - optionalDependencies: - fsevents: 2.3.2 - transitivePeerDependencies: - - metro - dev: true - - /jest-haste-map@29.6.1: - resolution: {integrity: sha512-0m7f9PZXxOCk1gRACiVgX85knUKPKLPg4oRCjLoqIm9brTHXaorMA0JpmtmVkQiT8nmXyIVoZd/nnH1cfC33ig==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.6.1 - '@types/graceful-fs': 4.1.5 - '@types/node': 18.16.19 - anymatch: 3.1.2 - fb-watchman: 2.0.1 - graceful-fs: 4.2.10 - jest-regex-util: 29.4.3 - jest-util: 29.6.1 - jest-worker: 29.6.1 + jest-worker: 29.6.1(metro@0.76.0) micromatch: 4.0.5 walker: 1.0.8 optionalDependencies: @@ -38899,14 +38150,6 @@ packages: pretty-format: 28.1.3 dev: true - /jest-leak-detector@29.6.1: - resolution: {integrity: sha512-OrxMNyZirpOEwkF3UHnIkAiZbtkBWiye+hhBweCHkVbCgyEy71Mwbb5zgeTNYWJBi1qgDVfPC1IwO9dVEeTLwQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - jest-get-type: 29.4.3 - pretty-format: 29.6.1 - dev: true - /jest-matcher-utils@24.9.0: resolution: {integrity: sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA==} engines: {node: '>= 6'} @@ -38952,7 +38195,7 @@ packages: chalk: 4.1.2 jest-diff: 29.5.0 jest-get-type: 29.4.3 - pretty-format: 29.5.0 + pretty-format: 29.6.1 dev: true /jest-matcher-utils@29.6.1: @@ -39011,20 +38254,6 @@ packages: /jest-message-util@29.5.0: resolution: {integrity: sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@babel/code-frame': 7.22.5 - '@jest/types': 29.6.1 - '@types/stack-utils': 2.0.1 - chalk: 4.1.2 - graceful-fs: 4.2.10 - micromatch: 4.0.5 - pretty-format: 29.5.0 - slash: 3.0.0 - stack-utils: 2.0.5 - - /jest-message-util@29.6.1: - resolution: {integrity: sha512-KoAW2zAmNSd3Gk88uJ56qXUWbFk787QKmjjJVOjtGFmmGSZgDBrlIL4AfQw1xyMYPNVD7dNInfIbur9B2rd/wQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@babel/code-frame': 7.22.5 '@jest/types': 29.6.1 @@ -39035,7 +38264,6 @@ packages: pretty-format: 29.6.1 slash: 3.0.0 stack-utils: 2.0.5 - dev: true /jest-mock@24.9.0: resolution: {integrity: sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==} @@ -39067,15 +38295,6 @@ packages: '@types/node': 18.16.19 jest-util: 29.6.1 - /jest-mock@29.6.1: - resolution: {integrity: sha512-brovyV9HBkjXAEdRooaTQK42n8usKoSRR3gihzUpYeV/vwqgSoNfrksO7UfSACnPmxasO/8TmHM3w9Hp3G1dgw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.6.1 - '@types/node': 18.16.19 - jest-util: 29.6.1 - dev: true - /jest-pnp-resolver@1.2.2(jest-resolve@24.9.0): resolution: {integrity: sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==} engines: {node: '>=6'} @@ -39111,18 +38330,6 @@ packages: jest-resolve: 28.1.3(metro@0.76.0) dev: true - /jest-pnp-resolver@1.2.2(jest-resolve@29.6.1): - resolution: {integrity: sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==} - engines: {node: '>=6'} - peerDependencies: - jest-resolve: '*' - peerDependenciesMeta: - jest-resolve: - optional: true - dependencies: - jest-resolve: 29.6.1 - dev: true - /jest-regex-util@24.9.0: resolution: {integrity: sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==} engines: {node: '>= 6'} @@ -39189,17 +38396,6 @@ packages: - supports-color dev: true - /jest-resolve-dependencies@29.6.1: - resolution: {integrity: sha512-BbFvxLXtcldaFOhNMXmHRWx1nXQO5LoXiKSGQcA1LxxirYceZT6ch8KTE1bK3X31TNG/JbkI7OkS/ABexVahiw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - jest-regex-util: 29.4.3 - jest-snapshot: 29.6.1 - transitivePeerDependencies: - - metro - - supports-color - dev: true - /jest-resolve@24.9.0: resolution: {integrity: sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==} engines: {node: '>= 6'} @@ -39262,23 +38458,6 @@ packages: - metro dev: true - /jest-resolve@29.6.1: - resolution: {integrity: sha512-AeRkyS8g37UyJiP9w3mmI/VXU/q8l/IH52vj/cDAyScDcemRbSBhfX/NMYIGilQgSVwsjxrCHf3XJu4f+lxCMg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - chalk: 4.1.2 - graceful-fs: 4.2.10 - jest-haste-map: 29.6.1 - jest-pnp-resolver: 1.2.2(jest-resolve@29.6.1) - jest-util: 29.6.1 - jest-validate: 29.6.1 - resolve: 1.22.1 - resolve.exports: 2.0.2 - slash: 3.0.0 - transitivePeerDependencies: - - metro - dev: true - /jest-runner@24.9.0: resolution: {integrity: sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg==} engines: {node: '>= 6'} @@ -39401,36 +38580,6 @@ packages: - supports-color dev: true - /jest-runner@29.6.1: - resolution: {integrity: sha512-tw0wb2Q9yhjAQ2w8rHRDxteryyIck7gIzQE4Reu3JuOBpGp96xWgF0nY8MDdejzrLCZKDcp8JlZrBN/EtkQvPQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/console': 29.6.1 - '@jest/environment': 29.6.1 - '@jest/test-result': 29.6.1 - '@jest/transform': 29.6.1 - '@jest/types': 29.6.1 - '@types/node': 18.16.19 - chalk: 4.1.2 - emittery: 0.13.1 - graceful-fs: 4.2.10 - jest-docblock: 29.4.3 - jest-environment-node: 29.6.1 - jest-haste-map: 29.6.1 - jest-leak-detector: 29.6.1 - jest-message-util: 29.6.1 - jest-resolve: 29.6.1 - jest-runtime: 29.6.1 - jest-util: 29.6.1 - jest-watcher: 29.6.1 - jest-worker: 29.6.1 - p-limit: 3.1.0 - source-map-support: 0.5.13 - transitivePeerDependencies: - - metro - - supports-color - dev: true - /jest-runtime@24.9.0: resolution: {integrity: sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw==} engines: {node: '>= 6'} @@ -39558,37 +38707,6 @@ packages: - supports-color dev: true - /jest-runtime@29.6.1: - resolution: {integrity: sha512-D6/AYOA+Lhs5e5il8+5pSLemjtJezUr+8zx+Sn8xlmOux3XOqx4d8l/2udBea8CRPqqrzhsKUsN/gBDE/IcaPQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/environment': 29.6.1 - '@jest/fake-timers': 29.6.1 - '@jest/globals': 29.6.1 - '@jest/source-map': 29.6.0 - '@jest/test-result': 29.6.1 - '@jest/transform': 29.6.1 - '@jest/types': 29.6.1 - '@types/node': 18.16.19 - chalk: 4.1.2 - cjs-module-lexer: 1.2.2 - collect-v8-coverage: 1.0.1 - glob: 7.2.3 - graceful-fs: 4.2.10 - jest-haste-map: 29.6.1 - jest-message-util: 29.6.1 - jest-mock: 29.6.1 - jest-regex-util: 29.4.3 - jest-resolve: 29.6.1 - jest-snapshot: 29.6.1 - jest-util: 29.6.1 - slash: 3.0.0 - strip-bom: 4.0.0 - transitivePeerDependencies: - - metro - - supports-color - dev: true - /jest-serializer@24.9.0: resolution: {integrity: sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==} engines: {node: '>= 6'} @@ -39723,36 +38841,6 @@ packages: - supports-color dev: true - /jest-snapshot@29.6.1: - resolution: {integrity: sha512-G4UQE1QQ6OaCgfY+A0uR1W2AY0tGXUPQpoUClhWHq1Xdnx1H6JOrC2nH5lqnOEqaDgbHFgIwZ7bNq24HpB180A==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@babel/core': 7.21.0 - '@babel/generator': 7.22.5 - '@babel/plugin-syntax-jsx': 7.18.6(@babel/core@7.21.0) - '@babel/plugin-syntax-typescript': 7.17.10(@babel/core@7.21.0) - '@babel/types': 7.22.5 - '@jest/expect-utils': 29.6.1 - '@jest/transform': 29.6.1 - '@jest/types': 29.6.1 - '@types/prettier': 2.6.0 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.21.0) - chalk: 4.1.2 - expect: 29.6.1 - graceful-fs: 4.2.10 - jest-diff: 29.6.1 - jest-get-type: 29.4.3 - jest-matcher-utils: 29.6.1 - jest-message-util: 29.6.1 - jest-util: 29.6.1 - natural-compare: 1.4.0 - pretty-format: 29.6.1 - semver: 7.5.3 - transitivePeerDependencies: - - metro - - supports-color - dev: true - /jest-util@24.9.0: resolution: {integrity: sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==} engines: {node: '>= 6'} @@ -39874,18 +38962,6 @@ packages: pretty-format: 28.1.3 dev: true - /jest-validate@29.6.1: - resolution: {integrity: sha512-r3Ds69/0KCN4vx4sYAbGL1EVpZ7MSS0vLmd3gV78O+NAx3PDQQukRU5hNHPXlyqCgFY8XUk7EuTMLugh0KzahA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.6.1 - camelcase: 6.3.0 - chalk: 4.1.2 - jest-get-type: 29.4.3 - leven: 3.1.0 - pretty-format: 29.6.1 - dev: true - /jest-watch-typeahead@0.4.2: resolution: {integrity: sha512-f7VpLebTdaXs81rg/oj4Vg/ObZy2QtGzAmGLNsqUS5G5KtSN68tFcIsbvNODfNyQxU78g7D8x77o3bgfBTR+2Q==} dependencies: @@ -39955,20 +39031,6 @@ packages: jest-util: 28.1.3 string-length: 4.0.2 - /jest-watcher@29.6.1: - resolution: {integrity: sha512-d4wpjWTS7HEZPaaj8m36QiaP856JthRZkrgcIY/7ISoUWPIillrXM23WPboZVLbiwZBt4/qn2Jke84Sla6JhFA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/test-result': 29.6.1 - '@jest/types': 29.6.1 - '@types/node': 18.16.19 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - emittery: 0.13.1 - jest-util: 29.6.1 - string-length: 4.0.2 - dev: true - /jest-worker@24.9.0: resolution: {integrity: sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==} engines: {node: '>= 6'} @@ -40136,7 +39198,7 @@ packages: supports-color: 8.1.1 dev: true - /jest-worker@29.6.1: + /jest-worker@29.6.1(metro@0.76.0): resolution: {integrity: sha512-U+Wrbca7S8ZAxAe9L6nb6g8kPdia5hj32Puu5iOqBCMTMWFHXuK6dOV2IFrpedbTV8fjMFLdWNttQTBL6u2MRA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -40148,6 +39210,7 @@ packages: '@types/node': 18.16.19 jest-util: 29.6.1 merge-stream: 2.0.0 + metro: 0.76.0 supports-color: 8.1.1 dev: true @@ -40227,6 +39290,27 @@ packages: - ts-node dev: true + /jest@28.1.3(@types/node@18.15.11): + resolution: {integrity: sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/core': 28.1.3 + '@jest/types': 28.1.3 + import-local: 3.1.0 + jest-cli: 28.1.3(@types/node@18.15.11) + transitivePeerDependencies: + - '@types/node' + - metro + - supports-color + - ts-node + dev: true + /jest@28.1.3(@types/node@18.15.11)(ts-node@10.7.0): resolution: {integrity: sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} @@ -40353,27 +39437,6 @@ packages: - ts-node dev: true - /jest@29.6.0(@types/node@18.15.11): - resolution: {integrity: sha512-do1J9gGrQ68E4UfMz/4OM71p9qCqQxu32N/9ZfeYFSSlx0uUOuxeyZxtJZNaUTW12ZA11ERhmBjBhy1Ho96R4g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/core': 29.6.1 - '@jest/types': 29.6.1 - import-local: 3.1.0 - jest-cli: 29.6.1(@types/node@18.15.11) - transitivePeerDependencies: - - '@types/node' - - metro - - supports-color - - ts-node - dev: true - /jetifier@1.6.8: resolution: {integrity: sha512-3Zi16h6L5tXDRQJTb221cnRoVG9/9OvreLdLU2/ZjRv/GILL+2Cemt0IKvkowwkDpvouAU1DQPOJ7qaiHeIdrw==} hasBin: true @@ -41292,7 +40355,6 @@ packages: dependencies: picocolors: 1.0.0 shell-quote: 1.7.3 - dev: true /lazy-cache@0.2.7: resolution: {integrity: sha512-gkX52wvU/R8DVMMt78ATVPFMJqfW8FPz1GZ1sVHBVQHmu/WvhIWE4cE1GBzhJNFicDeYhnwp6Rl35BcAIM3YOQ==} @@ -41697,7 +40759,6 @@ packages: big.js: 5.2.2 emojis-list: 3.0.0 json5: 2.2.3 - dev: true /loader-utils@3.2.0: resolution: {integrity: sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ==} @@ -43920,7 +42981,6 @@ packages: /mime-db@1.33.0: resolution: {integrity: sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==} engines: {node: '>= 0.6'} - dev: true /mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} @@ -43931,7 +42991,6 @@ packages: engines: {node: '>= 0.6'} dependencies: mime-db: 1.33.0 - dev: true /mime-types@2.1.35: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} @@ -44003,16 +43062,6 @@ packages: webpack: 4.42.0 webpack-sources: 1.4.3 - /mini-css-extract-plugin@2.6.1(webpack@5.72.1): - resolution: {integrity: sha512-wd+SD57/K6DiV7jIR34P+s3uckTRuQvx0tKPcvjFlrEylk6P4mQ2KSWk1hblj1Kxaqok7LogKOieygXqBczNlg==} - engines: {node: '>= 12.13.0'} - peerDependencies: - webpack: ^5.0.0 - dependencies: - schema-utils: 4.0.0 - webpack: 5.72.1 - dev: false - /mini-css-extract-plugin@2.6.1(webpack@5.76.1): resolution: {integrity: sha512-wd+SD57/K6DiV7jIR34P+s3uckTRuQvx0tKPcvjFlrEylk6P4mQ2KSWk1hblj1Kxaqok7LogKOieygXqBczNlg==} engines: {node: '>= 12.13.0'} @@ -44020,8 +43069,7 @@ packages: webpack: ^5.0.0 dependencies: schema-utils: 4.0.0 - webpack: 5.76.1(metro@0.76.0) - dev: true + webpack: 5.76.1 /minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} @@ -44523,7 +43571,7 @@ packages: resolution: {integrity: sha512-7GGVawqyHF4pfd0YFybhv/eM9JwTtPqx0mAanQ146O3FlSh3pA24zf9IRQTOsfTSqXTNzPSP5iagAJ94jjuVog==} engines: {node: '>=10'} dependencies: - semver: 7.3.8 + semver: 7.5.3 /node-addon-api@1.7.2: resolution: {integrity: sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==} @@ -45613,7 +44661,7 @@ packages: engines: {node: '>=0.10.0'} /path-is-inside@1.0.2: - resolution: {integrity: sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=} + resolution: {integrity: sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==} /path-key@2.0.1: resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} @@ -45655,7 +44703,6 @@ packages: /path-to-regexp@2.2.1: resolution: {integrity: sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==} - dev: true /path-to-regexp@6.2.1: resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} @@ -45985,13 +45032,13 @@ packages: postcss: 7.0.39 postcss-selector-parser: 6.0.10 - /postcss-attribute-case-insensitive@5.0.2(postcss@8.4.13): + /postcss-attribute-case-insensitive@5.0.2(postcss@8.4.21): resolution: {integrity: sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-selector-parser: 6.0.10 dev: false @@ -46004,15 +45051,15 @@ packages: browserslist: 4.21.5 postcss: 7.0.39 - /postcss-browser-comments@4.0.0(browserslist@4.20.3)(postcss@8.4.13): + /postcss-browser-comments@4.0.0(browserslist@4.21.5)(postcss@8.4.21): resolution: {integrity: sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==} engines: {node: '>=8'} peerDependencies: browserslist: '>=4' postcss: '>=8' dependencies: - browserslist: 4.20.3 - postcss: 8.4.13 + browserslist: 4.21.5 + postcss: 8.4.21 dev: false /postcss-browser-comments@4.0.0(postcss@7.0.39): @@ -46049,13 +45096,13 @@ packages: postcss: 7.0.39 postcss-value-parser: 4.2.0 - /postcss-clamp@4.1.0(postcss@8.4.13): + /postcss-clamp@4.1.0(postcss@8.4.21): resolution: {integrity: sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==} engines: {node: '>=7.6.0'} peerDependencies: postcss: ^8.4.6 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-value-parser: 4.2.0 dev: false @@ -46075,13 +45122,13 @@ packages: postcss: 7.0.39 postcss-value-parser: 4.2.0 - /postcss-color-functional-notation@4.2.4(postcss@8.4.13): + /postcss-color-functional-notation@4.2.4(postcss@8.4.21): resolution: {integrity: sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-value-parser: 4.2.0 dev: false @@ -46109,13 +45156,13 @@ packages: postcss: 7.0.39 postcss-value-parser: 4.2.0 - /postcss-color-hex-alpha@8.0.4(postcss@8.4.13): + /postcss-color-hex-alpha@8.0.4(postcss@8.4.21): resolution: {integrity: sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-value-parser: 4.2.0 dev: false @@ -46143,13 +45190,13 @@ packages: postcss: 7.0.39 postcss-value-parser: 4.2.0 - /postcss-color-rebeccapurple@7.1.1(postcss@8.4.13): + /postcss-color-rebeccapurple@7.1.1(postcss@8.4.21): resolution: {integrity: sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-value-parser: 4.2.0 dev: false @@ -46207,13 +45254,13 @@ packages: postcss: 7.0.39 postcss-value-parser: 4.2.0 - /postcss-custom-media@8.0.2(postcss@8.4.13): + /postcss-custom-media@8.0.2(postcss@8.4.21): resolution: {integrity: sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.3 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-value-parser: 4.2.0 dev: false @@ -46226,13 +45273,13 @@ packages: postcss: 7.0.39 postcss-value-parser: 4.2.0 - /postcss-custom-properties@12.1.8(postcss@8.4.13): + /postcss-custom-properties@12.1.8(postcss@8.4.21): resolution: {integrity: sha512-8rbj8kVu00RQh2fQF81oBqtduiANu4MIxhyf0HbbStgPtnFlWn0yiaYTpLHrPnJbffVY1s9apWsIoVZcc68FxA==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-value-parser: 4.2.0 dev: false @@ -46259,13 +45306,13 @@ packages: postcss: 7.0.39 postcss-selector-parser: 6.0.10 - /postcss-custom-selectors@6.0.3(postcss@8.4.13): + /postcss-custom-selectors@6.0.3(postcss@8.4.21): resolution: {integrity: sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.3 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-selector-parser: 6.0.10 dev: false @@ -46285,13 +45332,13 @@ packages: postcss: 7.0.39 postcss-selector-parser: 6.0.10 - /postcss-dir-pseudo-class@6.0.5(postcss@8.4.13): + /postcss-dir-pseudo-class@6.0.5(postcss@8.4.21): resolution: {integrity: sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-selector-parser: 6.0.10 dev: false @@ -46368,14 +45415,14 @@ packages: postcss: 7.0.39 postcss-value-parser: 4.2.0 - /postcss-double-position-gradients@3.1.2(postcss@8.4.13): + /postcss-double-position-gradients@3.1.2(postcss@8.4.21): resolution: {integrity: sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.13) - postcss: 8.4.13 + '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.21) + postcss: 8.4.21 postcss-value-parser: 4.2.0 dev: false @@ -46395,13 +45442,13 @@ packages: postcss: 7.0.39 postcss-value-parser: 4.2.0 - /postcss-env-function@4.0.6(postcss@8.4.13): + /postcss-env-function@4.0.6(postcss@8.4.21): resolution: {integrity: sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-value-parser: 4.2.0 dev: false @@ -46423,12 +45470,12 @@ packages: dependencies: postcss: 7.0.39 - /postcss-flexbugs-fixes@5.0.2(postcss@8.4.13): + /postcss-flexbugs-fixes@5.0.2(postcss@8.4.21): resolution: {integrity: sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==} peerDependencies: postcss: ^8.1.4 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 dev: false /postcss-focus-visible@4.0.0: @@ -46446,13 +45493,13 @@ packages: postcss: 7.0.39 postcss-selector-parser: 6.0.10 - /postcss-focus-visible@6.0.4(postcss@8.4.13): + /postcss-focus-visible@6.0.4(postcss@8.4.21): resolution: {integrity: sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-selector-parser: 6.0.10 dev: false @@ -46471,13 +45518,13 @@ packages: postcss: 7.0.39 postcss-selector-parser: 6.0.10 - /postcss-focus-within@5.0.4(postcss@8.4.13): + /postcss-focus-within@5.0.4(postcss@8.4.21): resolution: {integrity: sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-selector-parser: 6.0.10 dev: false @@ -46493,12 +45540,12 @@ packages: dependencies: postcss: 7.0.39 - /postcss-font-variant@5.0.0(postcss@8.4.13): + /postcss-font-variant@5.0.0(postcss@8.4.21): resolution: {integrity: sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==} peerDependencies: postcss: ^8.1.0 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 dev: false /postcss-gap-properties@2.0.0: @@ -46515,13 +45562,13 @@ packages: dependencies: postcss: 7.0.39 - /postcss-gap-properties@3.0.5(postcss@8.4.13): + /postcss-gap-properties@3.0.5(postcss@8.4.21): resolution: {integrity: sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 dev: false /postcss-image-set-function@3.0.1: @@ -46540,13 +45587,13 @@ packages: postcss: 7.0.39 postcss-value-parser: 4.2.0 - /postcss-image-set-function@4.0.7(postcss@8.4.13): + /postcss-image-set-function@4.0.7(postcss@8.4.21): resolution: {integrity: sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-value-parser: 4.2.0 dev: false @@ -46574,12 +45621,12 @@ packages: dependencies: postcss: 7.0.39 - /postcss-initial@4.0.1(postcss@8.4.13): + /postcss-initial@4.0.1(postcss@8.4.21): resolution: {integrity: sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==} peerDependencies: postcss: ^8.0.0 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 dev: false /postcss-js@4.0.0(postcss@8.4.21): @@ -46610,14 +45657,14 @@ packages: postcss: 7.0.39 postcss-value-parser: 4.2.0 - /postcss-lab-function@4.2.1(postcss@8.4.13): + /postcss-lab-function@4.2.1(postcss@8.4.21): resolution: {integrity: sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.13) - postcss: 8.4.13 + '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.21) + postcss: 8.4.21 postcss-value-parser: 4.2.0 dev: false @@ -46696,7 +45743,7 @@ packages: - browserslist dev: true - /postcss-loader@6.2.1(browserslist@4.20.3)(postcss@8.4.13)(webpack@5.72.1): + /postcss-loader@6.2.1(browserslist@4.21.5)(postcss@8.4.21)(webpack@5.76.1): resolution: {integrity: sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==} engines: {node: '>= 12.13.0'} peerDependencies: @@ -46705,12 +45752,12 @@ packages: dependencies: cosmiconfig: 7.0.1 klona: 2.0.5 - postcss: 8.4.13 - postcss-flexbugs-fixes: 5.0.2(postcss@8.4.13) - postcss-normalize: 10.0.1(browserslist@4.20.3)(postcss@8.4.13) - postcss-preset-env: 7.7.2(postcss@8.4.13) + postcss: 8.4.21 + postcss-flexbugs-fixes: 5.0.2(postcss@8.4.21) + postcss-normalize: 10.0.1(browserslist@4.21.5)(postcss@8.4.21) + postcss-preset-env: 7.7.2(postcss@8.4.21) semver: 7.5.3 - webpack: 5.72.1 + webpack: 5.76.1 transitivePeerDependencies: - browserslist dev: false @@ -46729,13 +45776,13 @@ packages: dependencies: postcss: 7.0.39 - /postcss-logical@5.0.4(postcss@8.4.13): + /postcss-logical@5.0.4(postcss@8.4.21): resolution: {integrity: sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 dev: false /postcss-media-minmax@4.0.0: @@ -46752,13 +45799,13 @@ packages: dependencies: postcss: 7.0.39 - /postcss-media-minmax@5.0.0(postcss@8.4.13): + /postcss-media-minmax@5.0.0(postcss@8.4.21): resolution: {integrity: sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==} engines: {node: '>=10.0.0'} peerDependencies: postcss: ^8.1.0 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 dev: false /postcss-media-query-parser@0.2.3: @@ -46968,14 +46015,14 @@ packages: postcss: 7.0.39 postcss-selector-parser: 6.0.10 - /postcss-nesting@10.1.10(postcss@8.4.13): + /postcss-nesting@10.1.10(postcss@8.4.21): resolution: {integrity: sha512-lqd7LXCq0gWc0wKXtoKDru5wEUNjm3OryLVNRZ8OnW8km6fSNUuFrjEhU3nklxXE2jvd4qrox566acgh+xQt8w==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - '@csstools/selector-specificity': 2.0.2(postcss-selector-parser@6.0.10)(postcss@8.4.13) - postcss: 8.4.13 + '@csstools/selector-specificity': 2.0.2(postcss-selector-parser@6.0.10)(postcss@8.4.21) + postcss: 8.4.21 postcss-selector-parser: 6.0.10 dev: false @@ -47139,7 +46186,7 @@ packages: postcss: 8.4.21 postcss-value-parser: 4.2.0 - /postcss-normalize@10.0.1(browserslist@4.20.3)(postcss@8.4.13): + /postcss-normalize@10.0.1(browserslist@4.21.5)(postcss@8.4.21): resolution: {integrity: sha512-+5w18/rDev5mqERcG3W5GZNMJa1eoYYNGo8gB7tEwaos0ajk3ZXAI4mHGcNT47NE+ZnZD1pEpUOFLvltIwmeJA==} engines: {node: '>= 12'} peerDependencies: @@ -47147,9 +46194,9 @@ packages: postcss: '>= 8' dependencies: '@csstools/normalize.css': 10.1.0 - browserslist: 4.20.3 - postcss: 8.4.13 - postcss-browser-comments: 4.0.0(browserslist@4.20.3)(postcss@8.4.13) + browserslist: 4.21.5 + postcss: 8.4.21 + postcss-browser-comments: 4.0.0(browserslist@4.21.5)(postcss@8.4.21) sanitize.css: 10.0.0 dev: false @@ -47212,13 +46259,13 @@ packages: postcss: 7.0.39 postcss-value-parser: 4.2.0 - /postcss-overflow-shorthand@3.0.4(postcss@8.4.13): + /postcss-overflow-shorthand@3.0.4(postcss@8.4.21): resolution: {integrity: sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-value-parser: 4.2.0 dev: false @@ -47234,12 +46281,12 @@ packages: dependencies: postcss: 7.0.39 - /postcss-page-break@3.0.4(postcss@8.4.13): + /postcss-page-break@3.0.4(postcss@8.4.21): resolution: {integrity: sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==} peerDependencies: postcss: ^8 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 dev: false /postcss-place@4.0.1: @@ -47258,13 +46305,13 @@ packages: postcss: 7.0.39 postcss-value-parser: 4.2.0 - /postcss-place@7.0.5(postcss@8.4.13): + /postcss-place@7.0.5(postcss@8.4.21): resolution: {integrity: sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-value-parser: 4.2.0 dev: false @@ -47365,59 +46412,59 @@ packages: postcss-selector-not: 6.0.1(postcss@7.0.39) postcss-value-parser: 4.2.0 - /postcss-preset-env@7.7.2(postcss@8.4.13): + /postcss-preset-env@7.7.2(postcss@8.4.21): resolution: {integrity: sha512-1q0ih7EDsZmCb/FMDRvosna7Gsbdx8CvYO5hYT120hcp2ZAuOHpSzibujZ4JpIUcAC02PG6b+eftxqjTFh5BNA==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - '@csstools/postcss-cascade-layers': 1.0.5(postcss@8.4.13) - '@csstools/postcss-color-function': 1.1.1(postcss@8.4.13) - '@csstools/postcss-font-format-keywords': 1.0.1(postcss@8.4.13) - '@csstools/postcss-hwb-function': 1.0.2(postcss@8.4.13) - '@csstools/postcss-ic-unit': 1.0.1(postcss@8.4.13) - '@csstools/postcss-is-pseudo-class': 2.0.7(postcss@8.4.13) - '@csstools/postcss-normalize-display-values': 1.0.1(postcss@8.4.13) - '@csstools/postcss-oklab-function': 1.1.1(postcss@8.4.13) - '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.13) - '@csstools/postcss-stepped-value-functions': 1.0.1(postcss@8.4.13) - '@csstools/postcss-trigonometric-functions': 1.0.2(postcss@8.4.13) - '@csstools/postcss-unset-value': 1.0.2(postcss@8.4.13) - autoprefixer: 10.4.8(postcss@8.4.13) + '@csstools/postcss-cascade-layers': 1.0.5(postcss@8.4.21) + '@csstools/postcss-color-function': 1.1.1(postcss@8.4.21) + '@csstools/postcss-font-format-keywords': 1.0.1(postcss@8.4.21) + '@csstools/postcss-hwb-function': 1.0.2(postcss@8.4.21) + '@csstools/postcss-ic-unit': 1.0.1(postcss@8.4.21) + '@csstools/postcss-is-pseudo-class': 2.0.7(postcss@8.4.21) + '@csstools/postcss-normalize-display-values': 1.0.1(postcss@8.4.21) + '@csstools/postcss-oklab-function': 1.1.1(postcss@8.4.21) + '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.21) + '@csstools/postcss-stepped-value-functions': 1.0.1(postcss@8.4.21) + '@csstools/postcss-trigonometric-functions': 1.0.2(postcss@8.4.21) + '@csstools/postcss-unset-value': 1.0.2(postcss@8.4.21) + autoprefixer: 10.4.8(postcss@8.4.21) browserslist: 4.21.5 - css-blank-pseudo: 3.0.3(postcss@8.4.13) - css-has-pseudo: 3.0.4(postcss@8.4.13) - css-prefers-color-scheme: 6.0.3(postcss@8.4.13) + css-blank-pseudo: 3.0.3(postcss@8.4.21) + css-has-pseudo: 3.0.4(postcss@8.4.21) + css-prefers-color-scheme: 6.0.3(postcss@8.4.21) cssdb: 6.6.3 - postcss: 8.4.13 - postcss-attribute-case-insensitive: 5.0.2(postcss@8.4.13) - postcss-clamp: 4.1.0(postcss@8.4.13) - postcss-color-functional-notation: 4.2.4(postcss@8.4.13) - postcss-color-hex-alpha: 8.0.4(postcss@8.4.13) - postcss-color-rebeccapurple: 7.1.1(postcss@8.4.13) - postcss-custom-media: 8.0.2(postcss@8.4.13) - postcss-custom-properties: 12.1.8(postcss@8.4.13) - postcss-custom-selectors: 6.0.3(postcss@8.4.13) - postcss-dir-pseudo-class: 6.0.5(postcss@8.4.13) - postcss-double-position-gradients: 3.1.2(postcss@8.4.13) - postcss-env-function: 4.0.6(postcss@8.4.13) - postcss-focus-visible: 6.0.4(postcss@8.4.13) - postcss-focus-within: 5.0.4(postcss@8.4.13) - postcss-font-variant: 5.0.0(postcss@8.4.13) - postcss-gap-properties: 3.0.5(postcss@8.4.13) - postcss-image-set-function: 4.0.7(postcss@8.4.13) - postcss-initial: 4.0.1(postcss@8.4.13) - postcss-lab-function: 4.2.1(postcss@8.4.13) - postcss-logical: 5.0.4(postcss@8.4.13) - postcss-media-minmax: 5.0.0(postcss@8.4.13) - postcss-nesting: 10.1.10(postcss@8.4.13) + postcss: 8.4.21 + postcss-attribute-case-insensitive: 5.0.2(postcss@8.4.21) + postcss-clamp: 4.1.0(postcss@8.4.21) + postcss-color-functional-notation: 4.2.4(postcss@8.4.21) + postcss-color-hex-alpha: 8.0.4(postcss@8.4.21) + postcss-color-rebeccapurple: 7.1.1(postcss@8.4.21) + postcss-custom-media: 8.0.2(postcss@8.4.21) + postcss-custom-properties: 12.1.8(postcss@8.4.21) + postcss-custom-selectors: 6.0.3(postcss@8.4.21) + postcss-dir-pseudo-class: 6.0.5(postcss@8.4.21) + postcss-double-position-gradients: 3.1.2(postcss@8.4.21) + postcss-env-function: 4.0.6(postcss@8.4.21) + postcss-focus-visible: 6.0.4(postcss@8.4.21) + postcss-focus-within: 5.0.4(postcss@8.4.21) + postcss-font-variant: 5.0.0(postcss@8.4.21) + postcss-gap-properties: 3.0.5(postcss@8.4.21) + postcss-image-set-function: 4.0.7(postcss@8.4.21) + postcss-initial: 4.0.1(postcss@8.4.21) + postcss-lab-function: 4.2.1(postcss@8.4.21) + postcss-logical: 5.0.4(postcss@8.4.21) + postcss-media-minmax: 5.0.0(postcss@8.4.21) + postcss-nesting: 10.1.10(postcss@8.4.21) postcss-opacity-percentage: 1.1.2 - postcss-overflow-shorthand: 3.0.4(postcss@8.4.13) - postcss-page-break: 3.0.4(postcss@8.4.13) - postcss-place: 7.0.5(postcss@8.4.13) - postcss-pseudo-class-any-link: 7.1.6(postcss@8.4.13) - postcss-replace-overflow-wrap: 4.0.0(postcss@8.4.13) - postcss-selector-not: 6.0.1(postcss@8.4.13) + postcss-overflow-shorthand: 3.0.4(postcss@8.4.21) + postcss-page-break: 3.0.4(postcss@8.4.21) + postcss-place: 7.0.5(postcss@8.4.21) + postcss-pseudo-class-any-link: 7.1.6(postcss@8.4.21) + postcss-replace-overflow-wrap: 4.0.0(postcss@8.4.21) + postcss-selector-not: 6.0.1(postcss@8.4.21) postcss-value-parser: 4.2.0 dev: false @@ -47437,13 +46484,13 @@ packages: postcss: 7.0.39 postcss-selector-parser: 6.0.10 - /postcss-pseudo-class-any-link@7.1.6(postcss@8.4.13): + /postcss-pseudo-class-any-link@7.1.6(postcss@8.4.21): resolution: {integrity: sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-selector-parser: 6.0.10 dev: false @@ -47496,12 +46543,12 @@ packages: dependencies: postcss: 7.0.39 - /postcss-replace-overflow-wrap@4.0.0(postcss@8.4.13): + /postcss-replace-overflow-wrap@4.0.0(postcss@8.4.21): resolution: {integrity: sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==} peerDependencies: postcss: ^8.0.3 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 dev: false /postcss-resolve-nested-selector@0.1.1: @@ -47544,13 +46591,13 @@ packages: postcss: 7.0.39 postcss-selector-parser: 6.0.10 - /postcss-selector-not@6.0.1(postcss@8.4.13): + /postcss-selector-not@6.0.1(postcss@8.4.21): resolution: {integrity: sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 dependencies: - postcss: 8.4.13 + postcss: 8.4.21 postcss-selector-parser: 6.0.10 dev: false @@ -47641,15 +46688,6 @@ packages: picocolors: 0.2.1 source-map: 0.6.1 - /postcss@8.4.13: - resolution: {integrity: sha512-jtL6eTBrza5MPzy8oJLFuUscHDXTV5KcLlqAWHl5q5WYRfnNRGSmOZmOZ1T6Gy7A99mOZfqungmZMpMmCVJ8ZA==} - engines: {node: ^10 || ^12 || >=14} - dependencies: - nanoid: 3.3.4 - picocolors: 1.0.0 - source-map-js: 1.0.2 - dev: false - /postcss@8.4.19: resolution: {integrity: sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==} engines: {node: ^10 || ^12 || >=14} @@ -47802,6 +46840,7 @@ packages: '@jest/schemas': 29.4.3 ansi-styles: 5.2.0 react-is: 18.1.0 + dev: true /pretty-format@29.6.1: resolution: {integrity: sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==} @@ -47810,7 +46849,6 @@ packages: '@jest/schemas': 29.6.0 ansi-styles: 5.2.0 react-is: 18.1.0 - dev: true /pretty-hrtime@1.0.3: resolution: {integrity: sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==} @@ -48136,10 +47174,6 @@ packages: dependencies: escape-goat: 2.1.1 - /pure-rand@6.0.2: - resolution: {integrity: sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==} - dev: true - /pushdata-bitcoin@1.0.1: resolution: {integrity: sha512-hw7rcYTJRAl4olM8Owe8x0fBuJJ+WGbMhQuLWOXEMN3PxPCKQHRkhfL+XG0+iXUmSHjkMmb3Ba55Mt21cZc9kQ==} dependencies: @@ -48319,7 +47353,6 @@ packages: /range-parser@1.2.0: resolution: {integrity: sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==} engines: {node: '>= 0.6'} - dev: true /range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} @@ -48485,7 +47518,7 @@ packages: - supports-color - vue-template-compiler - /react-dev-utils@12.0.1(eslint@8.15.0)(typescript@5.1.3)(webpack@5.72.1): + /react-dev-utils@12.0.1(eslint@8.41.0)(typescript@5.1.3)(webpack@5.76.1): resolution: {integrity: sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==} engines: {node: '>=14'} peerDependencies: @@ -48504,7 +47537,7 @@ packages: escape-string-regexp: 4.0.0 filesize: 8.0.7 find-up: 5.0.0 - fork-ts-checker-webpack-plugin: 6.5.2(eslint@8.15.0)(typescript@5.1.3)(webpack@5.72.1) + fork-ts-checker-webpack-plugin: 6.5.2(eslint@8.41.0)(typescript@5.1.3)(webpack@5.76.1) global-modules: 2.0.0 globby: 11.1.0 gzip-size: 6.0.0 @@ -48520,7 +47553,7 @@ packages: strip-ansi: 6.0.1 text-table: 0.2.0 typescript: 5.1.3 - webpack: 5.72.1 + webpack: 5.76.1 transitivePeerDependencies: - eslint - supports-color @@ -49857,54 +48890,54 @@ packages: optional: true dependencies: '@babel/core': 7.21.0 - '@pmmmwh/react-refresh-webpack-plugin': 0.5.7(react-refresh@0.11.0)(webpack-dev-server@4.9.3)(webpack@5.72.1) + '@pmmmwh/react-refresh-webpack-plugin': 0.5.7(react-refresh@0.11.0)(webpack-dev-server@4.12.0)(webpack@5.76.1) '@svgr/webpack': 5.5.0 babel-jest: 27.5.1(@babel/core@7.21.0) - babel-loader: 8.2.5(@babel/core@7.21.0)(webpack@5.72.1) + babel-loader: 8.2.5(@babel/core@7.21.0)(webpack@5.76.1) babel-plugin-named-asset-import: 0.3.8(@babel/core@7.21.0) babel-preset-react-app: 10.0.1 bfj: 7.0.2 - browserslist: 4.20.3 + browserslist: 4.21.5 camelcase: 6.3.0 case-sensitive-paths-webpack-plugin: 2.4.0 - css-loader: 6.7.1(webpack@5.72.1) - css-minimizer-webpack-plugin: 3.4.1(webpack@5.72.1) + css-loader: 6.7.1(webpack@5.76.1) + css-minimizer-webpack-plugin: 3.4.1(webpack@5.76.1) dotenv: 10.0.0 dotenv-expand: 5.1.0 - eslint: 8.15.0 - eslint-config-react-app: 7.0.1(eslint@8.15.0)(jest@27.5.1)(typescript@5.1.3) - eslint-webpack-plugin: 3.2.0(eslint@8.15.0)(webpack@5.72.1) - file-loader: 6.2.0(webpack@5.72.1) + eslint: 8.41.0 + eslint-config-react-app: 7.0.1(eslint@8.41.0)(jest@27.5.1)(typescript@5.1.3) + eslint-webpack-plugin: 3.2.0(eslint@8.41.0)(webpack@5.76.1) + file-loader: 6.2.0(webpack@5.76.1) fs-extra: 10.1.0 - html-webpack-plugin: 5.5.0(webpack@5.72.1) + html-webpack-plugin: 5.5.0(webpack@5.76.1) identity-obj-proxy: 3.0.0 jest: 27.5.1 jest-resolve: 27.5.1 jest-watch-typeahead: 1.1.0(jest@27.5.1) - mini-css-extract-plugin: 2.6.1(webpack@5.72.1) - postcss: 8.4.13 - postcss-flexbugs-fixes: 5.0.2(postcss@8.4.13) - postcss-loader: 6.2.1(browserslist@4.20.3)(postcss@8.4.13)(webpack@5.72.1) - postcss-normalize: 10.0.1(browserslist@4.20.3)(postcss@8.4.13) - postcss-preset-env: 7.7.2(postcss@8.4.13) + mini-css-extract-plugin: 2.6.1(webpack@5.76.1) + postcss: 8.4.21 + postcss-flexbugs-fixes: 5.0.2(postcss@8.4.21) + postcss-loader: 6.2.1(browserslist@4.21.5)(postcss@8.4.21)(webpack@5.76.1) + postcss-normalize: 10.0.1(browserslist@4.21.5)(postcss@8.4.21) + postcss-preset-env: 7.7.2(postcss@8.4.21) prompts: 2.4.2 react: 17.0.2 react-app-polyfill: 3.0.0 - react-dev-utils: 12.0.1(eslint@8.15.0)(typescript@5.1.3)(webpack@5.72.1) + react-dev-utils: 12.0.1(eslint@8.41.0)(typescript@5.1.3)(webpack@5.76.1) react-refresh: 0.11.0 - resolve: 1.22.0 + resolve: 1.22.1 resolve-url-loader: 4.0.0 - sass-loader: 12.6.0(webpack@5.72.1) - semver: 7.3.7 - source-map-loader: 3.0.1(webpack@5.72.1) - style-loader: 3.3.1(webpack@5.72.1) + sass-loader: 12.6.0(webpack@5.76.1) + semver: 7.5.3 + source-map-loader: 3.0.1(webpack@5.76.1) + style-loader: 3.3.1(webpack@5.76.1) tailwindcss: 3.1.7 - terser-webpack-plugin: 5.3.1(webpack@5.72.1) + terser-webpack-plugin: 5.3.1(webpack@5.76.1) typescript: 5.1.3 - webpack: 5.72.1 - webpack-dev-server: 4.9.3(webpack@5.72.1) - webpack-manifest-plugin: 4.1.1(webpack@5.72.1) - workbox-webpack-plugin: 6.5.4(webpack@5.72.1) + webpack: 5.76.1 + webpack-dev-server: 4.12.0(webpack@5.76.1) + webpack-manifest-plugin: 4.1.1(webpack@5.76.1) + workbox-webpack-plugin: 6.5.4(webpack@5.76.1) optionalDependencies: fsevents: 2.3.2 transitivePeerDependencies: @@ -50991,7 +50024,7 @@ packages: dependencies: adjust-sourcemap-loader: 4.0.0 convert-source-map: 1.8.0 - loader-utils: 2.0.2 + loader-utils: 2.0.4 postcss: 7.0.39 source-map: 0.6.1 dev: false @@ -51004,11 +50037,6 @@ packages: resolution: {integrity: sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==} engines: {node: '>=10'} - /resolve.exports@2.0.2: - resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} - engines: {node: '>=10'} - dev: true - /resolve@1.1.7: resolution: {integrity: sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==} @@ -51242,6 +50270,7 @@ packages: /rollup-plugin-terser@7.0.2(rollup@2.79.1): resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==} + deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser peerDependencies: rollup: ^2.0.0 dependencies: @@ -51410,7 +50439,7 @@ packages: /sanitize.css@10.0.0: resolution: {integrity: sha512-vTxrZz4dX5W86M6oVWVdOVe72ZiPs41Oi7Z6Km4W5Turyz28mrXSJhhEBZoRtzJWIv3833WKVwLSDWWkEfupMg==} - /sass-loader@12.6.0(webpack@5.72.1): + /sass-loader@12.6.0(webpack@5.76.1): resolution: {integrity: sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==} engines: {node: '>= 12.13.0'} peerDependencies: @@ -51431,7 +50460,7 @@ packages: dependencies: klona: 2.0.5 neo-async: 2.6.2 - webpack: 5.72.1 + webpack: 5.76.1 dev: false /sass-loader@8.0.2(webpack@4.42.0): @@ -51604,19 +50633,11 @@ packages: dependencies: node-forge: 0.10.0 - /selfsigned@2.0.1: - resolution: {integrity: sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ==} - engines: {node: '>=10'} - dependencies: - node-forge: 1.3.1 - dev: false - /selfsigned@2.1.1: resolution: {integrity: sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==} engines: {node: '>=10'} dependencies: node-forge: 1.3.1 - dev: true /semver-compare@1.0.0: resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} @@ -51772,7 +50793,6 @@ packages: path-is-inside: 1.0.2 path-to-regexp: 2.2.1 range-parser: 1.2.0 - dev: true /serve-index-75lb@2.0.1: resolution: {integrity: sha512-/d9r8bqJlFQcwy0a0nb1KnWAA+Mno+V+VaoKocdkbW5aXKRQd/+4bfnRhQRQr6uEoYwTRJ4xgztOyCJvWcpBpQ==} @@ -52275,18 +51295,6 @@ packages: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} - /source-map-loader@3.0.1(webpack@5.72.1): - resolution: {integrity: sha512-Vp1UsfyPvgujKQzi4pyDiTOnE3E4H+yHvkVRN3c/9PJmQS4CQJExvcDvaX/D+RV+xQben9HJ56jMJS3CgUeWyA==} - engines: {node: '>= 12.13.0'} - peerDependencies: - webpack: ^5.0.0 - dependencies: - abab: 2.0.6 - iconv-lite: 0.6.3 - source-map-js: 1.0.2 - webpack: 5.72.1 - dev: false - /source-map-loader@3.0.1(webpack@5.76.1): resolution: {integrity: sha512-Vp1UsfyPvgujKQzi4pyDiTOnE3E4H+yHvkVRN3c/9PJmQS4CQJExvcDvaX/D+RV+xQben9HJ56jMJS3CgUeWyA==} engines: {node: '>= 12.13.0'} @@ -52296,8 +51304,7 @@ packages: abab: 2.0.6 iconv-lite: 0.6.3 source-map-js: 1.0.2 - webpack: 5.76.1(metro@0.76.0) - dev: true + webpack: 5.76.1 /source-map-resolve@0.5.3: resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} @@ -53051,7 +52058,7 @@ packages: peerDependencies: webpack: ^4.0.0 || ^5.0.0 dependencies: - loader-utils: 2.0.2 + loader-utils: 2.0.4 schema-utils: 2.7.1 webpack: 4.42.1 dev: true @@ -53062,28 +52069,18 @@ packages: peerDependencies: webpack: ^4.0.0 || ^5.0.0 dependencies: - loader-utils: 2.0.2 + loader-utils: 2.0.4 schema-utils: 3.1.1 webpack: 5.76.1(metro@0.76.0) dev: true - /style-loader@3.3.1(webpack@5.72.1): - resolution: {integrity: sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==} - engines: {node: '>= 12.13.0'} - peerDependencies: - webpack: ^5.0.0 - dependencies: - webpack: 5.72.1 - dev: false - /style-loader@3.3.1(webpack@5.76.1): resolution: {integrity: sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==} engines: {node: '>= 12.13.0'} peerDependencies: webpack: ^5.0.0 dependencies: - webpack: 5.76.1(metro@0.76.0) - dev: true + webpack: 5.76.1 /style-search@0.1.0: resolution: {integrity: sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==} @@ -53915,6 +52912,7 @@ packages: webpack: 5.72.1(esbuild@0.17.14) transitivePeerDependencies: - metro + dev: true /terser-webpack-plugin@5.3.1(metro@0.76.0)(webpack@5.76.1): resolution: {integrity: sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==} @@ -53940,9 +52938,8 @@ packages: webpack: 5.76.1(metro@0.76.0) transitivePeerDependencies: - metro - dev: true - /terser-webpack-plugin@5.3.1(webpack@5.72.1): + /terser-webpack-plugin@5.3.1(webpack@5.76.1): resolution: {integrity: sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==} engines: {node: '>= 10.13.0'} peerDependencies: @@ -53963,10 +52960,9 @@ packages: serialize-javascript: 6.0.0 source-map: 0.6.1 terser: 5.16.8 - webpack: 5.72.1 + webpack: 5.76.1 transitivePeerDependencies: - metro - dev: false /terser@4.8.0: resolution: {integrity: sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==} @@ -54504,7 +53500,7 @@ packages: json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 - semver: 7.3.8 + semver: 7.5.3 typescript: 5.1.3 yargs-parser: 21.1.1 dev: true @@ -54538,7 +53534,7 @@ packages: json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 - semver: 7.3.8 + semver: 7.5.3 typescript: 5.1.3 yargs-parser: 21.1.1 dev: true @@ -54571,39 +53567,6 @@ packages: json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 - semver: 7.3.8 - typescript: 5.1.3 - yargs-parser: 21.1.1 - dev: true - - /ts-jest@29.1.1(jest@29.6.0)(typescript@5.1.3): - resolution: {integrity: sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - '@babel/core': '>=7.0.0-beta.0 <8' - '@jest/types': ^29.0.0 - babel-jest: ^29.0.0 - esbuild: '*' - jest: ^29.0.0 - typescript: '>=4.3 <6' - peerDependenciesMeta: - '@babel/core': - optional: true - '@jest/types': - optional: true - babel-jest: - optional: true - esbuild: - optional: true - dependencies: - bs-logger: 0.2.6 - fast-json-stable-stringify: 2.1.0 - jest: 29.6.0(@types/node@18.15.11) - jest-util: 29.5.0 - json5: 2.2.3 - lodash.memoize: 4.1.2 - make-error: 1.3.6 semver: 7.5.3 typescript: 5.1.3 yargs-parser: 21.1.1 @@ -55613,7 +54576,6 @@ packages: browserslist: 4.21.3 escalade: 3.1.1 picocolors: 1.0.0 - dev: true /update-browserslist-db@1.0.10(browserslist@4.21.5): resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} @@ -55702,7 +54664,7 @@ packages: optional: true dependencies: file-loader: 6.2.0(webpack@4.42.1) - loader-utils: 2.0.2 + loader-utils: 2.0.4 mime-types: 2.1.35 schema-utils: 3.1.1 webpack: 4.42.1 @@ -56674,6 +55636,7 @@ packages: dependencies: glob-to-regexp: 0.4.1 graceful-fs: 4.2.10 + dev: true /watchpack@2.4.0: resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==} @@ -56681,7 +55644,6 @@ packages: dependencies: glob-to-regexp: 0.4.1 graceful-fs: 4.2.10 - dev: true /wbuf@1.7.3: resolution: {integrity: sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==} @@ -57295,20 +56257,6 @@ packages: webpack: 5.76.1(metro@0.76.0) dev: true - /webpack-dev-middleware@5.3.3(webpack@5.72.1): - resolution: {integrity: sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==} - engines: {node: '>= 12.13.0'} - peerDependencies: - webpack: ^4.0.0 || ^5.0.0 - dependencies: - colorette: 2.0.16 - memfs: 3.4.6 - mime-types: 2.1.35 - range-parser: 1.2.1 - schema-utils: 4.0.0 - webpack: 5.72.1 - dev: false - /webpack-dev-middleware@5.3.3(webpack@5.76.1): resolution: {integrity: sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==} engines: {node: '>= 12.13.0'} @@ -57320,8 +56268,7 @@ packages: mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 4.0.0 - webpack: 5.76.1(metro@0.76.0) - dev: true + webpack: 5.76.1 /webpack-dev-server@3.11.0(webpack@4.42.0): resolution: {integrity: sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==} @@ -57411,61 +56358,13 @@ packages: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack: 5.76.1(metro@0.76.0) + webpack: 5.76.1 webpack-dev-middleware: 5.3.3(webpack@5.76.1) ws: 8.13.0 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - dev: true - - /webpack-dev-server@4.9.3(webpack@5.72.1): - resolution: {integrity: sha512-3qp/eoboZG5/6QgiZ3llN8TUzkSpYg1Ko9khWX1h40MIEUNS2mDoIa8aXsPfskER+GbTvs/IJZ1QTBBhhuetSw==} - engines: {node: '>= 12.13.0'} - hasBin: true - peerDependencies: - webpack: ^4.37.0 || ^5.0.0 - webpack-cli: '*' - peerDependenciesMeta: - webpack-cli: - optional: true - dependencies: - '@types/bonjour': 3.5.10 - '@types/connect-history-api-fallback': 1.3.5 - '@types/express': 4.17.13 - '@types/serve-index': 1.9.1 - '@types/serve-static': 1.13.10 - '@types/sockjs': 0.3.33 - '@types/ws': 8.5.3 - ansi-html-community: 0.0.8 - bonjour-service: 1.0.13 - chokidar: 3.5.3 - colorette: 2.0.16 - compression: 1.7.4 - connect-history-api-fallback: 2.0.0 - default-gateway: 6.0.3 - express: 4.18.1 - graceful-fs: 4.2.10 - html-entities: 2.3.3 - http-proxy-middleware: 2.0.6(@types/express@4.17.13) - ipaddr.js: 2.0.1 - open: 8.4.0 - p-retry: 4.6.2 - rimraf: 3.0.2 - schema-utils: 4.0.0 - selfsigned: 2.0.1 - serve-index: 1.9.1 - sockjs: 0.3.24 - spdy: 4.0.2 - webpack: 5.72.1 - webpack-dev-middleware: 5.3.3(webpack@5.72.1) - ws: 8.13.0 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - dev: false /webpack-filter-warnings-plugin@1.2.1(webpack@4.42.1): resolution: {integrity: sha512-Ez6ytc9IseDMLPo0qCuNNYzgtUl8NovOqjIq4uAU8LTD4uoa1w1KpZyyzFtLTEMZpkkOkLfL9eN+KGYdk1Qtwg==} @@ -57504,17 +56403,6 @@ packages: tapable: 1.1.3 webpack: 4.42.0 - /webpack-manifest-plugin@4.1.1(webpack@5.72.1): - resolution: {integrity: sha512-YXUAwxtfKIJIKkhg03MKuiFAD72PlrqCiwdwO4VEXdRO5V0ORCNwaOwAZawPZalCbmH9kBDmXnNeQOw+BIEiow==} - engines: {node: '>=12.22.0'} - peerDependencies: - webpack: ^4.44.2 || ^5.47.0 - dependencies: - tapable: 2.2.1 - webpack: 5.72.1 - webpack-sources: 2.3.1 - dev: false - /webpack-manifest-plugin@4.1.1(webpack@5.76.1): resolution: {integrity: sha512-YXUAwxtfKIJIKkhg03MKuiFAD72PlrqCiwdwO4VEXdRO5V0ORCNwaOwAZawPZalCbmH9kBDmXnNeQOw+BIEiow==} engines: {node: '>=12.22.0'} @@ -57522,9 +56410,8 @@ packages: webpack: ^4.44.2 || ^5.47.0 dependencies: tapable: 2.2.1 - webpack: 5.76.1(metro@0.76.0) + webpack: 5.76.1 webpack-sources: 2.3.1 - dev: true /webpack-sources@1.4.3: resolution: {integrity: sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==} @@ -57673,7 +56560,7 @@ packages: - supports-color dev: true - /webpack@5.72.1: + /webpack@5.72.1(esbuild@0.17.14): resolution: {integrity: sha512-dXG5zXCLspQR4krZVR6QgajnZOjW2K/djHvdcRaDQvsjV9z9vaW6+ja5dZOYbqBBjF6kGXka/2ZyxNdc+8Jung==} engines: {node: '>=10.13.0'} hasBin: true @@ -57704,7 +56591,7 @@ packages: neo-async: 2.6.2 schema-utils: 3.1.1 tapable: 2.2.1 - terser-webpack-plugin: 5.3.1(webpack@5.72.1) + terser-webpack-plugin: 5.3.1(esbuild@0.17.14)(webpack@5.72.1) watchpack: 2.3.1 webpack-sources: 3.2.3 transitivePeerDependencies: @@ -57712,10 +56599,10 @@ packages: - esbuild - metro - uglify-js - dev: false + dev: true - /webpack@5.72.1(esbuild@0.17.14): - resolution: {integrity: sha512-dXG5zXCLspQR4krZVR6QgajnZOjW2K/djHvdcRaDQvsjV9z9vaW6+ja5dZOYbqBBjF6kGXka/2ZyxNdc+8Jung==} + /webpack@5.76.1: + resolution: {integrity: sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -57729,11 +56616,11 @@ packages: '@webassemblyjs/ast': 1.11.1 '@webassemblyjs/wasm-edit': 1.11.1 '@webassemblyjs/wasm-parser': 1.11.1 - acorn: 8.7.1 - acorn-import-assertions: 1.8.0(acorn@8.7.1) - browserslist: 4.20.3 + acorn: 8.8.2 + acorn-import-assertions: 1.8.0(acorn@8.8.2) + browserslist: 4.21.3 chrome-trace-event: 1.0.3 - enhanced-resolve: 5.9.3 + enhanced-resolve: 5.10.0 es-module-lexer: 0.9.3 eslint-scope: 5.1.1 events: 3.3.0 @@ -57745,8 +56632,8 @@ packages: neo-async: 2.6.2 schema-utils: 3.1.1 tapable: 2.2.1 - terser-webpack-plugin: 5.3.1(esbuild@0.17.14)(webpack@5.72.1) - watchpack: 2.3.1 + terser-webpack-plugin: 5.3.1(webpack@5.76.1) + watchpack: 2.4.0 webpack-sources: 3.2.3 transitivePeerDependencies: - '@swc/core' @@ -57793,7 +56680,6 @@ packages: - esbuild - metro - uglify-js - dev: true /webpod@0.0.2: resolution: {integrity: sha512-cSwwQIeg8v4i3p4ajHhwgR7N6VyxAf+KYSSsY6Pd3aETE+xEU4vbitz7qQkB0I321xnhDdgtxuiSfk5r/FVtjg==} @@ -58284,7 +57170,7 @@ packages: webpack: 4.42.0 workbox-build: 4.3.1 - /workbox-webpack-plugin@6.5.4(webpack@5.72.1): + /workbox-webpack-plugin@6.5.4(webpack@5.76.1): resolution: {integrity: sha512-LmWm/zoaahe0EGmMTrSLUi+BjyR3cdGEfU3fS6PN1zKFYbqAKuQ+Oy/27e4VSXsyIwAw8+QDfk1XHNGtZu9nQg==} engines: {node: '>=10.0.0'} peerDependencies: @@ -58293,7 +57179,7 @@ packages: fast-json-stable-stringify: 2.1.0 pretty-bytes: 5.6.0 upath: 1.2.0 - webpack: 5.72.1 + webpack: 5.76.1 webpack-sources: 1.4.3 workbox-build: 6.5.4 transitivePeerDependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 701c41bf1634..8fb399851a89 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,7 +1,7 @@ packages: - "apps/*" - - "apps/ledger-live-desktop/tests/utils/**" - "libs/*" + - "libs/test-utils/**" - "libs/ledgerjs/**" - "libs/ui/packages/*" - "libs/ledger-live-common/tools" diff --git a/tools/actions/composites/setup-test-desktop/action.yml b/tools/actions/composites/setup-test-desktop/action.yml index cdd3f1d922d8..3709e0b0234e 100644 --- a/tools/actions/composites/setup-test-desktop/action.yml +++ b/tools/actions/composites/setup-test-desktop/action.yml @@ -51,7 +51,7 @@ runs: - name: Install dependencies env: LANG: en_US.UTF-8 - run: pnpm i --filter="ledger-live-desktop..." --filter="ledger-live" --filter="dummy-live-app" --filter="dummy-wallet-app" --unsafe-perm + run: pnpm i --filter="ledger-live-desktop..." --filter="ledger-live" --filter="dummy-*" --unsafe-perm shell: bash - name: Install playwright dependencies if: ${{ inputs.install_playwright }} @@ -76,5 +76,6 @@ runs: shell: bash - name: Build Dummy Live SDK and Dummy Wallet API apps for testing if: ${{ !inputs.skip_builds }} - run: pnpm desktop build:dummy-apps + run: | + pnpm test-utils dummy-apps:build shell: bash