From 9027882fb401df2a9df6a89facb2bdb94b8b731b Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Tue, 24 Jan 2023 09:06:27 -0600 Subject: [PATCH] Account switcher (#85) * Update the account-create and signin views to use the design system. Also: - Add borderDark to the theme - Start to an account selector in the signin flow * Dark mode fixes in signin ui * Track multiple active accounts and provide account-switching UI * Add test tooling for an in-memory pds * Add complete integration tests for login and the account switcher --- __mocks__/@gorhom/bottom-sheet.tsx | 57 ++ __tests__/accounts.test.tsx | 241 ++++++ __tests__/view/com/login/Signin.test.tsx | 126 --- __tests__/view/shell/mobile/Menu.test.tsx | 6 +- jest/jestSetup.js | 13 - jest/test-pds.ts | 199 +++++ jest/test-utils.tsx | 13 +- package.json | 6 +- src/state/index.ts | 4 +- src/state/models/session.ts | 220 +++-- src/view/com/login/CreateAccount.tsx | 327 +++---- src/view/com/login/Logo.tsx | 42 +- src/view/com/login/Signin.tsx | 593 ++++++++----- src/view/com/modals/ServerInput.tsx | 4 +- src/view/com/util/ViewHeader.tsx | 1 + src/view/lib/ThemeContext.tsx | 1 + src/view/lib/hooks/usePalette.ts | 4 + src/view/lib/themes.ts | 7 + src/view/screens/Login.tsx | 73 +- src/view/screens/Settings.tsx | 116 ++- src/view/shell/mobile/Menu.tsx | 2 +- src/view/shell/mobile/index.tsx | 18 +- yarn.lock | 991 +++++++++++++++++++++- 23 files changed, 2406 insertions(+), 658 deletions(-) create mode 100644 __mocks__/@gorhom/bottom-sheet.tsx create mode 100644 __tests__/accounts.test.tsx delete mode 100644 __tests__/view/com/login/Signin.test.tsx create mode 100644 jest/test-pds.ts diff --git a/__mocks__/@gorhom/bottom-sheet.tsx b/__mocks__/@gorhom/bottom-sheet.tsx new file mode 100644 index 00000000..d6f907a3 --- /dev/null +++ b/__mocks__/@gorhom/bottom-sheet.tsx @@ -0,0 +1,57 @@ +import React from 'react' +import {View, ScrollView, Modal, FlatList, TextInput} from 'react-native' + +const BottomSheetModalContext = React.createContext(null) + +const BottomSheetModalProvider = (props: any) => { + return +} +class BottomSheet extends React.Component { + snapToIndex() {} + snapToPosition() {} + expand() {} + collapse() {} + close() { + this.props.onClose?.() + } + forceClose() {} + + render() { + return {this.props.children} + } +} +const BottomSheetModal = (props: any) => + +const BottomSheetBackdrop = (props: any) => +const BottomSheetHandle = (props: any) => +const BottomSheetFooter = (props: any) => +const BottomSheetScrollView = (props: any) => +const BottomSheetFlatList = (props: any) => +const BottomSheetTextInput = (props: any) => + +const useBottomSheet = jest.fn() +const useBottomSheetModal = jest.fn() +const useBottomSheetSpringConfigs = jest.fn() +const useBottomSheetTimingConfigs = jest.fn() +const useBottomSheetInternal = jest.fn() +const useBottomSheetDynamicSnapPoints = jest.fn() + +export {useBottomSheet} +export {useBottomSheetModal} +export {useBottomSheetSpringConfigs} +export {useBottomSheetTimingConfigs} +export {useBottomSheetInternal} +export {useBottomSheetDynamicSnapPoints} + +export { + BottomSheetModalProvider, + BottomSheetBackdrop, + BottomSheetHandle, + BottomSheetModal, + BottomSheetFooter, + BottomSheetScrollView, + BottomSheetFlatList, + BottomSheetTextInput, +} + +export default BottomSheet diff --git a/__tests__/accounts.test.tsx b/__tests__/accounts.test.tsx new file mode 100644 index 00000000..f3ecb6af --- /dev/null +++ b/__tests__/accounts.test.tsx @@ -0,0 +1,241 @@ +import React from 'react' +import {MobileShell} from '../src/view/shell/mobile' +import {cleanup, fireEvent, render, waitFor} from '../jest/test-utils' +import {createServer, TestPDS} from '../jest/test-pds' +import {RootStoreModel, setupState} from '../src/state' + +const WAIT_OPTS = {timeout: 5e3} + +describe('Account flows', () => { + let pds: TestPDS | undefined + let rootStore: RootStoreModel | undefined + beforeAll(async () => { + jest.useFakeTimers() + pds = await createServer() + rootStore = await setupState(pds.pdsUrl) + }) + + afterAll(async () => { + jest.clearAllMocks() + cleanup() + await pds?.close() + }) + + it('renders initial screen', () => { + const {getByTestId} = render(, rootStore) + const signUpScreen = getByTestId('signinOrCreateAccount') + + expect(signUpScreen).toBeTruthy() + }) + + it('completes signin to the server', async () => { + const {getByTestId} = render(, rootStore) + + // move to signin view + fireEvent.press(getByTestId('signInButton')) + expect(getByTestId('signIn')).toBeTruthy() + expect(getByTestId('loginForm')).toBeTruthy() + + // input the target server + expect(getByTestId('loginSelectServiceButton')).toBeTruthy() + fireEvent.press(getByTestId('loginSelectServiceButton')) + expect(getByTestId('serverInputModal')).toBeTruthy() + fireEvent.changeText( + getByTestId('customServerTextInput'), + pds?.pdsUrl || '', + ) + fireEvent.press(getByTestId('customServerSelectBtn')) + await waitFor(() => { + expect(getByTestId('loginUsernameInput')).toBeTruthy() + }, WAIT_OPTS) + + // enter username & pass + fireEvent.changeText(getByTestId('loginUsernameInput'), 'alice') + fireEvent.changeText(getByTestId('loginPasswordInput'), 'hunter2') + await waitFor(() => { + expect(getByTestId('loginNextButton')).toBeTruthy() + }, WAIT_OPTS) + fireEvent.press(getByTestId('loginNextButton')) + + // signed in + await waitFor(() => { + expect(getByTestId('homeFeed')).toBeTruthy() + expect(rootStore?.me?.displayName).toBe('Alice') + expect(rootStore?.me?.handle).toBe('alice.test') + expect(rootStore?.session.accounts.length).toBe(1) + }, WAIT_OPTS) + expect(rootStore?.me?.displayName).toBe('Alice') + expect(rootStore?.me?.handle).toBe('alice.test') + expect(rootStore?.session.accounts.length).toBe(1) + }) + + it('opens the login screen when "add account" is pressed', async () => { + const {getByTestId, getAllByTestId} = render(, rootStore) + await waitFor(() => expect(getByTestId('homeFeed')).toBeTruthy(), WAIT_OPTS) + + // open side menu + fireEvent.press(getAllByTestId('viewHeaderBackOrMenuBtn')[0]) + await waitFor(() => expect(getByTestId('menuView')).toBeTruthy(), WAIT_OPTS) + + // nav to settings + fireEvent.press(getByTestId('menuItemButton-Settings')) + await waitFor( + () => expect(getByTestId('settingsScreen')).toBeTruthy(), + WAIT_OPTS, + ) + + // press '+ new account' in switcher + fireEvent.press(getByTestId('switchToNewAccountBtn')) + await waitFor( + () => expect(getByTestId('signinOrCreateAccount')).toBeTruthy(), + WAIT_OPTS, + ) + }) + + it('shows the "choose account" form when a previous session has been created', async () => { + const {getByTestId} = render(, rootStore) + + // move to signin view + fireEvent.press(getByTestId('signInButton')) + expect(getByTestId('signIn')).toBeTruthy() + expect(getByTestId('chooseAccountForm')).toBeTruthy() + }) + + it('logs directly into the account due to still possessing session tokens', async () => { + const {getByTestId} = render(, rootStore) + + // move to signin view + fireEvent.press(getByTestId('signInButton')) + expect(getByTestId('signIn')).toBeTruthy() + expect(getByTestId('chooseAccountForm')).toBeTruthy() + + // select the previous account + fireEvent.press(getByTestId('chooseAccountBtn-alice.test')) + + // signs in immediately + await waitFor(() => { + expect(getByTestId('homeFeed')).toBeTruthy() + expect(rootStore?.me?.displayName).toBe('Alice') + expect(rootStore?.me?.handle).toBe('alice.test') + expect(rootStore?.session.accounts.length).toBe(1) + }, WAIT_OPTS) + expect(rootStore?.me?.displayName).toBe('Alice') + expect(rootStore?.me?.handle).toBe('alice.test') + expect(rootStore?.session.accounts.length).toBe(1) + }) + + it('logs into a second account via the switcher', async () => { + const {getByTestId, getAllByTestId} = render(, rootStore) + await waitFor(() => expect(getByTestId('homeFeed')).toBeTruthy(), WAIT_OPTS) + + // open side menu + fireEvent.press(getAllByTestId('viewHeaderBackOrMenuBtn')[0]) + await waitFor(() => expect(getByTestId('menuView')).toBeTruthy(), WAIT_OPTS) + + // nav to settings + fireEvent.press(getByTestId('menuItemButton-Settings')) + await waitFor( + () => expect(getByTestId('settingsScreen')).toBeTruthy(), + WAIT_OPTS, + ) + + // press '+ new account' in switcher + fireEvent.press(getByTestId('switchToNewAccountBtn')) + await waitFor( + () => expect(getByTestId('signinOrCreateAccount')).toBeTruthy(), + WAIT_OPTS, + ) + + // move to signin view + fireEvent.press(getByTestId('signInButton')) + expect(getByTestId('signIn')).toBeTruthy() + expect(getByTestId('chooseAccountForm')).toBeTruthy() + + // select a new account + fireEvent.press(getByTestId('chooseNewAccountBtn')) + expect(getByTestId('loginForm')).toBeTruthy() + + // input the target server + expect(getByTestId('loginSelectServiceButton')).toBeTruthy() + fireEvent.press(getByTestId('loginSelectServiceButton')) + expect(getByTestId('serverInputModal')).toBeTruthy() + fireEvent.changeText( + getByTestId('customServerTextInput'), + pds?.pdsUrl || '', + ) + fireEvent.press(getByTestId('customServerSelectBtn')) + await waitFor( + () => expect(getByTestId('loginUsernameInput')).toBeTruthy(), + WAIT_OPTS, + ) + + // enter username & pass + fireEvent.changeText(getByTestId('loginUsernameInput'), 'bob') + fireEvent.changeText(getByTestId('loginPasswordInput'), 'hunter2') + await waitFor( + () => expect(getByTestId('loginNextButton')).toBeTruthy(), + WAIT_OPTS, + ) + fireEvent.press(getByTestId('loginNextButton')) + + // signed in + await waitFor(() => { + expect(getByTestId('settingsScreen')).toBeTruthy() // we go back to settings in this situation + expect(rootStore?.me?.displayName).toBe('Bob') + expect(rootStore?.me?.handle).toBe('bob.test') + expect(rootStore?.session.accounts.length).toBe(2) + }, WAIT_OPTS) + expect(rootStore?.me?.displayName).toBe('Bob') + expect(rootStore?.me?.handle).toBe('bob.test') + expect(rootStore?.session.accounts.length).toBe(2) + }) + + it('can instantly switch between accounts', async () => { + const {getByTestId} = render(, rootStore) + await waitFor( + () => expect(getByTestId('settingsScreen')).toBeTruthy(), + WAIT_OPTS, + ) + + // select the alice account + fireEvent.press(getByTestId('switchToAccountBtn-alice.test')) + + // swapped account + await waitFor(() => { + expect(rootStore?.me?.displayName).toBe('Alice') + expect(rootStore?.me?.handle).toBe('alice.test') + expect(rootStore?.session.accounts.length).toBe(2) + }, WAIT_OPTS) + expect(rootStore?.me?.displayName).toBe('Alice') + expect(rootStore?.me?.handle).toBe('alice.test') + expect(rootStore?.session.accounts.length).toBe(2) + }) + + it('will prompt for a password if you sign out', async () => { + const {getByTestId} = render(, rootStore) + await waitFor( + () => expect(getByTestId('settingsScreen')).toBeTruthy(), + WAIT_OPTS, + ) + + // press the sign out button + fireEvent.press(getByTestId('signOutBtn')) + + // in the logged out state + await waitFor( + () => expect(getByTestId('signinOrCreateAccount')).toBeTruthy(), + WAIT_OPTS, + ) + + // move to signin view + fireEvent.press(getByTestId('signInButton')) + expect(getByTestId('signIn')).toBeTruthy() + expect(getByTestId('chooseAccountForm')).toBeTruthy() + + // select an existing account + fireEvent.press(getByTestId('chooseAccountBtn-alice.test')) + + // goes to login screen instead of straight back to settings + expect(getByTestId('loginForm')).toBeTruthy() + }) +}) diff --git a/__tests__/view/com/login/Signin.test.tsx b/__tests__/view/com/login/Signin.test.tsx deleted file mode 100644 index e5b6bdbc..00000000 --- a/__tests__/view/com/login/Signin.test.tsx +++ /dev/null @@ -1,126 +0,0 @@ -import React from 'react' -import {Signin} from '../../../../src/view/com/login/Signin' -import {cleanup, fireEvent, render} from '../../../../jest/test-utils' -import {SessionServiceClient, sessionClient as AtpApi} from '@atproto/api' -import { - mockedSessionStore, - mockedShellStore, -} from '../../../../__mocks__/state-mock' -import {Keyboard} from 'react-native' - -describe('Signin', () => { - const requestPasswordResetMock = jest.fn() - const resetPasswordMock = jest.fn() - jest.spyOn(AtpApi, 'service').mockReturnValue({ - com: { - atproto: { - account: { - requestPasswordReset: requestPasswordResetMock, - resetPassword: resetPasswordMock, - }, - }, - }, - } as unknown as SessionServiceClient) - const mockedProps = { - onPressBack: jest.fn(), - } - afterAll(() => { - jest.clearAllMocks() - cleanup() - }) - - it('renders logs in form', async () => { - const {findByTestId} = render() - - const loginFormView = await findByTestId('loginFormView') - expect(loginFormView).toBeTruthy() - - const loginUsernameInput = await findByTestId('loginUsernameInput') - expect(loginUsernameInput).toBeTruthy() - - fireEvent.changeText(loginUsernameInput, 'testusername') - - const loginPasswordInput = await findByTestId('loginPasswordInput') - expect(loginPasswordInput).toBeTruthy() - - fireEvent.changeText(loginPasswordInput, 'test pass') - - const loginNextButton = await findByTestId('loginNextButton') - expect(loginNextButton).toBeTruthy() - - fireEvent.press(loginNextButton) - - expect(mockedSessionStore.login).toHaveBeenCalled() - }) - - it('renders selects service from login form', async () => { - const keyboardSpy = jest.spyOn(Keyboard, 'dismiss') - const {findByTestId} = render() - - const loginSelectServiceButton = await findByTestId( - 'loginSelectServiceButton', - ) - expect(loginSelectServiceButton).toBeTruthy() - - fireEvent.press(loginSelectServiceButton) - - expect(mockedShellStore.openModal).toHaveBeenCalled() - expect(keyboardSpy).toHaveBeenCalled() - }) - - it('renders new password form', async () => { - const {findByTestId} = render() - - const forgotPasswordButton = await findByTestId('forgotPasswordButton') - expect(forgotPasswordButton).toBeTruthy() - - fireEvent.press(forgotPasswordButton) - const forgotPasswordView = await findByTestId('forgotPasswordView') - expect(forgotPasswordView).toBeTruthy() - - const forgotPasswordEmail = await findByTestId('forgotPasswordEmail') - expect(forgotPasswordEmail).toBeTruthy() - fireEvent.changeText(forgotPasswordEmail, 'test@email.com') - - const newPasswordButton = await findByTestId('newPasswordButton') - expect(newPasswordButton).toBeTruthy() - fireEvent.press(newPasswordButton) - - expect(requestPasswordResetMock).toHaveBeenCalled() - - const newPasswordView = await findByTestId('newPasswordView') - expect(newPasswordView).toBeTruthy() - - const newPasswordInput = await findByTestId('newPasswordInput') - expect(newPasswordInput).toBeTruthy() - const resetCodeInput = await findByTestId('resetCodeInput') - expect(resetCodeInput).toBeTruthy() - - fireEvent.changeText(newPasswordInput, 'test pass') - fireEvent.changeText(resetCodeInput, 'test reset code') - - const setNewPasswordButton = await findByTestId('setNewPasswordButton') - expect(setNewPasswordButton).toBeTruthy() - - fireEvent.press(setNewPasswordButton) - - expect(resetPasswordMock).toHaveBeenCalled() - }) - - it('renders forgot password form', async () => { - const {findByTestId} = render() - - const forgotPasswordButton = await findByTestId('forgotPasswordButton') - expect(forgotPasswordButton).toBeTruthy() - - fireEvent.press(forgotPasswordButton) - const forgotPasswordSelectServiceButton = await findByTestId( - 'forgotPasswordSelectServiceButton', - ) - expect(forgotPasswordSelectServiceButton).toBeTruthy() - - fireEvent.press(forgotPasswordSelectServiceButton) - - expect(mockedShellStore.openModal).toHaveBeenCalled() - }) -}) diff --git a/__tests__/view/shell/mobile/Menu.test.tsx b/__tests__/view/shell/mobile/Menu.test.tsx index 0bffaff7..31325904 100644 --- a/__tests__/view/shell/mobile/Menu.test.tsx +++ b/__tests__/view/shell/mobile/Menu.test.tsx @@ -46,10 +46,10 @@ describe('Menu', () => { }) it("presses notifications menu item' button", () => { - const {getAllByTestId} = render() + const {getByTestId} = render() - const menuItemButton = getAllByTestId('menuItemButton') - fireEvent.press(menuItemButton[1]) + const menuItemButton = getByTestId('menuItemButton-Notifications') + fireEvent.press(menuItemButton) expect(onCloseMock).toHaveBeenCalled() expect(mockedNavigationStore.switchTo).toHaveBeenCalledWith(1, true) diff --git a/jest/jestSetup.js b/jest/jestSetup.js index b1f110a5..8f95062a 100644 --- a/jest/jestSetup.js +++ b/jest/jestSetup.js @@ -25,19 +25,6 @@ jest.mock('react-native-safe-area-context', () => { } }) -jest.mock('@gorhom/bottom-sheet', () => { - const react = require('react-native') - return { - __esModule: true, - default: react.View, - namedExport: { - ...require('react-native-reanimated/mock'), - ...jest.requireActual('@gorhom/bottom-sheet'), - BottomSheetFlatList: react.FlatList, - }, - } -}) - jest.mock('rn-fetch-blob', () => ({ config: jest.fn().mockReturnThis(), cancel: jest.fn(), diff --git a/jest/test-pds.ts b/jest/test-pds.ts new file mode 100644 index 00000000..4915b58e --- /dev/null +++ b/jest/test-pds.ts @@ -0,0 +1,199 @@ +import {AddressInfo} from 'net' +import os from 'os' +import path from 'path' +import * as crypto from '@atproto/crypto' +import PDSServer, { + Database as PDSDatabase, + MemoryBlobStore, + ServerConfig as PDSServerConfig, +} from '@atproto/pds' +import * as plc from '@atproto/plc' +import AtpApi, {ServiceClient} from '@atproto/api' + +export interface TestUser { + email: string + did: string + declarationCid: string + handle: string + password: string + api: ServiceClient +} + +export interface TestUsers { + alice: TestUser + bob: TestUser + carla: TestUser +} + +export interface TestPDS { + pdsUrl: string + users: TestUsers + close: () => Promise +} + +// NOTE +// deterministic date generator +// we use this to ensure the mock dataset is always the same +// which is very useful when testing +function* dateGen() { + let start = 1657846031914 + while (true) { + yield new Date(start).toISOString() + start += 1e3 + } + return '' +} + +export async function createServer(): Promise { + const keypair = await crypto.EcdsaKeypair.create() + + // run plc server + const plcDb = plc.Database.memory() + await plcDb.migrateToLatestOrThrow() + const plcServer = plc.PlcServer.create({db: plcDb}) + const plcListener = await plcServer.start() + const plcPort = (plcListener.address() as AddressInfo).port + const plcUrl = `http://localhost:${plcPort}` + + const recoveryKey = (await crypto.EcdsaKeypair.create()).did() + + const plcClient = new plc.PlcClient(plcUrl) + const serverDid = await plcClient.createDid( + keypair, + recoveryKey, + 'localhost', + 'https://pds.public.url', + ) + + const blobstoreLoc = path.join(os.tmpdir(), crypto.randomStr(5, 'base32')) + + const cfg = new PDSServerConfig({ + debugMode: true, + version: '0.0.0', + scheme: 'http', + hostname: 'localhost', + serverDid, + recoveryKey, + adminPassword: 'admin-pass', + inviteRequired: false, + didPlcUrl: plcUrl, + jwtSecret: 'jwt-secret', + availableUserDomains: ['.test'], + appUrlPasswordReset: 'app://forgot-password', + emailNoReplyAddress: 'noreply@blueskyweb.xyz', + publicUrl: 'https://pds.public.url', + imgUriSalt: '9dd04221f5755bce5f55f47464c27e1e', + imgUriKey: + 'f23ecd142835025f42c3db2cf25dd813956c178392760256211f9d315f8ab4d8', + dbPostgresUrl: process.env.DB_POSTGRES_URL, + blobstoreLocation: `${blobstoreLoc}/blobs`, + blobstoreTmp: `${blobstoreLoc}/tmp`, + }) + + const db = PDSDatabase.memory() + await db.migrateToLatestOrThrow() + const blobstore = new MemoryBlobStore() + + const pds = PDSServer.create({db, blobstore, keypair, config: cfg}) + const pdsServer = await pds.start() + const pdsPort = (pdsServer.address() as AddressInfo).port + const pdsUrl = `http://localhost:${pdsPort}` + const testUsers = await genMockData(pdsUrl) + + return { + pdsUrl, + users: testUsers, + async close() { + await pds.destroy() + await plcServer.destroy() + }, + } +} + +async function genMockData(pdsUrl: string): Promise { + const date = dateGen() + + const clients = { + loggedout: AtpApi.service(pdsUrl), + alice: AtpApi.service(pdsUrl), + bob: AtpApi.service(pdsUrl), + carla: AtpApi.service(pdsUrl), + } + const users: TestUser[] = [ + { + email: 'alice@test.com', + did: '', + declarationCid: '', + handle: 'alice.test', + password: 'hunter2', + api: clients.alice, + }, + { + email: 'bob@test.com', + did: '', + declarationCid: '', + handle: 'bob.test', + password: 'hunter2', + api: clients.bob, + }, + { + email: 'carla@test.com', + did: '', + declarationCid: '', + handle: 'carla.test', + password: 'hunter2', + api: clients.carla, + }, + ] + const alice = users[0] + const bob = users[1] + const carla = users[2] + + let _i = 1 + for (const user of users) { + const res = await clients.loggedout.com.atproto.account.create({ + email: user.email, + handle: user.handle, + password: user.password, + }) + user.api.setHeader('Authorization', `Bearer ${res.data.accessJwt}`) + const {data: profile} = await user.api.app.bsky.actor.getProfile({ + actor: user.handle, + }) + user.did = res.data.did + user.declarationCid = profile.declaration.cid + await user.api.app.bsky.actor.profile.create( + {did: user.did}, + { + displayName: ucfirst(user.handle).slice(0, -5), + description: `Test user ${_i++}`, + }, + ) + } + + // everybody follows everybody + const follow = async (author: TestUser, subject: TestUser) => { + await author.api.app.bsky.graph.follow.create( + {did: author.did}, + { + subject: { + did: subject.did, + declarationCid: subject.declarationCid, + }, + createdAt: date.next().value, + }, + ) + } + await follow(alice, bob) + await follow(alice, carla) + await follow(bob, alice) + await follow(bob, carla) + await follow(carla, alice) + await follow(carla, bob) + + return {alice, bob, carla} +} + +function ucfirst(str: string): string { + return str.at(0)?.toUpperCase() + str.slice(1) +} diff --git a/jest/test-utils.tsx b/jest/test-utils.tsx index c84ee637..5a74a6ef 100644 --- a/jest/test-utils.tsx +++ b/jest/test-utils.tsx @@ -4,20 +4,19 @@ import {GestureHandlerRootView} from 'react-native-gesture-handler' import {RootSiblingParent} from 'react-native-root-siblings' import {SafeAreaProvider} from 'react-native-safe-area-context' import {RootStoreProvider} from '../src/state' +import {ThemeProvider} from '../src/view/lib/ThemeContext' import {mockedRootStore} from '../__mocks__/state-mock' -const customRender = (ui: any, storeMock?: any) => +const customRender = (ui: any, rootStore?: any) => render( // eslint-disable-next-line react-native/no-inline-styles - {ui} + value={rootStore != null ? rootStore : mockedRootStore}> + + {ui} + , diff --git a/package.json b/package.json index b0bfdddd..5ee62c45 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "web": "react-scripts start", "start": "react-native start", "clean-cache": "rm -rf node_modules/.cache/babel-loader/*", - "test": "jest", + "test": "jest --forceExit", "test-watch": "jest --watchAll", "test-ci": "jest --ci --forceExit --reporters=default --reporters=jest-junit", "test-coverage": "jest --coverage", @@ -64,9 +64,11 @@ "react-native-version-number": "^0.3.6", "react-native-web": "^0.17.7", "rn-fetch-blob": "^0.12.0", - "tlds": "^1.234.0" + "tlds": "^1.234.0", + "zod": "^3.20.2" }, "devDependencies": { + "@atproto/pds": "^0.0.1", "@babel/core": "^7.12.9", "@babel/preset-env": "^7.14.0", "@babel/runtime": "^7.12.5", diff --git a/src/state/index.ts b/src/state/index.ts index 5c8b50ef..78fba2ec 100644 --- a/src/state/index.ts +++ b/src/state/index.ts @@ -13,13 +13,13 @@ export const DEFAULT_SERVICE = PROD_SERVICE const ROOT_STATE_STORAGE_KEY = 'root' const STATE_FETCH_INTERVAL = 15e3 -export async function setupState() { +export async function setupState(serviceUri = DEFAULT_SERVICE) { let rootStore: RootStoreModel let data: any libapi.doPolyfill() - const api = AtpApi.service(DEFAULT_SERVICE) as SessionServiceClient + const api = AtpApi.service(serviceUri) as SessionServiceClient rootStore = new RootStoreModel(api) try { data = (await storage.load(ROOT_STATE_STORAGE_KEY)) || {} diff --git a/src/state/models/session.ts b/src/state/models/session.ts index 13e0fcbe..89347af9 100644 --- a/src/state/models/session.ts +++ b/src/state/models/session.ts @@ -6,24 +6,44 @@ import { ComAtprotoServerGetAccountsConfig as GetAccountsConfig, } from '@atproto/api' import {isObj, hasProp} from '../lib/type-guards' +import {z} from 'zod' import {RootStoreModel} from './root-store' import {isNetworkError} from '../../lib/errors' export type ServiceDescription = GetAccountsConfig.OutputSchema -interface SessionData { - service: string - refreshJwt: string - accessJwt: string - handle: string - did: string -} +export const sessionData = z.object({ + service: z.string(), + refreshJwt: z.string(), + accessJwt: z.string(), + handle: z.string(), + did: z.string(), +}) +export type SessionData = z.infer + +export const accountData = z.object({ + service: z.string(), + refreshJwt: z.string().optional(), + accessJwt: z.string().optional(), + handle: z.string(), + did: z.string(), + displayName: z.string().optional(), + aviUrl: z.string().optional(), +}) +export type AccountData = z.infer export class SessionModel { + /** + * Current session data + */ data: SessionData | null = null + /** + * A listing of the currently & previous sessions, used for account switching + */ + accounts: AccountData[] = [] online = false attemptingConnect = false - private _connectPromise: Promise | undefined + private _connectPromise: Promise | undefined constructor(public rootStore: RootStoreModel) { makeAutoObservable(this, { @@ -37,51 +57,32 @@ export class SessionModel { return this.data !== null } + get hasAccounts() { + return this.accounts.length >= 1 + } + + get switchableAccounts() { + return this.accounts.filter(acct => acct.did !== this.data?.did) + } + serialize(): unknown { return { data: this.data, + accounts: this.accounts, } } hydrate(v: unknown) { + this.accounts = [] if (isObj(v)) { - if (hasProp(v, 'data') && isObj(v.data)) { - const data: SessionData = { - service: '', - refreshJwt: '', - accessJwt: '', - handle: '', - did: '', - } - if (hasProp(v.data, 'service') && typeof v.data.service === 'string') { - data.service = v.data.service - } - if ( - hasProp(v.data, 'refreshJwt') && - typeof v.data.refreshJwt === 'string' - ) { - data.refreshJwt = v.data.refreshJwt - } - if ( - hasProp(v.data, 'accessJwt') && - typeof v.data.accessJwt === 'string' - ) { - data.accessJwt = v.data.accessJwt - } - if (hasProp(v.data, 'handle') && typeof v.data.handle === 'string') { - data.handle = v.data.handle - } - if (hasProp(v.data, 'did') && typeof v.data.did === 'string') { - data.did = v.data.did - } - if ( - data.service && - data.refreshJwt && - data.accessJwt && - data.handle && - data.did - ) { - this.data = data + if (hasProp(v, 'data') && sessionData.safeParse(v.data)) { + this.data = v.data as SessionData + } + if (hasProp(v, 'accounts') && Array.isArray(v.accounts)) { + for (const account of v.accounts) { + if (accountData.safeParse(account)) { + this.accounts.push(account as AccountData) + } } } } @@ -113,6 +114,9 @@ export class SessionModel { } } + /** + * Sets up the XRPC API, must be called before connecting to a service + */ private configureApi(): boolean { if (!this.data) { return false @@ -137,19 +141,68 @@ export class SessionModel { return true } - async connect(): Promise { + /** + * Upserts the current session into the accounts + */ + private addSessionToAccounts() { + if (!this.data) { + return + } + const existingAccount = this.accounts.find( + acc => acc.service === this.data?.service && acc.did === this.data.did, + ) + const newAccount = { + service: this.data.service, + refreshJwt: this.data.refreshJwt, + accessJwt: this.data.accessJwt, + handle: this.data.handle, + did: this.data.did, + displayName: this.rootStore.me.displayName, + aviUrl: this.rootStore.me.avatar, + } + if (!existingAccount) { + this.accounts.push(newAccount) + } else { + this.accounts = this.accounts + .filter( + acc => + !(acc.service === this.data?.service && acc.did === this.data.did), + ) + .concat([newAccount]) + } + } + + /** + * Clears any session tokens from the accounts; used on logout. + */ + private clearSessionTokensFromAccounts() { + this.accounts = this.accounts.map(acct => ({ + service: acct.service, + handle: acct.handle, + did: acct.did, + displayName: acct.displayName, + aviUrl: acct.aviUrl, + })) + } + + /** + * Fetches the current session from the service, if possible. + * Requires an existing session (.data) to be populated with access tokens. + */ + async connect(): Promise { if (this._connectPromise) { return this._connectPromise } this._connectPromise = this._connect() - await this._connectPromise + const res = await this._connectPromise this._connectPromise = undefined + return res } - private async _connect(): Promise { + private async _connect(): Promise { this.attemptingConnect = true if (!this.configureApi()) { - return + return false } try { @@ -159,29 +212,44 @@ export class SessionModel { if (this.rootStore.me.did !== sess.data.did) { this.rootStore.me.clear() } - this.rootStore.me.load().catch(e => { - this.rootStore.log.error('Failed to fetch local user information', e) - }) - return // success + this.rootStore.me + .load() + .catch(e => { + this.rootStore.log.error( + 'Failed to fetch local user information', + e, + ) + }) + .then(() => { + this.addSessionToAccounts() + }) + return true // success } } catch (e: any) { if (isNetworkError(e)) { this.setOnline(false, false) // connection issue - return + return false } else { this.clear() // invalid session cached } } this.setOnline(false, false) + return false } + /** + * Helper to fetch the accounts config settings from an account. + */ async describeService(service: string): Promise { const api = AtpApi.service(service) as SessionServiceClient const res = await api.com.atproto.server.getAccountsConfig({}) return res.data } + /** + * Create a new session. + */ async login({ service, handle, @@ -203,12 +271,35 @@ export class SessionModel { }) this.configureApi() this.setOnline(true, false) - this.rootStore.me.load().catch(e => { - this.rootStore.log.error('Failed to fetch local user information', e) - }) + this.rootStore.me + .load() + .catch(e => { + this.rootStore.log.error('Failed to fetch local user information', e) + }) + .then(() => { + this.addSessionToAccounts() + }) } } + /** + * Attempt to resume a session that we still have access tokens for. + */ + async resumeSession(account: AccountData): Promise { + if (account.accessJwt && account.refreshJwt) { + this.setState({ + service: account.service, + accessJwt: account.accessJwt, + refreshJwt: account.refreshJwt, + handle: account.handle, + did: account.did, + }) + } else { + return false + } + return this.connect() + } + async createAccount({ service, email, @@ -239,12 +330,20 @@ export class SessionModel { }) this.rootStore.onboard.start() this.configureApi() - this.rootStore.me.load().catch(e => { - this.rootStore.log.error('Failed to fetch local user information', e) - }) + this.rootStore.me + .load() + .catch(e => { + this.rootStore.log.error('Failed to fetch local user information', e) + }) + .then(() => { + this.addSessionToAccounts() + }) } } + /** + * Close all sessions across all accounts. + */ async logout() { if (this.hasSession) { this.rootStore.api.com.atproto.session.delete().catch((e: any) => { @@ -254,6 +353,7 @@ export class SessionModel { ) }) } + this.clearSessionTokensFromAccounts() this.rootStore.clearAll() } } diff --git a/src/view/com/login/CreateAccount.tsx b/src/view/com/login/CreateAccount.tsx index 349c48ef..6c597408 100644 --- a/src/view/com/login/CreateAccount.tsx +++ b/src/view/com/login/CreateAccount.tsx @@ -12,7 +12,7 @@ import { import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {ComAtprotoAccountCreate} from '@atproto/api' import * as EmailValidator from 'email-validator' -import {Logo} from './Logo' +import {LogoTextHero} from './Logo' import {Picker} from '../util/Picker' import {TextLink} from '../util/Link' import {Text} from '../util/text/Text' @@ -25,8 +25,10 @@ import { import {useStores, DEFAULT_SERVICE} from '../../../state' import {ServiceDescription} from '../../../state/models/session' import {ServerInputModal} from '../../../state/models/shell-ui' +import {usePalette} from '../../lib/hooks/usePalette' export const CreateAccount = ({onPressBack}: {onPressBack: () => void}) => { + const pal = usePalette('default') const store = useStores() const [isProcessing, setIsProcessing] = useState(false) const [serviceUrl, setServiceUrl] = useState(DEFAULT_SERVICE) @@ -114,74 +116,14 @@ export const CreateAccount = ({onPressBack}: {onPressBack: () => void}) => { } } - const Policies = () => { - if (!serviceDescription) { - return - } - const tos = validWebLink(serviceDescription.links?.termsOfService) - const pp = validWebLink(serviceDescription.links?.privacyPolicy) - if (!tos && !pp) { - return ( - - - - - - This service has not provided terms of service or a privacy policy. - - - ) - } - const els = [] - if (tos) { - els.push( - , - ) - } - if (pp) { - els.push( - , - ) - } - if (els.length === 2) { - els.splice( - 1, - 0, - - {' '} - and{' '} - , - ) - } - return ( - - - By creating an account you agree to the {els}. - - - ) - } - const isReady = !!email && !!password && !!handle && is13 return ( - - - - - + + + {error ? ( - + @@ -189,41 +131,55 @@ export const CreateAccount = ({onPressBack}: {onPressBack: () => void}) => { ) : undefined} - - - Create a new account - - - + + + Service provider + + + + + - + {toNiceDomain(serviceUrl)} - + - Change + Change - {serviceDescription ? ( - <> + + {serviceDescription ? ( + <> + + + Account details + + + {serviceDescription?.inviteCodeRequired ? ( - + void}) => { /> ) : undefined} - + void}) => { editable={!isProcessing} /> - - + + void}) => { editable={!isProcessing} /> - - ) : undefined} - + + + ) : undefined} {serviceDescription ? ( <> - - - - Choose your username - - - - + + + Choose your username + + + + + setHandle(makeValidHandle(v))} @@ -290,15 +253,15 @@ export const CreateAccount = ({onPressBack}: {onPressBack: () => void}) => { /> {serviceDescription.availableUserDomains.length > 1 && ( - + ({ label: `.${d}`, @@ -309,41 +272,50 @@ export const CreateAccount = ({onPressBack}: {onPressBack: () => void}) => { /> )} - - + + Your full username will be{' '} - + @{createFullHandle(handle, userDomain)} - - - Legal - - + + + Legal + + + + setIs13(!is13)}> - + {is13 && ( )} - + I am 13 years old or older - + ) : undefined} - Back + + Back + {isReady ? ( @@ -351,21 +323,27 @@ export const CreateAccount = ({onPressBack}: {onPressBack: () => void}) => { testID="createAccountButton" onPress={onPressNext}> {isProcessing ? ( - + ) : ( - Next + + Next + )} ) : !serviceDescription && error ? ( - Retry + + Retry + ) : !serviceDescription ? ( <> - Connecting... + + Connecting... + ) : undefined} @@ -375,6 +353,69 @@ export const CreateAccount = ({onPressBack}: {onPressBack: () => void}) => { ) } +const Policies = ({ + serviceDescription, +}: { + serviceDescription: ServiceDescription +}) => { + const pal = usePalette('default') + if (!serviceDescription) { + return + } + const tos = validWebLink(serviceDescription.links?.termsOfService) + const pp = validWebLink(serviceDescription.links?.privacyPolicy) + if (!tos && !pp) { + return ( + + + + + + This service has not provided terms of service or a privacy policy. + + + ) + } + const els = [] + if (tos) { + els.push( + , + ) + } + if (pp) { + els.push( + , + ) + } + if (els.length === 2) { + els.splice( + 1, + 0, + + {' '} + and{' '} + , + ) + } + return ( + + + By creating an account you agree to the {els}. + + + ) +} + function validWebLink(url?: string): string | undefined { return url && (url.startsWith('http://') || url.startsWith('https://')) ? url @@ -382,42 +423,39 @@ function validWebLink(url?: string): string | undefined { } const styles = StyleSheet.create({ + noTopBorder: { + borderTopWidth: 0, + }, logoHero: { paddingTop: 30, paddingBottom: 40, }, group: { borderWidth: 1, - borderColor: colors.white, borderRadius: 10, marginBottom: 20, marginHorizontal: 20, - backgroundColor: colors.blue3, }, - groupTitle: { - flexDirection: 'row', - alignItems: 'center', - paddingVertical: 8, - paddingHorizontal: 12, + groupLabel: { + paddingHorizontal: 20, + paddingBottom: 5, }, groupContent: { borderTopWidth: 1, - borderTopColor: colors.blue1, flexDirection: 'row', alignItems: 'center', }, groupContentIcon: { - color: 'white', marginLeft: 10, }, textInput: { flex: 1, width: '100%', - backgroundColor: colors.blue3, - color: colors.white, paddingVertical: 10, paddingHorizontal: 12, - fontSize: 18, + fontSize: 17, + letterSpacing: 0.25, + fontWeight: '400', borderRadius: 10, }, textBtn: { @@ -427,47 +465,33 @@ const styles = StyleSheet.create({ }, textBtnLabel: { flex: 1, - color: colors.white, paddingVertical: 10, paddingHorizontal: 12, - fontSize: 18, }, textBtnFakeInnerBtn: { flexDirection: 'row', alignItems: 'center', - backgroundColor: colors.blue2, borderRadius: 6, paddingVertical: 6, paddingHorizontal: 8, marginHorizontal: 6, }, textBtnFakeInnerBtnIcon: { - color: colors.white, marginRight: 4, }, - textBtnFakeInnerBtnLabel: { - color: colors.white, - }, picker: { flex: 1, width: '100%', - backgroundColor: colors.blue3, - color: colors.white, paddingVertical: 10, paddingHorizontal: 12, - fontSize: 18, + fontSize: 17, borderRadius: 10, }, pickerLabel: { - color: colors.white, - fontSize: 18, - }, - pickerIcon: { - color: colors.white, + fontSize: 17, }, checkbox: { borderWidth: 1, - borderColor: colors.white, borderRadius: 2, width: 16, height: 16, @@ -475,8 +499,6 @@ const styles = StyleSheet.create({ }, checkboxFilled: { borderWidth: 1, - borderColor: colors.white, - backgroundColor: colors.white, borderRadius: 2, width: 16, height: 16, @@ -489,8 +511,6 @@ const styles = StyleSheet.create({ paddingBottom: 20, }, error: { - borderWidth: 1, - borderColor: colors.red5, backgroundColor: colors.red4, flexDirection: 'row', alignItems: 'center', @@ -509,7 +529,6 @@ const styles = StyleSheet.create({ errorIcon: { borderWidth: 1, borderColor: colors.white, - color: colors.white, borderRadius: 30, width: 16, height: 16, diff --git a/src/view/com/login/Logo.tsx b/src/view/com/login/Logo.tsx index d1dc9c67..7045e415 100644 --- a/src/view/com/login/Logo.tsx +++ b/src/view/com/login/Logo.tsx @@ -1,26 +1,29 @@ import React from 'react' import {StyleSheet, View} from 'react-native' +import LinearGradient from 'react-native-linear-gradient' import Svg, {Circle, Line, Text as SvgText} from 'react-native-svg' +import {s, gradients} from '../../lib/styles' +import {Text} from '../util/text/Text' -export const Logo = () => { +export const Logo = ({color, size = 100}: {color: string; size?: number}) => { return ( - + - - - - + + + + { ) } +export const LogoTextHero = () => { + return ( + + + + Bluesky + + + ) +} + const styles = StyleSheet.create({ logo: { flexDirection: 'row', justifyContent: 'center', }, + textHero: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + paddingRight: 20, + paddingVertical: 15, + marginBottom: 20, + }, }) diff --git a/src/view/com/login/Signin.tsx b/src/view/com/login/Signin.tsx index e99aaa65..a39ea5e7 100644 --- a/src/view/com/login/Signin.tsx +++ b/src/view/com/login/Signin.tsx @@ -11,23 +11,28 @@ import { import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import * as EmailValidator from 'email-validator' import {sessionClient as AtpApi, SessionServiceClient} from '@atproto/api' -import {Logo} from './Logo' +import {LogoTextHero} from './Logo' import {Text} from '../util/text/Text' +import {UserAvatar} from '../util/UserAvatar' import {s, colors} from '../../lib/styles' import {createFullHandle, toNiceDomain} from '../../../lib/strings' import {useStores, RootStoreModel, DEFAULT_SERVICE} from '../../../state' import {ServiceDescription} from '../../../state/models/session' import {ServerInputModal} from '../../../state/models/shell-ui' +import {AccountData} from '../../../state/models/session' import {isNetworkError} from '../../../lib/errors' +import {usePalette} from '../../lib/hooks/usePalette' enum Forms { Login, + ChooseAccount, ForgotPassword, SetNewPassword, PasswordUpdated, } export const Signin = ({onPressBack}: {onPressBack: () => void}) => { + const pal = usePalette('default') const store = useStores() const [error, setError] = useState('') const [retryDescribeTrigger, setRetryDescribeTrigger] = useState({}) @@ -35,7 +40,18 @@ export const Signin = ({onPressBack}: {onPressBack: () => void}) => { const [serviceDescription, setServiceDescription] = useState< ServiceDescription | undefined >(undefined) - const [currentForm, setCurrentForm] = useState(Forms.Login) + const [initialHandle, setInitialHandle] = useState('') + const [currentForm, setCurrentForm] = useState( + store.session.hasAccounts ? Forms.ChooseAccount : Forms.Login, + ) + + const onSelectAccount = (account?: AccountData) => { + if (account?.service) { + setServiceUrl(account.service) + } + setInitialHandle(account?.handle || '') + setCurrentForm(Forms.Login) + } const gotoForm = (form: Forms) => () => { setError('') @@ -73,16 +89,14 @@ export const Signin = ({onPressBack}: {onPressBack: () => void}) => { const onPressRetryConnect = () => setRetryDescribeTrigger({}) return ( - - - - + {currentForm === Forms.Login ? ( void}) => { onPressRetryConnect={onPressRetryConnect} /> ) : undefined} + {currentForm === Forms.ChooseAccount ? ( + + ) : undefined} {currentForm === Forms.ForgotPassword ? ( void}) => { ) } +const ChooseAccountForm = ({ + store, + onSelectAccount, + onPressBack, +}: { + store: RootStoreModel + onSelectAccount: (account?: AccountData) => void + onPressBack: () => void +}) => { + const pal = usePalette('default') + const [isProcessing, setIsProcessing] = React.useState(false) + + const onTryAccount = async (account: AccountData) => { + if (account.accessJwt && account.refreshJwt) { + setIsProcessing(true) + if (await store.session.resumeSession(account)) { + setIsProcessing(false) + return + } + setIsProcessing(false) + } + onSelectAccount(account) + } + + return ( + + + + Sign in as... + + {store.session.accounts.map(account => ( + onTryAccount(account)}> + + + + + + + {account.displayName || account.handle}{' '} + + + {account.handle} + + + + + + ))} + onSelectAccount(undefined)}> + + + + + + + Other account + + + + + + + + + Back + + + + {isProcessing && } + + + ) +} + const LoginForm = ({ store, error, serviceUrl, serviceDescription, + initialHandle, setError, setServiceUrl, onPressRetryConnect, @@ -134,14 +253,16 @@ const LoginForm = ({ error: string serviceUrl: string serviceDescription: ServiceDescription | undefined + initialHandle: string setError: (v: string) => void setServiceUrl: (v: string) => void onPressRetryConnect: () => void onPressBack: () => void onPressForgotPassword: () => void }) => { + const pal = usePalette('default') const [isProcessing, setIsProcessing] = useState(false) - const [handle, setHandle] = useState('') + const [handle, setHandle] = useState(initialHandle) const [password, setPassword] = useState('') const onPressSelectService = () => { @@ -197,31 +318,44 @@ const LoginForm = ({ const isReady = !!serviceDescription && !!handle && !!password return ( - <> - - - - Sign in to {toNiceDomain(serviceUrl)} - - - - Change - - - - + + + + Sign into + + + + + + + {toNiceDomain(serviceUrl)} + + + + + + + + + Account + + + + - - + + - Forgot + Forgot @@ -264,29 +401,37 @@ const LoginForm = ({ ) : undefined} - Back + + Back + {!serviceDescription && error ? ( - Retry + + Retry + ) : !serviceDescription ? ( <> - - Connecting... + + + Connecting... + ) : isProcessing ? ( - + ) : isReady ? ( - Next + + Next + ) : undefined} - + ) } @@ -309,6 +454,7 @@ const ForgotPasswordForm = ({ onPressBack: () => void onEmailSent: () => void }) => { + const pal = usePalette('default') const [isProcessing, setIsProcessing] = useState(false) const [email, setEmail] = useState('') @@ -344,72 +490,88 @@ const ForgotPasswordForm = ({ return ( <> - Reset password - - Enter the email you used to create your account. We'll send you a "reset - code" so you can set a new password. - - - - - - {toNiceDomain(serviceUrl)} - - + + + + Reset password + + + Enter the email you used to create your account. We'll send you a + "reset code" so you can set a new password. + + + - Change - - - - - - - - {error ? ( - - - - - - {error} - - - ) : undefined} - - - Back - - - {!serviceDescription || isProcessing ? ( - - ) : !email ? ( - Next - ) : ( - - Next + + {toNiceDomain(serviceUrl)} + + + + - )} - {!serviceDescription || isProcessing ? ( - Processing... + + + + + + {error ? ( + + + + + + {error} + + ) : undefined} + + + + Back + + + + {!serviceDescription || isProcessing ? ( + + ) : !email ? ( + + Next + + ) : ( + + + Next + + + )} + {!serviceDescription || isProcessing ? ( + + Processing... + + ) : undefined} + ) @@ -430,6 +592,7 @@ const SetNewPasswordForm = ({ onPressBack: () => void onPasswordSet: () => void }) => { + const pal = usePalette('default') const [isProcessing, setIsProcessing] = useState(false) const [resetCode, setResetCode] = useState('') const [password, setPassword] = useState('') @@ -458,87 +621,119 @@ const SetNewPasswordForm = ({ return ( <> - Set new password - - You will receive an email with a "reset code." Enter that code here, - then enter your new password. - - - - - - - - - - - - {error ? ( - - - + + + + Set new password + + + You will receive an email with a "reset code." Enter that code here, + then enter your new password. + + + + + - - {error} + + + - ) : undefined} - - - Back - - - {isProcessing ? ( - - ) : !resetCode || !password ? ( - Next - ) : ( - - Next - - )} - {isProcessing ? ( - Updating... + {error ? ( + + + + + + {error} + + ) : undefined} + + + + Back + + + + {isProcessing ? ( + + ) : !resetCode || !password ? ( + + Next + + ) : ( + + + Next + + + )} + {isProcessing ? ( + + Updating... + + ) : undefined} + ) } const PasswordUpdatedForm = ({onPressNext}: {onPressNext: () => void}) => { + const pal = usePalette('default') return ( <> - Password updated! - - You can now sign in with your new password. - - - - - Okay - + + + + Password updated! + + + You can now sign in with your new password. + + + + + + Okay + + + ) @@ -546,53 +741,42 @@ const PasswordUpdatedForm = ({onPressNext}: {onPressNext: () => void}) => { const styles = StyleSheet.create({ screenTitle: { - color: colors.white, - fontSize: 26, marginBottom: 10, marginHorizontal: 20, }, instructions: { - color: colors.white, - fontSize: 16, marginBottom: 20, marginHorizontal: 20, }, - logoHero: { - paddingTop: 30, - paddingBottom: 40, - }, group: { borderWidth: 1, - borderColor: colors.white, borderRadius: 10, marginBottom: 20, marginHorizontal: 20, - backgroundColor: colors.blue3, }, - groupTitle: { - flexDirection: 'row', - alignItems: 'center', - paddingVertical: 8, - paddingHorizontal: 12, + groupLabel: { + paddingHorizontal: 20, + paddingBottom: 5, }, groupContent: { borderTopWidth: 1, - borderTopColor: colors.blue1, flexDirection: 'row', alignItems: 'center', }, + noTopBorder: { + borderTopWidth: 0, + }, groupContentIcon: { - color: 'white', marginLeft: 10, }, textInput: { flex: 1, width: '100%', - backgroundColor: colors.blue3, - color: colors.white, paddingVertical: 10, paddingHorizontal: 12, - fontSize: 18, + fontSize: 17, + letterSpacing: 0.25, + fontWeight: '400', borderRadius: 10, }, textInputInnerBtn: { @@ -602,28 +786,31 @@ const styles = StyleSheet.create({ paddingHorizontal: 8, marginHorizontal: 6, }, - textInputInnerBtnLabel: { - color: colors.white, + textBtn: { + flexDirection: 'row', + flex: 1, + alignItems: 'center', + }, + textBtnLabel: { + flex: 1, + paddingVertical: 10, + paddingHorizontal: 12, }, textBtnFakeInnerBtn: { flexDirection: 'row', alignItems: 'center', - backgroundColor: colors.blue2, borderRadius: 6, paddingVertical: 6, paddingHorizontal: 8, marginHorizontal: 6, }, - textBtnFakeInnerBtnIcon: { - color: colors.white, - marginRight: 4, - }, - textBtnFakeInnerBtnLabel: { - color: colors.white, + accountText: { + flex: 1, + flexDirection: 'row', + alignItems: 'baseline', + paddingVertical: 10, }, error: { - borderWidth: 1, - borderColor: colors.red5, backgroundColor: colors.red4, flexDirection: 'row', alignItems: 'center', diff --git a/src/view/com/modals/ServerInput.tsx b/src/view/com/modals/ServerInput.tsx index 884fb91e..c8174f3c 100644 --- a/src/view/com/modals/ServerInput.tsx +++ b/src/view/com/modals/ServerInput.tsx @@ -33,7 +33,7 @@ export function Component({ } return ( - + Choose Service @@ -64,6 +64,7 @@ export function Component({ Other service doSelect(customUrl)}> diff --git a/src/view/lib/ThemeContext.tsx b/src/view/lib/ThemeContext.tsx index 54ae7127..16a7d9cb 100644 --- a/src/view/lib/ThemeContext.tsx +++ b/src/view/lib/ThemeContext.tsx @@ -18,6 +18,7 @@ export type PaletteColor = { textInverted: string link: string border: string + borderDark: string icon: string [k: string]: string } diff --git a/src/view/lib/hooks/usePalette.ts b/src/view/lib/hooks/usePalette.ts index 890439f3..5b9929c7 100644 --- a/src/view/lib/hooks/usePalette.ts +++ b/src/view/lib/hooks/usePalette.ts @@ -6,6 +6,7 @@ export interface UsePaletteValue { view: ViewStyle btn: ViewStyle border: ViewStyle + borderDark: ViewStyle text: TextStyle textLight: TextStyle textInverted: TextStyle @@ -25,6 +26,9 @@ export function usePalette(color: PaletteColorName): UsePaletteValue { border: { borderColor: palette.border, }, + borderDark: { + borderColor: palette.borderDark, + }, text: { color: palette.text, }, diff --git a/src/view/lib/themes.ts b/src/view/lib/themes.ts index b9e2bdac..84e2b788 100644 --- a/src/view/lib/themes.ts +++ b/src/view/lib/themes.ts @@ -13,6 +13,7 @@ export const defaultTheme: Theme = { textInverted: colors.white, link: colors.blue3, border: '#f0e9e9', + borderDark: '#e0d9d9', icon: colors.gray3, // non-standard @@ -32,6 +33,7 @@ export const defaultTheme: Theme = { textInverted: colors.blue3, link: colors.blue0, border: colors.blue4, + borderDark: colors.blue5, icon: colors.blue4, }, secondary: { @@ -42,6 +44,7 @@ export const defaultTheme: Theme = { textInverted: colors.green4, link: colors.green1, border: colors.green4, + borderDark: colors.green5, icon: colors.green4, }, inverted: { @@ -52,6 +55,7 @@ export const defaultTheme: Theme = { textInverted: colors.black, link: colors.blue2, border: colors.gray3, + borderDark: colors.gray2, icon: colors.gray5, }, error: { @@ -62,6 +66,7 @@ export const defaultTheme: Theme = { textInverted: colors.red3, link: colors.red1, border: colors.red4, + borderDark: colors.red5, icon: colors.red4, }, }, @@ -257,6 +262,7 @@ export const darkTheme: Theme = { textInverted: colors.black, link: colors.blue3, border: colors.gray6, + borderDark: colors.gray5, icon: colors.gray5, // non-standard @@ -284,6 +290,7 @@ export const darkTheme: Theme = { textInverted: colors.white, link: colors.blue3, border: colors.gray3, + borderDark: colors.gray4, icon: colors.gray1, }, }, diff --git a/src/view/screens/Login.tsx b/src/view/screens/Login.tsx index 8363dbfe..7d99f144 100644 --- a/src/view/screens/Login.tsx +++ b/src/view/screens/Login.tsx @@ -1,17 +1,21 @@ import React, {useState} from 'react' import { + SafeAreaView, StyleSheet, TouchableOpacity, View, useWindowDimensions, } from 'react-native' import Svg, {Line} from 'react-native-svg' +import LinearGradient from 'react-native-linear-gradient' import {observer} from 'mobx-react-lite' import {Signin} from '../com/login/Signin' import {Logo} from '../com/login/Logo' import {CreateAccount} from '../com/login/CreateAccount' import {Text} from '../com/util/text/Text' +import {ErrorBoundary} from '../com/util/ErrorBoundary' import {s, colors} from '../lib/styles' +import {usePalette} from '../lib/hooks/usePalette' enum ScreenState { SigninOrCreateAccount, @@ -31,7 +35,7 @@ const SigninOrCreateAccount = ({ return ( <> - + Bluesky [ private beta ] @@ -76,40 +80,61 @@ const SigninOrCreateAccount = ({ export const Login = observer( (/*{navigation}: RootTabsScreenProps<'Login'>*/) => { + const pal = usePalette('default') const [screenState, setScreenState] = useState( ScreenState.SigninOrCreateAccount, ) + if (screenState === ScreenState.SigninOrCreateAccount) { + return ( + + + + setScreenState(ScreenState.Signin)} + onPressCreateAccount={() => + setScreenState(ScreenState.CreateAccount) + } + /> + + + + ) + } + return ( - - {screenState === ScreenState.SigninOrCreateAccount ? ( - setScreenState(ScreenState.Signin)} - onPressCreateAccount={() => - setScreenState(ScreenState.CreateAccount) - } - /> - ) : undefined} - {screenState === ScreenState.Signin ? ( - - setScreenState(ScreenState.SigninOrCreateAccount) - } - /> - ) : undefined} - {screenState === ScreenState.CreateAccount ? ( - - setScreenState(ScreenState.SigninOrCreateAccount) - } - /> - ) : undefined} + + + + {screenState === ScreenState.Signin ? ( + + setScreenState(ScreenState.SigninOrCreateAccount) + } + /> + ) : undefined} + {screenState === ScreenState.CreateAccount ? ( + + setScreenState(ScreenState.SigninOrCreateAccount) + } + /> + ) : undefined} + + ) }, ) const styles = StyleSheet.create({ + container: { + height: '100%', + }, outer: { flex: 1, }, diff --git a/src/view/screens/Settings.tsx b/src/view/screens/Settings.tsx index 22230f24..2c698268 100644 --- a/src/view/screens/Settings.tsx +++ b/src/view/screens/Settings.tsx @@ -1,5 +1,12 @@ import React, {useEffect} from 'react' -import {StyleSheet, TouchableOpacity, View} from 'react-native' +import { + ActivityIndicator, + ScrollView, + StyleSheet, + TouchableOpacity, + View, +} from 'react-native' +import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {observer} from 'mobx-react-lite' import {useStores} from '../../state' import {ScreenParams} from '../routes' @@ -7,8 +14,10 @@ import {s} from '../lib/styles' import {ViewHeader} from '../com/util/ViewHeader' import {Link} from '../com/util/Link' import {Text} from '../com/util/text/Text' +import * as Toast from '../com/util/Toast' import {UserAvatar} from '../com/util/UserAvatar' import {usePalette} from '../lib/hooks/usePalette' +import {AccountData} from '../../state/models/session' export const Settings = observer(function Settings({ navIdx, @@ -16,6 +25,7 @@ export const Settings = observer(function Settings({ }: ScreenParams) { const pal = usePalette('default') const store = useStores() + const [isSwitching, setIsSwitching] = React.useState(false) useEffect(() => { if (!visible) { @@ -25,45 +35,114 @@ export const Settings = observer(function Settings({ store.nav.setTitle(navIdx, 'Settings') }, [visible, store]) + const onPressSwitchAccount = async (acct: AccountData) => { + setIsSwitching(true) + if (await store.session.resumeSession(acct)) { + setIsSwitching(false) + Toast.show(`Signed in as ${acct.displayName || acct.handle}`) + return + } + setIsSwitching(false) + Toast.show('Sorry! We need you to enter your password.') + store.session.clear() + } + const onPressAddAccount = () => { + store.session.clear() + } const onPressSignout = () => { store.session.logout() } return ( - + - + - + Signed in as - + Sign out - + {isSwitching ? ( + + + ) : ( + + + + + + {store.me.displayName || store.me.handle} + + @{store.me.handle} + + + + )} + + Switch to: + + {store.session.switchableAccounts.map(account => ( + onPressSwitchAccount(account) + }> - {store.me.displayName || store.me.handle} + {account.displayName || account.handle} - @{store.me.handle} + @{account.handle} + + ))} + + + + + Add account + - - + + Developer tools @@ -80,12 +159,15 @@ export const Settings = observer(function Settings({ Storybook - + ) }) const styles = StyleSheet.create({ + dimmed: { + opacity: 0.5, + }, title: { fontSize: 32, fontWeight: 'bold', diff --git a/src/view/shell/mobile/Menu.tsx b/src/view/shell/mobile/Menu.tsx index 875bb5a3..26cb5b9b 100644 --- a/src/view/shell/mobile/Menu.tsx +++ b/src/view/shell/mobile/Menu.tsx @@ -62,7 +62,7 @@ export const Menu = observer( onPress?: () => void }) => ( onNavigate(url || '/')}> diff --git a/src/view/shell/mobile/index.tsx b/src/view/shell/mobile/index.tsx index c4ca7b9f..b999d05d 100644 --- a/src/view/shell/mobile/index.tsx +++ b/src/view/shell/mobile/index.tsx @@ -5,7 +5,6 @@ import { Easing, FlatList, GestureResponderEvent, - SafeAreaView, StatusBar, StyleSheet, TouchableOpacity, @@ -16,7 +15,6 @@ import { ViewStyle, } from 'react-native' import {ScreenContainer, Screen} from 'react-native-screens' -import LinearGradient from 'react-native-linear-gradient' import {useSafeAreaInsets} from 'react-native-safe-area-context' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {IconProp} from '@fortawesome/fontawesome-svg-core' @@ -34,7 +32,7 @@ import {Text} from '../../com/util/text/Text' import {ErrorBoundary} from '../../com/util/ErrorBoundary' import {TabsSelector} from './TabsSelector' import {Composer} from './Composer' -import {s, colors} from '../../lib/styles' +import {colors} from '../../lib/styles' import {clamp} from '../../../lib/numbers' import { GridIcon, @@ -323,18 +321,10 @@ export const MobileShell: React.FC = observer(() => { if (!store.session.hasSession) { return ( - - - - - - + + - + ) } if (store.onboard.isOnboarding) { diff --git a/yarn.lock b/yarn.lock index 69897fc4..8fc9492a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -27,6 +27,55 @@ "@atproto/xrpc" "*" typed-emitter "^2.1.0" +"@atproto/auth@*": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@atproto/auth/-/auth-0.0.1.tgz#0ae07bfb6e4e86605504a20f0302e448ba3f8b0e" + integrity sha512-eom7V/LmXttlFE31TcOJ0BInTszkm5ZBS2mqoLqbnA5ZTcTsgQsMKhGzARFf2zwBM9h8pbVa1XMI83gnrTHfxA== + dependencies: + "@atproto/crypto" "*" + "@atproto/did-resolver" "*" + "@ucans/core" "0.11.0" + uint8arrays "3.0.0" + +"@atproto/common@*": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@atproto/common/-/common-0.0.1.tgz#228a5d19574113ad69888fd1c617fe56f8b301ac" + integrity sha512-SdFoMx5Rdx7iUke3tCe7oiRUpTJXbTFgRJafYWehw/3dY2pFcUu4fK1z2CG0VbmyFUzR0J6TejScFpaYcP03uw== + dependencies: + "@ipld/dag-cbor" "^7.0.3" + multiformats "^9.6.4" + pino "^8.6.1" + zod "^3.14.2" + +"@atproto/crypto@*": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@atproto/crypto/-/crypto-0.0.1.tgz#2eb3528f895336ce58326393d458370125a10bf7" + integrity sha512-+Wb6xfEXn+14FyKlUkkKobN0hQwcaT4h4rqW2WeWbaYvsYuhMPzMrt8UsXzQ17cy9gYfu6FqR3C4fAiWgSdBZA== + dependencies: + "@noble/secp256k1" "^1.7.0" + "@ucans/core" "0.11.0" + big-integer "^1.6.51" + multiformats "^9.6.4" + one-webcrypto "^1.0.3" + uint8arrays "3.0.0" + +"@atproto/did-resolver@*": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@atproto/did-resolver/-/did-resolver-0.0.1.tgz#e54c1b7fddff2cd6adf87c044b4a3b6f00d5eff7" + integrity sha512-sdva3+nydMaWXwHJED558UZdVZuajfC2CHcsIZz0pQybicm3VI+khkf42ClZeOhf4Bwa4V4SOaaAqwyf86bDew== + dependencies: + "@atproto/common" "*" + "@atproto/crypto" "*" + axios "^0.24.0" + did-resolver "^4.0.0" + +"@atproto/handle@*": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@atproto/handle/-/handle-0.0.1.tgz#783f88aaef1f57920deb61da8d72e5191cd9d515" + integrity sha512-foWqpzyVufo6/LxHeqBqoz9KhoLIGpIQ3zqYXlJWX4YD6OlFq3RfrGYbJrqHIiHhe1xgm6GIgEax8V6QIEbATA== + dependencies: + "@sideway/address" "^5.0.0" + "@atproto/lexicon@*", "@atproto/lexicon@^0.0.4": version "0.0.4" resolved "https://registry.yarnpkg.com/@atproto/lexicon/-/lexicon-0.0.4.tgz#f0a6688ad54adb2ec4a8d1f11fcbf45e96203c4b" @@ -41,6 +90,97 @@ resolved "https://registry.yarnpkg.com/@atproto/nsid/-/nsid-0.0.1.tgz#0cdc00cefe8f0b1385f352b9f57b3ad37fff09a4" integrity sha512-t5M6/CzWBVYoBbIvfKDpqPj/+ZmyoK9ydZSStcTXosJ27XXwOPhz0VDUGKK2SM9G5Y7TPes8S5KTAU0UdVYFCw== +"@atproto/pds@^0.0.1": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@atproto/pds/-/pds-0.0.1.tgz#4492595cd0796a3dc4c10836cd121bb3b132f858" + integrity sha512-8CaAIBzri05CN2gkMtXnUlNxCdUwaWp1qz4b9RXpMQ83Pk1+j3nw09fsml0kjlMCPcWokTF+iGJXrrTL3XVjOw== + dependencies: + "@atproto/auth" "*" + "@atproto/common" "*" + "@atproto/crypto" "*" + "@atproto/did-resolver" "*" + "@atproto/handle" "*" + "@atproto/lexicon" "*" + "@atproto/plc" "*" + "@atproto/repo" "*" + "@atproto/uri" "*" + "@atproto/xrpc-server" "*" + better-sqlite3 "^7.6.2" + bytes "^3.1.2" + cors "^2.8.5" + dotenv "^16.0.0" + express "^4.17.2" + express-async-errors "^3.1.1" + file-type "^16.5.4" + handlebars "^4.7.7" + http-errors "^2.0.0" + http-terminator "^3.2.0" + jsonwebtoken "^8.5.1" + kysely "^0.22.0" + multiformats "^9.6.4" + nodemailer "^6.8.0" + nodemailer-html-to-text "^3.2.0" + p-queue "^6.6.2" + pg "^8.8.0" + pino "^8.6.1" + pino-http "^8.2.1" + sharp "^0.31.2" + uint8arrays "3.0.0" + +"@atproto/plc@*": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@atproto/plc/-/plc-0.0.1.tgz#713de881fd2b803a0f1afbee57735de8382a8ed3" + integrity sha512-9JM027ioAb6rG+2F/p89DJlIXBOH85rGWXFcG3dImZJ8SalFqRZ0/7gtdFN387IZ/HNAWRmmFaAxMEmJ9NgKpQ== + dependencies: + "@atproto/common" "*" + "@atproto/crypto" "*" + "@ipld/dag-cbor" "^7.0.3" + async-mutex "^0.4.0" + axios "^0.27.2" + better-sqlite3 "^7.6.2" + cors "^2.8.5" + dotenv "^16.0.2" + express "^4.17.2" + express-async-errors "^3.1.1" + http-terminator "^3.2.0" + kysely "^0.22.0" + pg "^8.8.0" + pino "^8.6.1" + pino-http "^8.2.1" + uint8arrays "3.0.0" + zod "^3.14.2" + +"@atproto/repo@*": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@atproto/repo/-/repo-0.0.1.tgz#41c63943a7e6a0942fc3e721c05d8c836c2fcfc2" + integrity sha512-tBZjaeaRL7fJynZCA5F+ZjRQuf5fpL7Cj5VqP6KtXYacuNP/LufwrHARSOwxJMMZpPOoWmwv4R8bETiQozehEA== + dependencies: + "@atproto/auth" "*" + "@atproto/common" "*" + "@atproto/nsid" "*" + "@ipld/car" "^3.2.3" + "@ipld/dag-cbor" "^7.0.0" + multiformats "^9.6.4" + uint8arrays "3.0.0" + zod "^3.14.2" + +"@atproto/uri@*": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@atproto/uri/-/uri-0.0.1.tgz#bfab68eda17ec987647f10d102168d417bc8a326" + integrity sha512-Tm+20Bxdie+a4yvberrfWaDhrze/p3AvA5v5IV6XyZJYu2+fnionUrufUjkcs3PIWeSd6VMgVcRp3GaoiUvSvQ== + +"@atproto/xrpc-server@*": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@atproto/xrpc-server/-/xrpc-server-0.0.1.tgz#62891d8e24b0813a7006d8ba947716b7c69e5667" + integrity sha512-W9pb9k9wgDlZdDF3eIDMXhEs1trg3zSRd70f1BfN22h+Or4wsoq5dAxXg6q9os3+DNkVkD9BWeRwVppCF6FxGg== + dependencies: + "@atproto/common" "*" + "@atproto/lexicon" "*" + express "^4.17.2" + http-errors "^2.0.0" + mime-types "^2.1.35" + zod "^3.14.2" + "@atproto/xrpc@*", "@atproto/xrpc@^0.0.3": version "0.0.3" resolved "https://registry.yarnpkg.com/@atproto/xrpc/-/xrpc-0.0.3.tgz#510028753d51dffd754ee4f96897b74bcba50bda" @@ -1387,6 +1527,11 @@ dependencies: nanoid "^3.3.1" +"@hapi/hoek@^10.0.0": + version "10.0.1" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-10.0.1.tgz#ee9da297fabc557e1c040a0f44ee89c266ccc306" + integrity sha512-CvlW7jmOhWzuqOqiJQ3rQVLMcREh0eel4IBnxDx2FAcK8g7qoJRQK4L1CPBASoCY6y8e6zuCy3f2g+HWdkzcMw== + "@hapi/hoek@^9.0.0": version "9.3.0" resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" @@ -1418,6 +1563,23 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@ipld/car@^3.2.3": + version "3.2.4" + resolved "https://registry.yarnpkg.com/@ipld/car/-/car-3.2.4.tgz#115951ba2255ec51d865773a074e422c169fb01c" + integrity sha512-rezKd+jk8AsTGOoJKqzfjLJ3WVft7NZNH95f0pfPbicROvzTyvHCNy567HzSUd6gRXZ9im29z5ZEv9Hw49jSYw== + dependencies: + "@ipld/dag-cbor" "^7.0.0" + multiformats "^9.5.4" + varint "^6.0.0" + +"@ipld/dag-cbor@^7.0.0", "@ipld/dag-cbor@^7.0.3": + version "7.0.3" + resolved "https://registry.yarnpkg.com/@ipld/dag-cbor/-/dag-cbor-7.0.3.tgz#aa31b28afb11a807c3d627828a344e5521ac4a1e" + integrity sha512-1VVh2huHsuohdXC1bGJNE8WR72slZ9XE2T3wbBBq31dm7ZBatmKLLxrB+XAqafxfRFjv08RZmj/W/ZqaM13AuA== + dependencies: + cborg "^1.6.0" + multiformats "^9.5.4" + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -1921,6 +2083,11 @@ dependencies: eslint-scope "5.1.1" +"@noble/secp256k1@^1.7.0": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" + integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -2250,6 +2417,13 @@ dependencies: "@hapi/hoek" "^9.0.0" +"@sideway/address@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@sideway/address/-/address-5.0.0.tgz#015f191a4a29e2b2f9ad1aabe7465c3088241536" + integrity sha512-IEZ3Gi972M1yubSPhcpzpVTT/Vb46F9L0W+K/GhqvWv6aAvVbNNVsYFekXWEemHHFfTVrxFcURrzsPGPPKkxKQ== + dependencies: + "@hapi/hoek" "^10.0.0" + "@sideway/formula@^3.0.0": version "3.0.1" resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.1.tgz#80fcbcbaf7ce031e0ef2dd29b1bfc7c3f583611f" @@ -2417,6 +2591,11 @@ dependencies: pretty-format "^29.0.0" +"@tokenizer/token@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" + integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== + "@tootallnate/once@1": version "1.1.2" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" @@ -2960,6 +3139,13 @@ "@typescript-eslint/types" "5.48.2" eslint-visitor-keys "^3.3.0" +"@ucans/core@0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@ucans/core/-/core-0.11.0.tgz#8201680294d980f2b1f5edfaf77b42a86d3a5688" + integrity sha512-SHX67e313kKBaur5Cp+6WFeOLC7aBhkf1i1jIFpFb9f0f1cvM/lC3mjzOyUBeDg3QwmcN5QSZzaogVFvuVvzvg== + dependencies: + uint8arrays "3.0.0" + "@webassemblyjs/ast@1.11.1": version "1.11.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" @@ -3202,7 +3388,7 @@ ajv-keywords@^5.0.0: dependencies: fast-deep-equal "^3.1.3" -ajv@^6.10.0, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: +ajv@^6.10.0, ajv@^6.11.0, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -3445,6 +3631,13 @@ async-limiter@~1.0.0: resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== +async-mutex@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.4.0.tgz#ae8048cd4d04ace94347507504b3cf15e631c25f" + integrity sha512-eJFZ1YhRR8UN8eBLoNzcDPcy/jqjsg6I1AP+KvWQX80BqOSW1oJPJXDylPUEeMr2ZQvHgnQ//Lp6f3RQ1zI7HA== + dependencies: + tslib "^2.4.0" + async@^3.2.2, async@^3.2.3: version "3.2.4" resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" @@ -3465,6 +3658,11 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== +atomic-sleep@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" + integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== + autoprefixer@^10.4.13: version "10.4.13" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.13.tgz#b5136b59930209a321e9fa3dca2e7c4d223e83a8" @@ -3482,6 +3680,21 @@ axe-core@^4.4.3: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.6.1.tgz#79cccdee3e3ab61a8f42c458d4123a6768e6fbce" integrity sha512-lCZN5XRuOnpG4bpMq8v0khrWtUOn+i8lZSb6wHZH56ZfbIEv6XwJV84AAueh9/zi7qPVJ/E4yz6fmsiyOmXR4w== +axios@^0.24.0: + version "0.24.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6" + integrity sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA== + dependencies: + follow-redirects "^1.14.4" + +axios@^0.27.2: + version "0.27.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" + integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== + dependencies: + follow-redirects "^1.14.9" + form-data "^4.0.0" + axobject-query@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" @@ -3735,6 +3948,14 @@ batch@0.6.1: resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== +better-sqlite3@^7.6.2: + version "7.6.2" + resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-7.6.2.tgz#47cd8cad5b9573cace535f950ac321166bc31384" + integrity sha512-S5zIU1Hink2AH4xPsN0W43T1/AJ5jrPh7Oy07ocuW/AKYYY02GWzz9NH0nbSMn/gw6fDZ5jZ1QsHt1BXAwJ6Lg== + dependencies: + bindings "^1.5.0" + prebuild-install "^7.1.0" + bfj@^7.0.2: version "7.0.2" resolved "https://registry.yarnpkg.com/bfj/-/bfj-7.0.2.tgz#1988ce76f3add9ac2913fd8ba47aad9e651bfbb2" @@ -3745,6 +3966,11 @@ bfj@^7.0.2: hoopy "^0.1.4" tryer "^1.0.1" +big-integer@^1.6.51: + version "1.6.51" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" + integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== + big.js@^5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" @@ -3755,7 +3981,14 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -bl@^4.1.0: +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bl@^4.0.3, bl@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== @@ -3802,6 +4035,11 @@ boolbase@^1.0.0, boolbase@~1.0.0: resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== +boolean@^3.1.4: + version "3.2.0" + resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.2.0.tgz#9e5294af4e98314494cbb17979fa54ca159f116b" + integrity sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -3862,11 +4100,21 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== + buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== +buffer-writer@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04" + integrity sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw== + buffer@^5.4.3, buffer@^5.5.0: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" @@ -3875,6 +4123,14 @@ buffer@^5.4.3, buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + builtin-modules@^3.1.0: version "3.3.0" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" @@ -3885,7 +4141,7 @@ bytes@3.0.0: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== -bytes@3.1.2: +bytes@3.1.2, bytes@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== @@ -3980,6 +4236,11 @@ case-sensitive-paths-webpack-plugin@^2.4.0: resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4" integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw== +cborg@^1.6.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/cborg/-/cborg-1.10.0.tgz#0fe157961dd47b537ccb84dc9ba681de8b699013" + integrity sha512-/eM0JCaL99HDHxjySNQJLaolZFVdl6VA0/hEKIoiQPcQzE5LrG5QHdml0HaBt31brgB9dNe1zMr3f8IVrpotRQ== + chalk@^2.0.0, chalk@^2.4.1: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -4027,6 +4288,11 @@ chokidar@^3.4.2, chokidar@^3.5.3: optionalDependencies: fsevents "~2.3.2" +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + chrome-trace-event@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" @@ -4163,11 +4429,27 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== -color-name@^1.1.4, color-name@~1.1.4: +color-name@^1.0.0, color-name@^1.1.4, color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-string@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4" + integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/color/-/color-4.2.3.tgz#d781ecb5e57224ee43ea9627560107c0e0c6463a" + integrity sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A== + dependencies: + color-convert "^2.0.1" + color-string "^1.9.0" + colord@^2.9.1: version "2.9.3" resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43" @@ -4344,6 +4626,14 @@ core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== +cors@^2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + cosmiconfig@^5.0.5, cosmiconfig@^5.1.0: version "5.2.1" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" @@ -4679,11 +4969,23 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + deep-is@^0.1.3, deep-is@~0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" @@ -4753,6 +5055,11 @@ defined@^1.0.0: resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.1.tgz#c0b9db27bfaffd95d6f61399419b893df0f91ebf" integrity sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q== +delay@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d" + integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw== + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -4796,6 +5103,11 @@ destroy@1.2.0: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== +detect-libc@^2.0.0, detect-libc@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd" + integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w== + detect-newline@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" @@ -4823,6 +5135,11 @@ detective@^5.2.1: defined "^1.0.0" minimist "^1.2.6" +did-resolver@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/did-resolver/-/did-resolver-4.0.1.tgz#11bb3f19ed1c8f53f4af4702912fa9f7852fc305" + integrity sha512-eHs2VLKhcANmh08S87PKvOauIAmSOd7nb7AlhNxcvOyDAIGQY1UfbiqI1VOW5IDKvOO6aEWY+5edOt1qrCp1Eg== + didyoumean@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" @@ -4989,7 +5306,7 @@ dotenv@^10.0.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== -dotenv@^16.0.3: +dotenv@^16.0.0, dotenv@^16.0.2, dotenv@^16.0.3: version "16.0.3" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== @@ -4999,6 +5316,13 @@ duplexer@^0.1.2: resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== +ecdsa-sig-formatter@1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" + integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== + dependencies: + safe-buffer "^5.0.1" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -5056,7 +5380,7 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -end-of-stream@^1.1.0: +end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== @@ -5584,12 +5908,12 @@ event-target-shim@^5.0.0, event-target-shim@^5.0.1: resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== -eventemitter3@^4.0.0: +eventemitter3@^4.0.0, eventemitter3@^4.0.4: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== -events@^3.2.0: +events@^3.2.0, events@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== @@ -5640,6 +5964,11 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + expect@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/expect/-/expect-27.5.1.tgz#83ce59f1e5bdf5f9d2b94b61d2050db48f3fef74" @@ -5661,7 +5990,12 @@ expect@^29.3.1: jest-message-util "^29.3.1" jest-util "^29.3.1" -express@^4.17.3: +express-async-errors@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/express-async-errors/-/express-async-errors-3.1.1.tgz#6053236d61d21ddef4892d6bd1d736889fc9da41" + integrity sha512-h6aK1da4tpqWSbyCa3FxB/V6Ehd4EEB15zyQq9qe75OZBp0krinNKuH4rAY+S/U/2I36vdLAUFSjQJ+TFmODng== + +express@^4.17.2, express@^4.17.3: version "4.18.2" resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== @@ -5753,6 +6087,16 @@ fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== +fast-json-stringify@^2.7.10: + version "2.7.13" + resolved "https://registry.yarnpkg.com/fast-json-stringify/-/fast-json-stringify-2.7.13.tgz#277aa86c2acba4d9851bd6108ed657aa327ed8c0" + integrity sha512-ar+hQ4+OIurUGjSJD1anvYSDcUflywhKjfxnsW4TBTD7+u0tJufv6DKRWoQk3vI6YBOWMoz0TQtfbe7dxbQmvA== + dependencies: + ajv "^6.11.0" + deepmerge "^4.2.2" + rfdc "^1.2.0" + string-similarity "^4.0.1" + fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" @@ -5763,6 +6107,25 @@ fast-loops@^1.1.3: resolved "https://registry.yarnpkg.com/fast-loops/-/fast-loops-1.1.3.tgz#ce96adb86d07e7bf9b4822ab9c6fac9964981f75" integrity sha512-8EZzEP0eKkEEVX+drtd9mtuQ+/QrlfW/5MlwcwK5Nds6EkZ/tRzEexkzUY2mIssnAyVLT+TKHuRXmFNNXYUd6g== +fast-printf@^1.6.9: + version "1.6.9" + resolved "https://registry.yarnpkg.com/fast-printf/-/fast-printf-1.6.9.tgz#212f56570d2dc8ccdd057ee93d50dd414d07d676" + integrity sha512-FChq8hbz65WMj4rstcQsFB0O7Cy++nmbNfLYnD9cYv2cRn8EG6k/MGn9kO/tjO66t09DLDugj3yL+V2o6Qftrg== + dependencies: + boolean "^3.1.4" + +fast-redact@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.1.2.tgz#d58e69e9084ce9fa4c1a6fa98a3e1ecf5d7839aa" + integrity sha512-+0em+Iya9fKGfEQGcd62Yv6onjBmmhV1uh86XVfOU8VwAe6kaFdQCWI9s0/Nnugx5Vd9tdbZ7e6gE2tR9dzXdw== + +fast-url-parser@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/fast-url-parser/-/fast-url-parser-1.1.3.tgz#f4af3ea9f34d8a271cf58ad2b3759f431f0b318d" + integrity sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ== + dependencies: + punycode "^1.3.2" + fastq@^1.6.0: version "1.15.0" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" @@ -5817,6 +6180,20 @@ file-loader@^6.2.0: loader-utils "^2.0.0" schema-utils "^3.0.0" +file-type@^16.5.4: + version "16.5.4" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-16.5.4.tgz#474fb4f704bee427681f98dd390058a172a6c2fd" + integrity sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw== + dependencies: + readable-web-to-node-stream "^3.0.0" + strtok3 "^6.2.4" + token-types "^4.1.1" + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + filelist@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" @@ -5936,7 +6313,7 @@ flow-parser@^0.185.0: resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.185.2.tgz#cb7ee57f77377d6c5d69a469e980f6332a15e492" integrity sha512-2hJ5ACYeJCzNtiVULov6pljKOLygy0zddoqSI1fFetM+XRPpRshFdGEijtqlamA1XwyZ+7rhryI6FQFzvtLWUQ== -follow-redirects@^1.0.0: +follow-redirects@^1.0.0, follow-redirects@^1.14.4, follow-redirects@^1.14.9: version "1.15.2" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== @@ -5974,6 +6351,15 @@ form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + forwarded@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" @@ -5996,6 +6382,11 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + fs-extra@^10.0.0: version "10.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" @@ -6113,6 +6504,11 @@ get-value@^2.0.3, get-value@^2.0.6: resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== + glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -6184,6 +6580,13 @@ globals@^13.19.0: dependencies: type-fest "^0.20.2" +globalthis@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" + integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== + dependencies: + define-properties "^1.1.3" + globby@^11.0.4, globby@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" @@ -6225,6 +6628,18 @@ handle-thing@^2.0.0: resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== +handlebars@^4.7.7: + version "4.7.7" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" + integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== + dependencies: + minimist "^1.2.5" + neo-async "^2.6.0" + source-map "^0.6.1" + wordwrap "^1.0.0" + optionalDependencies: + uglify-js "^3.1.4" + harmony-reflect@^1.4.6: version "1.6.2" resolved "https://registry.yarnpkg.com/harmony-reflect/-/harmony-reflect-1.6.2.tgz#31ecbd32e648a34d030d86adb67d4d47547fe710" @@ -6378,6 +6793,16 @@ html-minifier-terser@^6.0.2: relateurl "^0.2.7" terser "^5.10.0" +html-to-text@7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/html-to-text/-/html-to-text-7.1.1.tgz#69de8d85b91646b4bc14fdf4f850e9e046efff15" + integrity sha512-c9QWysrfnRZevVpS8MlE7PyOdSuIOjg8Bt8ZE10jMU/BEngA6j3llj4GRfAmtQzcd1FjKE0sWu5IHXRUH9YxIQ== + dependencies: + deepmerge "^4.2.2" + he "^1.2.0" + htmlparser2 "^6.1.0" + minimist "^1.2.5" + html-webpack-plugin@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz#c3911936f57681c1f9f4d8b68c158cd9dfe52f50" @@ -6404,7 +6829,7 @@ http-deceiver@^1.2.7: resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== -http-errors@2.0.0: +http-errors@2.0.0, http-errors@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== @@ -6459,6 +6884,16 @@ http-proxy@^1.18.1: follow-redirects "^1.0.0" requires-port "^1.0.0" +http-terminator@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/http-terminator/-/http-terminator-3.2.0.tgz#bc158d2694b733ca4fbf22a35065a81a609fb3e9" + integrity sha512-JLjck1EzPaWjsmIf8bziM3p9fgR1Y3JoUKAkyYEbZmFrIvJM6I8vVJfBGWlEtV9IWOvzNnaTtjuwZeBY2kwB4g== + dependencies: + delay "^5.0.0" + p-wait-for "^3.2.0" + roarr "^7.0.4" + type-fest "^2.3.3" + https-proxy-agent@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" @@ -6513,7 +6948,7 @@ identity-obj-proxy@^3.0.0: dependencies: harmony-reflect "^1.4.6" -ieee754@^1.1.13: +ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -6585,7 +7020,7 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== -ini@^1.3.5: +ini@^1.3.5, ini@~1.3.0: version "1.3.8" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== @@ -6648,6 +7083,11 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + is-bigint@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" @@ -8050,6 +8490,22 @@ jsonpointer@^5.0.0: resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.1.tgz#2110e0af0900fd37467b5907ecd13a7884a1b559" integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== +jsonwebtoken@^8.5.1: + version "8.5.1" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" + integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w== + dependencies: + jws "^3.2.2" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + semver "^5.6.0" + "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.2: version "3.3.3" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz#76b3e6e6cece5c69d49a5792c3d01bd1a0cdc7ea" @@ -8058,6 +8514,23 @@ jsonpointer@^5.0.0: array-includes "^3.1.5" object.assign "^4.1.3" +jwa@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" + integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jws@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" + integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== + dependencies: + jwa "^1.4.1" + safe-buffer "^5.0.1" + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -8092,6 +8565,11 @@ klona@^2.0.4, klona@^2.0.5: resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.5.tgz#d166574d90076395d9963aa7a928fabb8d76afbc" integrity sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ== +kysely@^0.22.0: + version "0.22.0" + resolved "https://registry.yarnpkg.com/kysely/-/kysely-0.22.0.tgz#8aac53942da3cadc604d7d154a746d983fe8f7b9" + integrity sha512-ZE3qWtnqLOalodzfK5QUEcm7AEulhxsPNuKaGFsC3XiqO92vMLm+mAHk/NnbSIOtC4RmGm0nsv700i8KDp1gfQ== + language-subtag-registry@^0.3.20: version "0.3.22" resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" @@ -8186,11 +8664,41 @@ lodash.debounce@^4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== + lodash.isequal@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw== + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== + lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" @@ -8206,6 +8714,11 @@ lodash.omit@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60" integrity sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg== +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== + lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" @@ -8781,7 +9294,7 @@ mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: +mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@^2.1.35, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -8803,6 +9316,11 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + min-indent@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" @@ -8834,7 +9352,7 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" -minimist@^1.2.0, minimist@^1.2.6: +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6: version "1.2.7" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== @@ -8847,6 +9365,11 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" +mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + mkdirp@^0.5.1, mkdirp@~0.5.1: version "0.5.6" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" @@ -8892,6 +9415,11 @@ multicast-dns@^7.2.5: dns-packet "^5.2.2" thunky "^1.0.2" +multiformats@^9.4.2, multiformats@^9.5.4, multiformats@^9.6.4: + version "9.9.0" + resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-9.9.0.tgz#c68354e7d21037a8f1f8833c8ccd68618e8f1d37" + integrity sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg== + nanoid@^3.3.1, nanoid@^3.3.4: version "3.3.4" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" @@ -8914,6 +9442,11 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" +napi-build-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" + integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + natural-compare-lite@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" @@ -8929,7 +9462,7 @@ negotiator@0.6.3: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== -neo-async@^2.5.0, neo-async@^2.6.2: +neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== @@ -8952,6 +9485,18 @@ nocache@^3.0.1: resolved "https://registry.yarnpkg.com/nocache/-/nocache-3.0.4.tgz#5b37a56ec6e09fc7d401dceaed2eab40c8bfdf79" integrity sha512-WDD0bdg9mbq6F4mRxEYcPWwfA1vxd0mrvKOyxI7Xj/atfRHVeutzuWByG//jfm4uPzp0y4Kj051EORCBSQMycw== +node-abi@^3.3.0: + version "3.31.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.31.0.tgz#dfb2ea3d01188eb80859f69bb4a4354090c1b355" + integrity sha512-eSKV6s+APenqVh8ubJyiu/YhZgxQpGP66ntzUb3lY1xB9ukSRaGnx0AIxI+IM+1+IVYC1oWobgG5L3Lt9ARykQ== + dependencies: + semver "^7.3.5" + +node-addon-api@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-5.1.0.tgz#49da1ca055e109a23d537e9de43c09cca21eb762" + integrity sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA== + node-dir@^0.1.17: version "0.1.17" resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5" @@ -8986,6 +9531,18 @@ node-stream-zip@^1.9.1: resolved "https://registry.yarnpkg.com/node-stream-zip/-/node-stream-zip-1.15.0.tgz#158adb88ed8004c6c49a396b50a6a5de3bca33ea" integrity sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw== +nodemailer-html-to-text@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/nodemailer-html-to-text/-/nodemailer-html-to-text-3.2.0.tgz#91b959491fef8f7d91796047abb728aa86d4a12b" + integrity sha512-RJUC6640QV1PzTHHapOrc6IzrAJUZtk2BdVdINZ9VTLm+mcQNyBO9LYyhrnufkzqiD9l8hPLJ97rSyK4WanPNg== + dependencies: + html-to-text "7.1.1" + +nodemailer@^6.8.0: + version "6.9.0" + resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.9.0.tgz#a17488ff470ff9edf1bb31d9ec23079bc94f7dd3" + integrity sha512-jFaCEGTeT3E/m/5R2MHWiyQH3pSARECRUDM+1hokOYc3lQAAG7ASuy+2jIsYVf+RVa9zePopSQwKNVFH8DKUpA== + normalize-css-color@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/normalize-css-color/-/normalize-css-color-1.0.2.tgz#02991e97cccec6623fe573afbbf0de6a1f3e9f8d" @@ -9054,7 +9611,7 @@ ob1@0.73.7: resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.73.7.tgz#14c9b6ddc26cf99144f59eb542d7ae956e6b3192" integrity sha512-DfelfvR843KADhSUATGGhuepVMRcf5VQX+6MQLy5AW0BKDLlO7Usj6YZeAAZP7P86QwsoTxB0RXCFiA7t6S1IQ== -object-assign@^4.1.0, object-assign@^4.1.1: +object-assign@^4, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== @@ -9157,6 +9714,11 @@ obuf@^1.0.0, obuf@^1.1.2: resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== +on-exit-leak-free@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz#5c703c968f7e7f851885f6459bf8a8a57edc9cc4" + integrity sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w== + on-finished@2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" @@ -9183,6 +9745,11 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" +one-webcrypto@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/one-webcrypto/-/one-webcrypto-1.0.3.tgz#f951243cde29b79b6745ad14966fc598a609997c" + integrity sha512-fu9ywBVBPx0gS9K0etIROTiCkvI5S1TDjFsYFb3rC1ewFxeOqsbzq7aIMBHsYfrTHBcGXJaONXXjTl8B01cW1Q== + onetime@^5.1.0, onetime@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" @@ -9295,6 +9862,14 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" +p-queue@^6.6.2: + version "6.6.2" + resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-6.6.2.tgz#2068a9dcf8e67dd0ec3e7a2bcb76810faa85e426" + integrity sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ== + dependencies: + eventemitter3 "^4.0.4" + p-timeout "^3.2.0" + p-retry@^4.5.0: version "4.6.2" resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" @@ -9303,11 +9878,30 @@ p-retry@^4.5.0: "@types/retry" "0.12.0" retry "^0.13.1" +p-timeout@^3.0.0, p-timeout@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" + integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== + dependencies: + p-finally "^1.0.0" + p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +p-wait-for@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/p-wait-for/-/p-wait-for-3.2.0.tgz#640429bcabf3b0dd9f492c31539c5718cb6a3f1f" + integrity sha512-wpgERjNkLrBiFmkMEjuZJEWKKDrNfHCKA1OhyN1wg1FrLkULbviEy6py1AyJUgZ72YWFbZ38FIpnqvVqAlDUwA== + dependencies: + p-timeout "^3.0.0" + +packet-reader@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-1.0.0.tgz#9238e5480dedabacfe1fe3f2771063f164157d74" + integrity sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ== + param-case@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" @@ -9404,11 +9998,67 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +peek-readable@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.1.0.tgz#4ece1111bf5c2ad8867c314c81356847e8a62e72" + integrity sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg== + performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== +pg-connection-string@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.5.0.tgz#538cadd0f7e603fc09a12590f3b8a452c2c0cf34" + integrity sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ== + +pg-int8@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" + integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw== + +pg-pool@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.5.2.tgz#ed1bed1fb8d79f1c6fd5fb1c99e990fbf9ddf178" + integrity sha512-His3Fh17Z4eg7oANLob6ZvH8xIVen3phEZh2QuyrIl4dQSDVEabNducv6ysROKpDNPSD+12tONZVWfSgMvDD9w== + +pg-protocol@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.5.0.tgz#b5dd452257314565e2d54ab3c132adc46565a6a0" + integrity sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ== + +pg-types@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3" + integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA== + dependencies: + pg-int8 "1.0.1" + postgres-array "~2.0.0" + postgres-bytea "~1.0.0" + postgres-date "~1.0.4" + postgres-interval "^1.1.0" + +pg@^8.8.0: + version "8.8.0" + resolved "https://registry.yarnpkg.com/pg/-/pg-8.8.0.tgz#a77f41f9d9ede7009abfca54667c775a240da686" + integrity sha512-UXYN0ziKj+AeNNP7VDMwrehpACThH7LUl/p8TDFpEUuSejCUIwGSfxpHsPvtM6/WXFy6SU4E5RG4IJV/TZAGjw== + dependencies: + buffer-writer "2.0.0" + packet-reader "1.0.0" + pg-connection-string "^2.5.0" + pg-pool "^3.5.2" + pg-protocol "^1.5.0" + pg-types "^2.1.0" + pgpass "1.x" + +pgpass@1.x: + version "1.0.5" + resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.5.tgz#9b873e4a564bb10fa7a7dbd55312728d422a223d" + integrity sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug== + dependencies: + split2 "^4.1.0" + picocolors@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" @@ -9434,6 +10084,47 @@ pify@^4.0.1: resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== +pino-abstract-transport@v1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-1.0.0.tgz#cc0d6955fffcadb91b7b49ef220a6cc111d48bb3" + integrity sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA== + dependencies: + readable-stream "^4.0.0" + split2 "^4.0.0" + +pino-http@^8.2.1: + version "8.3.1" + resolved "https://registry.yarnpkg.com/pino-http/-/pino-http-8.3.1.tgz#d33ade22044ce6efa7b5ed512e1bd7afdf9904ba" + integrity sha512-wqQMH2H+Di4ur5gaCYvWOMYhGmmmygHsgJduKr2HASSoegNsxfxiCDGxYYV8muOB8jKDHPoBXKGp03af+JESqg== + dependencies: + fast-url-parser "^1.1.3" + get-caller-file "^2.0.5" + pino "^8.0.0" + pino-std-serializers "^6.0.0" + process-warning "^2.0.0" + +pino-std-serializers@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-6.1.0.tgz#307490fd426eefc95e06067e85d8558603e8e844" + integrity sha512-KO0m2f1HkrPe9S0ldjx7za9BJjeHqBku5Ch8JyxETxT8dEFGz1PwgrHaOQupVYitpzbFSYm7nnljxD8dik2c+g== + +pino@^8.0.0, pino@^8.6.1: + version "8.8.0" + resolved "https://registry.yarnpkg.com/pino/-/pino-8.8.0.tgz#1f0d6695a224aa06afc7ad60f2ccc4772d3b9233" + integrity sha512-cF8iGYeu2ODg2gIwgAHcPrtR63ILJz3f7gkogaHC/TXVVXxZgInmNYiIpDYEwgEkxZti2Se6P2W2DxlBIZe6eQ== + 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-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" + thread-stream "^2.0.0" + pirates@^4.0.4, pirates@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" @@ -10017,6 +10708,46 @@ postcss@^8.3.5, postcss@^8.4.18, postcss@^8.4.19, postcss@^8.4.4: picocolors "^1.0.0" source-map-js "^1.0.2" +postgres-array@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" + integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA== + +postgres-bytea@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35" + integrity sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w== + +postgres-date@~1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.7.tgz#51bc086006005e5061c591cee727f2531bf641a8" + integrity sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q== + +postgres-interval@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695" + integrity sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ== + dependencies: + xtend "^4.0.0" + +prebuild-install@^7.1.0, prebuild-install@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45" + integrity sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw== + dependencies: + detect-libc "^2.0.0" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^1.0.1" + node-abi "^3.3.0" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^4.0.0" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -10095,6 +10826,16 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +process-warning@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-2.1.0.tgz#1e60e3bfe8183033bbc1e702c2da74f099422d1a" + integrity sha512-9C20RLxrZU/rFnxWncDkuF6O999NdIf3E1ws4B0ZeY3sRVPzWBMsYDE2lxjxhiXxg464cQTgKUGm8/i6y2YGXg== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + promise@^7.1.1: version "7.3.1" resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" @@ -10147,6 +10888,11 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" +punycode@^1.3.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== + punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" @@ -10174,6 +10920,11 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +quick-format-unescaped@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz#93ef6dd8d3453cbc7970dd614fad4c5954d6b5a7" + integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg== + quick-lru@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" @@ -10208,6 +10959,16 @@ raw-body@2.5.1: iconv-lite "0.4.24" unpipe "1.0.0" +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + react-app-polyfill@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz#95221e0a9bd259e5ca6b177c7bb1cb6768f68fd7" @@ -10617,7 +11378,7 @@ readable-stream@^2.0.1, readable-stream@~2.3.6: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.0.6, readable-stream@^3.4.0: +readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -10626,6 +11387,23 @@ readable-stream@^3.0.6, readable-stream@^3.4.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" +readable-stream@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-4.3.0.tgz#0914d0c72db03b316c9733bb3461d64a3cc50cba" + integrity sha512-MuEnA0lbSi7JS8XM+WNJlWZkHAAdm7gETHdFK//Q/mChGyj2akEFtdLZh32jSdkWGbRwCW9pn6g3LWDdDeZnBQ== + dependencies: + abort-controller "^3.0.0" + buffer "^6.0.3" + events "^3.3.0" + process "^0.11.10" + +readable-web-to-node-stream@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz#5d52bb5df7b54861fd48d015e93a2cb87b3ee0bb" + integrity sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw== + dependencies: + readable-stream "^3.6.0" + readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -10638,6 +11416,11 @@ readline@^1.3.0: resolved "https://registry.yarnpkg.com/readline/-/readline-1.3.0.tgz#c580d77ef2cfc8752b132498060dc9793a7ac01c" integrity sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg== +real-require@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/real-require/-/real-require-0.2.0.tgz#209632dea1810be2ae063a6ac084fee7e33fba78" + integrity sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg== + recast@^0.20.4: version "0.20.5" resolved "https://registry.yarnpkg.com/recast/-/recast-0.20.5.tgz#8e2c6c96827a1b339c634dd232957d230553ceae" @@ -10868,6 +11651,11 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== +rfdc@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -10895,6 +11683,18 @@ rn-fetch-blob@^0.12.0: base-64 "0.1.0" glob "7.0.6" +roarr@^7.0.4: + version "7.14.2" + resolved "https://registry.yarnpkg.com/roarr/-/roarr-7.14.2.tgz#2d4865b9f06779901258f1a5a8f6b4315fc46f5f" + integrity sha512-9vC/n53oTJEyAl0ZJczKjJ5mJheb2DaqiaNSnxDWrqiRTrozxSvSq05yCTN+Fc7e5mhDRTTZ14RlMu1x4tEc0w== + dependencies: + boolean "^3.1.4" + fast-json-stringify "^2.7.10" + fast-printf "^1.6.9" + globalthis "^1.0.2" + safe-stable-stringify "^2.4.1" + semver-compare "^1.0.0" + rollup-plugin-terser@^7.0.0: version "7.0.2" resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz#e8fbba4869981b2dc35ae7e8a502d5c6c04d324d" @@ -10931,7 +11731,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -10952,6 +11752,11 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" +safe-stable-stringify@^2.3.1, safe-stable-stringify@^2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.2.tgz#ec7b037768098bf65310d1d64370de0dc02353aa" + integrity sha512-gMxvPJYhP0O9n2pvcfYfIuYgbledAOJFcqRThtPRmjscaipiwcwPPKLytpVzMkG2HAN87Qmo2d4PtGiri1dSLA== + "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -11046,6 +11851,11 @@ selfsigned@^2.1.1: dependencies: node-forge "^1" +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow== + semver@7.3.8, semver@^7.3.2, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8: version "7.3.8" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" @@ -11161,6 +11971,20 @@ shallow-clone@^3.0.0: dependencies: kind-of "^6.0.2" +sharp@^0.31.2: + version "0.31.3" + resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.31.3.tgz#60227edc5c2be90e7378a210466c99aefcf32688" + integrity sha512-XcR4+FCLBFKw1bdB+GEhnUNXNXvnt0tDo4WsBsraKymuo/IAuPuCBVAL2wIkUw2r/dwFW5Q5+g66Kwl2dgDFVg== + dependencies: + color "^4.2.3" + detect-libc "^2.0.1" + node-addon-api "^5.0.0" + prebuild-install "^7.1.1" + semver "^7.3.8" + simple-get "^4.0.1" + tar-fs "^2.1.1" + tunnel-agent "^0.6.0" + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -11204,6 +12028,27 @@ signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^4.0.0, simple-get@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" + integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== + dependencies: + decompress-response "^6.0.0" + once "^1.3.1" + simple-concat "^1.0.0" + +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg== + dependencies: + is-arrayish "^0.3.1" + sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -11267,6 +12112,13 @@ sockjs@^0.3.24: uuid "^8.3.2" websocket-driver "^0.7.4" +sonic-boom@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-3.2.1.tgz#972ceab831b5840a08a002fa95a672008bda1c38" + integrity sha512-iITeTHxy3B9FGu8aVdiDXUVAcHMF9Ss0cCsAOo2HfCrmVGT3/DT5oYaeu0M/YKZDlKTvChEyPq0zI9Hf33EX6A== + dependencies: + atomic-sleep "^1.0.0" + source-list-map@^2.0.0, source-list-map@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" @@ -11375,6 +12227,11 @@ split-string@^3.0.1, split-string@^3.0.2: dependencies: extend-shallow "^3.0.0" +split2@^4.0.0, split2@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-4.1.0.tgz#101907a24370f85bb782f08adaabe4e281ecf809" + integrity sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ== + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -11448,6 +12305,11 @@ string-natural-compare@^3.0.1: resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4" integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw== +string-similarity@^4.0.1: + version "4.0.4" + resolved "https://registry.yarnpkg.com/string-similarity/-/string-similarity-4.0.4.tgz#42d01ab0b34660ea8a018da8f56a3309bb8b2a5b" + integrity sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ== + string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" @@ -11570,6 +12432,19 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== + +strtok3@^6.2.4: + version "6.3.0" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.3.0.tgz#358b80ffe6d5d5620e19a073aa78ce947a90f9a0" + integrity sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw== + dependencies: + "@tokenizer/token" "^0.3.0" + peek-readable "^4.1.0" + style-loader@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575" @@ -11703,6 +12578,27 @@ tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== +tar-fs@^2.0.0, tar-fs@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + temp-dir@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e" @@ -11776,6 +12672,13 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== +thread-stream@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-2.3.0.tgz#4fc07fb39eff32ae7bad803cb7dd9598349fed33" + integrity sha512-kaDqm1DET9pp3NXwR8382WHbnpXnRkN9xGN9dQt3B2+dmXiW8X1SOwmFOxAErEQ47ObhZ96J6yhZNXuyCOL7KA== + dependencies: + real-require "^0.2.0" + throat@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" @@ -11851,6 +12754,14 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== +token-types@^4.1.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/token-types/-/token-types-4.2.1.tgz#0f897f03665846982806e138977dbe72d44df753" + integrity sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ== + dependencies: + "@tokenizer/token" "^0.3.0" + ieee754 "^1.2.1" + tough-cookie@^4.0.0: version "4.1.2" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874" @@ -11900,7 +12811,7 @@ tslib@^1.8.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0: +tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0: version "2.4.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== @@ -11912,6 +12823,13 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -11951,6 +12869,11 @@ type-fest@^0.7.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== +type-fest@^2.3.3: + version "2.19.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" + integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== + type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -11991,6 +12914,18 @@ uglify-es@^3.1.9: commander "~2.13.0" source-map "~0.6.1" +uglify-js@^3.1.4: + version "3.17.4" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" + integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== + +uint8arrays@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-3.0.0.tgz#260869efb8422418b6f04e3fac73a3908175c63b" + integrity sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA== + dependencies: + multiformats "^9.4.2" + unbox-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" @@ -12175,7 +13110,12 @@ v8-to-istanbul@^9.0.1: "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0" -vary@~1.1.2: +varint@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/varint/-/varint-6.0.0.tgz#9881eb0ce8feaea6512439d19ddf84bf551661d0" + integrity sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg== + +vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== @@ -12459,6 +13399,11 @@ word-wrap@^1.2.3, word-wrap@~1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== +wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== + workbox-background-sync@6.5.4: version "6.5.4" resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-6.5.4.tgz#3141afba3cc8aa2ae14c24d0f6811374ba8ff6a9" @@ -12710,7 +13655,7 @@ xmlchars@^2.2.0: resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== -xtend@^4.0.2, xtend@~4.0.1: +xtend@^4.0.0, xtend@^4.0.2, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== @@ -12806,7 +13751,7 @@ yocto-queue@^0.1.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== -zod@^3.14.2: +zod@^3.14.2, zod@^3.20.2: version "3.20.2" resolved "https://registry.yarnpkg.com/zod/-/zod-3.20.2.tgz#068606642c8f51b3333981f91c0a8ab37dfc2807" integrity sha512-1MzNQdAvO+54H+EaK5YpyEy0T+Ejo/7YLHS93G3RnYWh5gaotGHwGeN/ZO687qEDU2y4CdStQYXVHIgrUl5UVQ==