diff --git a/.gitignore b/.gitignore index 4fe613cb..b94f1479 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /node_modules /dist -.DS_Store \ No newline at end of file +.DS_Store +.idea \ No newline at end of file diff --git a/README.md b/README.md index 44105df9..4043a06a 100644 --- a/README.md +++ b/README.md @@ -28,57 +28,38 @@ npm build ## Documentation -Apps built with this Sdk are meant to be run in an iframe inside the Safe Web UI. -This library exposes a single method called `initSdk` that receives a single optional parameter, an array of regular expressions. By default it's configured to accept messages from this URLs: - -- mainnet: https://gnosis-safe.io, -- mainnet-staging: https://safe-team.staging.gnosisdev.com, -- rinkeby: https://rinkeby.gnosis-safe.io, -- rinkeby-staging: https://safe-team-rinkeby.staging.gnosisdev.com, -- rinkeby-dev: https://safe-team.dev.gnosisdev.com -- localhost (for the desktop app) - -By passing the argument to `initSdk` you can add more URLs to the list. It's useful when you are running your own instance of Safe Multisig. +Apps built with the Safe Apps SDK are meant to be run in an iframe inside the Safe Web UI. +This library exposes a class as a default export. It accepts an optional options object: +`whitelistedDomains` - Array of regular expressions for origins you want to accept messages from. If not passed, accepts +messages from any origin (default). ```js -import initSdk from '@gnosis.pm/safe-apps-sdk'; +import SafeAppsSDK from '@gnosis.pm/safe-apps-sdk'; -const appsSdk = initSdk(); -``` - -It returns a SDK instance that allows you to interact with the Safe Multisig application. +const opts = { + whitelistedDomains: [/gnosis-safe\\.io/], +}; -### Subscribing to events +const appsSdk = new SafeAppsSDK(opts); +``` -Once you get the SDK instance, you will be able to subscribe to events from the Safe Multisig. +The instance allows you to interact with the Safe Multisig application. -The SDK instance exposes a method called `addListeners` that receives an object with known keys, over these keys you will be able to subscribe to different events. +### Getting Safe information -- `onSafeInfo`: It will provide you first level information like the safeAddress, network, etc. -- `onTransactionConfirmation`: Fired when the user confirms the transaction inside his wallet. The response will include `requestId` and `safeTxHash` of the transaction. +Safe information can be obtained by calling `.getSafeInfo()` ```js -import { SafeInfo } from '@gnosis.pm/safe-apps-sdk'; - -const onSafeInfo = (safeInfo: SafeInfo): void => { - console.log(safeInfo); -}; - -const onTransactionConfirmation = ({ requestId, safeTxHash }) => { - console.log(requestId, safeTxHash); -}; - -appsSdk.addListeners({ - onSafeInfo, - onTransactionConfirmation, -}); +const safe = await appsSdk.getSafeInfo(); +// { +// "safeAddress": "0x2fC97b3c7324EFc0BeC094bf75d5dCdFEb082C53", +// "network": "RINKEBY" +// } ``` -You can remove listeners by calling `appsSdk.removeListeners()`. - ### Sending TXs -Sending a TX through the Safe Multisig is as simple as invoking `sendTransactionsWithParams` method with an array of TXs. +Sending a TX through the Safe Multisig is as simple as invoking `.txs.send()` ```js // Create a web3 instance @@ -102,24 +83,161 @@ const params = { safeTxGas: 500000, }; -// Send to Safe-multisig -const message = appsSdk.sendTransactionsWithParams(txs, params); -console.log(message.requestId); +try { + const txs = await appsSdk.txs.send({ txs, params }); + // { safeTxHash: '0x...' } +} catch (err) { + console.error(err.message); +} ``` -`sendTransactionsWithParams` returns a message containing the requestId. You can use it to map transaction calls with `onTransactionConfirmation` events. - > Note: `value` accepts a number or a string as a decimal or hex number. ### Retrieving transaction's status -Once you received safe transaction hash from `onTransactionConfirmation` event listener, you might want to get the status of the transaction (was it executed? how many confirmations does it have?): +Once you received safe transaction hash, you might want to get the status of the transaction (was it executed? how many confirmations does it have?): + +```js +const tx = await sdk.txs.getBySafeTxHash(safeTxHash); +``` + +It will return the following structure https://github.com/gnosis/safe-apps-sdk/blob/development/src/types.ts#L182 or throw an error if the backend hasn't synced the transaction yet + +## RPC Calls + +### The default block parameter + +The following methods have an extra default block parameter: + +- getBalance +- getCode +- getStorageAt +- call + +When requests are made that act on the state of ethereum, the last default block parameter determines the height of the block. + +The following options are possible for the defaultBlock parameter: + +`HEX String` - an integer block number +`String "earliest"` for the earliest/genesis block +`String "latest"` - for the latest mined block (default) +`String "pending"` - for the pending state/transactions + +### getBalance + +Returns the balance of the account of given address. + +```js +const balance = await appsSdk.eth.getBalance(['0x...']); +``` + +### getCode + +Returns code at a given address. + +```js +const code = await appsSdk.eth.getCode(['0x...']); +``` + +### getStorageAt + +Returns the value from a storage position at a given address. ```js -const tx = sdk.txs.getBySafeTxHash(safeTxHash); +const value = await appsSdk.eth.getStorageAt(['0x...', 0]); ``` -It will return the following structure https://github.com/gnosis/safe-apps-sdk/blob/development/src/types.ts#L157 or throw an error if the backend hasn't synced the transaction yet +### call + +Executes a new message call immediately without creating a transaction on the block chain. + +```js +const config = { + from: '0x0000000000000000000000000000000000000000', + to: '0x0000000000000000000000000000000000000000', +}; + +const result = await appsSdk.eth.call([config]); +``` + +The transaction call object: +`from` - (optional) The address the transaction is sent from. +`to` 20 Bytes - The address the transaction is directed to. +`gas` - (optional) Integer of the gas provided for the transaction execution. eth_call consumes zero gas, but this parameter may be needed by some executions. +`gasPrice` - (optional) Integer of the gasPrice used for each paid gas +`value` - (optional) Integer of the value sent with this transaction +`data` - (optional) Hash of the method signature and encoded parameters. For details see [Ethereum Contract ABI in the Solidity documentation](https://docs.soliditylang.org/en/latest/abi-spec.html) + +### getPastLogs + +Returns an array of all logs matching a given filter object. + +```js +const params = [ + { + fromBlock: 11054275, + toBlock: 'latest', + }, +]; + +const logs = await appsSdk.eth.getPastLogs([params]); +``` + +The filter options: +`fromBlock` - Integer block number, or "latest" for the last mined block or "pending", "earliest" for not yet mined transactions. +`toBlock` - Integer block number, or "latest" for the last mined block or "pending", "earliest" for not yet mined transactions. +`address` - (optional) Contract address or a list of addresses from which logs should originate. +`topics` - (optional) Array of 32 Bytes DATA topics. Topics are order-dependent. Each topic can also be an array of DATA with “or” options. + +### getBlockByHash + +Returns information about a block by hash. + +```js +const hash = '0x1955a9f306903669e295196752b11bc0dee33b48cabdf44b1103b7cea086cae7'; + +const block = await appsSdk.eth.getBlockByHash([hash, true]); +``` + +Parameters +`DATA` - Hash of a block. +`Boolean` (default: false) - If true it returns the full transaction objects, if false only the hashes of the transactions. + +### getBlockByNumber + +Returns information about a block by block number. + +```js +const number = 11054275; + +const block = await appsSdk.eth.getBlockByNumber([number]); +``` + +Parameters +`QUANTITY|TAG` - integer of a block number, or the string "earliest", "latest" or "pending", as in the default block parameter. +`Boolean` (default: false) - If true it returns the full transaction objects, if false only the hashes of the transactions. + +### getTransactionByHash + +Returns the information about a transaction requested by transaction hash. + +```js +const tx = await appsSdk.eth.getTransactionByHash([ + '0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b', +]); +``` + +### getTransactionReceipt + +Returns the receipt of a transaction by transaction hash. + +> Note: That the receipt is not available for pending transactions. + +```js +const tx = await appsSdk.eth.getTransactionReceipt([ + '0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238', +]); +``` ## Testing in the Safe Multisig application @@ -165,7 +283,7 @@ For this we recommend to use [react-app-rewired](https://www.npmjs.com/package/r }, ``` -Additionally you need to create the `config-overrides.js` file in the root of the project to confirgure the **CORS** headers. The content of the file should be: +Additionally, you need to create the `config-overrides.js` file in the root of the project to confirgure the **CORS** headers. The content of the file should be: ```js /* config-overrides.js */ diff --git a/package.json b/package.json index 11d9f38f..59f5ba2e 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { "name": "@gnosis.pm/safe-apps-sdk", - "version": "0.4.2", + "version": "1.0.0", "description": "SDK developed to integrate third-party apps with Safe-Multisig app.", - "main": "dist/index.js", - "typings": "dist/index.d.ts", + "main": "dist/src/index.js", + "typings": "dist/src/index.d.ts", "files": [ "dist/**/*", "README.md" @@ -23,22 +23,24 @@ "author": "Gnosis (https://gnosis.pm)", "license": "MIT", "dependencies": { + "semver": "^7.3.2", "web3-core": "^1.3.0" }, "devDependencies": { "@types/jest": "^26.0.15", - "@types/node": "^14.14.6", - "@typescript-eslint/eslint-plugin": "^4.6.0", - "@typescript-eslint/parser": "^4.6.0", - "eslint": "^7.12.1", + "@types/node": "^14.14.8", + "@types/semver": "^7.3.4", + "@typescript-eslint/eslint-plugin": "^4.8.1", + "@typescript-eslint/parser": "^4.8.1", + "eslint": "^7.13.0", "eslint-config-prettier": "^6.15.0", "eslint-plugin-prettier": "^3.1.4", "husky": "^4.3.0", - "jest": "^26.6.1", - "lint-staged": "^10.5.0", + "jest": "^26.6.3", + "lint-staged": "^10.5.1", "prettier": "^2.1.2", "rimraf": "^3.0.2", - "ts-jest": "^26.4.3", + "ts-jest": "^26.4.4", "tslint": "^6.1.3", "tslint-config-prettier": "^1.18.0", "typescript": "^4.0.5" diff --git a/src/communication/index.ts b/src/communication/index.ts index d195740f..91cb3be8 100644 --- a/src/communication/index.ts +++ b/src/communication/index.ts @@ -1,108 +1,69 @@ -import { - InterfaceMessageIds, - InterfaceMessageEvent, - SentSDKMessage, - SDKMessageIds, - SDKMessageToPayload, - RequestId, - InterfaceMessageToPayload, - Communicator, -} from '../types'; -import { INTERFACE_MESSAGES } from './messageIds'; +import semver from 'semver'; +import { InterfaceMessageEvent, Communicator, Methods, Response } from '../types'; +import { MessageFormatter } from './messageFormatter'; -class InterfaceCommunicator implements Communicator { - private allowedOrigins: RegExp[] = []; +// eslint-disable-next-line +type Callback = (response: any) => void; - constructor(allowedOrigins: RegExp[]) { +class PostMessageCommunicator implements Communicator { + private readonly allowedOrigins: RegExp[] | null = null; + private callbacks = new Map(); + + constructor(allowedOrigins: RegExp[] | null = null) { this.allowedOrigins = allowedOrigins; window.addEventListener('message', this.onParentMessage); } - private isValidMessage({ origin, data }: InterfaceMessageEvent): boolean { - const emptyOrMalformed = !data || !data.messageId; - const unknownOrigin = this.allowedOrigins?.find((regExp) => regExp.test(origin)) === undefined; - const sameOrigin = origin === window.origin; + private isValidMessage = ({ origin, data, source }: InterfaceMessageEvent): boolean => { + const emptyOrMalformed = !data; + const sentFromParentEl = source === window.parent; + const allowedSDKVersion = typeof data.version !== 'undefined' ? semver.gte(data.version, '1.0.0') : false; + let validOrigin = true; + if (Array.isArray(this.allowedOrigins)) { + validOrigin = this.allowedOrigins.find((regExp) => regExp.test(origin)) !== undefined; + } - return !emptyOrMalformed && !unknownOrigin && !sameOrigin; - } + return !emptyOrMalformed && sentFromParentEl && allowedSDKVersion && validOrigin; + }; - private logIncomingMessage(origin: string, payload: InterfaceMessageToPayload[InterfaceMessageIds]): void { - console.info(`SafeConnector: A message was received from origin ${origin}. `, payload); - } - - private onParentMessage(msg: InterfaceMessageEvent): void { - this.logIncomingMessage(msg.origin, msg.data); + private logIncomingMessage = (msg: InterfaceMessageEvent): void => { + console.info(`Safe Apps SDK v1: A message was received from origin ${msg.origin}. `, msg.data); + }; + private onParentMessage = (msg: InterfaceMessageEvent): void => { if (this.isValidMessage(msg)) { - this.handleIncomingMessage(msg.data.messageId, msg.data.data, msg.data.requestId); + this.logIncomingMessage(msg); + this.handleIncomingMessage(msg.data); } - } - - private handleIncomingMessage( - messageId: InterfaceMessageIds, - payload: InterfaceMessageToPayload[InterfaceMessageIds], - requestId: RequestId, - ): void { - console.log(payload, requestId); - switch (messageId) { - case INTERFACE_MESSAGES.ENV_INFO: - // const typedPayload = payload as InterfaceMessageToPayload[typeof INTERFACE_MESSAGES.ENV_INFO]; + }; - break; + private handleIncomingMessage = (payload: InterfaceMessageEvent['data']): void => { + const { id } = payload; - case INTERFACE_MESSAGES.ON_SAFE_INFO: { - /* tslint:disable-next-line:no-shadowed-variable */ - // const typedPayload = payload as InterfaceMessageToPayload[typeof INTERFACE_MESSAGES.ON_SAFE_INFO]; + const cb = this.callbacks.get(id); + if (cb) { + cb(payload); - break; - } - - case INTERFACE_MESSAGES.TRANSACTION_CONFIRMED: { - /* tslint:disable-next-line:no-shadowed-variable */ - // const typedPayload = payload as InterfaceMessageToPayload[typeof INTERFACE_MESSAGES.TRANSACTION_CONFIRMED]; - - break; - } - - case INTERFACE_MESSAGES.TRANSACTION_REJECTED: { - break; - } - - default: { - console.warn( - `SafeConnector: A message was received from origin ${origin} with an unknown message id: ${messageId}`, - ); - break; - } + this.callbacks.delete(id); } - } + }; - public send( - messageId: T, - data: D, - requestId?: RequestId, - ): SentSDKMessage { - if (!requestId) { - if (typeof window !== 'undefined') { - requestId = Math.trunc(window?.performance.now()); - } else { - requestId = Math.trunc(Date.now()); - } - } - const message = { - messageId, - requestId, - data, - }; + public send = (method: M, params: P): Promise> => { + const request = MessageFormatter.makeRequest(method, params); - if (typeof window !== 'undefined') { - window.parent.postMessage(message, '*'); + if (typeof window === 'undefined') { + throw new Error("Window doesn't exist"); } - return message; - } + window.parent.postMessage(request, '*'); + return new Promise((resolve) => { + this.callbacks.set(request.id, (response: Response) => { + resolve(response); + }); + }); + }; } -export default InterfaceCommunicator; -export * from './messageIds'; +export default PostMessageCommunicator; +export * from './methods'; diff --git a/src/communication/messageFormatter.ts b/src/communication/messageFormatter.ts new file mode 100644 index 00000000..04df22c0 --- /dev/null +++ b/src/communication/messageFormatter.ts @@ -0,0 +1,34 @@ +import { ErrorResponse, SDKRequestData, Methods, RequestId, SuccessResponse, MethodToResponse } from '../types'; +import { generateRequestId } from './utils'; +import { getSDKVersion } from '../utils'; + +class MessageFormatter { + static makeRequest = (method: M, params: P): SDKRequestData => { + const id = generateRequestId(); + + return { + id, + method, + params, + env: { + sdkVersion: getSDKVersion(), + }, + }; + }; + + static makeResponse = (id: RequestId, data: MethodToResponse[Methods], version: string): SuccessResponse => ({ + id, + success: true, + version, + data, + }); + + static makeErrorResponse = (id: RequestId, error: string, version: string): ErrorResponse => ({ + id, + success: false, + error, + version, + }); +} + +export { MessageFormatter }; diff --git a/src/communication/messageIds.ts b/src/communication/messageIds.ts deleted file mode 100644 index b1fec587..00000000 --- a/src/communication/messageIds.ts +++ /dev/null @@ -1,14 +0,0 @@ -export const INTERFACE_MESSAGES = { - ENV_INFO: 'ENV_INFO', - ON_SAFE_INFO: 'ON_SAFE_INFO', - TRANSACTION_CONFIRMED: 'TRANSACTION_CONFIRMED', - TRANSACTION_REJECTED: 'TRANSACTION_REJECTED', - RPC_CALL_RESPONSE: 'RPC_CALL_RESPONSE', -} as const; - -export const SDK_MESSAGES = { - SAFE_APP_SDK_INITIALIZED: 'SAFE_APP_SDK_INITIALIZED', - SEND_TRANSACTIONS: 'SEND_TRANSACTIONS', - RPC_CALL: 'RPC_CALL', - SEND_TRANSACTIONS_V2: 'SEND_TRANSACTIONS_V2', -} as const; diff --git a/src/communication/methods.ts b/src/communication/methods.ts new file mode 100644 index 00000000..54db5f10 --- /dev/null +++ b/src/communication/methods.ts @@ -0,0 +1,6 @@ +export const METHODS = { + getEnvInfo: 'getEnvInfo', + sendTransactions: 'sendTransactions', + rpcCall: 'rpcCall', + getSafeInfo: 'getSafeInfo', +} as const; diff --git a/src/communication/utils.ts b/src/communication/utils.ts new file mode 100644 index 00000000..2ea0d609 --- /dev/null +++ b/src/communication/utils.ts @@ -0,0 +1,9 @@ +const generateRequestId = (): string => { + if (typeof window !== 'undefined') { + return window?.performance.now().toString(36); + } + + return new Date().getTime().toString(36); +}; + +export { generateRequestId }; diff --git a/src/eth/eth.test.ts b/src/eth/eth.test.ts index a789423a..ae3f3a06 100644 --- a/src/eth/eth.test.ts +++ b/src/eth/eth.test.ts @@ -1,9 +1,9 @@ import { TransactionConfig, PastLogsOptions } from 'web3-core'; import SDK from '../index'; -import { SDK_MESSAGES } from '../communication/messageIds'; +import { METHODS } from '../communication'; describe('Safe Apps SDK Read RPC Requests', () => { - const sdkInstance = new SDK([/http:\/\/localhost:3000/]); + const sdkInstance = new SDK({ whitelistedDomains: [/http:\/\/localhost:3000/] }); /* eslint-disable-next-line */ let spy: jest.SpyInstance; @@ -17,199 +17,150 @@ describe('Safe Apps SDK Read RPC Requests', () => { describe('Methods requiring default block param', () => { describe('getBalance', () => { - it('Should send a valid message to the interface and return a request ID', () => { - const requestId = '1000'; + it('Should send a valid message to the interface', () => { const addr = '0x0000000000000000000000000000000000000000'; - const request = sdkInstance.eth.getBalance({ - params: [addr, 'pending'], - requestId, - }); + sdkInstance.eth.getBalance([addr, 'pending']); expect(spy).toHaveBeenCalledWith( - { - messageId: SDK_MESSAGES.RPC_CALL, - data: { + expect.objectContaining({ + method: METHODS.rpcCall, + params: { call: 'eth_getBalance', params: [addr, 'pending'], }, - requestId, - }, + }), '*', ); - expect(request.requestId).toEqual(requestId); }); it('Should add `latest` as a default block parameter when one is not passed', () => { - const requestId = '1000'; const addr = '0x0000000000000000000000000000000000000000'; - const request = sdkInstance.eth.getBalance({ - params: [addr], - requestId, - }); + sdkInstance.eth.getBalance([addr]); expect(spy).toHaveBeenCalledWith( - { - messageId: SDK_MESSAGES.RPC_CALL, - data: { + expect.objectContaining({ + method: METHODS.rpcCall, + params: { call: 'eth_getBalance', params: [addr, 'latest'], }, - requestId, - }, + }), '*', ); - expect(request.requestId).toEqual(requestId); }); }); describe('getCode', () => { - it('Should send a valid message to the interface and return a request ID', () => { - const requestId = '1000'; + it('Should send a valid message to the interface', () => { const addr = '0x0000000000000000000000000000000000000000'; - const request = sdkInstance.eth.getCode({ - params: [addr, 'pending'], - requestId, - }); + sdkInstance.eth.getCode([addr, 'pending']); expect(spy).toHaveBeenCalledWith( - { - messageId: SDK_MESSAGES.RPC_CALL, - data: { + expect.objectContaining({ + method: METHODS.rpcCall, + params: { call: 'eth_getCode', params: [addr, 'pending'], }, - requestId, - }, + }), '*', ); - expect(request.requestId).toEqual(requestId); }); it('Should add `latest` as a default block parameter when one is not passed', () => { - const requestId = '1000'; const addr = '0x0000000000000000000000000000000000000000'; - const request = sdkInstance.eth.getCode({ - params: [addr], - requestId, - }); + sdkInstance.eth.getCode([addr]); expect(spy).toHaveBeenCalledWith( - { - messageId: SDK_MESSAGES.RPC_CALL, - data: { + expect.objectContaining({ + method: METHODS.rpcCall, + params: { call: 'eth_getCode', params: [addr, 'latest'], }, - requestId, - }, + }), '*', ); - expect(request.requestId).toEqual(requestId); }); }); describe('getStorageAt', () => { - it('Should send a valid message to the interface and return a request ID', () => { - const requestId = '1000'; + it('Should send a valid message to the interface', () => { const addr = '0x0000000000000000000000000000000000000000'; - const request = sdkInstance.eth.getStorageAt({ - params: [addr, 'earliest'], - requestId, - }); + sdkInstance.eth.getStorageAt([addr, 0, 'earliest']); expect(spy).toHaveBeenCalledWith( - { - messageId: SDK_MESSAGES.RPC_CALL, - data: { + expect.objectContaining({ + method: METHODS.rpcCall, + params: { call: 'eth_getStorageAt', - params: [addr, 'earliest'], + params: [addr, '0x0', 'earliest'], }, - requestId, - }, + }), '*', ); - expect(request.requestId).toEqual(requestId); }); it('Should add `latest` as a default block parameter when one is not passed', () => { - const requestId = '1000'; const addr = '0x0000000000000000000000000000000000000000'; - const request = sdkInstance.eth.getStorageAt({ - params: [addr], - requestId, - }); + sdkInstance.eth.getStorageAt([addr, 0]); expect(spy).toHaveBeenCalledWith( - { - messageId: SDK_MESSAGES.RPC_CALL, - data: { + expect.objectContaining({ + method: METHODS.rpcCall, + params: { call: 'eth_getStorageAt', - params: [addr, 'latest'], + params: [addr, '0x0', 'latest'], }, - requestId, - }, + }), '*', ); - expect(request.requestId).toEqual(requestId); }); }); describe('call', () => { - it('Should send a valid message to the interface and return a request ID', () => { - const requestId = '1000'; + it('Should send a valid message to the interface', () => { const config: TransactionConfig = { from: '0x0000000000000000000000000000000000000000', to: '0x0000000000000000000000000000000000000000', }; - const request = sdkInstance.eth.call({ - params: [config, 'pending'], - requestId, - }); + sdkInstance.eth.call([config, 'pending']); expect(spy).toHaveBeenCalledWith( - { - messageId: SDK_MESSAGES.RPC_CALL, - data: { + expect.objectContaining({ + method: METHODS.rpcCall, + params: { call: 'eth_call', params: [config, 'pending'], }, - requestId, - }, + }), '*', ); - expect(request.requestId).toEqual(requestId); }); it('Should add `latest` as a default block parameter when one is not passed', () => { - const requestId = '1000'; const config: TransactionConfig = { from: '0x0000000000000000000000000000000000000000', to: '0x0000000000000000000000000000000000000000', }; - const request = sdkInstance.eth.call({ - params: [config], - requestId, - }); + sdkInstance.eth.call([config]); expect(spy).toHaveBeenCalledWith( - { - messageId: SDK_MESSAGES.RPC_CALL, - data: { + expect.objectContaining({ + method: METHODS.rpcCall, + params: { call: 'eth_call', params: [config, 'latest'], }, - requestId, - }, + }), '*', ); - expect(request.requestId).toEqual(requestId); }); }); }); describe('getPastLogs', () => { - it('Should send a valid message to the interface and return a request ID', () => { - const requestId = '1000'; + it('Should send a valid message to the interface', () => { const number = 11054275; const params: [PastLogsOptions] = [ { @@ -217,163 +168,122 @@ describe('Safe Apps SDK Read RPC Requests', () => { toBlock: 'latest', }, ]; - const request = sdkInstance.eth.getPastLogs({ - params, - requestId, - }); + sdkInstance.eth.getPastLogs(params); expect(spy).toHaveBeenCalledWith( - { - messageId: SDK_MESSAGES.RPC_CALL, - data: { + expect.objectContaining({ + method: METHODS.rpcCall, + params: { call: 'eth_getLogs', params, }, - requestId, - }, + }), '*', ); - expect(request.requestId).toEqual(requestId); }); }); describe('getBlockByHash', () => { - it('Should send a valid message to the interface and return a request ID', () => { - const requestId = '1000'; + it('Should send a valid message to the interface', () => { const hash = '0x1955a9f306903669e295196752b11bc0dee33b48cabdf44b1103b7cea086cae7'; - const request = sdkInstance.eth.getBlockByHash({ - params: [hash], - requestId, - }); + sdkInstance.eth.getBlockByHash([hash]); expect(spy).toHaveBeenCalledWith( - { - messageId: SDK_MESSAGES.RPC_CALL, - data: { + expect.objectContaining({ + method: METHODS.rpcCall, + params: { call: 'eth_getBlockByHash', params: [hash, false], }, - requestId, - }, + }), '*', ); - expect(request.requestId).toEqual(requestId); }); it('Should respect passed full tx object boolean param', () => { - const requestId = '1000'; const hash = '0x1955a9f306903669e295196752b11bc0dee33b48cabdf44b1103b7cea086cae7'; - const request = sdkInstance.eth.getBlockByHash({ - params: [hash, true], - requestId, - }); + sdkInstance.eth.getBlockByHash([hash, true]); expect(spy).toHaveBeenCalledWith( - { - messageId: SDK_MESSAGES.RPC_CALL, - data: { + expect.objectContaining({ + method: METHODS.rpcCall, + params: { call: 'eth_getBlockByHash', params: [hash, true], }, - requestId, - }, + }), '*', ); - expect(request.requestId).toEqual(requestId); }); }); describe('getBlockByNumber', () => { - it('Should send a valid message to the interface and return a request ID', () => { - const requestId = '1000'; - const number = '11054275'; - const request = sdkInstance.eth.getBlockByNumber({ - params: [number], - requestId, - }); + it('Should send a valid message to the interface', () => { + const number = 11054275; + sdkInstance.eth.getBlockByNumber([number]); expect(spy).toHaveBeenCalledWith( - { - messageId: SDK_MESSAGES.RPC_CALL, - data: { + expect.objectContaining({ + method: METHODS.rpcCall, + params: { call: 'eth_getBlockByNumber', - params: [number, false], + params: ['0xa8acc3', false], }, - requestId, - }, + }), '*', ); - expect(request.requestId).toEqual(requestId); }); it('Should respect passed full tx object boolean param', () => { - const requestId = '1000'; - const number = '11054275'; - const request = sdkInstance.eth.getBlockByNumber({ - params: [number, true], - requestId, - }); + const number = 11054275; + sdkInstance.eth.getBlockByNumber([number, true]); expect(spy).toHaveBeenCalledWith( - { - messageId: SDK_MESSAGES.RPC_CALL, - data: { + expect.objectContaining({ + method: METHODS.rpcCall, + params: { call: 'eth_getBlockByNumber', - params: [number, true], + params: ['0xa8acc3', true], }, - requestId, - }, + }), '*', ); - expect(request.requestId).toEqual(requestId); }); }); describe('getTransactionByHash', () => { - it('Should send a valid message to the interface and return a request ID', () => { - const requestId = '1000'; + it('Should send a valid message to the interface', () => { const hash = '0x0e6cd6237b4d3e5c3f348b78399f031b527e832bd30924951ba4921cdbf440d7'; - const request = sdkInstance.eth.getTransactionByHash({ - params: [hash], - requestId, - }); + sdkInstance.eth.getTransactionByHash([hash]); expect(spy).toHaveBeenCalledWith( - { - messageId: SDK_MESSAGES.RPC_CALL, - data: { + expect.objectContaining({ + method: METHODS.rpcCall, + params: { call: 'eth_getTransactionByHash', params: [hash], }, - requestId, - }, + }), '*', ); - expect(request.requestId).toEqual(requestId); }); }); describe('getTransactionReceipt', () => { - it('Should send a valid message to the interface and return a request ID', () => { - const requestId = '1000'; + it('Should send a valid message to the interface', () => { const hash = '0x0e6cd6237b4d3e5c3f348b78399f031b527e832bd30924951ba4921cdbf440d7'; - const request = sdkInstance.eth.getTransactionReceipt({ - params: [hash], - requestId, - }); + sdkInstance.eth.getTransactionReceipt([hash]); expect(spy).toHaveBeenCalledWith( - { - messageId: SDK_MESSAGES.RPC_CALL, - data: { + expect.objectContaining({ + method: METHODS.rpcCall, + params: { call: 'eth_getTransactionReceipt', params: [hash], }, - requestId, - }, + }), '*', ); - expect(request.requestId).toEqual(requestId); }); }); }); diff --git a/src/eth/index.ts b/src/eth/index.ts index b4034bb9..3e697879 100644 --- a/src/eth/index.ts +++ b/src/eth/index.ts @@ -1,11 +1,28 @@ import { TransactionConfig, PastLogsOptions } from 'web3-core'; import { RPC_CALLS } from '../eth/constants'; -import { RpcCallNames, RequestArgs, RPCPayload, SentSDKMessage, Communicator } from './../types'; -import { SDK_MESSAGES } from './../communication/messageIds'; +import { + RpcCallNames, + Communicator, + Log, + BlockTransactionString, + BlockTransactionObject, + Web3TransactionObject, + RPCPayload, +} from '../types'; +import { METHODS } from '../communication/methods'; -const inputFormatters = { +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type Formatter = (arg: any) => any; + +const inputFormatters: Record = { defaultBlockParam: (arg = 'latest') => arg, - fullTxObjectParam: (arg = false) => arg, + returnFullTxObjectParam: (arg = false): boolean => arg, + numberToHex: (arg: number): string => `0x${arg.toString(16)}`, +}; + +type BuildRequestArgs = { + call: RpcCallNames; + formatters?: (Formatter | null)[]; }; class Eth { @@ -18,72 +35,67 @@ class Eth { public getBlockByNumber; public getTransactionByHash; public getTransactionReceipt; - private communicator; + #communicator: Communicator; constructor(communicator: Communicator) { - this.communicator = communicator; - this.call = this.buildRequest<[TransactionConfig, string?], typeof RPC_CALLS.eth_call>({ + this.#communicator = communicator; + this.call = this.buildRequest<[TransactionConfig, string?], string>({ call: RPC_CALLS.eth_call, formatters: [null, inputFormatters.defaultBlockParam], }); - this.getBalance = this.buildRequest<[string, string?], typeof RPC_CALLS.eth_getBalance>({ + this.getBalance = this.buildRequest<[string, string?], string>({ call: RPC_CALLS.eth_getBalance, formatters: [null, inputFormatters.defaultBlockParam], }); - this.getCode = this.buildRequest<[string, string?], typeof RPC_CALLS.eth_getCode>({ + this.getCode = this.buildRequest<[string, string?], string>({ call: RPC_CALLS.eth_getCode, formatters: [null, inputFormatters.defaultBlockParam], }); - this.getStorageAt = this.buildRequest<[string, string?], typeof RPC_CALLS.eth_getStorageAt>({ + this.getStorageAt = this.buildRequest<[string, number, string?], string>({ call: RPC_CALLS.eth_getStorageAt, - formatters: [null, inputFormatters.defaultBlockParam], + formatters: [null, inputFormatters.numberToHex, inputFormatters.defaultBlockParam], }); - this.getPastLogs = this.buildRequest<[PastLogsOptions], typeof RPC_CALLS.eth_getLogs>({ + this.getPastLogs = this.buildRequest<[PastLogsOptions], Log[]>({ call: RPC_CALLS.eth_getLogs, }); - this.getBlockByHash = this.buildRequest<[string, boolean?], typeof RPC_CALLS.eth_getBlockByHash>({ + this.getBlockByHash = this.buildRequest<[string, boolean?], BlockTransactionString | BlockTransactionObject>({ call: RPC_CALLS.eth_getBlockByHash, - formatters: [null, inputFormatters.fullTxObjectParam], + formatters: [null, inputFormatters.returnFullTxObjectParam], }); - this.getBlockByNumber = this.buildRequest<[string, boolean?], typeof RPC_CALLS.eth_getBlockByNumber>({ + this.getBlockByNumber = this.buildRequest<[number, boolean?], BlockTransactionString | BlockTransactionObject>({ call: RPC_CALLS.eth_getBlockByNumber, - formatters: [null, inputFormatters.fullTxObjectParam], + formatters: [inputFormatters.numberToHex, inputFormatters.returnFullTxObjectParam], }); - this.getTransactionByHash = this.buildRequest<[string], typeof RPC_CALLS.eth_getTransactionByHash>({ + this.getTransactionByHash = this.buildRequest<[string], Web3TransactionObject>({ call: RPC_CALLS.eth_getTransactionByHash, }); - this.getTransactionReceipt = this.buildRequest<[string], typeof RPC_CALLS.eth_getTransactionReceipt>({ + this.getTransactionReceipt = this.buildRequest<[string], Web3TransactionObject>({ call: RPC_CALLS.eth_getTransactionReceipt, }); } - private buildRequest

({ - call, - formatters, - }: { - call: C; - /* eslint-disable-next-line */ - formatters?: (((arg: any) => any) | null)[]; - }) { - return (args: RequestArgs

): SentSDKMessage<'RPC_CALL', RPCPayload> => { - const params = args.params; - + private buildRequest

({ call, formatters }: BuildRequestArgs) { + return async (params: P): Promise => { if (formatters && Array.isArray(params)) { formatters.forEach((formatter: ((...args: unknown[]) => unknown) | null, i) => { if (formatter) { - params[i] = formatter((args.params as unknown[])[i]); + params[i] = formatter(params[i]); } }); } - const payload = { + const payload: RPCPayload

= { call, params, }; - const message = this.communicator.send(SDK_MESSAGES.RPC_CALL, payload, args.requestId); + const response = await this.#communicator.send<'rpcCall', RPCPayload

, R>(METHODS.rpcCall, payload); + + if (!response.success) { + throw new Error(response.error); + } - return message; + return response.data; }; } } diff --git a/src/index.ts b/src/index.ts index a29ec3b8..ffa8dbfb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,8 @@ import SDK from './sdk'; export default SDK; - +export * from './sdk'; export * from './types'; -export * from './communication/messageIds'; +export * from './communication/methods'; +export * from './communication/messageFormatter'; +export { getSDKVersion } from './utils'; diff --git a/src/sdk.test.ts b/src/sdk.test.ts index 0f55b6f0..9548490c 100644 --- a/src/sdk.test.ts +++ b/src/sdk.test.ts @@ -1,68 +1,29 @@ import SDK, { SdkInstance } from './index'; -import { SDK_MESSAGES } from './communication/messageIds'; describe('Safe apps SDK', () => { let sdkInstance: SdkInstance; describe('initSdk', () => { - test('Should initialize with regExp', () => { - sdkInstance = new SDK([/http:\/\/localhost:3000/]); - expect(sdkInstance.sendTransactions).not.toBeUndefined(); + test('Should initialize with opts', () => { + sdkInstance = new SDK({ whitelistedDomains: [/http:\/\/localhost:3000/] }); + expect(sdkInstance.txs.send).not.toBeUndefined(); }); - test('Should initialize without regExp', () => { - sdkInstance = new SDK([/http:\/\/localhost:3000/]); - expect(sdkInstance.sendTransactions).not.toBeUndefined(); + test('Should initialize without opts', () => { + sdkInstance = new SDK(); + expect(sdkInstance.txs.send).not.toBeUndefined(); }); - test('Should send initialization message', () => { + test("should send a getEnvInfo message to obtain information about interface's env", () => { const spy = jest.spyOn(window.parent, 'postMessage'); - sdkInstance = new SDK([/http:\/\/localhost:3000/]); + sdkInstance = new SDK(); + expect(spy).toHaveBeenCalledWith( expect.objectContaining({ - messageId: SDK_MESSAGES.SAFE_APP_SDK_INITIALIZED, - data: undefined, - requestId: expect.any(Number), + method: 'getEnvInfo', }), '*', ); }); }); - - describe('sendTransactions', () => { - test('Should throw an error when passing an empty array', () => { - expect(() => { - sdkInstance.sendTransactions({ txs: [] }); - }).toThrow(); - }); - - test('Should call window.parent.postMessage with a requestId when passing array of TXs', () => { - const requestId = '1000'; - const spy = jest.spyOn(window.parent, 'postMessage'); - const txs = [{ to: 'address', value: '0', data: '0x' }]; - sdkInstance.sendTransactions({ txs, requestId }); - expect(spy).toHaveBeenCalledWith( - { messageId: SDK_MESSAGES.SEND_TRANSACTIONS_V2, data: { txs, params: undefined }, requestId }, - '*', - ); - }); - - test('Should return a message containing requestId', () => { - const txs = [{ to: 'address', value: '0', data: '0x' }]; - sdkInstance.sendTransactions({ txs }); - - // expect(typeof request.requestId).toBe('number'); - // expect(request.data).toEqual({ txs }); - }); - - test('Should include passed safeTxGas and requestId params to a message body', () => { - const txs = [{ to: 'address', value: '0', data: '0x' }]; - const requestId = 1234; - const params = { safeTxGas: 5000 }; - sdkInstance.sendTransactions({ txs, params, requestId }); - - // expect(request.requestId).toBe(requestId); - // expect(request.data).toEqual({ txs, params }); - }); - }); }); diff --git a/src/sdk.ts b/src/sdk.ts index c2e9d878..5b8276ec 100644 --- a/src/sdk.ts +++ b/src/sdk.ts @@ -1,40 +1,56 @@ -import { SendTransactionsArgs, Communicator } from './types'; -import InterfaceCommunicator, { SDK_MESSAGES } from './communication'; +import { METHODS } from './communication'; +import { Communicator, SafeInfo, EnvInfo } from './types'; +import InterfaceCommunicator from './communication'; import { TXs } from './txs'; import { Eth } from './eth'; -class SDK { +type Opts = { + whitelistedDomains?: RegExp[]; +}; + +class SafeAppsSDK { #communicator: Communicator; public readonly eth; public readonly txs; - constructor(safeAppUrlsRegExp: RegExp[] = []) { + constructor(opts: Opts = {}) { if (typeof window === 'undefined') { throw new Error('Error initializing the sdk: window is undefined'); } - this.#communicator = new InterfaceCommunicator(safeAppUrlsRegExp); + const { whitelistedDomains = null } = opts; + + this.#communicator = new InterfaceCommunicator(whitelistedDomains); this.eth = new Eth(this.#communicator); - this.txs = new TXs(); - this.sendInitializationMessage(); + this.txs = new TXs(this.#communicator); + this.bootstrap(); } - private sendInitializationMessage() { - this.#communicator.send('SAFE_APP_SDK_INITIALIZED', undefined); + private async bootstrap(): Promise { + const { txServiceUrl } = await this.getEnvInfo(); + + this.txs.setTxServiceUrl(txServiceUrl); } - sendTransactions({ txs, params, requestId }: SendTransactionsArgs): void { - if (!txs || !txs.length) { - throw new Error('sendTransactionsWithParams: No transactions were passed'); + private async getEnvInfo(): Promise { + const response = await this.#communicator.send<'getEnvInfo', undefined, EnvInfo>(METHODS.getEnvInfo, undefined); + + if (!response.success) { + throw new Error(response.error); } - const messagePayload = { - txs, - params, - }; + return response.data; + } + + async getSafeInfo(): Promise { + const response = await this.#communicator.send<'getSafeInfo', undefined, SafeInfo>(METHODS.getSafeInfo, undefined); + + if (!response.success) { + throw new Error(response.error); + } - this.#communicator.send(SDK_MESSAGES.SEND_TRANSACTIONS_V2, messagePayload, requestId); + return response.data; } } -export default SDK; +export default SafeAppsSDK; diff --git a/src/txs/index.ts b/src/txs/index.ts index 9cedc677..075f60c3 100644 --- a/src/txs/index.ts +++ b/src/txs/index.ts @@ -1,7 +1,13 @@ -import { TxServiceModel } from './../types'; +import { METHODS } from '../communication/methods'; +import { TxServiceModel, SendTransactionsArgs, Communicator, SendTransactionsResponse } from '../types'; class TXs { #txServiceUrl: string | null = null; + #communicator: Communicator; + + constructor(communicator: Communicator) { + this.#communicator = communicator; + } async getBySafeTxHash(safeTxHash: string): Promise { if (!this.#txServiceUrl) { @@ -25,6 +31,28 @@ class TXs { } } + async send({ txs, params }: SendTransactionsArgs): Promise { + if (!txs || !txs.length) { + throw new Error('No transactions were passed'); + } + + const messagePayload = { + txs, + params, + }; + + const response = await this.#communicator.send<'sendTransactions', SendTransactionsArgs, SendTransactionsResponse>( + METHODS.sendTransactions, + messagePayload, + ); + + if (!response.success) { + throw new Error(response.error); + } + + return response.data; + } + public setTxServiceUrl(url: string): void { this.#txServiceUrl = url; } diff --git a/src/txs/txs.test.ts b/src/txs/txs.test.ts new file mode 100644 index 00000000..d6d6d4a7 --- /dev/null +++ b/src/txs/txs.test.ts @@ -0,0 +1,43 @@ +import SDK from '../index'; +import { METHODS } from '../communication/methods'; + +describe('Safe Apps SDK transaction methods', () => { + const sdkInstance = new SDK(); + /* eslint-disable-next-line */ + let spy: jest.SpyInstance; + + beforeEach(() => { + spy = jest.spyOn(window.parent, 'postMessage'); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + describe('SDK.txs.send', () => { + test('Should throw an error when passing an empty array', async () => { + await expect(sdkInstance.txs.send({ txs: [] })).rejects.toEqual(new Error('No transactions were passed')); + }); + + test('Should call window.parent.postMessage when passing array of TXs', () => { + const txs = [{ to: 'address', value: '0', data: '0x' }]; + + sdkInstance.txs.send({ txs }); + expect(spy).toHaveBeenCalledWith( + expect.objectContaining({ method: METHODS.sendTransactions, params: { txs, params: undefined } }), + '*', + ); + }); + + test('Should include passed params to a message body', () => { + const txs = [{ to: 'address', value: '0', data: '0x' }]; + const params = { safeTxGas: 5000 }; + + sdkInstance.txs.send({ txs, params }); + expect(spy).toHaveBeenCalledWith( + expect.objectContaining({ method: METHODS.sendTransactions, params: { txs, params } }), + '*', + ); + }); + }); +}); diff --git a/src/types.ts b/src/types.ts index e3b272af..4c6a1673 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,4 @@ -import { INTERFACE_MESSAGES, SDK_MESSAGES } from './communication/messageIds'; +import { METHODS } from './communication/methods'; import { RPC_CALLS } from './eth/constants'; import { TXs } from './txs'; import { Eth } from './eth'; @@ -38,7 +38,7 @@ export interface Transaction { data: string; } -export type RequestId = number | string; +export type RequestId = string; export interface SendTransactionParams { safeTxGas?: number; @@ -47,10 +47,13 @@ export interface SendTransactionParams { export interface SendTransactionsArgs { txs: Transaction[]; params?: SendTransactionParams; - requestId?: RequestId; } + +export type SendTransactionsResponse = { + safeTxHash: string; +}; + export interface SdkInstance { - sendTransactions: (args: SendTransactionsArgs) => void; txs: TXs; eth: Eth; } @@ -58,64 +61,53 @@ export interface SdkInstance { export interface SafeInfo { safeAddress: string; network: LowercaseNetworks; - ethBalance: string; } -export interface TxConfirmationEvent { - requestId: RequestId; - safeTxHash: string; -} +export type Methods = keyof typeof METHODS; -export interface TxRejectionEvent { - requestId: RequestId; -} +export type SDKRequestData = { + id: RequestId; + params: P; + env: { + sdkVersion: string; + }; + method: M; +}; -export type InterfaceMessageIds = keyof typeof INTERFACE_MESSAGES; +export type SDKMessageEvent = MessageEvent; -export interface InterfaceMessageEvent extends MessageEvent { - data: { - requestId: RequestId; - messageId: InterfaceMessageIds; - data: InterfaceMessageToPayload[InterfaceMessageIds]; - }; -} +export type ErrorResponse = { + id: RequestId; + success: false; + error: string; + version?: string; +}; -export interface SDKMessageToPayload { - [SDK_MESSAGES.SAFE_APP_SDK_INITIALIZED]: undefined; - [SDK_MESSAGES.SEND_TRANSACTIONS]: Transaction[]; - [SDK_MESSAGES.RPC_CALL]: { - call: RpcCallNames; - params: unknown[]; - }; - [SDK_MESSAGES.SEND_TRANSACTIONS_V2]: { - txs: Transaction[]; - params?: SendTransactionParams; - }; -} +export type SuccessResponse = { + id: RequestId; + data: T; + version?: string; + success: true; +}; -export type SDKMessageIds = keyof typeof SDK_MESSAGES; +export type Response = ErrorResponse | SuccessResponse; -export interface InterfaceMessageToPayload { - [INTERFACE_MESSAGES.ON_SAFE_INFO]: SafeInfo; - [INTERFACE_MESSAGES.TRANSACTION_CONFIRMED]: { - safeTxHash: string; - }; - [INTERFACE_MESSAGES.ENV_INFO]: { - txServiceUrl: string; - }; - [INTERFACE_MESSAGES.TRANSACTION_REJECTED]: Record; - [INTERFACE_MESSAGES.RPC_CALL_RESPONSE]: unknown; -} +export type InterfaceMessageEvent = MessageEvent; -export type RPCPayload = { - call: R; - params: P; +export type EnvInfo = { + txServiceUrl: string; }; -export type SentSDKMessage = { - messageId: T; - requestId: RequestId; - data: D; +export interface MethodToResponse { + [METHODS.getEnvInfo]: EnvInfo; + [METHODS.sendTransactions]: Record; + [METHODS.rpcCall]: unknown; + [METHODS.getSafeInfo]: SafeInfo; +} + +export type RPCPayload

= { + call: RpcCallNames; + params: P; }; // copy-pasting all the types below from safe-react makes me think we might want to export them to a package @@ -220,15 +212,63 @@ export type TxServiceModel = { export type RpcCallNames = keyof typeof RPC_CALLS; -export type RequestArgs = { - params: T; - requestId?: RequestId; -}; - export interface Communicator { - send( - messageId: T, - data: D, - requestId?: RequestId, - ): SentSDKMessage; + send(method: M, params: P): Promise>; +} + +export interface Log { + address: string; + data: string; + topics: string[]; + logIndex: number; + transactionIndex: number; + transactionHash: string; + blockHash: string; + blockNumber: number; +} + +export interface BlockHeader { + number: number; + hash: string; + parentHash: string; + nonce: string; + sha3Uncles: string; + logsBloom: string; + transactionRoot: string; + stateRoot: string; + receiptRoot: string; + miner: string; + extraData: string; + gasLimit: number; + gasUsed: number; + timestamp: number | string; +} + +export interface BlockTransactionBase extends BlockHeader { + size: number; + difficulty: number; + totalDifficulty: number; + uncles: string[]; +} + +export interface BlockTransactionObject extends BlockTransactionBase { + transactions: Transaction[]; +} + +export interface BlockTransactionString extends BlockTransactionBase { + transactions: string[]; +} + +export interface Web3TransactionObject { + hash: string; + nonce: number; + blockHash: string | null; + blockNumber: number | null; + transactionIndex: number | null; + from: string; + to: string | null; + value: string; + gasPrice: string; + gas: number; + input: string; } diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 00000000..d0a4d518 --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,3 @@ +import pkg from '../package.json'; + +export const getSDKVersion = (): string => pkg.version; diff --git a/tsconfig.json b/tsconfig.json index 56ead9bd..6d6b24a2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,7 +14,8 @@ "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, - "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, + "resolveJsonModule": true }, "include": ["src"] } diff --git a/yarn.lock b/yarn.lock index 560ef831..259c77b3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -257,6 +257,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" +"@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz#dd6c0b357ac1bb142d98537450a319625d13d2a0" + integrity sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/template@^7.3.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278" @@ -440,98 +447,93 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== -"@jest/console@^26.6.1": - version "26.6.1" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-26.6.1.tgz#6a19eaac4aa8687b4db9130495817c65aec3d34e" - integrity sha512-cjqcXepwC5M+VeIhwT6Xpi/tT4AiNzlIx8SMJ9IihduHnsSrnWNvTBfKIpmqOOCNOPqtbBx6w2JqfoLOJguo8g== +"@jest/console@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-26.6.2.tgz#4e04bc464014358b03ab4937805ee36a0aeb98f2" + integrity sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g== dependencies: - "@jest/types" "^26.6.1" + "@jest/types" "^26.6.2" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^26.6.1" - jest-util "^26.6.1" + jest-message-util "^26.6.2" + jest-util "^26.6.2" slash "^3.0.0" -"@jest/core@^26.6.1": - version "26.6.1" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-26.6.1.tgz#77426822f667a2cda82bf917cee11cc8ba71f9ac" - integrity sha512-p4F0pgK3rKnoS9olXXXOkbus1Bsu6fd8pcvLMPsUy4CVXZ8WSeiwQ1lK5hwkCIqJ+amZOYPd778sbPha/S8Srw== +"@jest/core@^26.6.3": + version "26.6.3" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-26.6.3.tgz#7639fcb3833d748a4656ada54bde193051e45fad" + integrity sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw== dependencies: - "@jest/console" "^26.6.1" - "@jest/reporters" "^26.6.1" - "@jest/test-result" "^26.6.1" - "@jest/transform" "^26.6.1" - "@jest/types" "^26.6.1" + "@jest/console" "^26.6.2" + "@jest/reporters" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/transform" "^26.6.2" + "@jest/types" "^26.6.2" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" exit "^0.1.2" graceful-fs "^4.2.4" - jest-changed-files "^26.6.1" - jest-config "^26.6.1" - jest-haste-map "^26.6.1" - jest-message-util "^26.6.1" + jest-changed-files "^26.6.2" + jest-config "^26.6.3" + jest-haste-map "^26.6.2" + jest-message-util "^26.6.2" jest-regex-util "^26.0.0" - jest-resolve "^26.6.1" - jest-resolve-dependencies "^26.6.1" - jest-runner "^26.6.1" - jest-runtime "^26.6.1" - jest-snapshot "^26.6.1" - jest-util "^26.6.1" - jest-validate "^26.6.1" - jest-watcher "^26.6.1" + jest-resolve "^26.6.2" + jest-resolve-dependencies "^26.6.3" + jest-runner "^26.6.3" + jest-runtime "^26.6.3" + jest-snapshot "^26.6.2" + jest-util "^26.6.2" + jest-validate "^26.6.2" + jest-watcher "^26.6.2" micromatch "^4.0.2" p-each-series "^2.1.0" rimraf "^3.0.0" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/create-cache-key-function@^26.5.0": - version "26.5.0" - resolved "https://registry.yarnpkg.com/@jest/create-cache-key-function/-/create-cache-key-function-26.5.0.tgz#1d07947adc51ea17766d9f0ccf5a8d6ea94c47dc" - integrity sha512-DJ+pEBUIqarrbv1W/C39f9YH0rJ4wsXZ/VC6JafJPlHW2HOucKceeaqTOQj9MEDQZjySxMLkOq5mfXZXNZcmWw== - -"@jest/environment@^26.6.1": - version "26.6.1" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-26.6.1.tgz#38a56f1cc66f96bf53befcc5ebeaf1c2dce90e9a" - integrity sha512-GNvHwkOFJtNgSwdzH9flUPzF9AYAZhUg124CBoQcwcZCM9s5TLz8Y3fMtiaWt4ffbigoetjGk5PU2Dd8nLrSEw== +"@jest/environment@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-26.6.2.tgz#ba364cc72e221e79cc8f0a99555bf5d7577cf92c" + integrity sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA== dependencies: - "@jest/fake-timers" "^26.6.1" - "@jest/types" "^26.6.1" + "@jest/fake-timers" "^26.6.2" + "@jest/types" "^26.6.2" "@types/node" "*" - jest-mock "^26.6.1" + jest-mock "^26.6.2" -"@jest/fake-timers@^26.6.1": - version "26.6.1" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-26.6.1.tgz#5aafba1822075b7142e702b906094bea15f51acf" - integrity sha512-T/SkMLgOquenw/nIisBRD6XAYpFir0kNuclYLkse5BpzeDUukyBr+K31xgAo9M0hgjU9ORlekAYPSzc0DKfmKg== +"@jest/fake-timers@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-26.6.2.tgz#459c329bcf70cee4af4d7e3f3e67848123535aad" + integrity sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA== dependencies: - "@jest/types" "^26.6.1" + "@jest/types" "^26.6.2" "@sinonjs/fake-timers" "^6.0.1" "@types/node" "*" - jest-message-util "^26.6.1" - jest-mock "^26.6.1" - jest-util "^26.6.1" + jest-message-util "^26.6.2" + jest-mock "^26.6.2" + jest-util "^26.6.2" -"@jest/globals@^26.6.1": - version "26.6.1" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-26.6.1.tgz#b232c7611d8a2de62b4bf9eb9a007138322916f4" - integrity sha512-acxXsSguuLV/CeMYmBseefw6apO7NuXqpE+v5r3yD9ye2PY7h1nS20vY7Obk2w6S7eJO4OIAJeDnoGcLC/McEQ== +"@jest/globals@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-26.6.2.tgz#5b613b78a1aa2655ae908eba638cc96a20df720a" + integrity sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA== dependencies: - "@jest/environment" "^26.6.1" - "@jest/types" "^26.6.1" - expect "^26.6.1" + "@jest/environment" "^26.6.2" + "@jest/types" "^26.6.2" + expect "^26.6.2" -"@jest/reporters@^26.6.1": - version "26.6.1" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-26.6.1.tgz#582ede05278cf5eeffe58bc519f4a35f54fbcb0d" - integrity sha512-J6OlXVFY3q1SXWJhjme5i7qT/BAZSikdOK2t8Ht5OS32BDo6KfG5CzIzzIFnAVd82/WWbc9Hb7SJ/jwSvVH9YA== +"@jest/reporters@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-26.6.2.tgz#1f518b99637a5f18307bd3ecf9275f6882a667f6" + integrity sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^26.6.1" - "@jest/test-result" "^26.6.1" - "@jest/transform" "^26.6.1" - "@jest/types" "^26.6.1" + "@jest/console" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/transform" "^26.6.2" + "@jest/types" "^26.6.2" chalk "^4.0.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" @@ -542,63 +544,63 @@ istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.0.2" - jest-haste-map "^26.6.1" - jest-resolve "^26.6.1" - jest-util "^26.6.1" - jest-worker "^26.6.1" + jest-haste-map "^26.6.2" + jest-resolve "^26.6.2" + jest-util "^26.6.2" + jest-worker "^26.6.2" slash "^3.0.0" source-map "^0.6.0" string-length "^4.0.1" terminal-link "^2.0.0" - v8-to-istanbul "^6.0.1" + v8-to-istanbul "^7.0.0" optionalDependencies: node-notifier "^8.0.0" -"@jest/source-map@^26.5.0": - version "26.5.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-26.5.0.tgz#98792457c85bdd902365cd2847b58fff05d96367" - integrity sha512-jWAw9ZwYHJMe9eZq/WrsHlwF8E3hM9gynlcDpOyCb9bR8wEd9ZNBZCi7/jZyzHxC7t3thZ10gO2IDhu0bPKS5g== +"@jest/source-map@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-26.6.2.tgz#29af5e1e2e324cafccc936f218309f54ab69d535" + integrity sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA== dependencies: callsites "^3.0.0" graceful-fs "^4.2.4" source-map "^0.6.0" -"@jest/test-result@^26.6.1": - version "26.6.1" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-26.6.1.tgz#d75698d8a06aa663e8936663778c831512330cc1" - integrity sha512-wqAgIerIN2gSdT2A8WeA5+AFh9XQBqYGf8etK143yng3qYd0mF0ie2W5PVmgnjw4VDU6ammI9NdXrKgNhreawg== +"@jest/test-result@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-26.6.2.tgz#55da58b62df134576cc95476efa5f7949e3f5f18" + integrity sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ== dependencies: - "@jest/console" "^26.6.1" - "@jest/types" "^26.6.1" + "@jest/console" "^26.6.2" + "@jest/types" "^26.6.2" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^26.6.1": - version "26.6.1" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-26.6.1.tgz#34216ac2c194b0eeebde30d25424d1134703fd2e" - integrity sha512-0csqA/XApZiNeTIPYh6koIDCACSoR6hi29T61tKJMtCZdEC+tF3PoNt7MS0oK/zKC6daBgCbqXxia5ztr/NyCQ== +"@jest/test-sequencer@^26.6.3": + version "26.6.3" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz#98e8a45100863886d074205e8ffdc5a7eb582b17" + integrity sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw== dependencies: - "@jest/test-result" "^26.6.1" + "@jest/test-result" "^26.6.2" graceful-fs "^4.2.4" - jest-haste-map "^26.6.1" - jest-runner "^26.6.1" - jest-runtime "^26.6.1" + jest-haste-map "^26.6.2" + jest-runner "^26.6.3" + jest-runtime "^26.6.3" -"@jest/transform@^26.6.1": - version "26.6.1" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.1.tgz#f70786f96e0f765947b4fb4f54ffcfb7bd783711" - integrity sha512-oNFAqVtqRxZRx6vXL3I4bPKUK0BIlEeaalkwxyQGGI8oXDQBtYQBpiMe5F7qPs4QdvvFYB42gPGIMMcxXaBBxQ== +"@jest/transform@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.2.tgz#5ac57c5fa1ad17b2aae83e73e45813894dcf2e4b" + integrity sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA== dependencies: "@babel/core" "^7.1.0" - "@jest/types" "^26.6.1" + "@jest/types" "^26.6.2" babel-plugin-istanbul "^6.0.0" chalk "^4.0.0" convert-source-map "^1.4.0" fast-json-stable-stringify "^2.0.0" graceful-fs "^4.2.4" - jest-haste-map "^26.6.1" + jest-haste-map "^26.6.2" jest-regex-util "^26.0.0" - jest-util "^26.6.1" + jest-util "^26.6.2" micromatch "^4.0.2" pirates "^4.0.1" slash "^3.0.0" @@ -637,6 +639,17 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" +"@jest/types@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" + integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^15.0.0" + chalk "^4.0.0" + "@nodelib/fs.scandir@2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" @@ -800,10 +813,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.0.tgz#a0f841c195bdbe0b5070da9278b3e22189e8c8f6" integrity sha512-4BVAE9yp5DU3ISqBInsaRp9J474HWNaNVs8eZ1Far3dI1MwS3Wk0EvBRMM4xBh3Oz+c05hUgJmcbtAVmG8bv7w== -"@types/node@^14.14.6": - version "14.14.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.6.tgz#146d3da57b3c636cc0d1769396ce1cfa8991147f" - integrity sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw== +"@types/node@^14.14.8": + version "14.14.8" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.8.tgz#2127bd81949a95c8b7d3240f3254352d72563aec" + integrity sha512-z/5Yd59dCKI5kbxauAJgw6dLPzW+TNOItNE00PkpzNwUIEwdj/Lsqwq94H5DdYBX7C13aRA0CY32BK76+neEUA== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -820,6 +833,11 @@ resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.0.2.tgz#5bb52ee68d0f8efa9cc0099920e56be6cc4e37f3" integrity sha512-IkVfat549ggtkZUthUzEX49562eGikhSYeVGX97SkMFn+sTZrgRewXjQ4tPKFPCykZHkX1Zfd9OoELGqKU2jJA== +"@types/semver@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.4.tgz#43d7168fec6fa0988bb1a513a697b29296721afb" + integrity sha512-+nVsLKlcUCeMzD2ufHEYuJ9a2ovstb6Dp52A5VsoKxDXgvE051XgHI/33I1EymwkRGQkwnA0LkhnUzituGs4EQ== + "@types/stack-utils@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff" @@ -837,61 +855,61 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@^4.6.0": - version "4.6.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.6.0.tgz#210cd538bb703f883aff81d3996961f5dba31fdb" - integrity sha512-1+419X+Ynijytr1iWI+/IcX/kJryc78YNpdaXR1aRO1sU3bC0vZrIAF1tIX7rudVI84W7o7M4zo5p1aVt70fAg== +"@typescript-eslint/eslint-plugin@^4.8.1": + version "4.8.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.8.1.tgz#b362abe0ee478a6c6d06c14552a6497f0b480769" + integrity sha512-d7LeQ7dbUrIv5YVFNzGgaW3IQKMmnmKFneRWagRlGYOSfLJVaRbj/FrBNOBC1a3tVO+TgNq1GbHvRtg1kwL0FQ== dependencies: - "@typescript-eslint/experimental-utils" "4.6.0" - "@typescript-eslint/scope-manager" "4.6.0" + "@typescript-eslint/experimental-utils" "4.8.1" + "@typescript-eslint/scope-manager" "4.8.1" debug "^4.1.1" functional-red-black-tree "^1.0.1" regexpp "^3.0.0" semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/experimental-utils@4.6.0": - version "4.6.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.6.0.tgz#f750aef4dd8e5970b5c36084f0a5ca2f0db309a4" - integrity sha512-pnh6Beh2/4xjJVNL+keP49DFHk3orDHHFylSp3WEjtgW3y1U+6l+jNnJrGlbs6qhAz5z96aFmmbUyKhunXKvKw== +"@typescript-eslint/experimental-utils@4.8.1": + version "4.8.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.8.1.tgz#27275c20fa4336df99ebcf6195f7d7aa7aa9f22d" + integrity sha512-WigyLn144R3+lGATXW4nNcDJ9JlTkG8YdBWHkDlN0lC3gUGtDi7Pe3h5GPvFKMcRz8KbZpm9FJV9NTW8CpRHpg== dependencies: "@types/json-schema" "^7.0.3" - "@typescript-eslint/scope-manager" "4.6.0" - "@typescript-eslint/types" "4.6.0" - "@typescript-eslint/typescript-estree" "4.6.0" + "@typescript-eslint/scope-manager" "4.8.1" + "@typescript-eslint/types" "4.8.1" + "@typescript-eslint/typescript-estree" "4.8.1" eslint-scope "^5.0.0" eslint-utils "^2.0.0" -"@typescript-eslint/parser@^4.6.0": - version "4.6.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.6.0.tgz#7e9ff7df2f21d5c8f65f17add3b99eeeec33199d" - integrity sha512-Dj6NJxBhbdbPSZ5DYsQqpR32MwujF772F2H3VojWU6iT4AqL4BKuoNWOPFCoSZvCcADDvQjDpa6OLDAaiZPz2Q== +"@typescript-eslint/parser@^4.8.1": + version "4.8.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.8.1.tgz#4fe2fbdbb67485bafc4320b3ae91e34efe1219d1" + integrity sha512-QND8XSVetATHK9y2Ltc/XBl5Ro7Y62YuZKnPEwnNPB8E379fDsvzJ1dMJ46fg/VOmk0hXhatc+GXs5MaXuL5Uw== dependencies: - "@typescript-eslint/scope-manager" "4.6.0" - "@typescript-eslint/types" "4.6.0" - "@typescript-eslint/typescript-estree" "4.6.0" + "@typescript-eslint/scope-manager" "4.8.1" + "@typescript-eslint/types" "4.8.1" + "@typescript-eslint/typescript-estree" "4.8.1" debug "^4.1.1" -"@typescript-eslint/scope-manager@4.6.0": - version "4.6.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.6.0.tgz#b7d8b57fe354047a72dfb31881d9643092838662" - integrity sha512-uZx5KvStXP/lwrMrfQQwDNvh2ppiXzz5TmyTVHb+5TfZ3sUP7U1onlz3pjoWrK9konRyFe1czyxObWTly27Ang== +"@typescript-eslint/scope-manager@4.8.1": + version "4.8.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.8.1.tgz#e343c475f8f1d15801b546cb17d7f309b768fdce" + integrity sha512-r0iUOc41KFFbZdPAdCS4K1mXivnSZqXS5D9oW+iykQsRlTbQRfuFRSW20xKDdYiaCoH+SkSLeIF484g3kWzwOQ== dependencies: - "@typescript-eslint/types" "4.6.0" - "@typescript-eslint/visitor-keys" "4.6.0" + "@typescript-eslint/types" "4.8.1" + "@typescript-eslint/visitor-keys" "4.8.1" -"@typescript-eslint/types@4.6.0": - version "4.6.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.6.0.tgz#157ca925637fd53c193c6bf226a6c02b752dde2f" - integrity sha512-5FAgjqH68SfFG4UTtIFv+rqYJg0nLjfkjD0iv+5O27a0xEeNZ5rZNDvFGZDizlCD1Ifj7MAbSW2DPMrf0E9zjA== +"@typescript-eslint/types@4.8.1": + version "4.8.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.8.1.tgz#23829c73c5fc6f4fcd5346a7780b274f72fee222" + integrity sha512-ave2a18x2Y25q5K05K/U3JQIe2Av4+TNi/2YuzyaXLAsDx6UZkz1boZ7nR/N6Wwae2PpudTZmHFXqu7faXfHmA== -"@typescript-eslint/typescript-estree@4.6.0": - version "4.6.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.6.0.tgz#85bd98dcc8280511cfc5b2ce7b03a9ffa1732b08" - integrity sha512-s4Z9qubMrAo/tw0CbN0IN4AtfwuehGXVZM0CHNMdfYMGBDhPdwTEpBrecwhP7dRJu6d9tT9ECYNaWDHvlFSngA== +"@typescript-eslint/typescript-estree@4.8.1": + version "4.8.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.8.1.tgz#7307e3f2c9e95df7daa8dc0a34b8c43b7ec0dd32" + integrity sha512-bJ6Fn/6tW2g7WIkCWh3QRlaSU7CdUUK52shx36/J7T5oTQzANvi6raoTsbwGM11+7eBbeem8hCCKbyvAc0X3sQ== dependencies: - "@typescript-eslint/types" "4.6.0" - "@typescript-eslint/visitor-keys" "4.6.0" + "@typescript-eslint/types" "4.8.1" + "@typescript-eslint/visitor-keys" "4.8.1" debug "^4.1.1" globby "^11.0.1" is-glob "^4.0.1" @@ -899,12 +917,12 @@ semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/visitor-keys@4.6.0": - version "4.6.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.6.0.tgz#fb05d6393891b0a089b243fc8f9fb8039383d5da" - integrity sha512-38Aa9Ztl0XyFPVzmutHXqDMCu15Xx8yKvUo38Gu3GhsuckCh3StPI5t2WIO9LHEsOH7MLmlGfKUisU8eW1Sjhg== +"@typescript-eslint/visitor-keys@4.8.1": + version "4.8.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.8.1.tgz#794f68ee292d1b2e3aa9690ebedfcb3a8c90e3c3" + integrity sha512-3nrwXFdEYALQh/zW8rFwP4QltqsanCDz4CwWMPiIZmwlk9GlvBeueEIbq05SEq4ganqM0g9nh02xXgv5XI3PeQ== dependencies: - "@typescript-eslint/types" "4.6.0" + "@typescript-eslint/types" "4.8.1" eslint-visitor-keys "^2.0.0" abab@^2.0.3: @@ -1110,16 +1128,16 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== -babel-jest@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-26.6.1.tgz#07bd7bec14de47fe0f2c9a139741329f1f41788b" - integrity sha512-duMWEOKrSBYRVTTNpL2SipNIWnZOjP77auOBMPQ3zXAdnDbyZQWU8r/RxNWpUf9N6cgPFecQYelYLytTVXVDtA== +babel-jest@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-26.6.3.tgz#d87d25cb0037577a0c89f82e5755c5d293c01056" + integrity sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA== dependencies: - "@jest/transform" "^26.6.1" - "@jest/types" "^26.6.1" + "@jest/transform" "^26.6.2" + "@jest/types" "^26.6.2" "@types/babel__core" "^7.1.7" babel-plugin-istanbul "^6.0.0" - babel-preset-jest "^26.5.0" + babel-preset-jest "^26.6.2" chalk "^4.0.0" graceful-fs "^4.2.4" slash "^3.0.0" @@ -1135,20 +1153,20 @@ babel-plugin-istanbul@^6.0.0: istanbul-lib-instrument "^4.0.0" test-exclude "^6.0.0" -babel-plugin-jest-hoist@^26.5.0: - version "26.5.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.5.0.tgz#3916b3a28129c29528de91e5784a44680db46385" - integrity sha512-ck17uZFD3CDfuwCLATWZxkkuGGFhMij8quP8CNhwj8ek1mqFgbFzRJ30xwC04LLscj/aKsVFfRST+b5PT7rSuw== +babel-plugin-jest-hoist@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz#8185bd030348d254c6d7dd974355e6a28b21e62d" + integrity sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw== dependencies: "@babel/template" "^7.3.3" "@babel/types" "^7.3.3" "@types/babel__core" "^7.0.0" "@types/babel__traverse" "^7.0.6" -babel-preset-current-node-syntax@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.3.tgz#b4b547acddbf963cba555ba9f9cbbb70bfd044da" - integrity sha512-uyexu1sVwcdFnyq9o8UQYsXwXflIh8LvrF5+cKrYam93ned1CStffB3+BEcsxGSgagoA3GEyjDqO4a/58hyPYQ== +babel-preset-current-node-syntax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.0.tgz#cf5feef29551253471cfa82fc8e0f5063df07a77" + integrity sha512-mGkvkpocWJes1CmMKtgGUwCeeq0pOhALyymozzDWYomHTbDLwueDYG6p4TK1YOeYHCzBzYPsWkgTto10JubI1Q== dependencies: "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-bigint" "^7.8.3" @@ -1161,14 +1179,15 @@ babel-preset-current-node-syntax@^0.1.3: "@babel/plugin-syntax-object-rest-spread" "^7.8.3" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" -babel-preset-jest@^26.5.0: - version "26.5.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-26.5.0.tgz#f1b166045cd21437d1188d29f7fba470d5bdb0e7" - integrity sha512-F2vTluljhqkiGSJGBg/jOruA8vIIIL11YrxRcO7nviNTMbbofPSHwnm8mgP7d/wS7wRSexRoI6X1A6T74d4LQA== +babel-preset-jest@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz#747872b1171df032252426586881d62d31798fee" + integrity sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ== dependencies: - babel-plugin-jest-hoist "^26.5.0" - babel-preset-current-node-syntax "^0.1.3" + babel-plugin-jest-hoist "^26.6.2" + babel-preset-current-node-syntax "^1.0.0" balanced-match@^1.0.0: version "1.0.0" @@ -1372,10 +1391,10 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== -cjs-module-lexer@^0.4.2: - version "0.4.3" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-0.4.3.tgz#9e31f7fe701f5fcee5793f77ab4e58fa8dcde8bc" - integrity sha512-5RLK0Qfs0PNDpEyBXIr3bIT1Muw3ojSlvpw6dAmkUcO0+uTrsBn7GuEIgx40u+OzbCBLDta7nvmud85P4EmTsQ== +cjs-module-lexer@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz#4186fcca0eae175970aee870b9fe2d6cf8d5655f" + integrity sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw== class-utils@^0.3.5: version "0.3.6" @@ -1470,10 +1489,10 @@ commander@^2.12.1: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commander@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-6.1.0.tgz#f8d722b78103141006b66f4c7ba1e97315ba75bc" - integrity sha512-wl7PNrYWd2y5mp1OK/LhTlv8Ff4kQJQRXXAvF+uU/TPNiVJUxZLRYGj/B0y/lPGAVcSbJqH2Za/cvHmrPMC8mA== +commander@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.0.tgz#b990bfb8ac030aedc6d11bc04d1488ffef56db75" + integrity sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q== compare-versions@^3.6.0: version "3.6.0" @@ -1607,6 +1626,13 @@ debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: dependencies: ms "^2.1.1" +debug@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1" + integrity sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg== + dependencies: + ms "2.1.2" + decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -1686,6 +1712,11 @@ diff-sequences@^26.5.0: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.5.0.tgz#ef766cf09d43ed40406611f11c6d8d9dd8b2fefd" integrity sha512-ZXx86srb/iYy6jG71k++wBN9P9J05UNQ5hQHQd9MtMPvcqXPx/vKU69jfHV637D00Q2gSgPk2D+jSx3l1lDW/Q== +diff-sequences@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" + integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q== + diff@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" @@ -1869,10 +1900,10 @@ eslint-visitor-keys@^2.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== -eslint@^7.12.1: - version "7.12.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.12.1.tgz#bd9a81fa67a6cfd51656cdb88812ce49ccec5801" - integrity sha512-HlMTEdr/LicJfN08LB3nM1rRYliDXOmfoO4vj39xN6BLpFzF00hbwBoqHk8UcJ2M/3nlARZWy/mslvGEuZFvsg== +eslint@^7.13.0: + version "7.13.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.13.0.tgz#7f180126c0dcdef327bfb54b211d7802decc08da" + integrity sha512-uCORMuOO8tUzJmsdRtrvcGq5qposf7Rw0LwkTJkoDbOycVQtQjmnhZSuLQnozLE4TmAzlMVV45eCHmQ1OpDKUQ== dependencies: "@babel/code-frame" "^7.0.0" "@eslint/eslintrc" "^0.2.1" @@ -2014,7 +2045,7 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -execa@^4.0.0, execa@^4.0.3: +execa@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/execa/-/execa-4.0.3.tgz#0a34dabbad6d66100bd6f2c576c8669403f317f2" integrity sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A== @@ -2029,6 +2060,21 @@ execa@^4.0.0, execa@^4.0.3: signal-exit "^3.0.2" strip-final-newline "^2.0.0" +execa@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" + integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" @@ -2047,16 +2093,16 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expect@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/expect/-/expect-26.6.1.tgz#e1e053cdc43b21a452b36fc7cc9401e4603949c1" - integrity sha512-BRfxIBHagghMmr1D2MRY0Qv5d3Nc8HCqgbDwNXw/9izmM5eBb42a2YjLKSbsqle76ozGkAEPELQX4IdNHAKRNA== +expect@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/expect/-/expect-26.6.2.tgz#c6b996bf26bf3fe18b67b2d0f51fc981ba934417" + integrity sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA== dependencies: - "@jest/types" "^26.6.1" + "@jest/types" "^26.6.2" ansi-styles "^4.0.0" jest-get-type "^26.3.0" - jest-matcher-utils "^26.6.1" - jest-message-util "^26.6.1" + jest-matcher-utils "^26.6.2" + jest-message-util "^26.6.2" jest-regex-util "^26.0.0" ext@^1.1.2: @@ -2826,57 +2872,57 @@ istanbul-reports@^3.0.2: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jest-changed-files@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-26.6.1.tgz#2fac3dc51297977ee883347948d8e3d37c417fba" - integrity sha512-NhSdZ5F6b/rIN5V46x1l31vrmukD/bJUXgYAY8VtP1SknYdJwjYDRxuLt7Z8QryIdqCjMIn2C0Cd98EZ4umo8Q== +jest-changed-files@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-26.6.2.tgz#f6198479e1cc66f22f9ae1e22acaa0b429c042d0" + integrity sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ== dependencies: - "@jest/types" "^26.6.1" + "@jest/types" "^26.6.2" execa "^4.0.0" throat "^5.0.0" -jest-cli@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-26.6.1.tgz#8952242fa812c05bd129abf7c022424045b7fd67" - integrity sha512-aPLoEjlwFrCWhiPpW5NUxQA1X1kWsAnQcQ0SO/fHsCvczL3W75iVAcH9kP6NN+BNqZcHNEvkhxT5cDmBfEAh+w== +jest-cli@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-26.6.3.tgz#43117cfef24bc4cd691a174a8796a532e135e92a" + integrity sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg== dependencies: - "@jest/core" "^26.6.1" - "@jest/test-result" "^26.6.1" - "@jest/types" "^26.6.1" + "@jest/core" "^26.6.3" + "@jest/test-result" "^26.6.2" + "@jest/types" "^26.6.2" chalk "^4.0.0" exit "^0.1.2" graceful-fs "^4.2.4" import-local "^3.0.2" is-ci "^2.0.0" - jest-config "^26.6.1" - jest-util "^26.6.1" - jest-validate "^26.6.1" + jest-config "^26.6.3" + jest-util "^26.6.2" + jest-validate "^26.6.2" prompts "^2.0.1" yargs "^15.4.1" -jest-config@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-26.6.1.tgz#8c343fbdd9c24ad003e261f73583c3c020f32b42" - integrity sha512-mtJzIynIwW1d1nMlKCNCQiSgWaqFn8cH/fOSNY97xG7Y9tBCZbCSuW2GTX0RPmceSJGO7l27JgwC18LEg0Vg+g== +jest-config@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-26.6.3.tgz#64f41444eef9eb03dc51d5c53b75c8c71f645349" + integrity sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg== dependencies: "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^26.6.1" - "@jest/types" "^26.6.1" - babel-jest "^26.6.1" + "@jest/test-sequencer" "^26.6.3" + "@jest/types" "^26.6.2" + babel-jest "^26.6.3" chalk "^4.0.0" deepmerge "^4.2.2" glob "^7.1.1" graceful-fs "^4.2.4" - jest-environment-jsdom "^26.6.1" - jest-environment-node "^26.6.1" + jest-environment-jsdom "^26.6.2" + jest-environment-node "^26.6.2" jest-get-type "^26.3.0" - jest-jasmine2 "^26.6.1" + jest-jasmine2 "^26.6.3" jest-regex-util "^26.0.0" - jest-resolve "^26.6.1" - jest-util "^26.6.1" - jest-validate "^26.6.1" + jest-resolve "^26.6.2" + jest-util "^26.6.2" + jest-validate "^26.6.2" micromatch "^4.0.2" - pretty-format "^26.6.1" + pretty-format "^26.6.2" jest-diff@^25.2.1: version "25.3.0" @@ -2888,7 +2934,7 @@ jest-diff@^25.2.1: jest-get-type "^25.2.6" pretty-format "^25.3.0" -jest-diff@^26.0.0, jest-diff@^26.6.1: +jest-diff@^26.0.0: version "26.6.1" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.6.1.tgz#38aa194979f454619bb39bdee299fb64ede5300c" integrity sha512-BBNy/zin2m4kG5In126O8chOBxLLS/XMTuuM2+YhgyHk87ewPzKTuTJcqj3lOWOi03NNgrl+DkMeV/exdvG9gg== @@ -2898,6 +2944,16 @@ jest-diff@^26.0.0, jest-diff@^26.6.1: jest-get-type "^26.3.0" pretty-format "^26.6.1" +jest-diff@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.6.2.tgz#1aa7468b52c3a68d7d5c5fdcdfcd5e49bd164394" + integrity sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA== + dependencies: + chalk "^4.0.0" + diff-sequences "^26.6.2" + jest-get-type "^26.3.0" + pretty-format "^26.6.2" + jest-docblock@^26.0.0: version "26.0.0" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-26.0.0.tgz#3e2fa20899fc928cb13bd0ff68bd3711a36889b5" @@ -2905,41 +2961,41 @@ jest-docblock@^26.0.0: dependencies: detect-newline "^3.0.0" -jest-each@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-26.6.1.tgz#e968e88309a3e2ae9648634af8f89d8ee5acfddd" - integrity sha512-gSn8eB3buchuq45SU7pLB7qmCGax1ZSxfaWuEFblCyNMtyokYaKFh9dRhYPujK6xYL57dLIPhLKatjmB5XWzGA== +jest-each@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-26.6.2.tgz#02526438a77a67401c8a6382dfe5999952c167cb" + integrity sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A== dependencies: - "@jest/types" "^26.6.1" + "@jest/types" "^26.6.2" chalk "^4.0.0" jest-get-type "^26.3.0" - jest-util "^26.6.1" - pretty-format "^26.6.1" + jest-util "^26.6.2" + pretty-format "^26.6.2" -jest-environment-jsdom@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-26.6.1.tgz#63093bf89daee6139616568a43633b84cf7aac21" - integrity sha512-A17RiXuHYNVlkM+3QNcQ6n5EZyAc6eld8ra9TW26luounGWpku4tj03uqRgHJCI1d4uHr5rJiuCH5JFRtdmrcA== +jest-environment-jsdom@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz#78d09fe9cf019a357009b9b7e1f101d23bd1da3e" + integrity sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q== dependencies: - "@jest/environment" "^26.6.1" - "@jest/fake-timers" "^26.6.1" - "@jest/types" "^26.6.1" + "@jest/environment" "^26.6.2" + "@jest/fake-timers" "^26.6.2" + "@jest/types" "^26.6.2" "@types/node" "*" - jest-mock "^26.6.1" - jest-util "^26.6.1" + jest-mock "^26.6.2" + jest-util "^26.6.2" jsdom "^16.4.0" -jest-environment-node@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-26.6.1.tgz#4d73d8b33c26989a92a0ed3ad0bfd6f7a196d9bd" - integrity sha512-YffaCp6h0j1kbcf1NVZ7umC6CPgD67YS+G1BeornfuSkx5s3xdhuwG0DCxSiHPXyT81FfJzA1L7nXvhq50OWIg== +jest-environment-node@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-26.6.2.tgz#824e4c7fb4944646356f11ac75b229b0035f2b0c" + integrity sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag== dependencies: - "@jest/environment" "^26.6.1" - "@jest/fake-timers" "^26.6.1" - "@jest/types" "^26.6.1" + "@jest/environment" "^26.6.2" + "@jest/fake-timers" "^26.6.2" + "@jest/types" "^26.6.2" "@types/node" "*" - jest-mock "^26.6.1" - jest-util "^26.6.1" + jest-mock "^26.6.2" + jest-util "^26.6.2" jest-get-type@^25.2.6: version "25.2.6" @@ -2951,89 +3007,90 @@ jest-get-type@^26.3.0: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig== -jest-haste-map@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.1.tgz#97e96f5fd7576d980307fbe6160b10c016b543d4" - integrity sha512-9kPafkv0nX6ta1PrshnkiyhhoQoFWncrU/uUBt3/AP1r78WSCU5iLceYRTwDvJl67H3RrXqSlSVDDa/AsUB7OQ== +jest-haste-map@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa" + integrity sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w== dependencies: - "@jest/types" "^26.6.1" + "@jest/types" "^26.6.2" "@types/graceful-fs" "^4.1.2" "@types/node" "*" anymatch "^3.0.3" fb-watchman "^2.0.0" graceful-fs "^4.2.4" jest-regex-util "^26.0.0" - jest-serializer "^26.5.0" - jest-util "^26.6.1" - jest-worker "^26.6.1" + jest-serializer "^26.6.2" + jest-util "^26.6.2" + jest-worker "^26.6.2" micromatch "^4.0.2" sane "^4.0.3" walker "^1.0.7" optionalDependencies: fsevents "^2.1.2" -jest-jasmine2@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-26.6.1.tgz#11c92603d1fa97e3c33404359e69d6cec7e57017" - integrity sha512-2uYdT32o/ZzSxYAPduAgokO8OlAL1YdG/9oxcEY138EDNpIK5XRRJDaGzTZdIBWSxk0aR8XxN44FvfXtHB+Fiw== +jest-jasmine2@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz#adc3cf915deacb5212c93b9f3547cd12958f2edd" + integrity sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg== dependencies: "@babel/traverse" "^7.1.0" - "@jest/environment" "^26.6.1" - "@jest/source-map" "^26.5.0" - "@jest/test-result" "^26.6.1" - "@jest/types" "^26.6.1" + "@jest/environment" "^26.6.2" + "@jest/source-map" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/types" "^26.6.2" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" - expect "^26.6.1" + expect "^26.6.2" is-generator-fn "^2.0.0" - jest-each "^26.6.1" - jest-matcher-utils "^26.6.1" - jest-message-util "^26.6.1" - jest-runtime "^26.6.1" - jest-snapshot "^26.6.1" - jest-util "^26.6.1" - pretty-format "^26.6.1" + jest-each "^26.6.2" + jest-matcher-utils "^26.6.2" + jest-message-util "^26.6.2" + jest-runtime "^26.6.3" + jest-snapshot "^26.6.2" + jest-util "^26.6.2" + pretty-format "^26.6.2" throat "^5.0.0" -jest-leak-detector@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-26.6.1.tgz#f63e46dc4e3aa30d29b40ae49966a15730d25bbe" - integrity sha512-j9ZOtJSJKlHjrs4aIxWjiQUjyrffPdiAQn2Iw0916w7qZE5Lk0T2KhIH6E9vfhzP6sw0Q0jtnLLb4vQ71o1HlA== +jest-leak-detector@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz#7717cf118b92238f2eba65054c8a0c9c653a91af" + integrity sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg== dependencies: jest-get-type "^26.3.0" - pretty-format "^26.6.1" + pretty-format "^26.6.2" -jest-matcher-utils@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-26.6.1.tgz#bc90822d352c91c2ec1814731327691d06598400" - integrity sha512-9iu3zrsYlUnl8pByhREF9rr5eYoiEb1F7ymNKg6lJr/0qD37LWS5FSW/JcoDl8UdMX2+zAzabDs7sTO+QFKjCg== +jest-matcher-utils@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz#8e6fd6e863c8b2d31ac6472eeb237bc595e53e7a" + integrity sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw== dependencies: chalk "^4.0.0" - jest-diff "^26.6.1" + jest-diff "^26.6.2" jest-get-type "^26.3.0" - pretty-format "^26.6.1" + pretty-format "^26.6.2" -jest-message-util@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-26.6.1.tgz#d62c20c0fe7be10bfd6020b675abb9b5fa933ff3" - integrity sha512-cqM4HnqncIebBNdTKrBoWR/4ufHTll0pK/FWwX0YasK+TlBQEMqw3IEdynuuOTjDPFO3ONlFn37280X48beByw== +jest-message-util@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-26.6.2.tgz#58173744ad6fc0506b5d21150b9be56ef001ca07" + integrity sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA== dependencies: "@babel/code-frame" "^7.0.0" - "@jest/types" "^26.6.1" + "@jest/types" "^26.6.2" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" graceful-fs "^4.2.4" micromatch "^4.0.2" + pretty-format "^26.6.2" slash "^3.0.0" stack-utils "^2.0.2" -jest-mock@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-26.6.1.tgz#6c12a92a82fc833f81a5b6de6b67d78386e276a3" - integrity sha512-my0lPTBu1awY8iVG62sB2sx9qf8zxNDVX+5aFgoB8Vbqjb6LqIOsfyFA8P1z6H2IsqMbvOX9oCJnK67Y3yUIMA== +jest-mock@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-26.6.2.tgz#d6cb712b041ed47fe0d9b6fc3474bc6543feb302" + integrity sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew== dependencies: - "@jest/types" "^26.6.1" + "@jest/types" "^26.6.2" "@types/node" "*" jest-pnp-resolver@^1.2.2: @@ -3046,116 +3103,116 @@ jest-regex-util@^26.0.0: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== -jest-resolve-dependencies@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.1.tgz#e9d091a159ad198c029279737a8b4c507791d75c" - integrity sha512-MN6lufbZJ3RBfTnJesZtHu3hUCBqPdHRe2+FhIt0yiqJ3fMgzWRqMRQyN/d/QwOE7KXwAG2ekZutbPhuD7s51A== +jest-resolve-dependencies@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz#6680859ee5d22ee5dcd961fe4871f59f4c784fb6" + integrity sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg== dependencies: - "@jest/types" "^26.6.1" + "@jest/types" "^26.6.2" jest-regex-util "^26.0.0" - jest-snapshot "^26.6.1" + jest-snapshot "^26.6.2" -jest-resolve@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-26.6.1.tgz#e9a9130cc069620d5aeeb87043dd9e130b68c6a1" - integrity sha512-hiHfQH6rrcpAmw9xCQ0vD66SDuU+7ZulOuKwc4jpbmFFsz0bQG/Ib92K+9/489u5rVw0btr/ZhiHqBpmkbCvuQ== +jest-resolve@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-26.6.2.tgz#a3ab1517217f469b504f1b56603c5bb541fbb507" + integrity sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ== dependencies: - "@jest/types" "^26.6.1" + "@jest/types" "^26.6.2" chalk "^4.0.0" graceful-fs "^4.2.4" jest-pnp-resolver "^1.2.2" - jest-util "^26.6.1" + jest-util "^26.6.2" read-pkg-up "^7.0.1" resolve "^1.18.1" slash "^3.0.0" -jest-runner@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-26.6.1.tgz#a945971b5a23740c1fe20e372a38de668b7c76bf" - integrity sha512-DmpNGdgsbl5s0FGkmsInmqnmqCtliCSnjWA2TFAJS1m1mL5atwfPsf+uoZ8uYQ2X0uDj4NM+nPcDnUpbNTRMBA== +jest-runner@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-26.6.3.tgz#2d1fed3d46e10f233fd1dbd3bfaa3fe8924be159" + integrity sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ== dependencies: - "@jest/console" "^26.6.1" - "@jest/environment" "^26.6.1" - "@jest/test-result" "^26.6.1" - "@jest/types" "^26.6.1" + "@jest/console" "^26.6.2" + "@jest/environment" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/types" "^26.6.2" "@types/node" "*" chalk "^4.0.0" emittery "^0.7.1" exit "^0.1.2" graceful-fs "^4.2.4" - jest-config "^26.6.1" + jest-config "^26.6.3" jest-docblock "^26.0.0" - jest-haste-map "^26.6.1" - jest-leak-detector "^26.6.1" - jest-message-util "^26.6.1" - jest-resolve "^26.6.1" - jest-runtime "^26.6.1" - jest-util "^26.6.1" - jest-worker "^26.6.1" + jest-haste-map "^26.6.2" + jest-leak-detector "^26.6.2" + jest-message-util "^26.6.2" + jest-resolve "^26.6.2" + jest-runtime "^26.6.3" + jest-util "^26.6.2" + jest-worker "^26.6.2" source-map-support "^0.5.6" throat "^5.0.0" -jest-runtime@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-26.6.1.tgz#9a131e7b4f0bc6beefd62e7443f757c1d5fa9dec" - integrity sha512-7uOCNeezXDWgjEyzYbRN2ViY7xNZzusNVGAMmU0UHRUNXuY4j4GBHKGMqPo/cBPZA9bSYp+lwK2DRRBU5Dv6YQ== - dependencies: - "@jest/console" "^26.6.1" - "@jest/environment" "^26.6.1" - "@jest/fake-timers" "^26.6.1" - "@jest/globals" "^26.6.1" - "@jest/source-map" "^26.5.0" - "@jest/test-result" "^26.6.1" - "@jest/transform" "^26.6.1" - "@jest/types" "^26.6.1" +jest-runtime@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-26.6.3.tgz#4f64efbcfac398331b74b4b3c82d27d401b8fa2b" + integrity sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw== + dependencies: + "@jest/console" "^26.6.2" + "@jest/environment" "^26.6.2" + "@jest/fake-timers" "^26.6.2" + "@jest/globals" "^26.6.2" + "@jest/source-map" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/transform" "^26.6.2" + "@jest/types" "^26.6.2" "@types/yargs" "^15.0.0" chalk "^4.0.0" - cjs-module-lexer "^0.4.2" + cjs-module-lexer "^0.6.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" glob "^7.1.3" graceful-fs "^4.2.4" - jest-config "^26.6.1" - jest-haste-map "^26.6.1" - jest-message-util "^26.6.1" - jest-mock "^26.6.1" + jest-config "^26.6.3" + jest-haste-map "^26.6.2" + jest-message-util "^26.6.2" + jest-mock "^26.6.2" jest-regex-util "^26.0.0" - jest-resolve "^26.6.1" - jest-snapshot "^26.6.1" - jest-util "^26.6.1" - jest-validate "^26.6.1" + jest-resolve "^26.6.2" + jest-snapshot "^26.6.2" + jest-util "^26.6.2" + jest-validate "^26.6.2" slash "^3.0.0" strip-bom "^4.0.0" yargs "^15.4.1" -jest-serializer@^26.5.0: - version "26.5.0" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.5.0.tgz#f5425cc4c5f6b4b355f854b5f0f23ec6b962bc13" - integrity sha512-+h3Gf5CDRlSLdgTv7y0vPIAoLgX/SI7T4v6hy+TEXMgYbv+ztzbg5PSN6mUXAT/hXYHvZRWm+MaObVfqkhCGxA== +jest-serializer@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.6.2.tgz#d139aafd46957d3a448f3a6cdabe2919ba0742d1" + integrity sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g== dependencies: "@types/node" "*" graceful-fs "^4.2.4" -jest-snapshot@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-26.6.1.tgz#469e9d0b749496aea7dad0d7e5e5c88b91cdb4cc" - integrity sha512-JA7bZp7HRTIJYAi85pJ/OZ2eur2dqmwIToA5/6d7Mn90isGEfeF9FvuhDLLEczgKP1ihreBzrJ6Vr7zteP5JNA== +jest-snapshot@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-26.6.2.tgz#f3b0af1acb223316850bd14e1beea9837fb39c84" + integrity sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og== dependencies: "@babel/types" "^7.0.0" - "@jest/types" "^26.6.1" + "@jest/types" "^26.6.2" "@types/babel__traverse" "^7.0.4" "@types/prettier" "^2.0.0" chalk "^4.0.0" - expect "^26.6.1" + expect "^26.6.2" graceful-fs "^4.2.4" - jest-diff "^26.6.1" + jest-diff "^26.6.2" jest-get-type "^26.3.0" - jest-haste-map "^26.6.1" - jest-matcher-utils "^26.6.1" - jest-message-util "^26.6.1" - jest-resolve "^26.6.1" + jest-haste-map "^26.6.2" + jest-matcher-utils "^26.6.2" + jest-message-util "^26.6.2" + jest-resolve "^26.6.2" natural-compare "^1.4.0" - pretty-format "^26.6.1" + pretty-format "^26.6.2" semver "^7.3.2" jest-util@^26.1.0: @@ -3170,60 +3227,60 @@ jest-util@^26.1.0: is-ci "^2.0.0" micromatch "^4.0.2" -jest-util@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.1.tgz#4cc0d09ec57f28d12d053887eec5dc976a352e9b" - integrity sha512-xCLZUqVoqhquyPLuDXmH7ogceGctbW8SMyQVjD9o+1+NPWI7t0vO08udcFLVPLgKWcvc+zotaUv/RuaR6l8HIA== +jest-util@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1" + integrity sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q== dependencies: - "@jest/types" "^26.6.1" + "@jest/types" "^26.6.2" "@types/node" "*" chalk "^4.0.0" graceful-fs "^4.2.4" is-ci "^2.0.0" micromatch "^4.0.2" -jest-validate@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-26.6.1.tgz#28730eb8570d60968d9d06f1a8c94d922167bd2a" - integrity sha512-BEFpGbylKocnNPZULcnk+TGaz1oFZQH/wcaXlaXABbu0zBwkOGczuWgdLucUouuQqn7VadHZZeTvo8VSFDLMOA== +jest-validate@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-26.6.2.tgz#23d380971587150467342911c3d7b4ac57ab20ec" + integrity sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ== dependencies: - "@jest/types" "^26.6.1" + "@jest/types" "^26.6.2" camelcase "^6.0.0" chalk "^4.0.0" jest-get-type "^26.3.0" leven "^3.1.0" - pretty-format "^26.6.1" + pretty-format "^26.6.2" -jest-watcher@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-26.6.1.tgz#debfa34e9c5c3e735593403794fe53d2955bfabc" - integrity sha512-0LBIPPncNi9CaLKK15bnxyd2E8OMl4kJg0PTiNOI+MXztXw1zVdtX/x9Pr6pXaQYps+eS/ts43O4+HByZ7yJSw== +jest-watcher@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-26.6.2.tgz#a5b683b8f9d68dbcb1d7dae32172d2cca0592975" + integrity sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ== dependencies: - "@jest/test-result" "^26.6.1" - "@jest/types" "^26.6.1" + "@jest/test-result" "^26.6.2" + "@jest/types" "^26.6.2" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" - jest-util "^26.6.1" + jest-util "^26.6.2" string-length "^4.0.1" -jest-worker@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.1.tgz#c2ae8cde6802cc14056043f997469ec170d9c32a" - integrity sha512-R5IE3qSGz+QynJx8y+ICEkdI2OJ3RJjRQVEyCcFAd3yVhQSEtquziPO29Mlzgn07LOVE8u8jhJ1FqcwegiXWOw== +jest-worker@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== dependencies: "@types/node" "*" merge-stream "^2.0.0" supports-color "^7.0.0" -jest@^26.6.1: - version "26.6.1" - resolved "https://registry.yarnpkg.com/jest/-/jest-26.6.1.tgz#821e8280d2bdeeed40ac7bc43941dceff0f1b650" - integrity sha512-f+ahfqw3Ffy+9vA7sWFGpTmhtKEMsNAZiWBVXDkrpIO73zIz22iimjirnV78kh/eWlylmvLh/0WxHN6fZraZdA== +jest@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest/-/jest-26.6.3.tgz#40e8fdbe48f00dfa1f0ce8121ca74b88ac9148ef" + integrity sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q== dependencies: - "@jest/core" "^26.6.1" + "@jest/core" "^26.6.3" import-local "^3.0.2" - jest-cli "^26.6.1" + jest-cli "^26.6.3" js-sha3@0.5.7: version "0.5.7" @@ -3387,20 +3444,20 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= -lint-staged@^10.5.0: - version "10.5.0" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-10.5.0.tgz#c923c2447a84c595874f3de696778736227e7a7a" - integrity sha512-gjC9+HGkBubOF+Yyoj9pd52Qfm/kYB+dRX1UOgWjHKvSDYl+VHkZXlBMlqSZa2cH3Kp5/uNL480sV6e2dTgXSg== +lint-staged@^10.5.1: + version "10.5.1" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-10.5.1.tgz#901e915c2360072dded0e7d752a0d9a49e079daa" + integrity sha512-fTkTGFtwFIJJzn/PbUO3RXyEBHIhbfYBE7+rJyLcOXabViaO/h6OslgeK6zpeUtzkDrzkgyAYDTLAwx6JzDTHw== dependencies: chalk "^4.1.0" cli-truncate "^2.1.0" - commander "^6.0.0" + commander "^6.2.0" cosmiconfig "^7.0.0" - debug "^4.1.1" + debug "^4.2.0" dedent "^0.7.0" enquirer "^2.3.6" - execa "^4.0.3" - listr2 "^2.6.0" + execa "^4.1.0" + listr2 "^3.2.2" log-symbols "^4.0.0" micromatch "^4.0.2" normalize-path "^3.0.0" @@ -3408,10 +3465,10 @@ lint-staged@^10.5.0: string-argv "0.3.1" stringify-object "^3.3.0" -listr2@^2.6.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/listr2/-/listr2-2.6.2.tgz#4912eb01e1e2dd72ec37f3895a56bf2622d6f36a" - integrity sha512-6x6pKEMs8DSIpA/tixiYY2m/GcbgMplMVmhQAaLFxEtNSKLeWTGjtmU57xvv6QCm2XcqzyNXL/cTSVf4IChCRA== +listr2@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.2.2.tgz#d20feb75015e506992b55af40722ba1af168b8f1" + integrity sha512-AajqcZEUikF2ioph6PfH3dIuxJclhr3i3kHgTOP0xeXdWQohrvJAAmqVcV43/GI987HFY/vzT73jYXoa4esDHg== dependencies: chalk "^4.1.0" cli-truncate "^2.1.0" @@ -3419,7 +3476,7 @@ listr2@^2.6.0: indent-string "^4.0.0" log-update "^4.0.0" p-map "^4.0.0" - rxjs "^6.6.2" + rxjs "^6.6.3" through "^2.3.8" locate-path@^5.0.0: @@ -3610,7 +3667,7 @@ ms@2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -ms@^2.1.1: +ms@2.1.2, ms@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== @@ -3982,6 +4039,16 @@ pretty-format@^26.0.0, pretty-format@^26.6.1: ansi-styles "^4.0.0" react-is "^17.0.1" +pretty-format@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" + integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg== + dependencies: + "@jest/types" "^26.6.2" + ansi-regex "^5.0.0" + ansi-styles "^4.0.0" + react-is "^17.0.1" + process@~0.5.1: version "0.5.2" resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" @@ -4234,7 +4301,7 @@ run-parallel@^1.1.9: resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679" integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q== -rxjs@^6.6.2: +rxjs@^6.6.3: version "6.6.3" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.3.tgz#8ca84635c4daa900c0d3967a6ee7ac60271ee552" integrity sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ== @@ -4788,12 +4855,11 @@ tr46@^2.0.2: dependencies: punycode "^2.1.1" -ts-jest@^26.4.3: - version "26.4.3" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-26.4.3.tgz#d153a616033e7ec8544b97ddbe2638cbe38d53db" - integrity sha512-pFDkOKFGY+nL9v5pkhm+BIFpoAuno96ff7GMnIYr/3L6slFOS365SI0fGEVYx2RKGji5M2elxhWjDMPVcOCdSw== +ts-jest@^26.4.4: + version "26.4.4" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-26.4.4.tgz#61f13fb21ab400853c532270e52cc0ed7e502c49" + integrity sha512-3lFWKbLxJm34QxyVNNCgXX1u4o/RV0myvA2y2Bxm46iGIjKlaY0own9gIckbjZJPn+WaJEnfPPJ20HHGpoq4yg== dependencies: - "@jest/create-cache-key-function" "^26.5.0" "@types/jest" "26.x" bs-logger "0.x" buffer-from "1.x" @@ -4994,10 +5060,10 @@ v8-compile-cache@^2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745" integrity sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ== -v8-to-istanbul@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-6.0.1.tgz#7ef0e32faa10f841fe4c1b0f8de96ed067c0be1e" - integrity sha512-PzM1WlqquhBvsV+Gco6WSFeg1AGdD53ccMRkFeyHRE/KRZaVacPOmQYP3EeVgDBtKD2BJ8kgynBQ5OtKiHCH+w== +v8-to-istanbul@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-7.0.0.tgz#b4fe00e35649ef7785a9b7fcebcea05f37c332fc" + integrity sha512-fLL2rFuQpMtm9r8hrAV2apXX/WqHJ6+IC4/eQVdMDGBUgH/YMV4Gv3duk3kjmyg6uiQWBAA9nJwue4iJUOkHeA== dependencies: "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0"