diff --git a/.github/workflows/lint-build-test.yaml b/.github/workflows/lint-build-test.yaml index e79c6bf6..2eb80568 100644 --- a/.github/workflows/lint-build-test.yaml +++ b/.github/workflows/lint-build-test.yaml @@ -31,5 +31,8 @@ jobs: - name: Lint run: yarn run lint + - name: Test + run: yarn run test + - name: Build run: yarn run build diff --git a/package.json b/package.json index c09e1bd1..058ae278 100755 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "prepare": "husky install", "purge": "npx turbo@latest run purge && rm -rf node_modules", "reinstall": "yarn clean && yarn purge && yarn && yarn run build:deps", - "test": "turbo run test" + "test": "turbo run test --filter='@vechainfoundation/*'" }, "husky": { "hooks": { diff --git a/packages/dapp-kit/package.json b/packages/dapp-kit/package.json index 145461ae..ac4ac6be 100644 --- a/packages/dapp-kit/package.json +++ b/packages/dapp-kit/package.json @@ -9,6 +9,7 @@ "clean": "rm -rf dist .turbo", "lint": "tsc --noEmit && eslint src --ext .js,.jsx,.ts,.tsx", "purge": "yarn clean && rm -rf node_modules", + "test": "vitest run --coverage", "watch": "tsup src/index.ts --format cjs,esm --watch --dts" }, "dependencies": { @@ -25,9 +26,14 @@ "@types/react": "^18.2.28", "@types/react-dom": "^18.2.13", "@vechain/repo-config": "https://github.com/vechainfoundation/repo-config#v0.0.1", + "@vitest/coverage-v8": "^0.34.6", "@walletconnect/types": "2.10.2", "eslint": "*", + "happy-dom": "^12.10.3", + "lokijs": "^1.5.12", "tsup": "*", - "typescript": "*" + "typescript": "*", + "vite": "^4.5.0", + "vitest": "^0.34.6" } } diff --git a/packages/dapp-kit/src/connex.ts b/packages/dapp-kit/src/connex.ts index 66c6fece..87e3c45c 100644 --- a/packages/dapp-kit/src/connex.ts +++ b/packages/dapp-kit/src/connex.ts @@ -1,10 +1,9 @@ -import { createNoVendor } from '@vechain/connex/esm/driver'; +import { createNoVendor, LazyDriver } from '@vechain/connex/esm/driver'; import { newThor } from '@vechain/connex-framework/dist/thor'; import type { DriverNoVendor } from '@vechain/connex-driver'; import { newVendor } from '@vechain/connex-framework'; import type { ConnexOptions } from './types'; import { normalizeGenesisBlock } from './genesis'; -import { FullDriver } from './full-driver'; import { WalletManager } from './wallet-manager'; class MultiWalletConnex { @@ -23,10 +22,11 @@ class MultiWalletConnex { ); const walletManager = new WalletManager(options); - const fullDriver = new FullDriver(thorOnlyDriver, walletManager); + const lazyDriver = new LazyDriver(Promise.resolve(walletManager)); + lazyDriver.setNoVendor(thorOnlyDriver); - const thor = newThor(fullDriver); - const vendor = newVendor(fullDriver); + const thor = newThor(lazyDriver); + const vendor = newVendor(lazyDriver); this.thor = thor; this.vendor = vendor; diff --git a/packages/dapp-kit/src/full-driver.ts b/packages/dapp-kit/src/full-driver.ts deleted file mode 100644 index 817c6517..00000000 --- a/packages/dapp-kit/src/full-driver.ts +++ /dev/null @@ -1,78 +0,0 @@ -import type { DriverNoVendor } from '@vechain/connex-driver'; - -export class FullDriver implements Connex.Driver { - constructor( - private readonly driver: DriverNoVendor, - private signer: Connex.Signer, - ) {} - - get genesis(): Connex.Thor.Block { - return this.driver.genesis; - } - - get head(): Connex.Thor.Status['head'] { - return this.driver.head; - } - - pollHead = (): Promise => - this.driver.pollHead(); - - getBlock = (revision: string | number): Promise => - this.driver.getBlock(revision); - - getTransaction = ( - id: string, - allowPending: boolean, - ): Promise => - this.driver.getTransaction(id, allowPending); - - getReceipt = ( - id: string, - ): Promise => - this.driver.getReceipt(id); - - getAccount = ( - addr: string, - revision: string, - ): Promise => this.driver.getAccount(addr, revision); - - getCode = ( - addr: string, - revision: string, - ): Promise => this.driver.getCode(addr, revision); - - getStorage = ( - addr: string, - key: string, - revision: string, - ): Promise => - this.driver.getStorage(addr, key, revision); - - explain = ( - arg: Connex.Driver.ExplainArg, - revision: string, - cacheHints?: string[], - ): Promise => - this.driver.explain(arg, revision, cacheHints); - - filterEventLogs = ( - arg: Connex.Driver.FilterEventLogsArg, - ): Promise[]> => - this.driver.filterEventLogs(arg); - - filterTransferLogs = ( - arg: Connex.Driver.FilterTransferLogsArg, - ): Promise[]> => - this.driver.filterTransferLogs(arg); - - signTx = async ( - msg: Connex.Vendor.TxMessage, - options: Connex.Signer.TxOptions, - ): Promise => this.signer.signTx(msg, options); - - signCert = async ( - msg: Connex.Vendor.CertMessage, - options: Connex.Signer.CertOptions, - ): Promise => - this.signer.signCert(msg, options); -} diff --git a/packages/dapp-kit/src/wallet-connect/signer.ts b/packages/dapp-kit/src/wallet-connect/signer.ts index 0150184e..47eea468 100644 --- a/packages/dapp-kit/src/wallet-connect/signer.ts +++ b/packages/dapp-kit/src/wallet-connect/signer.ts @@ -1,4 +1,3 @@ -/// import type { SessionTypes } from '@walletconnect/types'; import type { ProposalTypes } from '@walletconnect/types/dist/types/sign-client/proposal'; import type { EngineTypes } from '@walletconnect/types/dist/types/sign-client/engine'; @@ -152,12 +151,12 @@ export const newWcSigner = ({ vechain: namespace, }; - const { uri, approval } = await signClient.connect({ + const res = await signClient.connect({ requiredNamespaces, }); - if (uri) { - await web3Modal.openModal({ uri }); + if (res.uri) { + await web3Modal.openModal({ uri: res.uri }); } return await new Promise((resolve, reject) => { @@ -168,7 +167,7 @@ export const newWcSigner = ({ } }); - approval() + res.approval() .then((newSession) => { session = newSession; endSubscription(); diff --git a/packages/dapp-kit/test/create-wallet.test.ts b/packages/dapp-kit/test/create-wallet.test.ts new file mode 100644 index 00000000..8e3fdc43 --- /dev/null +++ b/packages/dapp-kit/test/create-wallet.test.ts @@ -0,0 +1,88 @@ +import { describe, expect, it, vi } from 'vitest'; +import type { Connex1 } from '@vechain/connex/esm/signer'; +import { createWallet } from '../src/create-wallet'; +import type { ConnexOptions, WalletConnectOptions, WalletSource } from '../src'; + +type ICreateWallet = ConnexOptions & { + source: WalletSource; + onDisconnected: () => void; +}; +const createOptions = ( + source: WalletSource, + wcOptions?: WalletConnectOptions, +): ICreateWallet => { + return { + nodeUrl: 'https://testnet.veblocks.net/', + source, + walletConnectOptions: wcOptions, + genesis: 'main', + customWcModal: undefined, + onDisconnected: () => {}, + }; +}; + +vi.mock('@walletconnect/modal'); + +describe('createWallet', () => { + describe('sync', () => { + it('is NOT in sync browser', () => { + window.connex = undefined; + + expect(() => { + createWallet(createOptions('sync')); + }).toThrowError('User is not in a Sync wallet'); + }); + + it('is in sync2 browser', () => { + window.connex = {} as Connex1; + + const wallet = createWallet(createOptions('sync2')); + + expect(wallet).toBeDefined(); + }); + }); + + describe('veworld-extension', () => { + it('is not installed', () => { + window.vechain = undefined; + + expect(() => { + createWallet(createOptions('veworld-extension')); + }).toThrowError('VeWorld Extension is not installed'); + }); + + it('is installed', () => { + window.vechain = { + newConnexSigner: () => ({} as Connex.Signer), + }; + + const wallet = createWallet(createOptions('veworld-extension')); + + expect(wallet).toBeDefined(); + }); + }); + + describe('wallet-connect', () => { + it('no options provided', () => { + expect(() => { + createWallet(createOptions('wallet-connect')); + }).toThrowError('WalletConnect options are not provided'); + }); + + it('options provided', () => { + const wallet = createWallet( + createOptions('wallet-connect', { + projectId: '123', + metadata: { + name: 'test', + description: 'test', + url: 'test', + icons: ['test'], + }, + }), + ); + + expect(wallet).toBeDefined(); + }); + }); +}); diff --git a/packages/dapp-kit/test/genesis.test.ts b/packages/dapp-kit/test/genesis.test.ts new file mode 100644 index 00000000..8ebc321d --- /dev/null +++ b/packages/dapp-kit/test/genesis.test.ts @@ -0,0 +1,56 @@ +import { describe, expect, it } from 'vitest'; +import { genesisBlocks } from '@vechain/connex/esm/config'; +import { normalizeGenesisBlock, normalizeGenesisId } from '../src/genesis'; + +const customBlock = { + number: 0, + id: '0x00000000c05a20fbca2bf6ae3affba6af4a74b800b585bf7a4988aba7aea69f6', + size: 170, + parentID: + '0xffffffff00000000000000000000000000000000000000000000000000000000', + timestamp: 1526400000, + gasLimit: 10000000, + beneficiary: '0x0000000000000000000000000000000000000000', + gasUsed: 0, + totalScore: 0, + txsRoot: + '0x45b0cfc220ceec5b7c1c62c4d4193d38e4eba48e8815729ce75f9c0ab0e4c1c0', + txsFeatures: 0, + stateRoot: + '0x93de0ffb1f33bc0af053abc2a87c4af44594f5dcb1cb879dd823686a15d68550', + receiptsRoot: + '0x45b0cfc220ceec5b7c1c62c4d4193d38e4eba48e8815729ce75f9c0ab0e4c1c0', + signer: '0x0000000000000000000000000000000000000000', + isTrunk: true, + transactions: [], +}; + +describe('genesis', () => { + describe('normalizeGenesisId', () => { + it('normalizes `main`', () => { + expect(normalizeGenesisId('main')).toBe(genesisBlocks.main.id); + }); + + it('normalizes `test`', () => { + expect(normalizeGenesisId('test')).toBe(genesisBlocks.test.id); + }); + + it('normalizes a block', () => { + expect(normalizeGenesisId(customBlock)).toBe(customBlock.id); + }); + }); + + describe('normalizeGenesisBlock', () => { + it('normalizes `main`', () => { + expect(normalizeGenesisBlock('main')).toBe(genesisBlocks.main); + }); + + it('normalizes `test`', () => { + expect(normalizeGenesisBlock('test')).toBe(genesisBlocks.test); + }); + + it('normalizes a block', () => { + expect(normalizeGenesisBlock(customBlock)).toBe(customBlock); + }); + }); +}); diff --git a/packages/dapp-kit/test/helpers/connex-helper.ts b/packages/dapp-kit/test/helpers/connex-helper.ts new file mode 100644 index 00000000..9b6849da --- /dev/null +++ b/packages/dapp-kit/test/helpers/connex-helper.ts @@ -0,0 +1,19 @@ +import { vi } from 'vitest'; +import type { WalletConnectOptions } from '../../src'; +import { MultiWalletConnex } from '../../src'; + +export const createUnitTestConnex = ( + walletConnectOptions?: WalletConnectOptions, +): MultiWalletConnex => { + return new MultiWalletConnex({ + nodeUrl: 'https://mainnet.vechain.org/', + walletConnectOptions, + customWcModal: { + openModal: vi.fn(), + closeModal: vi.fn(), + subscribeModal: () => { + return vi.fn(); + }, + }, + }); +}; diff --git a/packages/dapp-kit/test/helpers/mocked-sign-client.ts b/packages/dapp-kit/test/helpers/mocked-sign-client.ts new file mode 100644 index 00000000..fe2ee985 --- /dev/null +++ b/packages/dapp-kit/test/helpers/mocked-sign-client.ts @@ -0,0 +1,67 @@ +import { vi } from 'vitest'; +import type { + EngineTypes, + IEngine, +} from '@walletconnect/types/dist/types/sign-client/engine'; +import type { SessionTypes } from '@walletconnect/types'; +import type { ResolvedSignClient } from '../../src'; +import { DefaultMethods } from '../../src/wallet-connect/constants'; +import { wcSessionStruct } from './wc-fixtures'; +import { address, mockedConnexSigner } from './mocked-signer'; +import { randomUUID } from 'node:crypto'; + +const requestHandler: IEngine['request'] = vi.fn(); +const connectHandler: IEngine['connect'] = vi.fn(); +const disconnectHandler: IEngine['disconnect'] = vi.fn(); + +const defaultMockConnectHandler = (): ReturnType => { + return Promise.resolve({ + uri: 'wc://test', + approval: (): Promise => { + return Promise.resolve(wcSessionStruct); + }, + }); +}; + +const defaultMockRequestHandler = ( + params: EngineTypes.RequestParams, +): Promise => { + if (params.request.method === DefaultMethods.RequestTransaction) { + return Promise.resolve({ + txid: '0x123', + signer: address, + }); + } else if (params.request.method === DefaultMethods.SignCertificate) { + return Promise.resolve( + mockedConnexSigner.signCert( + params.request.params[0].message, + params.request.params[0].options, + ), + ); + } + throw new Error('Invalid method'); +}; + +const mockedSignClient = { + on: vi.fn(), + request: requestHandler, + disconnect: disconnectHandler, + connect: connectHandler, + session: { + keys: [], + get: vi.fn(), + }, + name: randomUUID(), +} as unknown as ResolvedSignClient; + +vi.mocked(mockedSignClient.request).mockImplementation( + defaultMockRequestHandler, +); +vi.mocked(mockedSignClient.connect).mockImplementation( + defaultMockConnectHandler, +); +vi.mocked(mockedSignClient.disconnect).mockImplementation((): Promise => { + return Promise.resolve(); +}); + +export { mockedSignClient }; diff --git a/packages/dapp-kit/test/helpers/mocked-signer.ts b/packages/dapp-kit/test/helpers/mocked-signer.ts new file mode 100644 index 00000000..796d21fc --- /dev/null +++ b/packages/dapp-kit/test/helpers/mocked-signer.ts @@ -0,0 +1,43 @@ +import { blake2b256, Certificate, HDNode, secp256k1 } from 'thor-devkit'; + +const mnemonicWords = + 'denial kitchen pet squirrel other broom bar gas better priority spoil cross'; + +const hdNode = HDNode.fromMnemonic(mnemonicWords.split(' ')); + +const firstAccount = hdNode.derive(0); + +const privateKey: Buffer = firstAccount.privateKey!; +const address = firstAccount.address; + +const mockedConnexSigner: Connex.Signer = { + signTx() { + return Promise.resolve({ txid: '0x1234', signer: address }); + }, + + signCert(msg) { + const certificate: Certificate = { + domain: ' localhost:3000', + timestamp: 12341234, + signer: address, + payload: msg.payload, + purpose: msg.purpose, + }; + + const signature = secp256k1.sign( + blake2b256(Certificate.encode(certificate)), + privateKey, + ); + + return Promise.resolve({ + annex: { + domain: certificate.domain, + timestamp: certificate.timestamp, + signer: certificate.signer, + }, + signature: `0x${signature.toString('hex')}`, + }); + }, +}; + +export { mockedConnexSigner, hdNode, mnemonicWords, privateKey, address }; diff --git a/packages/dapp-kit/test/helpers/request-data.ts b/packages/dapp-kit/test/helpers/request-data.ts new file mode 100644 index 00000000..59c78aec --- /dev/null +++ b/packages/dapp-kit/test/helpers/request-data.ts @@ -0,0 +1,7 @@ +export const certMessage: Connex.Vendor.CertMessage = { + purpose: 'identification', + payload: { + type: 'text', + content: 'Hello World', + }, +}; diff --git a/packages/dapp-kit/test/helpers/wc-fixtures.ts b/packages/dapp-kit/test/helpers/wc-fixtures.ts new file mode 100644 index 00000000..d670bdc9 --- /dev/null +++ b/packages/dapp-kit/test/helpers/wc-fixtures.ts @@ -0,0 +1,56 @@ +import type { SessionTypes, SignClientTypes } from '@walletconnect/types'; +import { normalizeGenesisBlock } from '../../src/genesis'; +import { DefaultMethods } from '../../src/wallet-connect/constants'; +import { address } from './mocked-signer'; + +const wcMetadata: SignClientTypes.Options['metadata'] = { + name: 'test', + description: 'test', + icons: ['test'], + url: 'test', +}; + +const defaultWcChains = [ + `vechain:${normalizeGenesisBlock('main').id.slice(-32)}`, +]; + +export const wcSessionStruct: SessionTypes.Struct = { + topic: 'wc-topic', + pairingTopic: 'wc-pairing-topic', + relay: { + protocol: 'irn', + }, + expiry: 0, + acknowledged: true, + controller: 'wc-controller', + namespaces: { + vechain: { + chains: defaultWcChains, + accounts: defaultWcChains.map((chain) => `${chain}:${address}`), + methods: [ + DefaultMethods.RequestTransaction, + DefaultMethods.SignCertificate, + ], + events: [], + }, + }, + requiredNamespaces: { + vechain: { + chains: defaultWcChains, + methods: [ + DefaultMethods.RequestTransaction, + DefaultMethods.SignCertificate, + ], + events: [], + }, + }, + optionalNamespaces: {}, + self: { + publicKey: 'wc-public-key', + metadata: wcMetadata, + }, + peer: { + publicKey: 'wc-public-key', + metadata: wcMetadata, + }, +}; diff --git a/packages/dapp-kit/test/setup/setup.ts b/packages/dapp-kit/test/setup/setup.ts new file mode 100644 index 00000000..d1e924ec --- /dev/null +++ b/packages/dapp-kit/test/setup/setup.ts @@ -0,0 +1,17 @@ +import { vi } from 'vitest'; + +vi.mock('@walletconnect/modal'); + +Object.defineProperty(window, 'matchMedia', { + writable: true, + value: vi.fn().mockImplementation((query) => ({ + matches: false, + media: query, + onchange: null, + addListener: vi.fn(), // deprecated + removeListener: vi.fn(), // deprecated + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + dispatchEvent: vi.fn(), + })), +}); diff --git a/packages/dapp-kit/test/wallet-connect/client.test.ts b/packages/dapp-kit/test/wallet-connect/client.test.ts new file mode 100644 index 00000000..e355b565 --- /dev/null +++ b/packages/dapp-kit/test/wallet-connect/client.test.ts @@ -0,0 +1,29 @@ +import { describe, it, vi } from 'vitest'; +import type { SignClientTypes } from '@walletconnect/types'; +import { SignClient } from '@walletconnect/sign-client'; +import { createWcClient } from '../../src'; +import { mockedSignClient } from '../helpers/mocked-sign-client'; + +vi.spyOn(SignClient, 'init').mockResolvedValue(mockedSignClient); + +const projectId = 'abc1234'; +const metadata: SignClientTypes.Options['metadata'] = { + name: 'test', + description: 'test', + icons: ['test'], + url: 'test', +}; + +describe('createWcClient', () => { + it('should cache the client', async () => { + const wcClient = createWcClient({ projectId, metadata }); + + const wcClient2 = createWcClient({ projectId, metadata }); + + const resolved1 = await wcClient.get(); + const resolved2 = await wcClient2.get(); + + expect(resolved1.name).toBeDefined(); + expect(resolved1.name).toBe(resolved2.name); + }); +}); diff --git a/packages/dapp-kit/test/wallet-connect/signer.test.ts b/packages/dapp-kit/test/wallet-connect/signer.test.ts new file mode 100644 index 00000000..209f6e15 --- /dev/null +++ b/packages/dapp-kit/test/wallet-connect/signer.test.ts @@ -0,0 +1,76 @@ +import { describe, expect, it, vi } from 'vitest'; +import { SignClient } from '@walletconnect/sign-client'; +import type { SignClientTypes } from '@walletconnect/types'; +import type { WCModal, WCSigner } from '../../src'; +import { createWcClient, newWcSigner } from '../../src'; +import { mockedSignClient } from '../helpers/mocked-sign-client'; +import { normalizeGenesisId } from '../../src/genesis'; +import { address } from '../helpers/mocked-signer'; + +vi.spyOn(SignClient, 'init').mockResolvedValue(mockedSignClient); + +const projectId = 'abc1234'; +const metadata: SignClientTypes.Options['metadata'] = { + name: 'test', + description: 'test', + icons: ['test'], + url: 'test', +}; + +const customModal: WCModal = { + openModal: vi.fn(), + closeModal: vi.fn(), + subscribeModal: () => { + return vi.fn(); + }, +}; + +const createNewSignClient = (): WCSigner => + newWcSigner({ + genesisId: normalizeGenesisId('main'), + wcClient: createWcClient({ projectId, metadata }), + onDisconnected: () => { + console.log('disconnected'); + }, + web3Modal: customModal, + }); + +describe('newWcSigner', () => { + it('can connect', async () => { + const signer = createNewSignClient(); + + const res = await signer.connect(); + + expect(res).toBe(address); + }); + + it('can connect before signing TX', async () => { + const signer = createNewSignClient(); + + const txRes = await signer.signTx([], {}); + + expect(txRes).toBeDefined(); + }); + + it('can sign a cert', async () => { + const signer = createNewSignClient(); + + const certRes = await signer.signCert( + { + payload: { type: 'text', content: 'Hello World' }, + purpose: 'identification', + }, + {}, + ); + + expect(certRes).toBeDefined(); + }); + + it('can disconnect', async () => { + const signer = createNewSignClient(); + + await signer.connect(); + + await signer.disconnect(); + }); +}); diff --git a/packages/dapp-kit/test/wallet-connect/web3-modal.test.ts b/packages/dapp-kit/test/wallet-connect/web3-modal.test.ts new file mode 100644 index 00000000..fa5f16b6 --- /dev/null +++ b/packages/dapp-kit/test/wallet-connect/web3-modal.test.ts @@ -0,0 +1,18 @@ +import { describe, it, vi } from 'vitest'; +import { SignClient } from '@walletconnect/sign-client'; +import { createWcModal } from '../../src'; +import { mockedSignClient } from '../helpers/mocked-sign-client'; + +vi.spyOn(SignClient, 'init').mockResolvedValue(mockedSignClient); + +const projectId = 'abc1234'; + +describe('createWcModal', () => { + it('should cache the modal', () => { + const wcModal = createWcModal(projectId); + + const wcModal2 = createWcModal(projectId); + + expect(wcModal).toEqual(wcModal2); + }); +}); diff --git a/packages/dapp-kit/test/wallet-manager.test.ts b/packages/dapp-kit/test/wallet-manager.test.ts new file mode 100644 index 00000000..fc89df84 --- /dev/null +++ b/packages/dapp-kit/test/wallet-manager.test.ts @@ -0,0 +1,119 @@ +import { describe, expect, it } from 'vitest'; +import type { WalletConnectOptions } from '../src'; +import { WalletManager } from '../src'; +import { mockedConnexSigner } from './helpers/mocked-signer'; + +const newWalletManager = (wcOptions?: WalletConnectOptions): WalletManager => { + return new WalletManager({ + nodeUrl: 'https://testnet.veblocks.net/', + walletConnectOptions: wcOptions, + genesis: 'main', + customWcModal: undefined, + }); +}; + +window.vechain = { + newConnexSigner: () => mockedConnexSigner, +}; + +const eventNames = (walletManager: WalletManager): string[] => + //@ts-ignore + walletManager.eventEmitter.eventNames(); + +const listener = () => {}; + +describe('WalletManager', () => { + describe('setSource', () => { + it('no wc options provided', () => { + const walletManager = newWalletManager(); + expect(() => { + walletManager.setSource('wallet-connect'); + }).toThrowError('WalletConnect options are not provided'); + }); + }); + + describe('connect', () => { + it('no source set', async () => { + const walletManager = newWalletManager(); + + await expect(async () => walletManager.connect()).rejects.toThrow( + 'No wallet has been selected', + ); + }); + }); + + describe('signTx', () => { + it('should sign the tx', async () => { + const walletManager = newWalletManager(); + walletManager.setSource('veworld-extension'); + const res = await walletManager.signTx([], {}); + + expect(res.txid).toBeDefined(); + }); + }); + + describe('signCert', () => { + it('should sign the cert', async () => { + const walletManager = newWalletManager(); + walletManager.setSource('veworld-extension'); + const res = await walletManager.signCert( + { + payload: { content: 'Hello world', type: 'text' }, + purpose: 'identification', + }, + {}, + ); + + expect(res.signature).toBeDefined(); + }); + }); + + describe('disconnect', () => { + it('is not connected', async () => { + const walletManager = newWalletManager(); + + await walletManager.disconnect(); + + expect(walletManager.getSource()).toEqual(null); + }); + + it('from remote', async () => { + const walletManager = newWalletManager(); + + walletManager.setSource('veworld-extension'); + + await walletManager.disconnect(true); + + expect(walletManager.getSource()).toEqual(null); + }); + }); + + describe('listeners', () => { + it('add disconnected listener', () => { + const walletManager = newWalletManager(); + + walletManager.onDisconnected(listener); + expect(eventNames(walletManager)).toEqual(['disconnected']); + }); + + it('can remove disconnected listener', () => { + const walletManager = newWalletManager(); + walletManager.onDisconnected(listener); + walletManager.removeOnDisconnected(listener); + expect(eventNames(walletManager)).toEqual([]); + }); + + it('can add onSourceChanged listener', () => { + const walletManager = newWalletManager(); + walletManager.onSourceChanged(listener); + expect(eventNames(walletManager)).toEqual(['source-changed']); + }); + + it('can remove onSourceChanged listener', () => { + const walletManager = newWalletManager(); + walletManager.onSourceChanged(listener); + walletManager.removeOnSourceChanged(listener); + expect(eventNames(walletManager)).toEqual([]); + }); + }); +}); diff --git a/packages/dapp-kit/test/wallet-tests/sync.test.ts b/packages/dapp-kit/test/wallet-tests/sync.test.ts new file mode 100644 index 00000000..bdbe2d44 --- /dev/null +++ b/packages/dapp-kit/test/wallet-tests/sync.test.ts @@ -0,0 +1,62 @@ +import { beforeEach, expect, vi } from 'vitest'; +import { mockedConnexSigner } from '../helpers/mocked-signer'; +import { createUnitTestConnex } from '../helpers/connex-helper'; + +vi.mock('@vechain/connex/esm/signer', () => { + return { + createSync: (): Promise => + Promise.resolve(mockedConnexSigner), + }; +}); + +describe('sync', () => { + describe('is in sync browser', () => { + beforeEach(() => { + window.connex = { + //eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-expect-error + test: 'hello world', + }; + }); + + it('window.connex is defined - should connect', async () => { + const connex = createUnitTestConnex(); + + connex.wallet.setSource('sync'); + + const res = await connex.wallet.connect(); + + expect(res.verified).toBe(true); + }); + + it('get available sources - should include sync', () => { + const connex = createUnitTestConnex(); + + const sources = connex.wallet.getAvailableSources(); + + expect(sources).toContain('sync'); + }); + }); + + describe('is NOT in sync browser', () => { + beforeEach(() => { + window.connex = undefined; + }); + + it('window.connex not defined - should throw error', () => { + const connex = createUnitTestConnex(); + + expect(() => connex.wallet.setSource('sync')).toThrowError( + 'User is not in a Sync wallet', + ); + }); + + it('get available sources - should not include veworld-extension', () => { + const connex = createUnitTestConnex(); + + const sources = connex.wallet.getAvailableSources(); + + expect(sources).not.toContain('sync'); + }); + }); +}); diff --git a/packages/dapp-kit/test/wallet-tests/sync2.test.ts b/packages/dapp-kit/test/wallet-tests/sync2.test.ts new file mode 100644 index 00000000..5f54be16 --- /dev/null +++ b/packages/dapp-kit/test/wallet-tests/sync2.test.ts @@ -0,0 +1,30 @@ +import { expect, vi } from 'vitest'; +import { mockedConnexSigner } from '../helpers/mocked-signer'; +import { createUnitTestConnex } from '../helpers/connex-helper'; + +vi.mock('@vechain/connex/esm/signer', () => { + return { + createSync2: (): Promise => + Promise.resolve(mockedConnexSigner), + }; +}); + +describe('sync2', () => { + it('should connect', async () => { + const connex = createUnitTestConnex(); + + connex.wallet.setSource('sync2'); + + const res = await connex.wallet.connect(); + + expect(res.verified).toBe(true); + }); + + it('is always available', () => { + const connex = createUnitTestConnex(); + + const sources = connex.wallet.getAvailableSources(); + + expect(sources).toContain('sync2'); + }); +}); diff --git a/packages/dapp-kit/test/wallet-tests/veworld-extension.test.ts b/packages/dapp-kit/test/wallet-tests/veworld-extension.test.ts new file mode 100644 index 00000000..275d331a --- /dev/null +++ b/packages/dapp-kit/test/wallet-tests/veworld-extension.test.ts @@ -0,0 +1,65 @@ +import { beforeEach, expect } from 'vitest'; +import { mockedConnexSigner } from '../helpers/mocked-signer'; +import { createUnitTestConnex } from '../helpers/connex-helper'; + +describe('veworld-extension', () => { + describe('is in veworld-extension browser', () => { + beforeEach(() => { + window.vechain = { + newConnexSigner: (): Connex.Signer => mockedConnexSigner, + }; + }); + + it('should connect', async () => { + const connex = createUnitTestConnex(); + + connex.wallet.setSource('veworld-extension'); + + const res = await connex.wallet.connect(); + + expect(res.verified).toBe(true); + }); + + it('can disconnect', async () => { + const connex = createUnitTestConnex(); + + connex.wallet.setSource('veworld-extension'); + + await connex.wallet.disconnect(); + + const currentSource = connex.wallet.getSource(); + + expect(currentSource).toBe(null); + }); + + it('get available sources - should include veworld-extension', () => { + const connex = createUnitTestConnex(); + + const sources = connex.wallet.getAvailableSources(); + + expect(sources).toContain('veworld-extension'); + }); + }); + + describe('is NOT in veworld-extension browser', () => { + beforeEach(() => { + window.vechain = undefined; + }); + + it('not installed - should throw error', () => { + const connex = createUnitTestConnex(); + + expect(() => + connex.wallet.setSource('veworld-extension'), + ).toThrowError('VeWorld Extension is not installed'); + }); + + it('get available sources - should not include veworld-extension', () => { + const connex = createUnitTestConnex(); + + const sources = connex.wallet.getAvailableSources(); + + expect(sources).not.toContain('veworld-extension'); + }); + }); +}); diff --git a/packages/dapp-kit/test/wallet-tests/wallet-connect.test.ts b/packages/dapp-kit/test/wallet-tests/wallet-connect.test.ts new file mode 100644 index 00000000..ba2b99cf --- /dev/null +++ b/packages/dapp-kit/test/wallet-tests/wallet-connect.test.ts @@ -0,0 +1,72 @@ +import { describe, expect, it, vi } from 'vitest'; +import { SignClient } from '@walletconnect/sign-client'; +import { createUnitTestConnex } from '../helpers/connex-helper'; +import type { WalletConnectOptions } from '../../src'; +import { mockedSignClient } from '../helpers/mocked-sign-client'; +import { certMessage } from '../helpers/request-data'; + +const wcOptions: WalletConnectOptions = { + projectId: 'test1234', + metadata: { + name: 'Test', + description: 'Test wallet', + url: 'https://test.com', + icons: ['https://test.com/icon.png'], + }, +}; + +vi.spyOn(SignClient, 'init').mockResolvedValue(mockedSignClient); + +describe('wallet-connect', () => { + describe('no options provided', () => { + it('get available sources - should not include WC', () => { + const connex = createUnitTestConnex(); + + const sources = connex.wallet.getAvailableSources(); + + expect(sources).not.toContain('wallet-connect'); + }); + }); + + describe('options provided', () => { + it('get available sources - should include WC', () => { + const connex = createUnitTestConnex(wcOptions); + + const sources = connex.wallet.getAvailableSources(); + + expect(sources).toContain('wallet-connect'); + }); + + it('can connect', async () => { + const connex = createUnitTestConnex(wcOptions); + + connex.wallet.setSource('wallet-connect'); + + const acc = await connex.wallet.connect(); + + expect(acc).toBeDefined(); + }); + + it('it can sign a cert', async () => { + const connex = createUnitTestConnex(wcOptions); + + connex.wallet.setSource('wallet-connect'); + + const certRes = await connex.vendor + .sign('cert', certMessage) + .request(); + + expect(certRes).toBeDefined(); + }); + + it('can sign a tx', async () => { + const connex = createUnitTestConnex(wcOptions); + + connex.wallet.setSource('wallet-connect'); + + const txRes = await connex.vendor.sign('tx', []).request(); + + expect(txRes).toBeDefined(); + }); + }); +}); diff --git a/packages/dapp-kit/vite.config.ts b/packages/dapp-kit/vite.config.ts new file mode 100644 index 00000000..f0bf9c60 --- /dev/null +++ b/packages/dapp-kit/vite.config.ts @@ -0,0 +1,17 @@ +/// +import { resolve } from 'node:path'; +import { defineConfig } from 'vitest/config'; + +// eslint-disable-next-line import/no-default-export +export default defineConfig({ + test: { + include: ['test/**/*.test.ts'], + environment: 'jsdom', + setupFiles: [resolve(__dirname, 'test/setup/setup.ts')], + reporters: 'dot', + coverage: { + reporter: ['text', 'json', 'html'], + }, + globals: true, + }, +}); diff --git a/yarn.lock b/yarn.lock index 85717e7f..17f5c0f5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -36,7 +36,7 @@ resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30" integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== -"@ampproject/remapping@^2.2.0": +"@ampproject/remapping@^2.2.0", "@ampproject/remapping@^2.2.1": version "2.2.1" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== @@ -3537,7 +3537,7 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": version "0.3.20" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== @@ -5551,6 +5551,18 @@ dependencies: "@types/node" "*" +"@types/chai-subset@^1.3.3": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/chai-subset/-/chai-subset-1.3.5.tgz#3fc044451f26985f45625230a7f22284808b0a9a" + integrity sha512-c2mPnw+xHtXDoHmdtcCXGwyLMiauiAyxWMzhGpqHC4nqI/Y5G2XhTampslK2rb59kpcuHon03UH8W6iYUzw88A== + dependencies: + "@types/chai" "*" + +"@types/chai@*", "@types/chai@^4.3.5": + version "4.3.10" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.10.tgz#2ad2959d1767edee5b0e4efb1a0cd2b500747317" + integrity sha512-of+ICnbqjmFCiixUnqRulbylyXQrPqIGf/B3Jax1wIF3DvSheysQxAWvqHhZiW3IQrycvokcLcFQlveGp+vyNg== + "@types/chai@^4.2.0": version "4.3.9" resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.9.tgz#144d762491967db8c6dea38e03d2206c2623feec" @@ -6247,6 +6259,66 @@ eslint-plugin-unicorn "^43.0.2" prettier-plugin-packagejson "^2.3.0" +"@vitest/coverage-v8@^0.34.6": + version "0.34.6" + resolved "https://registry.yarnpkg.com/@vitest/coverage-v8/-/coverage-v8-0.34.6.tgz#931d9223fa738474e00c08f52b84e0f39cedb6d1" + integrity sha512-fivy/OK2d/EsJFoEoxHFEnNGTg+MmdZBAVK9Ka4qhXR2K3J0DS08vcGVwzDtXSuUMabLv4KtPcpSKkcMXFDViw== + dependencies: + "@ampproject/remapping" "^2.2.1" + "@bcoe/v8-coverage" "^0.2.3" + istanbul-lib-coverage "^3.2.0" + istanbul-lib-report "^3.0.1" + istanbul-lib-source-maps "^4.0.1" + istanbul-reports "^3.1.5" + magic-string "^0.30.1" + picocolors "^1.0.0" + std-env "^3.3.3" + test-exclude "^6.0.0" + v8-to-istanbul "^9.1.0" + +"@vitest/expect@0.34.6": + version "0.34.6" + resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-0.34.6.tgz#608a7b7a9aa3de0919db99b4cc087340a03ea77e" + integrity sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw== + dependencies: + "@vitest/spy" "0.34.6" + "@vitest/utils" "0.34.6" + chai "^4.3.10" + +"@vitest/runner@0.34.6": + version "0.34.6" + resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-0.34.6.tgz#6f43ca241fc96b2edf230db58bcde5b974b8dcaf" + integrity sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ== + dependencies: + "@vitest/utils" "0.34.6" + p-limit "^4.0.0" + pathe "^1.1.1" + +"@vitest/snapshot@0.34.6": + version "0.34.6" + resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-0.34.6.tgz#b4528cf683b60a3e8071cacbcb97d18b9d5e1d8b" + integrity sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w== + dependencies: + magic-string "^0.30.1" + pathe "^1.1.1" + pretty-format "^29.5.0" + +"@vitest/spy@0.34.6": + version "0.34.6" + resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-0.34.6.tgz#b5e8642a84aad12896c915bce9b3cc8cdaf821df" + integrity sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ== + dependencies: + tinyspy "^2.1.1" + +"@vitest/utils@0.34.6": + version "0.34.6" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-0.34.6.tgz#38a0a7eedddb8e7291af09a2409cb8a189516968" + integrity sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A== + dependencies: + diff-sequences "^29.4.3" + loupe "^2.3.6" + pretty-format "^29.5.0" + "@vue/babel-helper-vue-jsx-merge-props@^1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.4.0.tgz#8d53a1e21347db8edbe54d339902583176de09f2" @@ -7276,7 +7348,7 @@ acorn-walk@^7.1.1: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== -acorn-walk@^8.0.0, acorn-walk@^8.0.2: +acorn-walk@^8.0.0, acorn-walk@^8.0.2, acorn-walk@^8.2.0: version "8.3.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.0.tgz#2097665af50fd0cf7a2dfccd2b9368964e66540f" integrity sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA== @@ -7291,7 +7363,7 @@ acorn@^7.1.1, acorn@^7.4.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.0.4, acorn@^8.0.5: +acorn@^8.0.4, acorn@^8.0.5, acorn@^8.10.0: version "8.11.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b" integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== @@ -8381,7 +8453,7 @@ bytes@3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== -cac@^6.7.12: +cac@^6.7.12, cac@^6.7.14: version "6.7.14" resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959" integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ== @@ -8481,7 +8553,7 @@ catering@^2.1.0, catering@^2.1.1: resolved "https://registry.yarnpkg.com/catering/-/catering-2.1.1.tgz#66acba06ed5ee28d5286133982a927de9a04b510" integrity sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w== -chai@^4.2.0: +chai@^4.2.0, chai@^4.3.10: version "4.3.10" resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.10.tgz#d784cec635e3b7e2ffb66446a63b4e33bd390384" integrity sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g== @@ -9824,7 +9896,7 @@ diff-sequences@^27.5.1: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== -diff-sequences@^29.6.3: +diff-sequences@^29.4.3, diff-sequences@^29.6.3: version "29.6.3" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== @@ -10131,6 +10203,11 @@ entities@^3.0.1: resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4" integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q== +entities@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + env-paths@^2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" @@ -10277,7 +10354,7 @@ es6-promisify@^5.0.0: dependencies: es6-promise "^4.0.3" -esbuild@^0.18.2: +esbuild@^0.18.10, esbuild@^0.18.2: version "0.18.20" resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.18.20.tgz#4709f5a34801b43b799ab7d6d82f7284a9b7a7a6" integrity sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA== @@ -12031,6 +12108,18 @@ handlebars@^4.0.1: optionalDependencies: uglify-js "^3.1.4" +happy-dom@^12.10.3: + version "12.10.3" + resolved "https://registry.yarnpkg.com/happy-dom/-/happy-dom-12.10.3.tgz#e61985eff163b822c110458be7f81aa4f94ad588" + integrity sha512-JzUXOh0wdNGY54oKng5hliuBkq/+aT1V3YpTM+lrN/GoLQTANZsMaIvmHiHe612rauHvPJnDZkZ+5GZR++1Abg== + dependencies: + css.escape "^1.5.1" + entities "^4.5.0" + iconv-lite "^0.6.3" + webidl-conversions "^7.0.0" + whatwg-encoding "^2.0.0" + whatwg-mimetype "^3.0.0" + hard-rejection@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" @@ -12469,7 +12558,7 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@^0.6.3: +iconv-lite@0.6.3, iconv-lite@^0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== @@ -13040,7 +13129,7 @@ istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: istanbul-lib-coverage "^3.2.0" semver "^6.3.0" -istanbul-lib-report@^3.0.0: +istanbul-lib-report@^3.0.0, istanbul-lib-report@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== @@ -13049,7 +13138,7 @@ istanbul-lib-report@^3.0.0: make-dir "^4.0.0" supports-color "^7.1.0" -istanbul-lib-source-maps@^4.0.0: +istanbul-lib-source-maps@^4.0.0, istanbul-lib-source-maps@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== @@ -13058,7 +13147,7 @@ istanbul-lib-source-maps@^4.0.0: istanbul-lib-coverage "^3.0.0" source-map "^0.6.1" -istanbul-reports@^3.1.3: +istanbul-reports@^3.1.3, istanbul-reports@^3.1.5: version "3.1.6" resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.6.tgz#2544bcab4768154281a2f0870471902704ccaa1a" integrity sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg== @@ -13827,6 +13916,11 @@ json5@^2.1.2, json5@^2.2.0, json5@^2.2.1, json5@^2.2.3: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== +jsonc-parser@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" + integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== + jsonfile@^2.1.0: version "2.4.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" @@ -14220,6 +14314,11 @@ loader-utils@^3.2.0: resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-3.2.1.tgz#4fb104b599daafd82ef3e1a41fb9265f87e1f576" integrity sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw== +local-pkg@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-0.4.3.tgz#0ff361ab3ae7f1c19113d9bb97b98b905dbc4963" + integrity sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g== + locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" @@ -14418,6 +14517,11 @@ log-update@^5.0.1: strip-ansi "^7.0.1" wrap-ansi "^8.0.1" +lokijs@^1.5.12: + version "1.5.12" + resolved "https://registry.yarnpkg.com/lokijs/-/lokijs-1.5.12.tgz#cb55b37009bdf09ee7952a6adddd555b893653a0" + integrity sha512-Q5ALD6JiS6xAUWCwX3taQmgwxyveCtIIuL08+ml0nHwT3k0S/GIFJN+Hd38b1qYIMaE5X++iqsqWVksz7SYW+Q== + loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -14488,7 +14592,7 @@ magic-string@^0.25.0, magic-string@^0.25.7: dependencies: sourcemap-codec "^1.4.8" -magic-string@^0.30.5: +magic-string@^0.30.1, magic-string@^0.30.5: version "0.30.5" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.5.tgz#1994d980bd1c8835dc6e78db7cbd4ae4f24746f9" integrity sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA== @@ -14786,6 +14890,16 @@ mkdirp@^2.1.5: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-2.1.6.tgz#964fbcb12b2d8c5d6fbc62a963ac95a273e2cc19" integrity sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A== +mlly@^1.2.0, mlly@^1.4.0: + version "1.4.2" + resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.4.2.tgz#7cf406aa319ff6563d25da6b36610a93f2a8007e" + integrity sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg== + dependencies: + acorn "^8.10.0" + pathe "^1.1.1" + pkg-types "^1.0.3" + ufo "^1.3.0" + mnemonist@^0.38.0: version "0.38.5" resolved "https://registry.yarnpkg.com/mnemonist/-/mnemonist-0.38.5.tgz#4adc7f4200491237fe0fa689ac0b86539685cade" @@ -15403,6 +15517,13 @@ p-limit@^3.0.2: dependencies: yocto-queue "^0.1.0" +p-limit@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-4.0.0.tgz#914af6544ed32bfa54670b061cafcbd04984b644" + integrity sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ== + dependencies: + yocto-queue "^1.0.0" + p-locate@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" @@ -15617,6 +15738,11 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +pathe@^1.1.0, pathe@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.1.tgz#1dd31d382b974ba69809adc9a7a347e65d84829a" + integrity sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q== + pathval@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" @@ -15720,6 +15846,15 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" +pkg-types@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.0.3.tgz#988b42ab19254c01614d13f4f65a2cfc7880f868" + integrity sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A== + dependencies: + jsonc-parser "^3.2.0" + mlly "^1.2.0" + pathe "^1.1.0" + pkg-up@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" @@ -16313,7 +16448,7 @@ postcss@^7.0.35, postcss@^7.0.36: picocolors "^0.2.1" source-map "^0.6.1" -postcss@^8.2.6, postcss@^8.3.5, postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.31, postcss@^8.4.4: +postcss@^8.2.6, postcss@^8.3.5, postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.27, postcss@^8.4.31, postcss@^8.4.4: version "8.4.31" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d" integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ== @@ -16418,7 +16553,7 @@ pretty-format@^28.1.3: ansi-styles "^5.0.0" react-is "^18.0.0" -pretty-format@^29.0.0, pretty-format@^29.7.0: +pretty-format@^29.0.0, pretty-format@^29.5.0, pretty-format@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== @@ -17326,7 +17461,7 @@ rollup@^2.43.1: optionalDependencies: fsevents "~2.3.2" -rollup@^3.2.5: +rollup@^3.2.5, rollup@^3.27.1: version "3.29.4" resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.4.tgz#4d70c0f9834146df8705bfb69a9a19c9e1109981" integrity sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw== @@ -17768,6 +17903,11 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" +siginfo@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/siginfo/-/siginfo-2.0.0.tgz#32e76c70b79724e3bb567cb9d543eb858ccfaf30" + integrity sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g== + signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" @@ -18050,6 +18190,11 @@ stack-utils@^2.0.3: dependencies: escape-string-regexp "^2.0.0" +stackback@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/stackback/-/stackback-0.0.2.tgz#1ac8a0d9483848d1695e418b6d031a3c3ce68e3b" + integrity sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw== + stackframe@^1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310" @@ -18079,6 +18224,11 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== +std-env@^3.3.3: + version "3.5.0" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.5.0.tgz#83010c9e29bd99bf6f605df87c19012d82d63b97" + integrity sha512-JGUEaALvL0Mf6JCfYnJOTcobY+Nc7sG/TemDRBqCA0wEr4DER7zDchaaixTlmOxAjG1uRJmX82EQcxwTQTkqVA== + stop-iteration-iterator@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz#6a60be0b4ee757d1ed5254858ec66b10c49285e4" @@ -18316,6 +18466,13 @@ strip-json-comments@^2.0.0: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== +strip-literal@^1.0.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/strip-literal/-/strip-literal-1.3.0.tgz#db3942c2ec1699e6836ad230090b84bb458e3a07" + integrity sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg== + dependencies: + acorn "^8.10.0" + style-loader@^3.3.1: version "3.3.3" resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.3.tgz#bba8daac19930169c0c9c96706749a597ae3acff" @@ -18746,6 +18903,21 @@ tiny-invariant@^1.0.6: resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642" integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw== +tinybench@^2.5.0: + version "2.5.1" + resolved "https://registry.yarnpkg.com/tinybench/-/tinybench-2.5.1.tgz#3408f6552125e53a5a48adee31261686fd71587e" + integrity sha512-65NKvSuAVDP/n4CqH+a9w2kTlLReS9vhsAP06MWx+/89nMinJyB2icyl58RIcqCmIggpojIGeuJGhjU1aGMBSg== + +tinypool@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-0.7.0.tgz#88053cc99b4a594382af23190c609d93fddf8021" + integrity sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww== + +tinyspy@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-2.2.0.tgz#9dc04b072746520b432f77ea2c2d17933de5d6ce" + integrity sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg== + titleize@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/titleize/-/titleize-3.0.0.tgz#71c12eb7fdd2558aa8a44b0be83b8a76694acd53" @@ -19189,6 +19361,11 @@ typical@^5.2.0: resolved "https://registry.yarnpkg.com/typical/-/typical-5.2.0.tgz#4daaac4f2b5315460804f0acf6cb69c52bb93066" integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg== +ufo@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.3.1.tgz#e085842f4627c41d4c1b60ebea1f75cdab4ce86b" + integrity sha512-uY/99gMLIOlJPwATcMVYfqDSxUR9//AUcgZMzwfSTJPDKzA1S8mX4VLqa+fiAtveraQUBCz4FFcwVZBGbwBXIw== + uglify-js@^3.1.4: version "3.17.4" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" @@ -19443,6 +19620,15 @@ v8-to-istanbul@^8.1.0: convert-source-map "^1.6.0" source-map "^0.7.3" +v8-to-istanbul@^9.1.0: + version "9.1.3" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.3.tgz#ea456604101cd18005ac2cae3cdd1aa058a6306b" + integrity sha512-9lDD+EVI2fjFsMWXc6dy5JJzBsVTcQ2fVkfBvncZ6xJWG9wtBhOldG+mHkSL0+V1K/xgZz0JDO5UT5hFwHUghg== + dependencies: + "@jridgewell/trace-mapping" "^0.3.12" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^2.0.0" + validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" @@ -19500,6 +19686,59 @@ viem@^1.0.0, viem@^1.18.4: isows "1.0.3" ws "8.13.0" +vite-node@0.34.6: + version "0.34.6" + resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-0.34.6.tgz#34d19795de1498562bf21541a58edcd106328a17" + integrity sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA== + dependencies: + cac "^6.7.14" + debug "^4.3.4" + mlly "^1.4.0" + pathe "^1.1.1" + picocolors "^1.0.0" + vite "^3.0.0 || ^4.0.0 || ^5.0.0-0" + +"vite@^3.0.0 || ^4.0.0 || ^5.0.0-0", "vite@^3.1.0 || ^4.0.0 || ^5.0.0-0", vite@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/vite/-/vite-4.5.0.tgz#ec406295b4167ac3bc23e26f9c8ff559287cff26" + integrity sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw== + dependencies: + esbuild "^0.18.10" + postcss "^8.4.27" + rollup "^3.27.1" + optionalDependencies: + fsevents "~2.3.2" + +vitest@^0.34.6: + version "0.34.6" + resolved "https://registry.yarnpkg.com/vitest/-/vitest-0.34.6.tgz#44880feeeef493c04b7f795ed268f24a543250d7" + integrity sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q== + dependencies: + "@types/chai" "^4.3.5" + "@types/chai-subset" "^1.3.3" + "@types/node" "*" + "@vitest/expect" "0.34.6" + "@vitest/runner" "0.34.6" + "@vitest/snapshot" "0.34.6" + "@vitest/spy" "0.34.6" + "@vitest/utils" "0.34.6" + acorn "^8.9.0" + acorn-walk "^8.2.0" + cac "^6.7.14" + chai "^4.3.10" + debug "^4.3.4" + local-pkg "^0.4.3" + magic-string "^0.30.1" + pathe "^1.1.1" + picocolors "^1.0.0" + std-env "^3.3.3" + strip-literal "^1.0.1" + tinybench "^2.5.0" + tinypool "^0.7.0" + vite "^3.1.0 || ^4.0.0 || ^5.0.0-0" + vite-node "0.34.6" + why-is-node-running "^2.2.2" + vm-browserify@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" @@ -19648,6 +19887,11 @@ webidl-conversions@^6.1.0: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== +webidl-conversions@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" + integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== + webpack-bundle-analyzer@^4.4.0: version "4.9.1" resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.9.1.tgz#d00bbf3f17500c10985084f22f1a2bf45cb2f09d" @@ -19820,6 +20064,13 @@ whatwg-encoding@^1.0.5: dependencies: iconv-lite "0.4.24" +whatwg-encoding@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz#e7635f597fd87020858626805a2729fa7698ac53" + integrity sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg== + dependencies: + iconv-lite "0.6.3" + whatwg-fetch@^3.6.2: version "3.6.19" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.19.tgz#caefd92ae630b91c07345537e67f8354db470973" @@ -19830,6 +20081,11 @@ whatwg-mimetype@^2.3.0: resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== +whatwg-mimetype@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz#5fa1a7623867ff1af6ca3dc72ad6b8a4208beba7" + integrity sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q== + whatwg-url@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" @@ -19925,6 +20181,14 @@ which@^2.0.1: dependencies: isexe "^2.0.0" +why-is-node-running@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/why-is-node-running/-/why-is-node-running-2.2.2.tgz#4185b2b4699117819e7154594271e7e344c9973e" + integrity sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA== + dependencies: + siginfo "^2.0.0" + stackback "0.0.2" + wildcard@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67" @@ -20348,6 +20612,11 @@ 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== +yocto-queue@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251" + integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g== + yorkie@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/yorkie/-/yorkie-2.0.0.tgz#92411912d435214e12c51c2ae1093e54b6bb83d9"