diff --git a/.eslintrc b/.eslintrc index b35f6c2f8..8002080e4 100644 --- a/.eslintrc +++ b/.eslintrc @@ -3,18 +3,39 @@ "react-app", "plugin:jsx-a11y/recommended", "plugin:react-hooks/recommended", - "plugin:prettier/recommended" + "plugin:prettier/recommended", + "plugin:import/recommended", + "plugin:import/typescript" ], "plugins": [ "jsx-a11y", - "react-hooks" + "react-hooks", + "import" ], "parser": "@typescript-eslint/parser", + "settings": { + "import/resolver": { + "typescript": { + "alwaysTryTypes": true + } + } + }, "rules": { "semi": 1, "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx", ".ts", ".tsx"] }], "no-unused-vars": "off", - "@typescript-eslint/no-unused-vars": ["error"], - "jsx-a11y/no-autofocus": "off" + "@typescript-eslint/no-unused-vars": ["error", { + "args": "after-used" + }], + "jsx-a11y/no-autofocus": "off", + "import/no-cycle": [ + 1, + { + "maxDepth": 10, + "ignoreExternal": true + } + ], + "import/no-named-as-default": 0, + "import/export": 1 } } diff --git a/.prettierrc b/.prettierrc index ff70333f1..a0329fa53 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,5 +1,10 @@ { -"singleQuote": true, -"arrowParens": "avoid", -"trailingComma": "none" + "singleQuote": true, + "arrowParens": "avoid", + "trailingComma": "none", + "importOrder": ["", "@src/*", "@popup/*", "@import-account-with-file/*", "@connect-to-app/*", "@signature-request/*", "@onboarding/*", "@background/*", "@hooks/*", "@content/*", "@libs/*", "^[./]"], + "importOrderSeparation": true, + "importOrderSortSpecifiers": true, + "importOrderGroupNamespaceSpecifiers": true, + "plugins": ["@trivago/prettier-plugin-sort-imports"] } \ No newline at end of file diff --git a/__mocks__/file-mock.js b/__mocks__/file-mock.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/__testHelpers__/withMarkups.ts b/__testHelpers__/withMarkups.ts deleted file mode 100644 index 62c6ca970..000000000 --- a/__testHelpers__/withMarkups.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { MatcherFunction } from '@testing-library/react'; - -type Query = (f: MatcherFunction) => HTMLElement; - -export const withMarkup = - (query: Query) => - (text: string): HTMLElement => - query((content: string, node: Element | null): boolean => { - if (!node) { - return false; - } - - const hasText = (node: Element) => node.textContent === text; - const childrenDontHaveText = Array.from(node.children).every( - child => !hasText(child) - ); - - return hasText(node) && childrenDontHaveText; - }); diff --git a/e2e-tests/constants.ts b/e2e-tests/constants.ts index a31e3dca8..a93495f4e 100644 --- a/e2e-tests/constants.ts +++ b/e2e-tests/constants.ts @@ -1,8 +1,10 @@ import path from 'path'; export const vaultPassword = '3hQqzYn4C7Y8rEZTVEZb'; -export const recoverSecretPhrase = +export const twentyFourWordsSecretPhrase = 'hold matrix spider subway bottom jazz charge fire lawn valley stay coil moral hospital dream cycle multiply december agree huge major tower devote old'; +export const twelveWordsSecretPhrase = + 'small vendor member cry motion lava hurdle gravity cry sentence medal seminar'; export const secretKeyPath = path.join(__dirname, './account_secret_key.pem'); export const ACCOUNT_NAMES = { @@ -19,21 +21,31 @@ export const IMPORTED_ACCOUNT = { accountName: ACCOUNT_NAMES.importedAccountName, publicKey: '0184f6d260f4ee6869ddb36affe15456de6ae045278fa2f467bb677561ce0dad55', - truncatedPublicKey: '0184f...dad55' + truncatedPublicKey: '0184f...dad55', + mediumTruncatedPublicKey: '0184f6d260...561ce0dad55' }; export const DEFAULT_FIRST_ACCOUNT = { accountName: ACCOUNT_NAMES.defaultFirstAccountName, publicKey: '0202b1943511b8c23b1b2b8ed7ddcedffcc7be70d9366a5005c7beab08a81b7ae633', - truncatedPublicKey: '0202b...ae633' + truncatedPublicKey: '0202b...ae633', + mediumTruncatedPublicKey: '0202b19435...a81b7ae633' }; export const DEFAULT_SECOND_ACCOUNT = { accountName: ACCOUNT_NAMES.defaultSecondAccountName, publicKey: '0203b2e05f074452f5e69ba512310deceaca152ebd3394eadcec26c6e68e91aa7724', - truncatedPublicKey: '0203b...a7724' + truncatedPublicKey: '0203b...a7724', + mediumTruncatedPublicKey: '0203b2e05f...8e91aa7724' +}; + +export const RECOVER_ACCOUNT_FROM_TWELVE_WORDS = { + accountName: 'Account 1', + publicKey: + '0202b869dbed03ef2cc6a76e54e1a5c588fbe6198f80937994f9a2c1fd3aff4adc1b', + truncatedPublicKey: '0202b...adc1b' }; export const VALIDATOR = { diff --git a/e2e-tests/fixtures.ts b/e2e-tests/fixtures.ts index 598dca7a4..c4eba6b35 100644 --- a/e2e-tests/fixtures.ts +++ b/e2e-tests/fixtures.ts @@ -6,7 +6,11 @@ import { } from '@playwright/test'; import path from 'path'; -import { PLAYGROUND_URL, vaultPassword } from './constants'; +import { + DEFAULT_FIRST_ACCOUNT, + PLAYGROUND_URL, + vaultPassword +} from './constants'; export const test = base.extend<{ context: BrowserContext; @@ -207,6 +211,7 @@ export const popup = test.extend<{ lockVault: () => Promise; createAccount: (newAccountName: string) => Promise; connectAccounts: () => Promise; + addContact: () => Promise; }>({ popupPage: async ({ extensionId, page }, use) => { await page.goto(`chrome-extension://${extensionId}/popup.html`); @@ -265,6 +270,27 @@ export const popup = test.extend<{ }; await use(connectAccounts); + }, + addContact: async ({ page }, use) => { + const addContact = async () => { + await page.getByTestId('menu-open-icon').click(); + await page.getByText('Contacts').click(); + + await page.getByRole('button', { name: 'Add contact' }).click(); + + await page + .getByPlaceholder('Name', { exact: true }) + .fill(DEFAULT_FIRST_ACCOUNT.accountName); + await page + .getByPlaceholder('Public key', { exact: true }) + .fill(DEFAULT_FIRST_ACCOUNT.publicKey); + + await page.getByRole('button', { name: 'Add contact' }).click(); + + await page.getByRole('button', { name: 'Done' }).click(); + }; + + await use(addContact); } }); diff --git a/e2e-tests/onboarding-flow/recover-secret-phrase-flow.spec.ts b/e2e-tests/onboarding-flow/recover-secret-phrase-flow.spec.ts index 568d680b7..b3d030e70 100644 --- a/e2e-tests/onboarding-flow/recover-secret-phrase-flow.spec.ts +++ b/e2e-tests/onboarding-flow/recover-secret-phrase-flow.spec.ts @@ -1,9 +1,14 @@ -import { onboardingExpect, onboarding } from '../fixtures'; -import { DEFAULT_FIRST_ACCOUNT, recoverSecretPhrase } from '../constants'; +import { + DEFAULT_FIRST_ACCOUNT, + RECOVER_ACCOUNT_FROM_TWELVE_WORDS, + twelveWordsSecretPhrase, + twentyFourWordsSecretPhrase +} from '../constants'; +import { onboarding, onboardingExpect } from '../fixtures'; onboarding.describe('Onboarding UI: recover secret phrase flow', () => { onboarding( - 'should recover account via secret phrase', + 'should recover account via 24 words secret phrase', async ({ page, createOnboardingPassword, extensionId }) => { await createOnboardingPassword(); @@ -19,7 +24,7 @@ onboarding.describe('Onboarding UI: recover secret phrase flow', () => { await page .getByPlaceholder('e.g. Bobcat Lemon Blanket…') - .fill(recoverSecretPhrase); + .fill(twentyFourWordsSecretPhrase); await page.getByRole('button', { name: 'Recover my wallet' }).click(); @@ -33,4 +38,37 @@ onboarding.describe('Onboarding UI: recover secret phrase flow', () => { ).toBeVisible(); } ); + onboarding( + 'should recover account via 12 words secret phrase', + async ({ page, createOnboardingPassword, extensionId }) => { + await createOnboardingPassword(); + + await page + .getByRole('button', { + name: 'Import an existing secret recovery phrase' + }) + .click(); + + await onboardingExpect( + page.getByText('Please enter your secret recovery phrase') + ).toBeVisible(); + + await page + .getByPlaceholder('e.g. Bobcat Lemon Blanket…') + .fill(twelveWordsSecretPhrase); + + await page.getByRole('button', { name: 'Recover my wallet' }).click(); + + await page.goto(`chrome-extension://${extensionId}/popup.html`); + + await onboardingExpect( + page.getByText(RECOVER_ACCOUNT_FROM_TWELVE_WORDS.accountName) + ).toBeVisible(); + await onboardingExpect( + page + .getByText(RECOVER_ACCOUNT_FROM_TWELVE_WORDS.truncatedPublicKey) + .nth(0) + ).toBeVisible(); + } + ); }); diff --git a/e2e-tests/popup/contacts/contacts.spec.ts b/e2e-tests/popup/contacts/contacts.spec.ts new file mode 100644 index 000000000..e7d617f1c --- /dev/null +++ b/e2e-tests/popup/contacts/contacts.spec.ts @@ -0,0 +1,240 @@ +import { popup, popupExpect } from '../../fixtures'; +import { + DEFAULT_FIRST_ACCOUNT, + DEFAULT_SECOND_ACCOUNT, + vaultPassword +} from '../../constants'; + +popup.describe('Popup UI: contacts', () => { + popup( + "should display an empty contacts list when no contacts are present in the user's contact book", + async ({ popupPage, unlockVault }) => { + await unlockVault(); + + await popupPage.getByTestId('menu-open-icon').click(); + await popupPage.getByText('Contacts').click(); + + await popupExpect( + popupPage.getByRole('heading', { name: 'No contacts just yet' }) + ).toBeVisible(); + + await popupExpect( + popupPage.getByText( + 'You can add here a list of contacts to make it easier for you to send tokens.' + ) + ).toBeVisible(); + } + ); + + popup( + 'should successfully add a contact and display it in the contacts list', + async ({ popupPage, unlockVault }) => { + await unlockVault(); + + await popupPage.getByTestId('menu-open-icon').click(); + await popupPage.getByText('Contacts').click(); + + await popupPage.getByRole('button', { name: 'Add contact' }).click(); + + await popupExpect( + popupPage.getByRole('heading', { name: 'New contact' }) + ).toBeVisible(); + + await popupPage + .getByPlaceholder('Name', { exact: true }) + .fill(DEFAULT_FIRST_ACCOUNT.accountName); + await popupPage + .getByPlaceholder('Public key', { exact: true }) + .fill(DEFAULT_FIRST_ACCOUNT.publicKey); + + await popupPage.getByRole('button', { name: 'Add contact' }).click(); + + await popupExpect( + popupPage.getByRole('heading', { name: 'All done!' }) + ).toBeVisible(); + + await popupExpect( + popupPage.getByText( + 'You will see this contact’s details and select it when you transfer or delegate tokens.' + ) + ).toBeVisible(); + + await popupPage.getByRole('button', { name: 'Done' }).click(); + + await popupExpect( + popupPage.getByRole('heading', { + name: 'Contacts' + }) + ).toBeVisible(); + + await popupExpect( + popupPage.getByText(DEFAULT_FIRST_ACCOUNT.accountName) + ).toBeVisible(); + + await popupExpect( + popupPage.getByText(DEFAULT_FIRST_ACCOUNT.mediumTruncatedPublicKey) + ).toBeVisible(); + } + ); + + popup( + 'should display an error message for addition of a contact with an invalid public key', + async ({ popupPage, unlockVault }) => { + await unlockVault(); + + await popupPage.getByTestId('menu-open-icon').click(); + await popupPage.getByText('Contacts').click(); + + await popupPage.getByRole('button', { name: 'Add contact' }).click(); + + await popupPage + .getByPlaceholder('Name', { exact: true }) + .fill(DEFAULT_FIRST_ACCOUNT.accountName); + await popupPage + .getByPlaceholder('Public key', { exact: true }) + .fill(DEFAULT_FIRST_ACCOUNT.truncatedPublicKey); + + await popupExpect( + popupPage.getByText('Public address should be a valid public key') + ).toBeVisible(); + await popupExpect( + popupPage.getByRole('button', { name: 'Add contact' }) + ).toBeDisabled(); + } + ); + + popup( + 'should show error message for duplicate contact name during contact addition', + async ({ popupPage, unlockVault, addContact }) => { + await unlockVault(); + await addContact(); + + await popupPage.getByRole('button', { name: 'Add contact' }).click(); + + await popupPage + .getByPlaceholder('Name', { exact: true }) + .fill(DEFAULT_FIRST_ACCOUNT.accountName); + await popupPage + .getByPlaceholder('Public key', { exact: true }) + .fill(DEFAULT_FIRST_ACCOUNT.publicKey); + + await popupExpect( + popupPage.getByText( + 'You’ve already got a contact with this name. Please find a new name for this one' + ) + ).toBeVisible(); + await popupExpect( + popupPage.getByRole('button', { name: 'Add contact' }) + ).toBeDisabled(); + } + ); + + popup( + 'should show contact details on contact selection', + async ({ popupPage, unlockVault, addContact }) => { + await unlockVault(); + await addContact(); + + await popupPage.getByText(DEFAULT_FIRST_ACCOUNT.accountName).click(); + + await popupExpect( + popupPage.getByRole('heading', { + name: DEFAULT_FIRST_ACCOUNT.accountName + }) + ).toBeVisible(); + + await popupExpect( + popupPage.getByText(DEFAULT_FIRST_ACCOUNT.publicKey) + ).toBeVisible(); + } + ); + + popup( + 'should edit a contact successfully and display the updated contact details', + async ({ popupPage, unlockVault, addContact }) => { + await unlockVault(); + await addContact(); + + await popupPage.getByText(DEFAULT_FIRST_ACCOUNT.accountName).click(); + + await popupPage.getByTestId('edit-contact-button').click(); + + await popupExpect( + popupPage.getByRole('heading', { name: 'Enter your password' }) + ).toBeVisible(); + + await popupPage + .getByPlaceholder('Password', { exact: true }) + .fill(vaultPassword); + await popupPage.getByRole('button', { name: 'Continue' }).click(); + + await popupExpect( + popupPage.getByRole('heading', { name: 'Edit contact' }) + ).toBeVisible(); + popupExpect( + await popupPage.getByPlaceholder('Name', { exact: true }).inputValue() + ).toBe(DEFAULT_FIRST_ACCOUNT.accountName); + popupExpect( + await popupPage + .getByPlaceholder('Public key', { exact: true }) + .inputValue() + ).toBe(DEFAULT_FIRST_ACCOUNT.publicKey); + + await popupPage + .getByPlaceholder('Name', { exact: true }) + .fill(DEFAULT_SECOND_ACCOUNT.accountName); + await popupPage + .getByPlaceholder('Public key', { exact: true }) + .fill(DEFAULT_SECOND_ACCOUNT.publicKey); + + await popupPage.getByRole('button', { name: 'Save' }).click(); + + await popupExpect( + popupPage.getByText(DEFAULT_FIRST_ACCOUNT.accountName) + ).not.toBeVisible(); + + await popupPage.getByText(DEFAULT_SECOND_ACCOUNT.accountName).click(); + + await popupExpect( + popupPage.getByRole('heading', { + name: DEFAULT_SECOND_ACCOUNT.accountName + }) + ).toBeVisible(); + + await popupExpect( + popupPage.getByText(DEFAULT_SECOND_ACCOUNT.publicKey) + ).toBeVisible(); + } + ); + + popup( + 'should remove a contact successfully', + async ({ popupPage, unlockVault, addContact }) => { + await unlockVault(); + await addContact(); + + await popupPage.getByText(DEFAULT_FIRST_ACCOUNT.accountName).click(); + + await popupPage.getByTestId('delete-contact-button').click(); + + await popupExpect( + popupPage.getByRole('heading', { name: 'Enter your password' }) + ).toBeVisible(); + + await popupPage + .getByPlaceholder('Password', { exact: true }) + .fill(vaultPassword); + await popupPage.getByRole('button', { name: 'Continue' }).click(); + + await popupExpect( + popupPage.getByRole('heading', { name: 'Delete contact' }) + ).toBeVisible(); + + await popupPage.getByRole('button', { name: 'Delete' }).click(); + + await popupExpect( + popupPage.getByText(DEFAULT_FIRST_ACCOUNT.accountName) + ).not.toBeVisible(); + } + ); +}); diff --git a/jest.config.js b/jest.config.js index 53d2d591d..6ed9233d0 100644 --- a/jest.config.js +++ b/jest.config.js @@ -8,13 +8,9 @@ module.exports = { coveragePathIgnorePatterns: ['/node_modules/'], testRegex: '(/tests?/.*|(\\.|/)(test|spec))\\.tsx?$', moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], - modulePathIgnorePatterns: ['/.*/__mocks__', '/e2e'], + modulePathIgnorePatterns: ['/e2e-tests'], moduleNameMapper: { - '\\.(jpg|jpeg|png|gif|webp|svg|ttf|woff|woff2)$': - '/__mocks__/file-mock.js', - '^@src/(.*)$': '/src/$1', - '^@mocks/(.*)$': '/__mocks__/$1', - '^@testHelpers/(.*)$': '/__testHelpers__/$1' + '^@src/(.*)$': '/src/$1' }, setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'], coverageReporters: ['json', 'text'], diff --git a/jest.tsconfig.json b/jest.tsconfig.json index 0dd43cbda..27b375c34 100644 --- a/jest.tsconfig.json +++ b/jest.tsconfig.json @@ -18,13 +18,12 @@ "@popup/*": ["src/apps/popup/*"], "@import-account-with-file/*": ["src/apps/import-account-with-file/*"], "@connect-to-app/*": ["src/apps/connect-to-app/*"], + "@signature-request/*": ["src/apps/signature-request/*"], + "@onboarding/*": ["src/apps/onboarding/*"], "@background/*": ["src/background/*"], "@content/*": ["src/content/*"], - "@layout/*": ["src/libs/layout/*"], "@libs/*": ["src/libs/*"], - "@hooks/*": ["src/hooks/*"], - "@mocks/*": ["__mocks__/*"], - "@testHelpers/*": ["__testHelpers__/*"] + "@hooks/*": ["src/hooks/*"] } }, "exclude": ["node_modules", "build"] diff --git a/package-lock.json b/package-lock.json index 40886c620..9003b39ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,6 @@ "casper-cep18-js-client": "1.0.2", "casper-js-sdk": "2.13.3", "date-fns": "^2.30.0", - "facepaint": "^1.2.1", "i18next": "^23.5.1", "i18next-browser-languagedetector": "^6.1.5", "i18next-http-backend": "^2.4.1", @@ -65,10 +64,10 @@ "@testing-library/react": "^12.1.2", "@testing-library/react-hooks": "^7.0.2", "@testing-library/user-event": "^13.5.0", + "@trivago/prettier-plugin-sort-imports": "^4.3.0", "@types/big.js": "^6.1.6", "@types/chrome": "0.0.246", "@types/expect": "^24.3.0", - "@types/facepaint": "^1.2.3", "@types/jest": "29.2.3", "@types/lodash.throttle": "4.1.7", "@types/node": "^20.9.0", @@ -87,8 +86,9 @@ "eslint-config-airbnb": "^19.0.4", "eslint-config-prettier": "^8.3.0", "eslint-config-react-app": "^7.0.0", + "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-flowtype": "^8.0.3", - "eslint-plugin-import": "^2.25.2", + "eslint-plugin-import": "^2.29.1", "eslint-plugin-jsx-a11y": "^6.7.1", "eslint-plugin-prettier": "^5.0.0", "eslint-plugin-react": "7.33.2", @@ -115,7 +115,7 @@ "tsconfig-paths-webpack-plugin": "^4.1.0", "typescript": "4.9.3", "url-loader": "^4.1.1", - "web-ext": "7.8.0", + "web-ext": "7.9.0", "webextension-polyfill": "0.10.0", "webpack": "5.88.2", "webpack-cli": "5.1.4", @@ -833,9 +833,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "engines": { "node": ">=6.9.0" } @@ -2917,9 +2917,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -2967,9 +2967,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", - "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz", + "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3251,12 +3251,12 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", - "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", + "@humanwhocodes/object-schema": "^2.0.1", "debug": "^4.1.1", "minimatch": "^3.0.5" }, @@ -3278,9 +3278,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, "node_modules/@isaacs/cliui": { @@ -4324,9 +4324,9 @@ } }, "node_modules/@mdn/browser-compat-data": { - "version": "5.3.14", - "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.3.14.tgz", - "integrity": "sha512-Y9XQrphVcE6u9xMm+gIqN86opbU/5s2W1pdPyKRyFV5B7+2jWM2gLI5JpfhZncaoDKvhy6FYwK04aCz5UM/bTQ==", + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.4.3.tgz", + "integrity": "sha512-+VnaO5zYUwFQVuRqp2qLPGR5GwhhJ/lrp0yEmamJ/nI15P2GKwGBEWRDiITZR8i6AYxeiQSu2rOi/gqxehnPuA==", "dev": true }, "node_modules/@noble/ciphers": { @@ -5935,6 +5935,120 @@ "node": ">= 6" } }, + "node_modules/@trivago/prettier-plugin-sort-imports": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-4.3.0.tgz", + "integrity": "sha512-r3n0onD3BTOVUNPhR4lhVK4/pABGpbA7bW3eumZnYdKaHkf1qEC+Mag6DPbGNuuh0eG8AaYj+YqmVHSiGslaTQ==", + "dev": true, + "dependencies": { + "@babel/generator": "7.17.7", + "@babel/parser": "^7.20.5", + "@babel/traverse": "7.23.2", + "@babel/types": "7.17.0", + "javascript-natural-sort": "0.7.1", + "lodash": "^4.17.21" + }, + "peerDependencies": { + "@vue/compiler-sfc": "3.x", + "prettier": "2.x - 3.x" + }, + "peerDependenciesMeta": { + "@vue/compiler-sfc": { + "optional": true + } + } + }, + "node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/generator": { + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.7.tgz", + "integrity": "sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.17.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/traverse": { + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/traverse/node_modules/@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/traverse/node_modules/@babel/types": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -6421,12 +6535,6 @@ "@types/send": "*" } }, - "node_modules/@types/facepaint": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/facepaint/-/facepaint-1.2.3.tgz", - "integrity": "sha512-Im/T/LMrEMKySMuIhOovOGVdFLFP7wlrWWR9nl5laArHFQnik6xRfUWNr0khAQIGkqU8a/pTQPxycYnfwswCqw==", - "dev": true - }, "node_modules/@types/filesystem": { "version": "0.0.32", "resolved": "https://registry.npmjs.org/@types/filesystem/-/filesystem-0.0.32.tgz", @@ -6895,9 +7003,9 @@ "dev": true }, "node_modules/@types/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", "dev": true, "dependencies": { "@types/node": "*" @@ -7167,6 +7275,12 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/@webassemblyjs/ast": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", @@ -7456,35 +7570,35 @@ } }, "node_modules/addons-linter": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/addons-linter/-/addons-linter-6.13.0.tgz", - "integrity": "sha512-vYgDXl8aLmN1zU4HmsQdG6tUFByg499mHnTEMWDUbSkoYDq3koTne08EsqU6sD+o814u8FxclQP7580L0g/tPQ==", + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/addons-linter/-/addons-linter-6.19.0.tgz", + "integrity": "sha512-Yz5YRfIQ12dIqXKmEoHNwoS/L1xIve2hdm9UEesOEsov5W0zeWMOWCnqdvJNVNy7f1FnPu1lnqzylelkTBS7dA==", "dev": true, "dependencies": { "@fluent/syntax": "0.19.0", - "@mdn/browser-compat-data": "5.3.14", + "@mdn/browser-compat-data": "5.4.3", "addons-moz-compare": "1.3.0", - "addons-scanner-utils": "9.3.0", + "addons-scanner-utils": "9.8.0", "ajv": "8.12.0", "chalk": "4.1.2", "cheerio": "1.0.0-rc.12", "columnify": "1.6.0", "common-tags": "1.8.2", "deepmerge": "4.3.1", - "eslint": "8.48.0", + "eslint": "8.55.0", "eslint-plugin-no-unsanitized": "4.0.2", "eslint-visitor-keys": "3.4.3", "espree": "9.6.1", "esprima": "4.0.1", "fast-json-patch": "3.1.1", - "glob": "10.3.4", + "glob": "10.3.10", "image-size": "1.0.2", "is-mergeable-object": "1.1.1", "jed": "1.1.1", "json-merge-patch": "1.0.2", "os-locale": "5.0.0", - "pino": "8.15.0", - "postcss": "8.4.29", + "pino": "8.16.2", + "postcss": "8.4.32", "relaxed-json": "1.0.3", "semver": "7.5.4", "sha.js": "2.4.11", @@ -7502,12 +7616,12 @@ } }, "node_modules/addons-linter/node_modules/addons-scanner-utils": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/addons-scanner-utils/-/addons-scanner-utils-9.3.0.tgz", - "integrity": "sha512-YZWzNpP+em650XlZNH7NbTUcHJXqC0ihLEgwn17GGTqervyChqQffd9sm/QXNur0dmj7Ks1mD77iTg9XcJw64A==", + "version": "9.8.0", + "resolved": "https://registry.npmjs.org/addons-scanner-utils/-/addons-scanner-utils-9.8.0.tgz", + "integrity": "sha512-nJJ4QazrtMImyb2OK9SGZlNtinNu25dzOR0lhWthhJQN2iDOf3yqHdSiVBEeZvCwuT/sS1cU6me4O4kgEATjFQ==", "dev": true, "dependencies": { - "@types/yauzl": "2.10.0", + "@types/yauzl": "2.10.3", "common-tags": "1.8.2", "first-chunk-stream": "3.0.0", "strip-bom-stream": "4.0.0", @@ -7690,18 +7804,19 @@ } }, "node_modules/addons-linter/node_modules/eslint": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", - "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz", + "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.48.0", - "@humanwhocodes/config-array": "^0.11.10", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.55.0", + "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -7810,19 +7925,19 @@ } }, "node_modules/addons-linter/node_modules/glob": { - "version": "10.3.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.4.tgz", - "integrity": "sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ==", + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", "dev": true, "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", + "jackspeak": "^2.3.5", "minimatch": "^9.0.1", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", "path-scurry": "^1.10.1" }, "bin": { - "glob": "dist/cjs/src/bin.js" + "glob": "dist/esm/bin.mjs" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -7859,9 +7974,9 @@ } }, "node_modules/addons-linter/node_modules/globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -8423,15 +8538,15 @@ "dev": true }, "node_modules/array-includes": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", - "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", "is-string": "^1.0.7" }, "engines": { @@ -8450,15 +8565,34 @@ "node": ">=8" } }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", + "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array.prototype.flat": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", - "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" }, "engines": { @@ -8469,14 +8603,14 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" }, "engines": { @@ -13016,13 +13150,14 @@ } }, "node_modules/eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, "dependencies": { "debug": "^3.2.7", - "resolve": "^1.20.0" + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" } }, "node_modules/eslint-import-resolver-node/node_modules/debug": { @@ -13034,17 +13169,46 @@ "ms": "^2.1.1" } }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", + "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "enhanced-resolve": "^5.12.0", + "eslint-module-utils": "^2.7.4", + "fast-glob": "^3.3.1", + "get-tsconfig": "^4.5.0", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*" + } + }, "node_modules/eslint-module-utils": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", - "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", "dev": true, "dependencies": { - "debug": "^3.2.7", - "find-up": "^2.1.0" + "debug": "^3.2.7" }, "engines": { "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, "node_modules/eslint-module-utils/node_modules/debug": { @@ -13075,24 +13239,28 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" }, "engines": { "node": ">=4" @@ -13102,12 +13270,12 @@ } }, "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "node_modules/eslint-plugin-import/node_modules/doctrine": { @@ -13122,12 +13290,6 @@ "node": ">=0.10.0" } }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, "node_modules/eslint-plugin-jest": { "version": "25.7.0", "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz", @@ -13870,11 +14032,6 @@ "node >=0.6.0" ] }, - "node_modules/facepaint": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/facepaint/-/facepaint-1.2.1.tgz", - "integrity": "sha512-oNvBekbhsm/0PNSOWca5raHNAi6dG960Bx6LJgxDPNF59WpuspgQ17bN5MKwOr7JcFdQYc7StW3VZ28DBZLavQ==" - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -14120,18 +14277,6 @@ "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", "dev": true }, - "node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/firefox-profile": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/firefox-profile/-/firefox-profile-4.3.2.tgz", @@ -14241,9 +14386,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.0.tgz", - "integrity": "sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ==", + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", + "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", "dev": true, "funding": [ { @@ -14495,9 +14640,12 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/function.prototype.name": { "version": "1.1.6", @@ -14752,6 +14900,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-tsconfig": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", + "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -15316,6 +15476,18 @@ "minimalistic-assert": "^1.0.1" } }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -16361,12 +16533,12 @@ } }, "node_modules/is-core-module": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", - "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -17027,6 +17199,12 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "node_modules/javascript-natural-sort": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", + "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==", + "dev": true + }, "node_modules/javascript-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", @@ -20177,19 +20355,6 @@ "lie": "3.1.1" } }, - "node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -21688,14 +21853,14 @@ } }, "node_modules/object.fromentries": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", - "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", + "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "engines": { "node": ">= 0.4" @@ -21704,6 +21869,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object.groupby": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", + "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1" + } + }, "node_modules/object.hasown": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", @@ -21718,14 +21895,14 @@ } }, "node_modules/object.values": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", - "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "engines": { "node": ">= 0.4" @@ -21971,39 +22148,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-locate/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-locate/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/p-map": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", @@ -22360,15 +22504,6 @@ "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" }, - "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -22494,21 +22629,21 @@ } }, "node_modules/pino": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/pino/-/pino-8.15.0.tgz", - "integrity": "sha512-olUADJByk4twxccmAxb1RiGKOSvddHugCV3wkqjyv+3Sooa2KLrmXrKEWOKi0XPCLasRR5jBXxioE1jxUa4KzQ==", + "version": "8.16.2", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.16.2.tgz", + "integrity": "sha512-2advCDGVEvkKu9TTVSa/kWW7Z3htI/sBKEZpqiHk6ive0i/7f5b1rsU8jn0aimxqfnSz5bj/nOYkwhBUn5xxvg==", "dev": true, "dependencies": { "atomic-sleep": "^1.0.0", "fast-redact": "^3.1.1", "on-exit-leak-free": "^2.1.0", - "pino-abstract-transport": "v1.0.0", + "pino-abstract-transport": "v1.1.0", "pino-std-serializers": "^6.0.0", "process-warning": "^2.0.0", "quick-format-unescaped": "^4.0.3", "real-require": "^0.2.0", "safe-stable-stringify": "^2.3.1", - "sonic-boom": "^3.1.0", + "sonic-boom": "^3.7.0", "thread-stream": "^2.0.0" }, "bin": { @@ -22516,9 +22651,9 @@ } }, "node_modules/pino-abstract-transport": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.0.0.tgz", - "integrity": "sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.1.0.tgz", + "integrity": "sha512-lsleG3/2a/JIWUtf9Q5gUNErBqwIu1tUKTT3dUzaf5DySw9ra1wcqKjJjLX1VTY64Wk1eEOYsVGSaGfCK85ekA==", "dev": true, "dependencies": { "readable-stream": "^4.0.0", @@ -22550,9 +22685,9 @@ } }, "node_modules/pino-abstract-transport/node_modules/readable-stream": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz", - "integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.1.tgz", + "integrity": "sha512-uQjbf34vmf/asGnOHQEw07Q4llgMACQZTWWa4MmICS0IKJoHbLwKCy71H3eR99Dw5iYejc6W+pqZZEeqRtUFAw==", "dev": true, "dependencies": { "abort-controller": "^3.0.0", @@ -22684,9 +22819,9 @@ } }, "node_modules/postcss": { - "version": "8.4.29", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", - "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", + "version": "8.4.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz", + "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==", "dev": true, "funding": [ { @@ -22703,7 +22838,7 @@ } ], "dependencies": { - "nanoid": "^3.3.6", + "nanoid": "^3.3.7", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -22880,9 +23015,9 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "node_modules/process-warning": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.3.1.tgz", - "integrity": "sha512-JjBvFEn7MwFbzUDa2SRtKJSsyO0LlER4V/FmwLMhBlXNbGgGxdyFCxIdMDLerWUycsVUyaoM9QFLvppFy4IWaQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.3.2.tgz", + "integrity": "sha512-n9wh8tvBe5sFmsqlg+XQhaQLumwpqoAUruLwjCopgTmUBjJ/fjtBsJzKleCaIGBOMXYEhp1YfKl4d7rJ5ZKJGA==", "dev": true }, "node_modules/progress": { @@ -24116,12 +24251,12 @@ "integrity": "sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A==" }, "node_modules/resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "dependencies": { - "is-core-module": "^2.8.1", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -24179,6 +24314,15 @@ "node": ">= 0.10" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/resolve.exports": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", @@ -26564,13 +26708,13 @@ "integrity": "sha512-FWqxGX2NHp5oCyaMd96o2y2uMQmSu8Dey6kvyuFdRJ2AzfmWo3kWa4UsPlCGlfQ/qu03m09ZZtppMoY8EMHuiA==" }, "node_modules/tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, "dependencies": { "@types/json5": "^0.0.29", - "json5": "^1.0.1", + "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } @@ -26697,7 +26841,7 @@ "node_modules/tsconfig-paths/node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, "engines": { "node": ">=4" @@ -27623,14 +27767,14 @@ } }, "node_modules/web-ext": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/web-ext/-/web-ext-7.8.0.tgz", - "integrity": "sha512-ta+VjbNfK5q0pqRmrlH/DQMdJ89sAJFfgcvpqoUoe2gPxLu18zZ5mIakGvyjmfjrkJLOZ2NCNF7suj/qd6xaEQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/web-ext/-/web-ext-7.9.0.tgz", + "integrity": "sha512-oWMiM3e+u5E8X7aUMgQ0BCGjlbZt4XwF6ExAXsXx9Btdz3nLmUY/4eKEZA1J+2T7WhCdRwN7Pdh2VKMej/pthQ==", "dev": true, "dependencies": { "@babel/runtime": "7.21.0", "@devicefarmer/adbkit": "3.2.3", - "addons-linter": "6.13.0", + "addons-linter": "6.19.0", "bunyan": "1.8.15", "camelcase": "7.0.1", "chrome-launcher": "0.15.1", @@ -29348,9 +29492,9 @@ } }, "@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==" + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==" }, "@babel/helper-validator-identifier": { "version": "7.22.20", @@ -30816,9 +30960,9 @@ "dev": true }, "@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -30850,9 +30994,9 @@ } }, "@eslint/js": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", - "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz", + "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==", "dev": true }, "@ethersproject/bignumber": { @@ -31065,12 +31209,12 @@ } }, "@humanwhocodes/config-array": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", - "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^1.2.1", + "@humanwhocodes/object-schema": "^2.0.1", "debug": "^4.1.1", "minimatch": "^3.0.5" } @@ -31082,9 +31226,9 @@ "dev": true }, "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, "@isaacs/cliui": { @@ -31882,9 +32026,9 @@ } }, "@mdn/browser-compat-data": { - "version": "5.3.14", - "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.3.14.tgz", - "integrity": "sha512-Y9XQrphVcE6u9xMm+gIqN86opbU/5s2W1pdPyKRyFV5B7+2jWM2gLI5JpfhZncaoDKvhy6FYwK04aCz5UM/bTQ==", + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.4.3.tgz", + "integrity": "sha512-+VnaO5zYUwFQVuRqp2qLPGR5GwhhJ/lrp0yEmamJ/nI15P2GKwGBEWRDiITZR8i6AYxeiQSu2rOi/gqxehnPuA==", "dev": true }, "@noble/ciphers": { @@ -33092,6 +33236,97 @@ "dev": true, "optional": true }, + "@trivago/prettier-plugin-sort-imports": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-4.3.0.tgz", + "integrity": "sha512-r3n0onD3BTOVUNPhR4lhVK4/pABGpbA7bW3eumZnYdKaHkf1qEC+Mag6DPbGNuuh0eG8AaYj+YqmVHSiGslaTQ==", + "dev": true, + "requires": { + "@babel/generator": "7.17.7", + "@babel/parser": "^7.20.5", + "@babel/traverse": "7.23.2", + "@babel/types": "7.17.0", + "javascript-natural-sort": "0.7.1", + "lodash": "^4.17.21" + }, + "dependencies": { + "@babel/generator": { + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.7.tgz", + "integrity": "sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==", + "dev": true, + "requires": { + "@babel/types": "^7.17.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/traverse": { + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "dependencies": { + "@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dev": true, + "requires": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + } + }, + "@babel/types": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", + "dev": true, + "requires": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + }, + "@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } + } + }, "@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -33577,12 +33812,6 @@ "@types/send": "*" } }, - "@types/facepaint": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/facepaint/-/facepaint-1.2.3.tgz", - "integrity": "sha512-Im/T/LMrEMKySMuIhOovOGVdFLFP7wlrWWR9nl5laArHFQnik6xRfUWNr0khAQIGkqU8a/pTQPxycYnfwswCqw==", - "dev": true - }, "@types/filesystem": { "version": "0.0.32", "resolved": "https://registry.npmjs.org/@types/filesystem/-/filesystem-0.0.32.tgz", @@ -34042,9 +34271,9 @@ "dev": true }, "@types/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", "dev": true, "requires": { "@types/node": "*" @@ -34202,6 +34431,12 @@ } } }, + "@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "@webassemblyjs/ast": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", @@ -34449,35 +34684,35 @@ "dev": true }, "addons-linter": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/addons-linter/-/addons-linter-6.13.0.tgz", - "integrity": "sha512-vYgDXl8aLmN1zU4HmsQdG6tUFByg499mHnTEMWDUbSkoYDq3koTne08EsqU6sD+o814u8FxclQP7580L0g/tPQ==", + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/addons-linter/-/addons-linter-6.19.0.tgz", + "integrity": "sha512-Yz5YRfIQ12dIqXKmEoHNwoS/L1xIve2hdm9UEesOEsov5W0zeWMOWCnqdvJNVNy7f1FnPu1lnqzylelkTBS7dA==", "dev": true, "requires": { "@fluent/syntax": "0.19.0", - "@mdn/browser-compat-data": "5.3.14", + "@mdn/browser-compat-data": "5.4.3", "addons-moz-compare": "1.3.0", - "addons-scanner-utils": "9.3.0", + "addons-scanner-utils": "9.8.0", "ajv": "8.12.0", "chalk": "4.1.2", "cheerio": "1.0.0-rc.12", "columnify": "1.6.0", "common-tags": "1.8.2", "deepmerge": "4.3.1", - "eslint": "8.48.0", + "eslint": "8.55.0", "eslint-plugin-no-unsanitized": "4.0.2", "eslint-visitor-keys": "3.4.3", "espree": "9.6.1", "esprima": "4.0.1", "fast-json-patch": "3.1.1", - "glob": "10.3.4", + "glob": "10.3.10", "image-size": "1.0.2", "is-mergeable-object": "1.1.1", "jed": "1.1.1", "json-merge-patch": "1.0.2", "os-locale": "5.0.0", - "pino": "8.15.0", - "postcss": "8.4.29", + "pino": "8.16.2", + "postcss": "8.4.32", "relaxed-json": "1.0.3", "semver": "7.5.4", "sha.js": "2.4.11", @@ -34489,12 +34724,12 @@ }, "dependencies": { "addons-scanner-utils": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/addons-scanner-utils/-/addons-scanner-utils-9.3.0.tgz", - "integrity": "sha512-YZWzNpP+em650XlZNH7NbTUcHJXqC0ihLEgwn17GGTqervyChqQffd9sm/QXNur0dmj7Ks1mD77iTg9XcJw64A==", + "version": "9.8.0", + "resolved": "https://registry.npmjs.org/addons-scanner-utils/-/addons-scanner-utils-9.8.0.tgz", + "integrity": "sha512-nJJ4QazrtMImyb2OK9SGZlNtinNu25dzOR0lhWthhJQN2iDOf3yqHdSiVBEeZvCwuT/sS1cU6me4O4kgEATjFQ==", "dev": true, "requires": { - "@types/yauzl": "2.10.0", + "@types/yauzl": "2.10.3", "common-tags": "1.8.2", "first-chunk-stream": "3.0.0", "strip-bom-stream": "4.0.0", @@ -34624,18 +34859,19 @@ "dev": true }, "eslint": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", - "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz", + "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.48.0", - "@humanwhocodes/config-array": "^0.11.10", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.55.0", + "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -34715,13 +34951,13 @@ } }, "glob": { - "version": "10.3.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.4.tgz", - "integrity": "sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ==", + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", "dev": true, "requires": { "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", + "jackspeak": "^2.3.5", "minimatch": "^9.0.1", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", "path-scurry": "^1.10.1" @@ -34748,9 +34984,9 @@ } }, "globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -35182,15 +35418,15 @@ "dev": true }, "array-includes": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", - "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", "is-string": "^1.0.7" } }, @@ -35200,27 +35436,40 @@ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, + "array.prototype.findlastindex": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", + "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + } + }, "array.prototype.flat": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", - "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" } }, "array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" } }, @@ -38799,13 +39048,14 @@ } }, "eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, "requires": { "debug": "^3.2.7", - "resolve": "^1.20.0" + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" }, "dependencies": { "debug": { @@ -38819,14 +39069,28 @@ } } }, + "eslint-import-resolver-typescript": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", + "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", + "dev": true, + "requires": { + "debug": "^4.3.4", + "enhanced-resolve": "^5.12.0", + "eslint-module-utils": "^2.7.4", + "fast-glob": "^3.3.1", + "get-tsconfig": "^4.5.0", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3" + } + }, "eslint-module-utils": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", - "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", "dev": true, "requires": { - "debug": "^3.2.7", - "find-up": "^2.1.0" + "debug": "^3.2.7" }, "dependencies": { "debug": { @@ -38851,33 +39115,37 @@ } }, "eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, "requires": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" }, "dependencies": { "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "doctrine": { @@ -38888,12 +39156,6 @@ "requires": { "esutils": "^2.0.2" } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true } } }, @@ -39270,11 +39532,6 @@ "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", "dev": true }, - "facepaint": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/facepaint/-/facepaint-1.2.1.tgz", - "integrity": "sha512-oNvBekbhsm/0PNSOWca5raHNAi6dG960Bx6LJgxDPNF59WpuspgQ17bN5MKwOr7JcFdQYc7StW3VZ28DBZLavQ==" - }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -39470,15 +39727,6 @@ "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", "dev": true }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, "firefox-profile": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/firefox-profile/-/firefox-profile-4.3.2.tgz", @@ -39574,9 +39822,9 @@ } }, "follow-redirects": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.0.tgz", - "integrity": "sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ==", + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", + "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", "dev": true }, "for-each": { @@ -39772,9 +40020,9 @@ "optional": true }, "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" }, "function.prototype.name": { "version": "1.1.6", @@ -39964,6 +40212,15 @@ "get-intrinsic": "^1.1.1" } }, + "get-tsconfig": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", + "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "dev": true, + "requires": { + "resolve-pkg-maps": "^1.0.0" + } + }, "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -40398,6 +40655,15 @@ "minimalistic-assert": "^1.0.1" } }, + "hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "requires": { + "function-bind": "^1.1.2" + } + }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -41170,12 +41436,12 @@ } }, "is-core-module": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", - "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, "requires": { - "has": "^1.0.3" + "hasown": "^2.0.0" } }, "is-date-object": { @@ -41631,6 +41897,12 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "javascript-natural-sort": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", + "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==", + "dev": true + }, "javascript-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", @@ -44022,16 +44294,6 @@ "lie": "3.1.1" } }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -45193,14 +45455,26 @@ } }, "object.fromentries": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", - "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", + "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + } + }, + "object.groupby": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", + "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1" } }, "object.hasown": { @@ -45214,14 +45488,14 @@ } }, "object.values": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", - "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" } }, "oblivious-set": { @@ -45405,32 +45679,6 @@ "yocto-queue": "^0.1.0" } }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - }, - "dependencies": { - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - } - } - }, "p-map": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", @@ -45682,12 +45930,6 @@ "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -45782,28 +46024,28 @@ "dev": true }, "pino": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/pino/-/pino-8.15.0.tgz", - "integrity": "sha512-olUADJByk4twxccmAxb1RiGKOSvddHugCV3wkqjyv+3Sooa2KLrmXrKEWOKi0XPCLasRR5jBXxioE1jxUa4KzQ==", + "version": "8.16.2", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.16.2.tgz", + "integrity": "sha512-2advCDGVEvkKu9TTVSa/kWW7Z3htI/sBKEZpqiHk6ive0i/7f5b1rsU8jn0aimxqfnSz5bj/nOYkwhBUn5xxvg==", "dev": true, "requires": { "atomic-sleep": "^1.0.0", "fast-redact": "^3.1.1", "on-exit-leak-free": "^2.1.0", - "pino-abstract-transport": "v1.0.0", + "pino-abstract-transport": "v1.1.0", "pino-std-serializers": "^6.0.0", "process-warning": "^2.0.0", "quick-format-unescaped": "^4.0.3", "real-require": "^0.2.0", "safe-stable-stringify": "^2.3.1", - "sonic-boom": "^3.1.0", + "sonic-boom": "^3.7.0", "thread-stream": "^2.0.0" } }, "pino-abstract-transport": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.0.0.tgz", - "integrity": "sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.1.0.tgz", + "integrity": "sha512-lsleG3/2a/JIWUtf9Q5gUNErBqwIu1tUKTT3dUzaf5DySw9ra1wcqKjJjLX1VTY64Wk1eEOYsVGSaGfCK85ekA==", "dev": true, "requires": { "readable-stream": "^4.0.0", @@ -45821,9 +46063,9 @@ } }, "readable-stream": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz", - "integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.1.tgz", + "integrity": "sha512-uQjbf34vmf/asGnOHQEw07Q4llgMACQZTWWa4MmICS0IKJoHbLwKCy71H3eR99Dw5iYejc6W+pqZZEeqRtUFAw==", "dev": true, "requires": { "abort-controller": "^3.0.0", @@ -45918,12 +46160,12 @@ "dev": true }, "postcss": { - "version": "8.4.29", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", - "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", + "version": "8.4.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz", + "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==", "dev": true, "requires": { - "nanoid": "^3.3.6", + "nanoid": "^3.3.7", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } @@ -46046,9 +46288,9 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "process-warning": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.3.1.tgz", - "integrity": "sha512-JjBvFEn7MwFbzUDa2SRtKJSsyO0LlER4V/FmwLMhBlXNbGgGxdyFCxIdMDLerWUycsVUyaoM9QFLvppFy4IWaQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.3.2.tgz", + "integrity": "sha512-n9wh8tvBe5sFmsqlg+XQhaQLumwpqoAUruLwjCopgTmUBjJ/fjtBsJzKleCaIGBOMXYEhp1YfKl4d7rJ5ZKJGA==", "dev": true }, "progress": { @@ -46990,12 +47232,12 @@ "integrity": "sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A==" }, "resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "requires": { - "is-core-module": "^2.8.1", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } @@ -47037,6 +47279,12 @@ "value-or-function": "^3.0.0" } }, + "resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true + }, "resolve.exports": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", @@ -48883,13 +49131,13 @@ "integrity": "sha512-FWqxGX2NHp5oCyaMd96o2y2uMQmSu8Dey6kvyuFdRJ2AzfmWo3kWa4UsPlCGlfQ/qu03m09ZZtppMoY8EMHuiA==" }, "tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, "requires": { "@types/json5": "^0.0.29", - "json5": "^1.0.1", + "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" }, @@ -48906,7 +49154,7 @@ "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true } } @@ -49715,14 +49963,14 @@ } }, "web-ext": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/web-ext/-/web-ext-7.8.0.tgz", - "integrity": "sha512-ta+VjbNfK5q0pqRmrlH/DQMdJ89sAJFfgcvpqoUoe2gPxLu18zZ5mIakGvyjmfjrkJLOZ2NCNF7suj/qd6xaEQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/web-ext/-/web-ext-7.9.0.tgz", + "integrity": "sha512-oWMiM3e+u5E8X7aUMgQ0BCGjlbZt4XwF6ExAXsXx9Btdz3nLmUY/4eKEZA1J+2T7WhCdRwN7Pdh2VKMej/pthQ==", "dev": true, "requires": { "@babel/runtime": "7.21.0", "@devicefarmer/adbkit": "3.2.3", - "addons-linter": "6.13.0", + "addons-linter": "6.19.0", "bunyan": "1.8.15", "camelcase": "7.0.1", "chrome-launcher": "0.15.1", diff --git a/package.json b/package.json index 2efadb5b9..7192aedfb 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "Casper Wallet", "description": "Securely manage your CSPR tokens and interact with dapps with the self-custody wallet for the Casper blockchain.", - "version": "1.8.0", + "version": "1.8.1", "author": "MAKE LLC", "scripts": { "devtools:redux": "redux-devtools --hostname=localhost", @@ -56,8 +56,8 @@ "@hookform/resolvers": "2.9.10", "@hot-loader/react-dom": "^17.0.1", "@lapo/asn1js": "1.2.4", - "@make-software/ces-js-parser": "1.3.2", "@lottiefiles/react-lottie-player": "3.5.3", + "@make-software/ces-js-parser": "1.3.2", "@noble/ciphers": "^0.3.0", "@scure/bip32": "1.3.2", "@scure/bip39": "1.2.1", @@ -68,7 +68,6 @@ "casper-cep18-js-client": "1.0.2", "casper-js-sdk": "2.13.3", "date-fns": "^2.30.0", - "facepaint": "^1.2.1", "i18next": "^23.5.1", "i18next-browser-languagedetector": "^6.1.5", "i18next-http-backend": "^2.4.1", @@ -109,10 +108,10 @@ "@testing-library/react": "^12.1.2", "@testing-library/react-hooks": "^7.0.2", "@testing-library/user-event": "^13.5.0", + "@trivago/prettier-plugin-sort-imports": "^4.3.0", "@types/big.js": "^6.1.6", "@types/chrome": "0.0.246", "@types/expect": "^24.3.0", - "@types/facepaint": "^1.2.3", "@types/jest": "29.2.3", "@types/lodash.throttle": "4.1.7", "@types/node": "^20.9.0", @@ -131,8 +130,9 @@ "eslint-config-airbnb": "^19.0.4", "eslint-config-prettier": "^8.3.0", "eslint-config-react-app": "^7.0.0", + "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-flowtype": "^8.0.3", - "eslint-plugin-import": "^2.25.2", + "eslint-plugin-import": "^2.29.1", "eslint-plugin-jsx-a11y": "^6.7.1", "eslint-plugin-prettier": "^5.0.0", "eslint-plugin-react": "7.33.2", @@ -159,7 +159,7 @@ "tsconfig-paths-webpack-plugin": "^4.1.0", "typescript": "4.9.3", "url-loader": "^4.1.1", - "web-ext": "7.8.0", + "web-ext": "7.9.0", "webextension-polyfill": "0.10.0", "webpack": "5.88.2", "webpack-cli": "5.1.4", diff --git a/src/apps/connect-to-app/app-router.tsx b/src/apps/connect-to-app/app-router.tsx index d39934a37..eb975dee3 100644 --- a/src/apps/connect-to-app/app-router.tsx +++ b/src/apps/connect-to-app/app-router.tsx @@ -1,16 +1,19 @@ import React, { useState } from 'react'; -import { Route, Routes } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; -import { HashRouter } from 'react-router-dom'; - -import { RouterPath } from '@src/apps/connect-to-app/router'; -import { SelectAccountPage } from '@src/apps/connect-to-app/pages/select-account'; -import { ApproveConnectionPage } from '@src/apps/connect-to-app/pages/approve-connection'; -import { ConnectingPage } from '@src/apps/connect-to-app/pages/connecting'; -import { useUserActivityTracker } from '@src/hooks/use-user-activity-tracker'; import { useSelector } from 'react-redux'; -import { selectVaultIsLocked } from '@src/background/redux/session/selectors'; -import { LockedRouter } from '@src/libs/layout/locked-router'; +import { HashRouter, Route, Routes } from 'react-router-dom'; + +import { ApproveConnectionPage } from '@connect-to-app/pages/approve-connection'; +import { ConnectingPage } from '@connect-to-app/pages/connecting'; +import { SelectAccountPage } from '@connect-to-app/pages/select-account'; +import { RouterPath } from '@connect-to-app/router'; + +import { selectVaultIsLocked } from '@background/redux/session/selectors'; + +import { useUserActivityTracker } from '@hooks/use-user-activity-tracker'; + +import { LockedRouter } from '@libs/layout'; + import { SwitchAccountPage } from './pages/switch-account'; export function AppRouter() { diff --git a/src/apps/connect-to-app/index.tsx b/src/apps/connect-to-app/index.tsx index 43148a6b7..0f66d017b 100644 --- a/src/apps/connect-to-app/index.tsx +++ b/src/apps/connect-to-app/index.tsx @@ -1,26 +1,26 @@ -import '@libs/i18n/i18n'; - import React, { Suspense, useState } from 'react'; import { render } from 'react-dom'; import { Provider as ReduxProvider } from 'react-redux'; import { ThemeProvider } from 'styled-components'; -import { AppRouter } from '@src/apps/connect-to-app/app-router'; -import { GlobalStyle, lightTheme, darkTheme } from '@libs/ui'; -import { ErrorBoundary } from '@src/libs/layout/error'; - -import { - createMainStoreReplica, - dispatchToMainStore, - PopupState -} from '@src/background/redux/utils'; -import { connectWindowInit } from '@src/background/redux/windowManagement/actions'; import { useSubscribeToRedux } from '@src/hooks/use-subscribe-to-redux'; -import { selectThemeModeSetting } from '@background/redux/settings/selectors'; -import { useSystemThemeDetector } from '@src/hooks'; +import { isSafariBuild } from '@src/utils'; + +import { AppRouter } from '@connect-to-app/app-router'; + +import { createMainStoreReplica } from '@background/redux/get-main-store'; import { themeModeSettingChanged } from '@background/redux/settings/actions'; +import { selectThemeModeSetting } from '@background/redux/settings/selectors'; import { ThemeMode } from '@background/redux/settings/types'; -import { isSafariBuild } from '@src/utils'; +import { PopupState } from '@background/redux/types'; +import { dispatchToMainStore } from '@background/redux/utils'; +import { connectWindowInit } from '@background/redux/windowManagement/actions'; + +import { useSystemThemeDetector } from '@hooks/use-system-theme-detector'; + +import '@libs/i18n/i18n'; +import { ErrorBoundary } from '@libs/layout'; +import { GlobalStyle, darkTheme, lightTheme } from '@libs/ui'; const Tree = () => { const [state, setState] = useState(null); diff --git a/src/apps/connect-to-app/pages/approve-connection/content.tsx b/src/apps/connect-to-app/pages/approve-connection/content.tsx index 2c077a6b5..8a6614e79 100644 --- a/src/apps/connect-to-app/pages/approve-connection/content.tsx +++ b/src/apps/connect-to-app/pages/approve-connection/content.tsx @@ -3,15 +3,20 @@ import { useTranslation } from 'react-i18next'; import styled from 'styled-components'; import { - ParagraphContainer, - PageContainer, - ContentContainer, BreakWordContainer, - VerticalSpaceContainer, + ContentContainer, ListItemClickableContainer, - SpacingSize -} from '@src/libs/layout'; -import { SiteFaviconBadge, List, SvgIcon, Typography } from '@src/libs/ui'; + PageContainer, + ParagraphContainer, + SpacingSize, + VerticalSpaceContainer +} from '@libs/layout'; +import { + List, + SiteFaviconBadge, + SvgIcon, + Typography +} from '@libs/ui/components'; const ListItemContainer = styled(ListItemClickableContainer)` cursor: unset; diff --git a/src/apps/connect-to-app/pages/approve-connection/index.tsx b/src/apps/connect-to-app/pages/approve-connection/index.tsx index ba61dafc5..c622c8f8c 100644 --- a/src/apps/connect-to-app/pages/approve-connection/index.tsx +++ b/src/apps/connect-to-app/pages/approve-connection/index.tsx @@ -3,20 +3,23 @@ import React from 'react'; import { Trans } from 'react-i18next'; import styled from 'styled-components'; -import { useAccountManager } from '@src/apps/popup/hooks/use-account-actions-with-events'; -import { closeCurrentWindow } from '@src/background/close-current-window'; +import { useAccountManager } from '@popup/hooks/use-account-actions-with-events'; + +import { closeCurrentWindow } from '@background/close-current-window'; +import { sendSdkResponseToSpecificTab } from '@background/send-sdk-response-to-specific-tab'; + +import { sdkMethod } from '@content/sdk-method'; + import { FooterButtonsContainer, + HeaderPopup, HeaderSubmenuBarNavLink, - LayoutWindow, - PopupHeader -} from '@src/libs/layout'; -import { Button, Typography } from '@src/libs/ui'; + LayoutWindow +} from '@libs/layout'; +import { Button, Typography } from '@libs/ui/components'; import { RouterPath, useTypedNavigate } from '../../router'; import { ApproveConnectionContent } from './content'; -import { sendSdkResponseToSpecificTab } from '@src/background/send-sdk-response-to-specific-tab'; -import { sdkMethod } from '@src/content/sdk-method'; const TextCentredContainer = styled.div` text-align: center; @@ -66,7 +69,7 @@ export function ApproveConnectionPage({ return ( ( - ( )} diff --git a/src/apps/connect-to-app/pages/connecting/content.tsx b/src/apps/connect-to-app/pages/connecting/content.tsx index aaaf4900e..550e7de9d 100644 --- a/src/apps/connect-to-app/pages/connecting/content.tsx +++ b/src/apps/connect-to-app/pages/connecting/content.tsx @@ -1,10 +1,15 @@ import React, { useEffect } from 'react'; -import { useTranslation, Trans } from 'react-i18next'; +import { Trans, useTranslation } from 'react-i18next'; import styled from 'styled-components'; -import { getFaviconUrlFromOrigin, SvgIcon, Typography } from '@libs/ui'; -import { closeCurrentWindow } from '@src/background/close-current-window'; +import { closeCurrentWindow } from '@background/close-current-window'; + import { AlignedFlexRow, SpacingSize } from '@libs/layout'; +import { + SvgIcon, + Typography, + getFaviconUrlFromOrigin +} from '@libs/ui/components'; const PageContainer = styled.div` display: flex; diff --git a/src/apps/connect-to-app/pages/connecting/index.tsx b/src/apps/connect-to-app/pages/connecting/index.tsx index 5732ece9e..f6bd949e6 100644 --- a/src/apps/connect-to-app/pages/connecting/index.tsx +++ b/src/apps/connect-to-app/pages/connecting/index.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { LayoutWindow, PopupHeader } from '@src/libs/layout'; +import { HeaderPopup, LayoutWindow } from '@libs/layout'; import { ConnectingContent } from './content'; @@ -11,7 +11,7 @@ export interface ConnectingPageProps { export function ConnectingPage({ origin }: ConnectingPageProps) { return ( } + renderHeader={() => } renderContent={() => } /> ); diff --git a/src/apps/connect-to-app/pages/select-account/content.tsx b/src/apps/connect-to-app/pages/select-account/content.tsx index d0c8b2818..985392154 100644 --- a/src/apps/connect-to-app/pages/select-account/content.tsx +++ b/src/apps/connect-to-app/pages/select-account/content.tsx @@ -1,33 +1,32 @@ -import React, { useMemo, useCallback, SetStateAction, Dispatch } from 'react'; +import React, { Dispatch, SetStateAction, useCallback, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; import styled from 'styled-components'; import { - Checkbox, - SiteFaviconBadge, - Hash, - HashVariant, - List, - Typography -} from '@src/libs/ui'; + selectConnectedAccountNamesWithActiveOrigin, + selectVaultAccounts, + selectVaultActiveAccount +} from '@background/redux/vault/selectors'; import { - PageContainer, + BreakWordContainer, ContentContainer, - ParagraphContainer, - ListItemClickableContainer, LeftAlignedFlexColumn, - BreakWordContainer, - VerticalSpaceContainer, - SpacingSize -} from '@src/libs/layout'; - + ListItemClickableContainer, + PageContainer, + ParagraphContainer, + SpacingSize, + VerticalSpaceContainer +} from '@libs/layout'; import { - selectConnectedAccountNamesWithActiveOrigin, - selectVaultAccounts, - selectVaultActiveAccount -} from '@src/background/redux/vault/selectors'; + Checkbox, + Hash, + HashVariant, + List, + SiteFaviconBadge, + Typography +} from '@libs/ui/components'; const AccountNameWithHashListItemContainer = styled(LeftAlignedFlexColumn)` width: 100%; diff --git a/src/apps/connect-to-app/pages/select-account/index.tsx b/src/apps/connect-to-app/pages/select-account/index.tsx index 2f293306e..29675cee3 100644 --- a/src/apps/connect-to-app/pages/select-account/index.tsx +++ b/src/apps/connect-to-app/pages/select-account/index.tsx @@ -1,22 +1,24 @@ import React, { Dispatch, SetStateAction } from 'react'; import { Trans, useTranslation } from 'react-i18next'; +import { useSelector } from 'react-redux'; +import styled from 'styled-components'; + +import { closeCurrentWindow } from '@background/close-current-window'; +import { selectIsActiveAccountConnectedWithActiveOrigin } from '@background/redux/vault/selectors'; +import { sendSdkResponseToSpecificTab } from '@background/send-sdk-response-to-specific-tab'; + +import { sdkMethod } from '@content/sdk-method'; import { FooterButtonsContainer, + HeaderPopup, HeaderSubmenuBarNavLink, - LayoutWindow, - PopupHeader -} from '@src/libs/layout'; -import { Button, Typography } from '@src/libs/ui'; + LayoutWindow +} from '@libs/layout'; +import { Button, Typography } from '@libs/ui/components'; import { RouterPath, useTypedNavigate } from '../../router'; import { SelectAccountContent } from './content'; -import styled from 'styled-components'; -import { sendSdkResponseToSpecificTab } from '@src/background/send-sdk-response-to-specific-tab'; -import { sdkMethod } from '@src/content/sdk-method'; -import { closeCurrentWindow } from '@src/background/close-current-window'; -import { selectIsActiveAccountConnectedWithActiveOrigin } from '@src/background/redux/vault/selectors'; -import { useSelector } from 'react-redux'; const TextCentredContainer = styled.div` text-align: center; @@ -69,7 +71,7 @@ export function SelectAccountPage({ return ( ( - ( ( - ( } + renderHeader={() => } renderContent={() => } /> } @@ -39,7 +39,7 @@ export function AppRouter() { path={RouterPath.ImportAccountWithFileFailure} element={ } + renderHeader={() => } renderContent={() => } /> } diff --git a/src/apps/import-account-with-file/index.tsx b/src/apps/import-account-with-file/index.tsx index eb909f2cf..2061642ff 100644 --- a/src/apps/import-account-with-file/index.tsx +++ b/src/apps/import-account-with-file/index.tsx @@ -1,26 +1,26 @@ -import '@libs/i18n/i18n'; - import React, { Suspense, useState } from 'react'; import { render } from 'react-dom'; -import { ThemeProvider } from 'styled-components'; import { Provider as ReduxProvider } from 'react-redux'; +import { ThemeProvider } from 'styled-components'; -import { importWindowInit } from '@src/background/redux/windowManagement/actions'; -import { - createMainStoreReplica, - dispatchToMainStore, - PopupState -} from '@src/background/redux/utils'; -import { darkTheme, GlobalStyle, lightTheme } from '@libs/ui'; -import { ErrorBoundary } from '@src/libs/layout/error'; - -import { AppRouter } from './app-router'; import { useSubscribeToRedux } from '@src/hooks/use-subscribe-to-redux'; -import { selectThemeModeSetting } from '@background/redux/settings/selectors'; -import { useSystemThemeDetector } from '@src/hooks'; +import { isSafariBuild } from '@src/utils'; + +import { createMainStoreReplica } from '@background/redux/get-main-store'; import { themeModeSettingChanged } from '@background/redux/settings/actions'; +import { selectThemeModeSetting } from '@background/redux/settings/selectors'; import { ThemeMode } from '@background/redux/settings/types'; -import { isSafariBuild } from '@src/utils'; +import { PopupState } from '@background/redux/types'; +import { dispatchToMainStore } from '@background/redux/utils'; +import { importWindowInit } from '@background/redux/windowManagement/actions'; + +import { useSystemThemeDetector } from '@hooks/use-system-theme-detector'; + +import '@libs/i18n/i18n'; +import { ErrorBoundary } from '@libs/layout'; +import { GlobalStyle, darkTheme, lightTheme } from '@libs/ui'; + +import { AppRouter } from './app-router'; const Tree = () => { const [state, setState] = useState(null); diff --git a/src/apps/import-account-with-file/pages/import-account-with-file-failure/index.tsx b/src/apps/import-account-with-file/pages/import-account-with-file-failure/index.tsx index 3cea071ff..e69b48ffa 100644 --- a/src/apps/import-account-with-file/pages/import-account-with-file-failure/index.tsx +++ b/src/apps/import-account-with-file/pages/import-account-with-file-failure/index.tsx @@ -1,21 +1,22 @@ import React from 'react'; import { Trans, useTranslation } from 'react-i18next'; -import { - FooterButtonsAbsoluteContainer, - ContentContainer, - ParagraphContainer, - IllustrationContainer, - SpacingSize -} from '@src/libs/layout'; -import { Button, SvgIcon, Typography } from '@src/libs/ui'; - import { RouterPath, useTypedLocation, useTypedNavigate -} from '@src/apps/import-account-with-file/router'; -import { closeCurrentWindow } from '@src/background/close-current-window'; +} from '@import-account-with-file/router'; + +import { closeCurrentWindow } from '@background/close-current-window'; + +import { + ContentContainer, + FooterButtonsAbsoluteContainer, + IllustrationContainer, + ParagraphContainer, + SpacingSize +} from '@libs/layout'; +import { Button, SvgIcon, Typography } from '@libs/ui/components'; export function ImportAccountWithFileFailureContentPage() { const { t } = useTranslation(); diff --git a/src/apps/import-account-with-file/pages/import-account-with-file-success/index.tsx b/src/apps/import-account-with-file/pages/import-account-with-file-success/index.tsx index f1b9ecf4d..14a37b011 100644 --- a/src/apps/import-account-with-file/pages/import-account-with-file-success/index.tsx +++ b/src/apps/import-account-with-file/pages/import-account-with-file-success/index.tsx @@ -1,16 +1,16 @@ import React from 'react'; import { Trans, useTranslation } from 'react-i18next'; +import { closeCurrentWindow } from '@background/close-current-window'; + import { - FooterButtonsAbsoluteContainer, ContentContainer, - ParagraphContainer, + FooterButtonsAbsoluteContainer, IllustrationContainer, + ParagraphContainer, SpacingSize -} from '@src/libs/layout'; -import { Button, SvgIcon, Typography } from '@src/libs/ui'; - -import { closeCurrentWindow } from '@src/background/close-current-window'; +} from '@libs/layout'; +import { Button, SvgIcon, Typography } from '@libs/ui/components'; export function ImportAccountWithFileSuccessContentPage() { const { t } = useTranslation(); diff --git a/src/apps/import-account-with-file/pages/import-account-with-file-upload/content.tsx b/src/apps/import-account-with-file/pages/import-account-with-file-upload/content.tsx index 9b0e5f866..89702baca 100644 --- a/src/apps/import-account-with-file/pages/import-account-with-file-upload/content.tsx +++ b/src/apps/import-account-with-file/pages/import-account-with-file-upload/content.tsx @@ -12,11 +12,10 @@ import { InputsContainer, ParagraphContainer, SpacingSize -} from '@src/libs/layout'; -import { Input, SvgIcon, Typography } from '@src/libs/ui'; +} from '@libs/layout'; +import { Input, SvgIcon, Typography } from '@libs/ui/components'; import { RouterPath, useTypedNavigate } from '../../router'; - import { ImportAccountFormValues } from './types'; interface ImportAccountWithFilePageContentProps { diff --git a/src/apps/import-account-with-file/pages/import-account-with-file-upload/hooks/use-secret-key-file-reader.ts b/src/apps/import-account-with-file/pages/import-account-with-file-upload/hooks/use-secret-key-file-reader.ts index 1af02eb73..67decbf67 100644 --- a/src/apps/import-account-with-file/pages/import-account-with-file-upload/hooks/use-secret-key-file-reader.ts +++ b/src/apps/import-account-with-file/pages/import-account-with-file-upload/hooks/use-secret-key-file-reader.ts @@ -1,9 +1,10 @@ import { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; -import { checkSecretKeyExist } from '@src/background/redux/import-account-actions-should-be-removed'; -import { Account } from '@src/background/redux/vault/types'; -import { parseSecretKeyString } from '@src/libs/crypto'; +import { checkSecretKeyExist } from '@background/redux/import-account-actions-should-be-removed'; + +import { parseSecretKeyString } from '@libs/crypto'; +import { Account } from '@libs/types/account'; type OnSuccess = (accountData: Account) => void; type OnFailure = (message?: string) => void; @@ -20,49 +21,56 @@ export function useSecretKeyFileReader({ const { t } = useTranslation(); const secretKeyFileReader = useCallback( - (name: string, secretKeyFile: Blob) => { + async (name: string, secretKeyFile: Blob) => { + const isFileValid = (fileContents: string): Error | undefined => { + if (!fileContents || fileContents.includes('PUBLIC KEY')) { + return new Error( + t('A private key was not detected. Try importing a different file.') + ); + } + }; + + const doesSecretKeyExist = async ( + secretKeyBase64: string + ): Promise => { + const existence = + secretKeyBase64 && (await checkSecretKeyExist(secretKeyBase64)); + if (existence) { + return new Error( + t('This account already exists. Try importing a different file.') + ); + } + }; + const reader = new FileReader(); + reader.readAsText(secretKeyFile); - reader.onload = async e => { + reader.onload = async () => { const fileContents = reader.result as string; - try { - if (!fileContents || fileContents.includes('PUBLIC KEY')) { - throw Error( - t( - 'A private key was not detected. Try importing a different file.' - ) - ); - } - - const { publicKeyHex, secretKeyBase64 } = - parseSecretKeyString(fileContents); + const fileValidationError = isFileValid(fileContents); + if (fileValidationError) { + return onFailure(fileValidationError.message); + } - const doesSecretKeyExist = - secretKeyBase64 && (await checkSecretKeyExist(secretKeyBase64)); - if (doesSecretKeyExist) { - throw Error( - t('This account already exists. Try importing a different file.') - ); - } + const { publicKeyHex, secretKeyBase64 } = + parseSecretKeyString(fileContents); - return onSuccess({ - imported: true, - name, - publicKey: publicKeyHex, - secretKey: secretKeyBase64 - }); - } catch (err) { - if (err instanceof Error) { - return onFailure(err.message); - } else { - console.error(err); - } + const secretKeyError = await doesSecretKeyExist(secretKeyBase64); + if (secretKeyError) { + return onFailure(secretKeyError.message); } + + return onSuccess({ + imported: true, + name, + publicKey: publicKeyHex, + secretKey: secretKeyBase64 + }); }; }, - [t, onFailure, onSuccess] + [t, onSuccess, onFailure] ); return { secretKeyFileReader }; diff --git a/src/apps/import-account-with-file/pages/import-account-with-file-upload/index.tsx b/src/apps/import-account-with-file/pages/import-account-with-file-upload/index.tsx index cde8867cc..5650bb41b 100644 --- a/src/apps/import-account-with-file/pages/import-account-with-file-upload/index.tsx +++ b/src/apps/import-account-with-file/pages/import-account-with-file-upload/index.tsx @@ -1,27 +1,25 @@ -import React, { useCallback } from 'react'; -import { UseFormProps } from 'react-hook-form/dist/types/form'; -import { FieldValues, useForm } from 'react-hook-form'; -import { yupResolver } from '@hookform/resolvers/yup/dist/yup'; import * as Yup from 'yup'; +import { yupResolver } from '@hookform/resolvers/yup/dist/yup'; +import React, { useCallback } from 'react'; +import { FieldValues, UseFormProps, useForm } from 'react-hook-form'; import { Trans, useTranslation } from 'react-i18next'; -import { - LayoutWindow, - PopupHeader, - FooterButtonsContainer -} from '@src/libs/layout'; -import { Button } from '@src/libs/ui'; -import { useAccountNameRule } from '@src/libs/ui/forms/form-validation-rules'; +import { checkAccountNameIsTaken } from '@background/redux/import-account-actions-should-be-removed'; +import { dispatchToMainStore } from '@background/redux/utils'; +import { accountImported } from '@background/redux/vault/actions'; -import { Account } from '@src/background/redux/vault/types'; -import { dispatchToMainStore } from '@src/background/redux/utils'; -import { accountImported } from '@src/background/redux/vault/actions'; -import { checkAccountNameIsTaken } from '@src/background/redux/import-account-actions-should-be-removed'; +import { + FooterButtonsContainer, + HeaderPopup, + LayoutWindow +} from '@libs/layout'; +import { Account } from '@libs/types/account'; +import { Button } from '@libs/ui/components'; +import { useAccountNameRule } from '@libs/ui/forms/form-validation-rules'; import { RouterPath, useTypedNavigate } from '../../router'; - -import { useSecretKeyFileReader } from './hooks/use-secret-key-file-reader'; import { ImportAccountWithFileUploadPageContent } from './content'; +import { useSecretKeyFileReader } from './hooks/use-secret-key-file-reader'; import { ImportAccountFormValues } from './types'; export function ImportAccountWithFileUploadPage() { @@ -109,7 +107,7 @@ export function ImportAccountWithFileUploadPage() { } + renderHeader={() => } renderContent={() => ( } + renderHeader={() => } renderContent={() => } renderFooter={() => ( diff --git a/src/apps/import-account-with-file/router/use-typed-location.ts b/src/apps/import-account-with-file/router/use-typed-location.ts index 9ad3c3ea9..398a9fd4a 100644 --- a/src/apps/import-account-with-file/router/use-typed-location.ts +++ b/src/apps/import-account-with-file/router/use-typed-location.ts @@ -1,4 +1,5 @@ import { useLocation } from 'react-router-dom'; + import { LocationState } from '@import-account-with-file/router/types'; export function useTypedLocation() { diff --git a/src/apps/import-account-with-file/router/use-typed-navigate.ts b/src/apps/import-account-with-file/router/use-typed-navigate.ts index 80819cb6f..cf746b01e 100644 --- a/src/apps/import-account-with-file/router/use-typed-navigate.ts +++ b/src/apps/import-account-with-file/router/use-typed-navigate.ts @@ -1,4 +1,5 @@ import { To, useNavigate } from 'react-router-dom'; + import { LocationState } from '@import-account-with-file/router/types'; export function useTypedNavigate() { diff --git a/src/apps/onboarding/app-router.tsx b/src/apps/onboarding/app-router.tsx index cf5291809..e6d76fa3e 100644 --- a/src/apps/onboarding/app-router.tsx +++ b/src/apps/onboarding/app-router.tsx @@ -1,52 +1,41 @@ -import React, { useState } from 'react'; -import { HashRouter, Route, Routes } from 'react-router-dom'; +import React from 'react'; import { useSelector } from 'react-redux'; +import { HashRouter, Route, Routes } from 'react-router-dom'; -import { SecretPhrase } from '@src/libs/crypto'; -import { ErrorPath, TabErrorPage } from '@src/libs/layout/error'; - +import { + FormState, + SetFormState, + useOnboardingFormState +} from '@onboarding/hooks/use-onboarding-form-state'; +import { useSessionStorage } from '@onboarding/hooks/use-session-storage'; +import { ConfirmSecretPhrasePage } from '@onboarding/pages/confirm-secret-phrase'; +import { ConfirmSecretPhraseSuccessPage } from '@onboarding/pages/confirm-secret-phrase-success'; +import { CreateSecretPhrasePage } from '@onboarding/pages/create-secret-phrase'; +import { CreateSecretPhraseConfirmationPage } from '@onboarding/pages/create-secret-phrase-confirmation'; +import { CreateVaultPasswordPage } from '@onboarding/pages/create-vault-password'; +import { OnboardingSuccessPage } from '@onboarding/pages/onboarding-success'; +import { RecoverFromSecretPhrasePage } from '@onboarding/pages/recover-from-secret-phrase'; +import { ResetWalletPage } from '@onboarding/pages/reset-wallet'; +import { UnlockWalletPage } from '@onboarding/pages/unlock-wallet'; +import { WelcomePage } from '@onboarding/pages/welcome'; +import { WriteDownSecretPhrasePage } from '@onboarding/pages/write-down-secret-phrase'; import { RouterPath, useTypedLocation, useTypedNavigate -} from '@src/apps/onboarding/router'; +} from '@onboarding/router'; -import { useSessionStorage } from '@src/apps/onboarding/hooks/use-session-storage'; +import { selectKeysDoesExist } from '@background/redux/keys/selectors'; +import { selectEncryptionKeyHash } from '@background/redux/session/selectors'; -import { UnlockWalletPage } from '@src/apps/onboarding/pages/unlock-wallet'; -import { ResetWalletPage } from '@src/apps/onboarding/pages/reset-wallet'; -import { WelcomePage } from '@src/apps/onboarding/pages/welcome'; -import { CreateVaultPasswordPage } from '@src/apps/onboarding/pages/create-vault-password'; -import { CreateSecretPhrasePage } from '@src/apps/onboarding/pages/create-secret-phrase'; -import { RecoverFromSecretPhrasePage } from '@src/apps/onboarding/pages/recover-from-secret-phrase'; -import { CreateSecretPhraseConfirmationPage } from '@src/apps/onboarding/pages/create-secret-phrase-confirmation'; -import { WriteDownSecretPhrasePage } from '@src/apps/onboarding/pages/write-down-secret-phrase'; -import { ConfirmSecretPhrasePage } from '@src/apps/onboarding/pages/confirm-secret-phrase'; -import { ConfirmSecretPhraseSuccessPage } from '@src/apps/onboarding/pages/confirm-secret-phrase-success'; -import { OnboardingSuccessPage } from '@src/apps/onboarding/pages/onboarding-success'; -import { selectKeysDoesExist } from '@src/background/redux/keys/selectors'; -import { selectEncryptionKeyHash } from '@src/background/redux/session/selectors'; - -export interface FormState { - secretPhrase: SecretPhrase | null; -} - -export type SetFormState = (name: keyof FormState, value: any) => void; +import { ErrorPath, TabErrorPage } from '@libs/layout'; export function AppRouter() { - const [onboardingFormState, setOnboardingFormState] = useState({ - secretPhrase: null - }); + const { onboardingFormState, setFormState } = useOnboardingFormState(); const { loadIsLoggedIn, saveIsLoggedIn } = useSessionStorage(); const isLoggedIn = loadIsLoggedIn(); - const setFormState: SetFormState = (name, value) => - setOnboardingFormState(prevOnboardingFormState => ({ - ...prevOnboardingFormState, - [name]: value - })); - const keysDoesExist = useSelector(selectKeysDoesExist); const encryptionKeyHash = useSelector(selectEncryptionKeyHash); diff --git a/src/apps/onboarding/hooks/use-onboarding-form-state.ts b/src/apps/onboarding/hooks/use-onboarding-form-state.ts new file mode 100644 index 000000000..0f16cc0ca --- /dev/null +++ b/src/apps/onboarding/hooks/use-onboarding-form-state.ts @@ -0,0 +1,25 @@ +import { useState } from 'react'; + +import { SecretPhrase } from '@libs/crypto'; + +export interface FormState { + secretPhrase: SecretPhrase | null; +} + +export type SetFormState = (name: keyof FormState, value: any) => void; +export const useOnboardingFormState = () => { + const [onboardingFormState, setOnboardingFormState] = useState({ + secretPhrase: null + }); + + const setFormState: SetFormState = (name, value) => + setOnboardingFormState(prevOnboardingFormState => ({ + ...prevOnboardingFormState, + [name]: value + })); + + return { + onboardingFormState, + setFormState + }; +}; diff --git a/src/apps/onboarding/index.tsx b/src/apps/onboarding/index.tsx index b3f59fe40..ec9d58b04 100644 --- a/src/apps/onboarding/index.tsx +++ b/src/apps/onboarding/index.tsx @@ -1,19 +1,19 @@ -import '@libs/i18n/i18n'; - import React, { Suspense, useState } from 'react'; import { render } from 'react-dom'; import { Provider as ReduxProvider } from 'react-redux'; import { ThemeProvider } from 'styled-components'; -import { ErrorBoundary } from '@src/libs/layout/error'; - -import { GlobalStyle, lightTheme } from '@libs/ui'; +import { useSubscribeToRedux } from '@src/hooks/use-subscribe-to-redux'; -import { AppRouter } from '@src/apps/onboarding/app-router'; +import { AppRouter } from '@onboarding/app-router'; +import { createMainStoreReplica } from '@background/redux/get-main-store'; +import { PopupState } from '@background/redux/types'; import { onboardingAppInit } from '@background/redux/windowManagement/actions'; -import { createMainStoreReplica, PopupState } from '@background/redux/utils'; -import { useSubscribeToRedux } from '@src/hooks/use-subscribe-to-redux'; + +import '@libs/i18n/i18n'; +import { ErrorBoundary } from '@libs/layout'; +import { GlobalStyle, lightTheme } from '@libs/ui'; const Tree = () => { const [state, setState] = useState(null); diff --git a/src/apps/onboarding/pages/confirm-secret-phrase-success/content.tsx b/src/apps/onboarding/pages/confirm-secret-phrase-success/content.tsx index 06675649c..6451ea71a 100644 --- a/src/apps/onboarding/pages/confirm-secret-phrase-success/content.tsx +++ b/src/apps/onboarding/pages/confirm-secret-phrase-success/content.tsx @@ -1,13 +1,13 @@ import React from 'react'; -import { useTranslation, Trans } from 'react-i18next'; +import { Trans, useTranslation } from 'react-i18next'; import { SpacingSize, TabPageContainer, TabTextContainer, VerticalSpaceContainer -} from '@src/libs/layout'; -import { Typography, TextList } from '@src/libs/ui'; +} from '@libs/layout'; +import { TextList, Typography } from '@libs/ui/components'; export function ConfirmSecretPhraseSuccessPageContent() { const { t } = useTranslation(); diff --git a/src/apps/onboarding/pages/confirm-secret-phrase-success/index.tsx b/src/apps/onboarding/pages/confirm-secret-phrase-success/index.tsx index 0462858e6..747085eec 100644 --- a/src/apps/onboarding/pages/confirm-secret-phrase-success/index.tsx +++ b/src/apps/onboarding/pages/confirm-secret-phrase-success/index.tsx @@ -1,17 +1,17 @@ import React from 'react'; -import { useTranslation, Trans } from 'react-i18next'; +import { Trans, useTranslation } from 'react-i18next'; + +import { Stepper } from '@onboarding/components/stepper'; +import { RouterPath } from '@onboarding/router'; +import { useTypedNavigate } from '@onboarding/router/use-typed-navigate'; import { + HeaderSubmenuBarNavLink, LayoutTab, - TabHeaderContainer, TabFooterContainer, - HeaderSubmenuBarNavLink + TabHeaderContainer } from '@libs/layout'; -import { Button } from '@libs/ui'; - -import { useTypedNavigate } from '@src/apps/onboarding/router/use-typed-navigate'; -import { RouterPath } from '@src/apps/onboarding/router'; -import { Stepper } from '@src/apps/onboarding/components/stepper'; +import { Button } from '@libs/ui/components'; import { ConfirmSecretPhraseSuccessPageContent } from './content'; diff --git a/src/apps/onboarding/pages/confirm-secret-phrase/content.tsx b/src/apps/onboarding/pages/confirm-secret-phrase/content.tsx index 8553424e9..1cb74f7be 100644 --- a/src/apps/onboarding/pages/confirm-secret-phrase/content.tsx +++ b/src/apps/onboarding/pages/confirm-secret-phrase/content.tsx @@ -1,9 +1,13 @@ import React, { Dispatch, SetStateAction } from 'react'; -import { useTranslation, Trans } from 'react-i18next'; +import { Trans, useTranslation } from 'react-i18next'; -import { TabPageContainer, TabTextContainer } from '@src/libs/layout'; -import { Typography, SecretPhraseWordsView, WordPicker } from '@src/libs/ui'; -import { SecretPhrase } from '@src/libs/crypto'; +import { SecretPhrase } from '@libs/crypto'; +import { TabPageContainer, TabTextContainer } from '@libs/layout'; +import { + SecretPhraseWordsView, + Typography, + WordPicker +} from '@libs/ui/components'; interface ConfirmSecretPhrasePageContentProps { phrase: SecretPhrase; diff --git a/src/apps/onboarding/pages/confirm-secret-phrase/index.tsx b/src/apps/onboarding/pages/confirm-secret-phrase/index.tsx index 1228b60b9..23f26e9be 100644 --- a/src/apps/onboarding/pages/confirm-secret-phrase/index.tsx +++ b/src/apps/onboarding/pages/confirm-secret-phrase/index.tsx @@ -2,23 +2,25 @@ import React, { useState } from 'react'; import { Trans, useTranslation } from 'react-i18next'; import { Navigate } from 'react-router-dom'; +import { Stepper } from '@onboarding/components/stepper'; +import { RouterPath } from '@onboarding/router'; +import { useTypedNavigate } from '@onboarding/router/use-typed-navigate'; + +import { initVault } from '@background/redux/sagas/actions'; +import { dispatchToMainStore } from '@background/redux/utils'; + +import { SecretPhrase } from '@libs/crypto'; import { + ErrorPath, HeaderSubmenuBarNavLink, LayoutTab, TabFooterContainer, - TabHeaderContainer -} from '@src/libs/layout'; -import { createErrorLocationState, ErrorPath } from '@src/libs/layout/error'; -import { Button } from '@src/libs/ui'; -import { SecretPhrase } from '@src/libs/crypto'; - -import { Stepper } from '@src/apps/onboarding/components/stepper'; -import { RouterPath } from '@src/apps/onboarding/router'; -import { useTypedNavigate } from '@src/apps/onboarding/router/use-typed-navigate'; + TabHeaderContainer, + createErrorLocationState +} from '@libs/layout'; +import { Button } from '@libs/ui/components'; import { ConfirmSecretPhrasePageContent } from './content'; -import { dispatchToMainStore } from '@src/background/redux/utils'; -import { initVault } from '@src/background/redux/sagas/actions'; interface ConfirmSecretPhrasePageProps { phrase: SecretPhrase | null; diff --git a/src/apps/onboarding/pages/create-secret-phrase-confirmation/content.tsx b/src/apps/onboarding/pages/create-secret-phrase-confirmation/content.tsx index e32459d27..1225cfe15 100644 --- a/src/apps/onboarding/pages/create-secret-phrase-confirmation/content.tsx +++ b/src/apps/onboarding/pages/create-secret-phrase-confirmation/content.tsx @@ -1,12 +1,12 @@ import React from 'react'; -import { useTranslation, Trans } from 'react-i18next'; +import { Trans, useTranslation } from 'react-i18next'; import { SpacingSize, TabPageContainer, VerticalSpaceContainer -} from '@src/libs/layout'; -import { Typography, TextList } from '@src/libs/ui'; +} from '@libs/layout'; +import { TextList, Typography } from '@libs/ui/components'; export function CreateSecretPhraseConfirmationPageContent() { const { t } = useTranslation(); diff --git a/src/apps/onboarding/pages/create-secret-phrase-confirmation/index.tsx b/src/apps/onboarding/pages/create-secret-phrase-confirmation/index.tsx index a9b776134..cdff335b1 100644 --- a/src/apps/onboarding/pages/create-secret-phrase-confirmation/index.tsx +++ b/src/apps/onboarding/pages/create-secret-phrase-confirmation/index.tsx @@ -1,21 +1,21 @@ import React, { useState } from 'react'; -import { useTranslation, Trans } from 'react-i18next'; +import { Trans, useTranslation } from 'react-i18next'; +import { Stepper } from '@onboarding/components/stepper'; +import { SetFormState } from '@onboarding/hooks/use-onboarding-form-state'; +import { RouterPath } from '@onboarding/router'; +import { useTypedNavigate } from '@onboarding/router/use-typed-navigate'; + +import { generateSecretPhrase } from '@libs/crypto'; import { + HeaderSubmenuBarNavLink, LayoutTab, - TabHeaderContainer, TabFooterContainer, - HeaderSubmenuBarNavLink + TabHeaderContainer } from '@libs/layout'; -import { Button, Checkbox } from '@libs/ui'; - -import { useTypedNavigate } from '@src/apps/onboarding/router/use-typed-navigate'; -import { RouterPath } from '@src/apps/onboarding/router'; -import { Stepper } from '@src/apps/onboarding/components/stepper'; -import { SetFormState } from '@src/apps/onboarding/app-router'; +import { Button, Checkbox } from '@libs/ui/components'; import { CreateSecretPhraseConfirmationPageContent } from './content'; -import { generateSecretPhrase } from '@src/libs/crypto'; interface CreateSecretPhraseConfirmationPageProps { setFormState: SetFormState; diff --git a/src/apps/onboarding/pages/create-secret-phrase/content.tsx b/src/apps/onboarding/pages/create-secret-phrase/content.tsx index c67ba91c2..e42557b30 100644 --- a/src/apps/onboarding/pages/create-secret-phrase/content.tsx +++ b/src/apps/onboarding/pages/create-secret-phrase/content.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { Trans, useTranslation } from 'react-i18next'; -import { Typography } from '@libs/ui'; -import { TabPageContainer, TabTextContainer } from '@src/libs/layout'; +import { TabPageContainer, TabTextContainer } from '@libs/layout'; +import { Typography } from '@libs/ui/components'; export function CreateSecretPhraseContent() { const { t } = useTranslation(); diff --git a/src/apps/onboarding/pages/create-secret-phrase/index.tsx b/src/apps/onboarding/pages/create-secret-phrase/index.tsx index b25f2f2ce..bb891810d 100644 --- a/src/apps/onboarding/pages/create-secret-phrase/index.tsx +++ b/src/apps/onboarding/pages/create-secret-phrase/index.tsx @@ -1,20 +1,22 @@ import React from 'react'; import { Trans, useTranslation } from 'react-i18next'; +import { Stepper } from '@onboarding/components/stepper'; +import { RouterPath } from '@onboarding/router'; +import { useTypedNavigate } from '@onboarding/router/use-typed-navigate'; + +import { resetVault } from '@background/redux/sagas/actions'; +import { dispatchToMainStore } from '@background/redux/utils'; + import { HeaderSubmenuBarNavLink, LayoutTab, TabFooterContainer, TabHeaderContainer } from '@libs/layout'; -import { Button } from '@libs/ui'; -import { Stepper } from '@src/apps/onboarding/components/stepper'; -import { RouterPath } from '@src/apps/onboarding/router'; -import { useTypedNavigate } from '@src/apps/onboarding/router/use-typed-navigate'; -import { dispatchToMainStore } from '@src/background/redux/utils'; +import { Button } from '@libs/ui/components'; import { CreateSecretPhraseContent } from './content'; -import { resetVault } from '@src/background/redux/sagas/actions'; export function CreateSecretPhrasePage() { const navigate = useTypedNavigate(); diff --git a/src/apps/onboarding/pages/create-vault-password/content.tsx b/src/apps/onboarding/pages/create-vault-password/content.tsx index 6d5a37f23..954536df2 100644 --- a/src/apps/onboarding/pages/create-vault-password/content.tsx +++ b/src/apps/onboarding/pages/create-vault-password/content.tsx @@ -1,8 +1,8 @@ import React from 'react'; -import { useTranslation, Trans } from 'react-i18next'; +import { Trans, useTranslation } from 'react-i18next'; -import { Typography } from '@libs/ui'; import { TabPageContainer, TabTextContainer } from '@libs/layout'; +import { Typography } from '@libs/ui/components'; import { minPasswordLength } from '@libs/ui/forms/form-validation-rules'; interface CreatePasswordPageContentProps { diff --git a/src/apps/onboarding/pages/create-vault-password/index.tsx b/src/apps/onboarding/pages/create-vault-password/index.tsx index 32e46977a..79814129e 100644 --- a/src/apps/onboarding/pages/create-vault-password/index.tsx +++ b/src/apps/onboarding/pages/create-vault-password/index.tsx @@ -1,7 +1,17 @@ import React, { useEffect, useState } from 'react'; +import { useWatch } from 'react-hook-form'; import { Trans, useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; -import { useWatch } from 'react-hook-form'; + +import { TermsLink } from '@src/constants'; + +import { Stepper } from '@onboarding/components/stepper'; +import { RouterPath } from '@onboarding/router'; +import { useTypedNavigate } from '@onboarding/router/use-typed-navigate'; + +import { selectPasswordHash } from '@background/redux/keys/selectors'; +import { initKeys } from '@background/redux/sagas/actions'; +import { dispatchToMainStore } from '@background/redux/utils'; import { HeaderSubmenuBarNavLink, @@ -9,20 +19,12 @@ import { TabFooterContainer, TabHeaderContainer } from '@libs/layout'; -import { Button, Checkbox, Link, PasswordInputs } from '@libs/ui'; +import { Button, Checkbox, Link, PasswordInputs } from '@libs/ui/components'; import { CreatePasswordFormValues, useCreatePasswordForm } from '@libs/ui/forms/create-password'; -import { Stepper } from '@src/apps/onboarding/components/stepper'; -import { RouterPath } from '@src/apps/onboarding/router'; -import { useTypedNavigate } from '@src/apps/onboarding/router/use-typed-navigate'; -import { selectPasswordHash } from '@src/background/redux/keys/selectors'; -import { initKeys } from '@src/background/redux/sagas/actions'; -import { dispatchToMainStore } from '@background/redux/utils'; -import { TermsLink } from '@src/constants'; - import { CreateVaultPasswordPageContent } from './content'; interface CreateVaultPasswordPageProps { diff --git a/src/apps/onboarding/pages/onboarding-success/content.tsx b/src/apps/onboarding/pages/onboarding-success/content.tsx index 6ee5fd69a..d6343d8b1 100644 --- a/src/apps/onboarding/pages/onboarding-success/content.tsx +++ b/src/apps/onboarding/pages/onboarding-success/content.tsx @@ -3,7 +3,7 @@ import { Trans, useTranslation } from 'react-i18next'; import styled from 'styled-components'; import { TabPageContainer, TabTextContainer } from '@libs/layout'; -import { Link, SvgIcon, Typography } from '@libs/ui'; +import { Link, SvgIcon, Typography } from '@libs/ui/components'; const TipContainer = styled.div` margin-top: 12px; diff --git a/src/apps/onboarding/pages/onboarding-success/index.tsx b/src/apps/onboarding/pages/onboarding-success/index.tsx index 9aa955bae..6f52ae18e 100644 --- a/src/apps/onboarding/pages/onboarding-success/index.tsx +++ b/src/apps/onboarding/pages/onboarding-success/index.tsx @@ -1,10 +1,10 @@ import React from 'react'; -import { useTranslation, Trans } from 'react-i18next'; +import { Trans, useTranslation } from 'react-i18next'; -import { LayoutTab, TabFooterContainer } from '@libs/layout'; -import { Button } from '@libs/ui'; +import { closeActiveTab } from '@onboarding/utils/close-active-tab'; -import { closeActiveTab } from '@src/apps/onboarding/utils/close-active-tab'; +import { LayoutTab, TabFooterContainer } from '@libs/layout'; +import { Button } from '@libs/ui/components'; import { OnboardingSuccessPageContent } from './content'; diff --git a/src/apps/onboarding/pages/recover-from-secret-phrase/content.tsx b/src/apps/onboarding/pages/recover-from-secret-phrase/content.tsx index c74f73d81..b5699ebdf 100644 --- a/src/apps/onboarding/pages/recover-from-secret-phrase/content.tsx +++ b/src/apps/onboarding/pages/recover-from-secret-phrase/content.tsx @@ -1,14 +1,19 @@ import React from 'react'; -import { useTranslation, Trans } from 'react-i18next'; import { UseFormRegister } from 'react-hook-form'; +import { Trans, useTranslation } from 'react-i18next'; import { + InputsContainer, TabPageContainer, - TabTextContainer, - InputsContainer + TabTextContainer } from '@libs/layout'; -import { FormField, FormFieldStatus, TextArea, Typography } from '@libs/ui'; -import { RecoverSecretPhraseFormValues } from '@src/libs/ui/forms/recover-from-secret-phrase'; +import { + FormField, + FormFieldStatus, + TextArea, + Typography +} from '@libs/ui/components'; +import { RecoverSecretPhraseFormValues } from '@libs/ui/forms/recover-from-secret-phrase'; interface RecoverFromSecretPhrasePageContentProps { register: UseFormRegister; @@ -29,8 +34,8 @@ export function RecoverFromSecretPhrasePageContent({ - Recover your wallet by entering each word of your 24-word secret - recovery phrase, separated by spaces. + Recover your wallet by entering each word of your 12-word or 24-word + secret recovery phrase, separated by spaces. diff --git a/src/apps/onboarding/pages/recover-from-secret-phrase/index.tsx b/src/apps/onboarding/pages/recover-from-secret-phrase/index.tsx index 7500bfaeb..1f3b14917 100644 --- a/src/apps/onboarding/pages/recover-from-secret-phrase/index.tsx +++ b/src/apps/onboarding/pages/recover-from-secret-phrase/index.tsx @@ -1,29 +1,31 @@ import React from 'react'; import { Trans, useTranslation } from 'react-i18next'; +import { Stepper } from '@onboarding/components/stepper'; +import { RouterPath } from '@onboarding/router'; +import { useTypedNavigate } from '@onboarding/router/use-typed-navigate'; +import { closeActiveTab } from '@onboarding/utils/close-active-tab'; + +import { initVault } from '@background/redux/sagas/actions'; +import { dispatchToMainStore } from '@background/redux/utils'; + +import { validateSecretPhrase } from '@libs/crypto'; import { + ErrorPath, HeaderSubmenuBarNavLink, LayoutTab, TabFooterContainer, - TabHeaderContainer -} from '@src/libs/layout'; -import { createErrorLocationState, ErrorPath } from '@src/libs/layout/error'; -import { Button } from '@src/libs/ui'; + TabHeaderContainer, + createErrorLocationState +} from '@libs/layout'; +import { Button } from '@libs/ui/components'; +import { calculateSubmitButtonDisabled } from '@libs/ui/forms/get-submit-button-state-from-validation'; import { RecoverSecretPhraseFormValues, useRecoverFromSecretPhraseForm -} from '@src/libs/ui/forms/recover-from-secret-phrase'; - -import { Stepper } from '@src/apps/onboarding/components/stepper'; -import { RouterPath } from '@src/apps/onboarding/router'; -import { useTypedNavigate } from '@src/apps/onboarding/router/use-typed-navigate'; -import { closeActiveTab } from '@src/apps/onboarding/utils/close-active-tab'; +} from '@libs/ui/forms/recover-from-secret-phrase'; import { RecoverFromSecretPhrasePageContent } from './content'; -import { dispatchToMainStore } from '@src/background/redux/utils'; -import { calculateSubmitButtonDisabled } from '@src/libs/ui/forms/get-submit-button-state-from-validation'; -import { validateSecretPhrase } from '@src/libs/crypto'; -import { initVault } from '@src/background/redux/sagas/actions'; export function RecoverFromSecretPhrasePage() { const navigate = useTypedNavigate(); diff --git a/src/apps/onboarding/pages/reset-wallet/content.tsx b/src/apps/onboarding/pages/reset-wallet/content.tsx index 0586389e4..5d0990d76 100644 --- a/src/apps/onboarding/pages/reset-wallet/content.tsx +++ b/src/apps/onboarding/pages/reset-wallet/content.tsx @@ -1,8 +1,8 @@ import React from 'react'; -import { useTranslation, Trans } from 'react-i18next'; +import { Trans, useTranslation } from 'react-i18next'; import { TabPageContainer, TabTextContainer } from '@libs/layout'; -import { Typography } from '@libs/ui'; +import { Typography } from '@libs/ui/components'; // Design of this page is temporary. Should be changed after it will be done in Figma diff --git a/src/apps/onboarding/pages/reset-wallet/index.tsx b/src/apps/onboarding/pages/reset-wallet/index.tsx index 045e57c25..1e5eaeb27 100644 --- a/src/apps/onboarding/pages/reset-wallet/index.tsx +++ b/src/apps/onboarding/pages/reset-wallet/index.tsx @@ -1,14 +1,15 @@ import React, { useState } from 'react'; -import { useTranslation, Trans } from 'react-i18next'; +import { Trans, useTranslation } from 'react-i18next'; -import { LayoutTab, TabFooterContainer } from '@libs/layout'; -import { Button, Checkbox } from '@libs/ui'; +import { useTypedNavigate } from '@onboarding/router'; +import { resetVault } from '@background/redux/sagas/actions'; import { dispatchToMainStore } from '@background/redux/utils'; +import { LayoutTab, TabFooterContainer } from '@libs/layout'; +import { Button, Checkbox } from '@libs/ui/components'; + import { ResetWalletPageContent } from './content'; -import { useTypedNavigate } from '@src/apps/onboarding/router'; -import { resetVault } from '@src/background/redux/sagas/actions'; // Design of this page is temporary. Should be changed after it will be done in Figma diff --git a/src/apps/onboarding/pages/unlock-wallet/content.tsx b/src/apps/onboarding/pages/unlock-wallet/content.tsx index efd610faf..f83f72280 100644 --- a/src/apps/onboarding/pages/unlock-wallet/content.tsx +++ b/src/apps/onboarding/pages/unlock-wallet/content.tsx @@ -1,22 +1,22 @@ import React, { useState } from 'react'; -import { Trans, useTranslation } from 'react-i18next'; import { UseFormRegister } from 'react-hook-form'; +import { Trans, useTranslation } from 'react-i18next'; import styled from 'styled-components'; import { + InputsContainer, TabPageContainer as TabPageContainerBase, - TabTextContainer, - InputsContainer -} from '@src/libs/layout'; + TabTextContainer +} from '@libs/layout'; import { - PasswordInputType, Input, - Typography, InputValidationType, + PasswordInputType, PasswordVisibilityIcon, - SvgIcon -} from '@libs/ui'; -import { UnlockWalletFormValues } from '@src/libs/ui/forms/unlock-wallet'; + SvgIcon, + Typography +} from '@libs/ui/components'; +import { UnlockWalletFormValues } from '@libs/ui/forms/unlock-wallet'; // Design of this page is temporary. Should be changed after it will be done in Figma const TabPageContainer = styled.div` diff --git a/src/apps/onboarding/pages/unlock-wallet/index.tsx b/src/apps/onboarding/pages/unlock-wallet/index.tsx index abb93202c..7f49ca499 100644 --- a/src/apps/onboarding/pages/unlock-wallet/index.tsx +++ b/src/apps/onboarding/pages/unlock-wallet/index.tsx @@ -1,25 +1,26 @@ import React from 'react'; -import { useSelector } from 'react-redux'; import { Trans, useTranslation } from 'react-i18next'; +import { useSelector } from 'react-redux'; import styled from 'styled-components'; +import { UnlockWalletPageContent } from '@onboarding/pages/unlock-wallet/content'; +import { RouterPath, useTypedNavigate } from '@onboarding/router'; + +import { + selectPasswordHash, + selectPasswordSaltHash +} from '@background/redux/keys/selectors'; +import { loginRetryCountReseted } from '@background/redux/login-retry-count/actions'; +import { selectLoginRetryCount } from '@background/redux/login-retry-count/selectors'; +import { dispatchToMainStore } from '@background/redux/utils'; + import { LayoutTab, TabFooterContainer as TabFooterContainerBase } from '@libs/layout'; -import { Button } from '@src/libs/ui'; +import { Button } from '@libs/ui/components'; import { useUnlockWalletForm } from '@libs/ui/forms/unlock-wallet'; -import { RouterPath, useTypedNavigate } from '@src/apps/onboarding/router'; -import { UnlockWalletPageContent } from '@src/apps/onboarding/pages/unlock-wallet/content'; -import { - selectPasswordHash, - selectPasswordSaltHash -} from '@src/background/redux/keys/selectors'; -import { selectLoginRetryCount } from '@src/background/redux/login-retry-count/selectors'; -import { dispatchToMainStore } from '@src/background/redux/utils'; -import { loginRetryCountReseted } from '@src/background/redux/login-retry-count/actions'; - // Design of this page is temporary. Should be changed after it will be done in Figma const TabFooterContainer = styled(TabFooterContainerBase)` margin-top: 0; diff --git a/src/apps/onboarding/pages/welcome/content.tsx b/src/apps/onboarding/pages/welcome/content.tsx index 0c775d25c..494eff12c 100644 --- a/src/apps/onboarding/pages/welcome/content.tsx +++ b/src/apps/onboarding/pages/welcome/content.tsx @@ -1,8 +1,8 @@ import React from 'react'; -import { useTranslation, Trans } from 'react-i18next'; +import { Trans, useTranslation } from 'react-i18next'; -import { SvgIcon, Typography } from '@libs/ui'; -import { TabPageContainer, TabTextContainer } from '@src/libs/layout'; +import { TabPageContainer, TabTextContainer } from '@libs/layout'; +import { SvgIcon, Typography } from '@libs/ui/components'; export function WelcomePageContent() { const { t } = useTranslation(); diff --git a/src/apps/onboarding/pages/welcome/index.tsx b/src/apps/onboarding/pages/welcome/index.tsx index 27e30f387..a88b7ea70 100644 --- a/src/apps/onboarding/pages/welcome/index.tsx +++ b/src/apps/onboarding/pages/welcome/index.tsx @@ -1,15 +1,16 @@ import React from 'react'; import { Trans, useTranslation } from 'react-i18next'; -import { Button } from '@libs/ui'; -import { LayoutTab, TabFooterContainer } from '@src/libs/layout'; +import { RouterPath } from '@onboarding/router'; +import { useTypedNavigate } from '@onboarding/router/use-typed-navigate'; -import { useTypedNavigate } from '@src/apps/onboarding/router/use-typed-navigate'; -import { RouterPath } from '@src/apps/onboarding/router'; +import { resetVault } from '@background/redux/sagas/actions'; +import { dispatchToMainStore } from '@background/redux/utils'; + +import { LayoutTab, TabFooterContainer } from '@libs/layout'; +import { Button } from '@libs/ui/components'; import { WelcomePageContent } from './content'; -import { dispatchToMainStore } from '@src/background/redux/utils'; -import { resetVault } from '@src/background/redux/sagas/actions'; export function WelcomePage() { const navigate = useTypedNavigate(); diff --git a/src/apps/onboarding/pages/write-down-secret-phrase/content.tsx b/src/apps/onboarding/pages/write-down-secret-phrase/content.tsx index 66b6da6a3..9099e306d 100644 --- a/src/apps/onboarding/pages/write-down-secret-phrase/content.tsx +++ b/src/apps/onboarding/pages/write-down-secret-phrase/content.tsx @@ -1,13 +1,13 @@ import React from 'react'; -import { useTranslation, Trans } from 'react-i18next'; +import { Trans, useTranslation } from 'react-i18next'; -import { TabPageContainer, TabTextContainer } from '@src/libs/layout'; +import { SecretPhrase } from '@libs/crypto'; +import { TabPageContainer, TabTextContainer } from '@libs/layout'; import { - Typography, + CopySecretPhraseBar, SecretPhraseWordsView, - CopySecretPhraseBar -} from '@src/libs/ui'; -import { SecretPhrase } from '@src/libs/crypto'; + Typography +} from '@libs/ui/components'; interface WriteDownSecretPhrasePageContentProps { phrase: SecretPhrase; diff --git a/src/apps/onboarding/pages/write-down-secret-phrase/index.tsx b/src/apps/onboarding/pages/write-down-secret-phrase/index.tsx index edda27653..8ae391daf 100644 --- a/src/apps/onboarding/pages/write-down-secret-phrase/index.tsx +++ b/src/apps/onboarding/pages/write-down-secret-phrase/index.tsx @@ -2,18 +2,18 @@ import React, { useState } from 'react'; import { Trans, useTranslation } from 'react-i18next'; import { Navigate } from 'react-router-dom'; +import { Stepper } from '@onboarding/components/stepper'; +import { RouterPath } from '@onboarding/router'; +import { useTypedNavigate } from '@onboarding/router/use-typed-navigate'; + +import { SecretPhrase } from '@libs/crypto'; import { + HeaderSubmenuBarNavLink, LayoutTab, - TabHeaderContainer, TabFooterContainer, - HeaderSubmenuBarNavLink -} from '@src/libs/layout'; -import { Button, Checkbox } from '@src/libs/ui'; -import { SecretPhrase } from '@src/libs/crypto'; - -import { RouterPath } from '@src/apps/onboarding/router'; -import { useTypedNavigate } from '@src/apps/onboarding/router/use-typed-navigate'; -import { Stepper } from '@src/apps/onboarding/components/stepper'; + TabHeaderContainer +} from '@libs/layout'; +import { Button, Checkbox } from '@libs/ui/components'; import { WriteDownSecretPhrasePageContent } from './content'; diff --git a/src/apps/onboarding/router/types.ts b/src/apps/onboarding/router/types.ts index 0d58a7d59..5518388f2 100644 --- a/src/apps/onboarding/router/types.ts +++ b/src/apps/onboarding/router/types.ts @@ -1,3 +1,3 @@ -import { ErrorLocationState } from '@layout/error/types'; +import { ErrorLocationState } from '@libs/layout'; export interface LocationState extends ErrorLocationState {} diff --git a/src/apps/onboarding/router/use-typed-location.ts b/src/apps/onboarding/router/use-typed-location.ts index a47c062ba..77e064b46 100644 --- a/src/apps/onboarding/router/use-typed-location.ts +++ b/src/apps/onboarding/router/use-typed-location.ts @@ -1,5 +1,6 @@ import { useLocation } from 'react-router-dom'; -import { LocationState } from '@src/apps/onboarding/router/types'; + +import { LocationState } from '@onboarding/router/types'; export function useTypedLocation() { const location = useLocation(); diff --git a/src/apps/onboarding/router/use-typed-navigate.ts b/src/apps/onboarding/router/use-typed-navigate.ts index 8b1a6b974..03b7d3dab 100644 --- a/src/apps/onboarding/router/use-typed-navigate.ts +++ b/src/apps/onboarding/router/use-typed-navigate.ts @@ -1,4 +1,5 @@ import { To, useNavigate } from 'react-router-dom'; + import { LocationState } from './types'; export function useTypedNavigate() { diff --git a/src/apps/onboarding/utils/close-active-tab.ts b/src/apps/onboarding/utils/close-active-tab.ts index 8ce9c8ab5..155c3475e 100644 --- a/src/apps/onboarding/utils/close-active-tab.ts +++ b/src/apps/onboarding/utils/close-active-tab.ts @@ -1,13 +1,13 @@ -import browser from 'webextension-polyfill'; +import { tabs } from 'webextension-polyfill'; export async function closeActiveTab() { try { - const tabs = await browser.tabs.query({ + const tabsList = await tabs.query({ active: true, currentWindow: true }); - if (tabs.length > 0 && tabs[0].id != null) { - await browser.tabs.remove(tabs[0].id); + if (tabsList.length > 0 && tabsList[0].id != null) { + await tabs.remove(tabsList[0].id); } } catch (e) { console.error(e); diff --git a/src/apps/popup/app-router.tsx b/src/apps/popup/app-router.tsx index 5f6a3ecce..9184113b1 100644 --- a/src/apps/popup/app-router.tsx +++ b/src/apps/popup/app-router.tsx @@ -1,47 +1,49 @@ -import '@libs/i18n/i18n'; - import React from 'react'; import { useSelector } from 'react-redux'; import { HashRouter, Route, Routes } from 'react-router-dom'; -import { HeaderSubmenuBarNavLink, PopupLayout } from '@libs/layout'; -import { PopupHeader } from '@libs/layout/header'; +import { useUserActivityTracker } from '@src/hooks/use-user-activity-tracker'; +import { AccountSettingsPage } from '@popup/pages/account-settings'; +import { ActivityDetailsPage } from '@popup/pages/activity-details'; +import { AddContactPage } from '@popup/pages/add-contact'; +import { BackupSecretPhrasePage } from '@popup/pages/backup-secret-phrase'; +import { ChangePasswordPage } from '@popup/pages/change-password'; +import { ConnectAnotherAccountPageContent } from '@popup/pages/connect-another-account'; +import { ConnectedSitesPage } from '@popup/pages/connected-sites'; +import { ContactDetailsPage } from '@popup/pages/contact-details'; +import { ContactsBookPage } from '@popup/pages/contacts'; +import { CreateAccountPage } from '@popup/pages/create-account'; +import { DownloadSecretKeysPage } from '@popup/pages/download-secret-keys'; +import { DownloadedSecretKeysPage } from '@popup/pages/downloaded-secret-keys'; import { HomePageContent } from '@popup/pages/home'; import { NavigationMenuPageContent } from '@popup/pages/navigation-menu'; -import { TimeoutPageContent } from '@popup/pages/timeout'; -import { ConnectAnotherAccountPageContent } from '@popup/pages/connect-another-account'; +import { NftDetailsPage } from '@popup/pages/nft-details'; import { NoConnectedAccountPageContent } from '@popup/pages/no-connected-account'; -import { ConnectedSitesPage } from '@popup/pages/connected-sites'; -import { AccountSettingsPage } from '@popup/pages/account-settings'; +import { ReceivePage } from '@popup/pages/receive'; import { RemoveAccountPageContent } from '@popup/pages/remove-account'; import { RenameAccountPageContent } from '@popup/pages/rename-account'; -import { BackupSecretPhrasePage } from '@popup/pages/backup-secret-phrase'; -import { CreateAccountPage } from '@src/apps/popup/pages/create-account'; -import { DownloadSecretKeysPage } from '@popup/pages/download-secret-keys'; -import { DownloadedSecretKeysPage } from '@popup/pages/downloaded-secret-keys'; - +import { StakesPage } from '@popup/pages/stakes'; +import { TimeoutPageContent } from '@popup/pages/timeout'; +import { TokenDetailPage } from '@popup/pages/token-details'; +import { TransferPage } from '@popup/pages/transfer'; +import { TransferNftPage } from '@popup/pages/transfer-nft'; +import { WalletQrCodePage } from '@popup/pages/wallet-qr-code'; import { RouterPath, useTypedLocation, useTypedNavigate } from '@popup/router'; +import { selectKeysDoesExist } from '@background/redux/keys/selectors'; +import { selectVaultIsLocked } from '@background/redux/session/selectors'; import { selectVaultHasAccounts } from '@background/redux/vault/selectors'; -import { useUserActivityTracker } from '@src/hooks/use-user-activity-tracker'; -import { selectVaultIsLocked } from '@src/background/redux/session/selectors'; -import { selectKeysDoesExist } from '@src/background/redux/keys/selectors'; -import { LockedRouter } from '@src/libs/layout/locked-router'; -import { TransferPage } from '@popup/pages/transfer'; -import { TokenDetailPage } from 'src/apps/popup/pages/token-details'; -import { ActivityDetailsPage } from '@popup/pages/activity-details'; -import { ReceivePage } from '@popup/pages/receive'; -import { NftDetailsPage } from '@popup/pages/nft-details'; -import { WalletQrCodePage } from '@popup/pages/wallet-qr-code'; -import { TransferNftPage } from '@popup/pages/transfer-nft'; -import { ChangePasswordPage } from '@popup/pages/change-password'; -import { StakesPage } from '@popup/pages/stakes'; -import { ErrorPath, WindowErrorPage } from '@layout/error'; -import { ContactsBookPage } from '@popup/pages/contacts'; -import { AddContactPage } from '@popup/pages/add-contact'; -import { ContactDetailsPage } from '@popup/pages/contact-details'; +import '@libs/i18n/i18n'; +import { + ErrorPath, + HeaderPopup, + HeaderSubmenuBarNavLink, + LockedRouter, + PopupLayout, + WindowErrorPage +} from '@libs/layout'; export function AppRouter() { const isLocked = useSelector(selectVaultIsLocked); @@ -77,7 +79,7 @@ function AppRoutes() { element={ ( - ( - + )} renderContent={() => } /> @@ -114,7 +116,7 @@ function AppRoutes() { element={ ( - ( - ( - ( - + )} renderContent={() => } /> @@ -179,7 +181,7 @@ function AppRoutes() { element={ ( - ( - ( - } /> } /> + } /> diff --git a/src/apps/popup/index.tsx b/src/apps/popup/index.tsx index c5adf3aed..b985b4ada 100644 --- a/src/apps/popup/index.tsx +++ b/src/apps/popup/index.tsx @@ -1,27 +1,27 @@ import React, { Suspense, useState } from 'react'; import { render } from 'react-dom'; +// skeleton styles +import 'react-loading-skeleton/dist/skeleton.css'; import { Provider as ReduxProvider } from 'react-redux'; import { ThemeProvider } from 'styled-components'; -import { darkTheme, GlobalStyle, lightTheme } from '@libs/ui'; -import { ErrorBoundary } from '@src/libs/layout/error'; -import { useSubscribeToRedux } from '@src/hooks/use-subscribe-to-redux'; -import { - createMainStoreReplica, - dispatchToMainStore, - PopupState -} from '@background/redux/utils'; -import { popupWindowInit } from '@background/redux/windowManagement/actions'; +import { isSafariBuild } from '@src/utils'; + +import { createMainStoreReplica } from '@background/redux/get-main-store'; +import { themeModeSettingChanged } from '@background/redux/settings/actions'; import { selectThemeModeSetting } from '@background/redux/settings/selectors'; import { ThemeMode } from '@background/redux/settings/types'; -import { useSystemThemeDetector } from '@src/hooks'; -import { themeModeSettingChanged } from '@background/redux/settings/actions'; -import { isSafariBuild } from '@src/utils'; +import { PopupState } from '@background/redux/types'; +import { dispatchToMainStore } from '@background/redux/utils'; +import { popupWindowInit } from '@background/redux/windowManagement/actions'; -import { AppRouter } from './app-router'; +import { useSubscribeToRedux } from '@hooks/use-subscribe-to-redux'; +import { useSystemThemeDetector } from '@hooks/use-system-theme-detector'; -// skeleton styles -import 'react-loading-skeleton/dist/skeleton.css'; +import { ErrorBoundary } from '@libs/layout'; +import { GlobalStyle, darkTheme, lightTheme } from '@libs/ui'; + +import { AppRouter } from './app-router'; const Tree = () => { const [state, setState] = useState(null); diff --git a/src/apps/popup/pages/account-settings/content.tsx b/src/apps/popup/pages/account-settings/content.tsx index 0c36362d7..4ade6ebe9 100644 --- a/src/apps/popup/pages/account-settings/content.tsx +++ b/src/apps/popup/pages/account-settings/content.tsx @@ -1,25 +1,34 @@ import React, { useCallback } from 'react'; -import { useParams } from 'react-router-dom'; +import { Trans, useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; -import { RootState } from 'typesafe-actions'; +import { useParams } from 'react-router-dom'; import styled from 'styled-components'; -import { Trans, useTranslation } from 'react-i18next'; +import { RootState } from 'typesafe-actions'; + +import { RouterPath, useTypedNavigate } from '@popup/router'; + +import { + selectVaultAccount, + selectVaultImportedAccounts +} from '@background/redux/vault/selectors'; +import { useFetchAccountInfo } from '@hooks/use-fetch-account-info'; + +import { getAccountHashFromPublicKey } from '@libs/entities/Account'; import { ContentContainer, FlexColumn, SpacingSize, TileContainer, VerticalSpaceContainer -} from '@src/libs/layout/containers'; -import { Hash, HashVariant, Tile, SvgIcon, Typography } from '@libs/ui'; +} from '@libs/layout'; import { - selectVaultAccount, - selectVaultImportedAccounts -} from '@src/background/redux/vault/selectors'; -import { RouterPath, useTypedNavigate } from '@popup/router'; -import { getAccountHashFromPublicKey } from '@libs/entities/Account'; -import { useFetchAccountInfo } from '@src/hooks'; + Hash, + HashVariant, + SvgIcon, + Tile, + Typography +} from '@libs/ui/components'; export function AccountSettingsPageContent() { const { t } = useTranslation(); diff --git a/src/apps/popup/pages/account-settings/index.tsx b/src/apps/popup/pages/account-settings/index.tsx index 61005171c..f605b4a1a 100644 --- a/src/apps/popup/pages/account-settings/index.tsx +++ b/src/apps/popup/pages/account-settings/index.tsx @@ -1,20 +1,23 @@ import React from 'react'; -import { useParams } from 'react-router-dom'; -import { RootState } from 'typesafe-actions'; import { Trans, useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; +import { useParams } from 'react-router-dom'; +import { RootState } from 'typesafe-actions'; + +import { getBlockExplorerAccountUrl } from '@src/constants'; + +import { RouterPath, useTypedNavigate } from '@popup/router'; + +import { selectApiConfigBasedOnActiveNetwork } from '@background/redux/settings/selectors'; +import { selectVaultAccount } from '@background/redux/vault/selectors'; import { FooterButtonsContainer, + HeaderPopup, HeaderSubmenuBarNavLink, - PopupHeader, PopupLayout } from '@libs/layout'; -import { Button, Link } from '@libs/ui'; -import { selectVaultAccount } from '@background/redux/vault/selectors'; -import { RouterPath, useTypedNavigate } from '@popup/router'; -import { getBlockExplorerAccountUrl } from '@src/constants'; -import { selectApiConfigBasedOnActiveNetwork } from '@src/background/redux/settings/selectors'; +import { Button, Link } from '@libs/ui/components'; import { AccountSettingsActionsGroup, @@ -39,7 +42,7 @@ export const AccountSettingsPage = () => { return ( ( - { return ( ( -