diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3e1a202b0..9e2415b49 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,5 +1,5 @@ name: CI -on: [push, pull_request] +on: [ push, pull_request ] jobs: build_project: name: Build, lint, and test on Node ${{ matrix.node }} and ${{ matrix.os }} @@ -7,8 +7,8 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - node: ['16.x'] - os: [ubuntu-latest] + node: [ '16.x' ] + os: [ ubuntu-latest ] steps: - name: Checkout repo @@ -22,14 +22,28 @@ jobs: - name: Install deps and build (with cache) uses: bahmutov/npm-install@v1 - - name: Test - run: yarn test + - name: Check + run: yarn run package-check - name: Build run: yarn build - - name: Check - run: yarn run package-check + - name: Test + run: yarn test + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v3 + with: + fail_ci_if_error: true + + - name: Check bundle size + uses: sarthak-saxena/JSBundleSize@3.0.0 + with: + # Skipping some commands with 'echo ok' + bootstrap: 'echo ok' + build_command: 'echo ok' + dist_path: 'build' + token: ${{ secrets.GITHUB_TOKEN }} build_examples: name: Build project examples @@ -37,8 +51,8 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - node: ['16.x'] - os: [ubuntu-latest] + node: [ '16.x' ] + os: [ ubuntu-latest ] example: [ 'nodejs', diff --git a/CHANGELOG.md b/CHANGELOG.md index 821f1b312..9e6f194be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,46 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [1.0.0-beta.2](https://github.com/nucypher/nucypher-ts/compare/v1.0.0-alpha.0...v1.0.0-beta.2) (2023-07-07) + +## [1.0.0-alpha.0](https://github.com/nucypher/nucypher-ts/compare/v1.0.0-beta.1...v1.0.0-alpha.0) (2023-06-27) + + +### ⚠ BREAKING CHANGES + +* hide dkg public params +* rename EvmCondition to ContractCondition +* remove unused revocation kit +* remove unused revoked strategy +* refactor conditions into a module + +### Features + +* add bare-bones impl of dkg client ([6f3eaf6](https://github.com/nucypher/nucypher-ts/commit/6f3eaf64d6b7c419d7b1159cd0a1a3264266e1ea)) +* add class metadata to serialized conditions ([76ac0f1](https://github.com/nucypher/nucypher-ts/commit/76ac0f1ae56ffcf9bb8410f015f52e3af6c98af1)) +* add conveniance method making encrypters ([81d23ef](https://github.com/nucypher/nucypher-ts/commit/81d23efb40f343cb84f22a99264b6836d2e482ac)) +* add coordinator contract ([2258350](https://github.com/nucypher/nucypher-ts/commit/22583506e564d4525e632e35a3b70697b2e43eb9)) +* add tdec endpoint to porter ([b6eb53e](https://github.com/nucypher/nucypher-ts/commit/b6eb53e1422c099d8c663ea5a97d82c67bf41d36)) +* hide dkg public params ([87e237f](https://github.com/nucypher/nucypher-ts/commit/87e237fcbad8cab509de12d2f4ff27c8ab79dc20)) +* make index in return value test optional ([ad52ec1](https://github.com/nucypher/nucypher-ts/commit/ad52ec174de3ad0ce1118b2fba7df47a96c262fb)) +* refactor conditions into a module ([85ff684](https://github.com/nucypher/nucypher-ts/commit/85ff684efe3e4a9b32d628e65606770459d96a7c)) +* remove unused revocation kit ([a0ea384](https://github.com/nucypher/nucypher-ts/commit/a0ea384ec813052c0fbab06e7f0644ebb105c089)) +* remove unused revoked strategy ([d1b9818](https://github.com/nucypher/nucypher-ts/commit/d1b9818b0513f093094d10945fc943c1690b7bcb)) +* rename EvmCondition to ContractCondition ([77278d6](https://github.com/nucypher/nucypher-ts/commit/77278d6cccacca87be176a0b807426a5a5b5c11f)) +* support user-provided params in condition context ([fa287d6](https://github.com/nucypher/nucypher-ts/commit/fa287d6132155fa9a453b0f6e3afc76bd36b57eb)) +* update nucypher-core to 0.9.0 ([e707abf](https://github.com/nucypher/nucypher-ts/commit/e707abf44665deda4df60ee838d72f1e743a52aa)) +* use e2e-encrypted decryption requests ([f78a55f](https://github.com/nucypher/nucypher-ts/commit/f78a55fb362c5c2eccc07f34d35ab89cc34118f7)) +* validate function abi params and method ([d7db27a](https://github.com/nucypher/nucypher-ts/commit/d7db27a90f8a27448568430a0654e6721813416e)) + + +### Bug Fixes + +* struct deser ([284df4a](https://github.com/nucypher/nucypher-ts/commit/284df4a26cb6c512749d918e079052808c4335c4)) + ## [1.0.0-beta.1](https://github.com/nucypher/nucypher-ts/compare/v1.0.0-beta.0...v1.0.0-beta.1) (2023-03-27) +### ⚠ BREAKING CHANGES +* `TimeLockCondition` no longer supported; instead `TimeCondition` with method name `blocktime` can be used ### ⚠ BREAKING CHANGES diff --git a/README.md b/README.md index 5cd089265..c85ae1b19 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,9 @@ Full documentation can be found [here](https://docs.threshold.network/app-develo > **Warning** > > `nucypher-ts` is under [active development](https://github.com/nucypher/nucypher-ts/pulls): -> -> - SDK does not support policy revocation. -> - We expect breaking changes. +> +> - SDK does not support policy revocation. +> - We expect breaking changes. ## Installation @@ -26,6 +26,7 @@ To learn more, follow the tutorial at Threshold Network's [docs](https://docs.th See [`nucypher-ts/examples`](https://github.com/nucypher/nucypher-ts/tree/main/examples) to find out how to integrate `nucypher-ts` into your favorite web framework. We also provide two code samples of TAC applications: + - [nucypher/tdec-sandbox](https://github.com/nucypher/tdec-sandbox) - [nucypher/tdec-nft-example](https://github.com/nucypher/tdec-nft-example) diff --git a/abi/Coordinator.json b/abi/Coordinator.json new file mode 100644 index 000000000..c572ea259 --- /dev/null +++ b/abi/Coordinator.json @@ -0,0 +1,572 @@ +[ + { + "inputs": [ + { + "internalType": "contract IAccessControlApplication", + "name": "app", + "type": "address" + }, + { + "internalType": "uint32", + "name": "_timeout", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "_maxDkgSize", + "type": "uint32" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint32", + "name": "ritualId", + "type": "uint32" + }, + { + "indexed": true, + "internalType": "address", + "name": "node", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "aggregatedTranscriptDigest", + "type": "bytes32" + } + ], + "name": "AggregationPosted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint32", + "name": "ritualId", + "type": "uint32" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "successful", + "type": "bool" + } + ], + "name": "EndRitual", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "oldSize", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newSize", + "type": "uint32" + } + ], + "name": "MaxDkgSizeChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint32", + "name": "ritualId", + "type": "uint32" + } + ], + "name": "StartAggregationRound", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint32", + "name": "ritualId", + "type": "uint32" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address[]", + "name": "participants", + "type": "address[]" + } + ], + "name": "StartRitual", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "oldTimeout", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newTimeout", + "type": "uint32" + } + ], + "name": "TimeoutChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint32", + "name": "ritualId", + "type": "uint32" + }, + { + "indexed": true, + "internalType": "address", + "name": "node", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "transcriptDigest", + "type": "bytes32" + } + ], + "name": "TranscriptPosted", + "type": "event" + }, + { + "inputs": [], + "name": "application", + "outputs": [ + { + "internalType": "contract IAccessControlApplication", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "nodes", + "type": "address[]" + } + ], + "name": "cohortFingerprint", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "ritualID", + "type": "uint256" + }, + { + "internalType": "address", + "name": "provider", + "type": "address" + } + ], + "name": "getParticipantFromProvider", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "provider", + "type": "address" + }, + { + "internalType": "bool", + "name": "aggregated", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "transcript", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "decryptionRequestStaticKey", + "type": "bytes" + } + ], + "internalType": "struct Coordinator.Participant", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "ritualId", + "type": "uint32" + } + ], + "name": "getParticipants", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "provider", + "type": "address" + }, + { + "internalType": "bool", + "name": "aggregated", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "transcript", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "decryptionRequestStaticKey", + "type": "bytes" + } + ], + "internalType": "struct Coordinator.Participant[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "ritualId", + "type": "uint256" + } + ], + "name": "getRitualState", + "outputs": [ + { + "internalType": "enum Coordinator.RitualState", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "providers", + "type": "address[]" + } + ], + "name": "initiateRitual", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxDkgSize", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "numberOfRituals", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "ritualId", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "aggregatedTranscript", + "type": "bytes" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "word0", + "type": "bytes32" + }, + { + "internalType": "bytes16", + "name": "word1", + "type": "bytes16" + } + ], + "internalType": "struct BLS12381.G1Point", + "name": "publicKey", + "type": "tuple" + }, + { + "internalType": "bytes", + "name": "decryptionRequestStaticKey", + "type": "bytes" + } + ], + "name": "postAggregation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "ritualId", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "transcript", + "type": "bytes" + } + ], + "name": "postTranscript", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rituals", + "outputs": [ + { + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "internalType": "uint32", + "name": "dkgSize", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "initTimestamp", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "totalTranscripts", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "totalAggregations", + "type": "uint32" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "word0", + "type": "bytes32" + }, + { + "internalType": "bytes16", + "name": "word1", + "type": "bytes16" + } + ], + "internalType": "struct BLS12381.G1Point", + "name": "publicKey", + "type": "tuple" + }, + { + "internalType": "bool", + "name": "aggregationMismatch", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "aggregatedTranscript", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "newSize", + "type": "uint32" + } + ], + "name": "setMaxDkgSize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "newTimeout", + "type": "uint32" + } + ], + "name": "setTimeout", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "timeout", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/examples/api-example.ts b/examples/api-example.ts index 6991b2a66..6ea4909d4 100644 --- a/examples/api-example.ts +++ b/examples/api-example.ts @@ -1,7 +1,7 @@ import { BlockchainPolicyParameters, Enrico } from '../src'; import { toBytes } from '../src/utils'; -import { fromBytes, mockAlice, mockBob, mockRemoteBob } from '../test/utils'; +import { fromBytes, fakeAlice, fakeBob, fakeRemoteBob } from '../test/utils'; /** * This is an abridged version of PRE API usage example. @@ -10,9 +10,9 @@ import { fromBytes, mockAlice, mockBob, mockRemoteBob } from '../test/utils'; async function example() { // Alice creates a policy and grants access to Bob - const alice = mockAlice(); + const alice = fakeAlice(); // `remoteBob` is a just a container for public keys of Bob - const remoteBob = mockRemoteBob(); + const remoteBob = fakeRemoteBob(); const policyParams: BlockchainPolicyParameters = { bob: remoteBob, label: 'fake-data-label', @@ -26,10 +26,10 @@ async function example() { // Enrico encrypts data on behalf of Alice const enrico = new Enrico(policy.policyKey); const message = 'secret-message-from-alice'; - const encryptedMessage = enrico.encryptMessage(toBytes(message)); + const encryptedMessage = enrico.encryptMessagePre(toBytes(message)); // Bob retrieves & decrypts encrypted message - const bob = mockBob(); + const bob = fakeBob(); const retrievedMessage = await bob.retrieveAndDecrypt( policy.policyKey, alice.verifyingKey, @@ -39,4 +39,3 @@ async function example() { const bobPlaintext = fromBytes(retrievedMessage[0]); console.log(bobPlaintext); } - diff --git a/package.json b/package.json index 7bcc725b3..025a952bc 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@nucypher/nucypher-ts", "author": "Piotr Roslaniec ", - "version": "1.0.0-beta.1", + "version": "1.0.0-beta.2", "license": "GPL-3.0-only", "repository": { "type": "git", @@ -35,7 +35,7 @@ "test:lint": "eslint src test --ext .ts", "test:exports": "ts-unused-exports tsconfig.json --ignoreFiles src/index.ts", "test:prettier": "prettier \"src/**/*.ts\" \"test/**/*.ts\" --list-different", - "test:unit": "jest", + "test:unit": "jest --detectOpenHandles --forceExit --runInBand", "watch:build": "tsc -p tsconfig.json -w", "watch:test": "jest --watch", "cov": "run-s build test:unit && open-cli coverage/index.html", @@ -45,26 +45,32 @@ "doc:publish": "gh-pages -m \"[ci skip] Updates\" -d build/docs", "version": "standard-version", "version:alpha": "standard-version --prerelease alpha", + "version:beta": "standard-version --prerelease beta", "reset-hard": "git clean -dfx && git reset --hard && yarn", "prepare-release": "run-s reset-hard test doc:html version doc:publish", "prepare-release:alpha": "run-s reset-hard test version:alpha ", + "prepare-release:beta": "run-s reset-hard test version:beta ", "typechain": "typechain --target=ethers-v5 \"abi/**/*.json\"", "prebuild": "yarn typechain" }, "dependencies": { - "@nucypher/nucypher-core": "0.4.0", + "@nucypher/nucypher-core": "^0.10.0", "axios": "^0.21.1", + "deep-equal": "^2.2.1", "ethers": "^5.4.1", "joi": "^17.7.0", - "qs": "^6.10.1" + "qs": "^6.10.1", + "semver": "^7.5.2" }, "devDependencies": { "@babel/core": "^7.18.10", "@babel/preset-env": "^7.15.6", "@skypack/package-check": "^0.2.2", "@typechain/ethers-v5": "^9.0.0", + "@types/deep-equal": "^1.0.1", "@types/jest": "^26.0.24", "@types/qs": "^6.9.7", + "@types/semver": "^7.5.0", "@typescript-eslint/eslint-plugin": "^4.0.1", "@typescript-eslint/parser": "^4.0.1", "cz-conventional-changelog": "^3.0.1", diff --git a/src/agents/contracts.ts b/src/agents/contracts.ts index f967d67d9..0ed03352f 100644 --- a/src/agents/contracts.ts +++ b/src/agents/contracts.ts @@ -1,27 +1,52 @@ import { ChainId, ChecksumAddress } from '../types'; type Contracts = { - readonly SUBSCRIPTION_MANAGER: ChecksumAddress; + readonly SUBSCRIPTION_MANAGER: ChecksumAddress | undefined; + readonly COORDINATOR: ChecksumAddress | undefined; }; const POLYGON: Contracts = { SUBSCRIPTION_MANAGER: '0xB0194073421192F6Cf38d72c791Be8729721A0b3', + COORDINATOR: undefined, }; const MUMBAI: Contracts = { SUBSCRIPTION_MANAGER: '0xb9015d7b35ce7c81dde38ef7136baa3b1044f313', + COORDINATOR: '0x0f019Ade1D34399D946CF2f161386362655Dd1A4', +}; + +const GOERLI: Contracts = { + SUBSCRIPTION_MANAGER: undefined, + COORDINATOR: '0x2cf19429168a0943992D8e7dE534E9b802C687B6', +}; + +const MAINNET: Contracts = { + SUBSCRIPTION_MANAGER: undefined, + COORDINATOR: undefined, }; const CONTRACTS: { readonly [key in ChainId]: Contracts } = { [ChainId.POLYGON]: POLYGON, [ChainId.MUMBAI]: MUMBAI, + [ChainId.GOERLI]: GOERLI, + [ChainId.MAINNET]: MAINNET, }; -export const getContracts = (chainId: number): Contracts => { +export const getContract = ( + chainId: number, + contract: keyof Contracts +): ChecksumAddress => { if (!Object.values(ChainId).includes(chainId)) { throw new Error(`No contracts found for chainId: ${chainId}`); } - return CONTRACTS[chainId as ChainId]; + if (!Object.keys(CONTRACTS[chainId as ChainId]).includes(contract)) { + throw new Error(`No contract found for name: ${contract}`); + } + const address = CONTRACTS[chainId as ChainId][contract]; + if (!address) { + throw new Error(`No address found for contract: ${contract}`); + } + return address; }; export const DEFAULT_WAIT_N_CONFIRMATIONS = 1; diff --git a/src/agents/coordinator.ts b/src/agents/coordinator.ts new file mode 100644 index 000000000..264e4ea50 --- /dev/null +++ b/src/agents/coordinator.ts @@ -0,0 +1,69 @@ +import { SessionStaticKey } from '@nucypher/nucypher-core'; +import { ethers } from 'ethers'; + +import { + Coordinator, + Coordinator__factory, +} from '../../types/ethers-contracts'; +import { BLS12381 } from '../../types/ethers-contracts/Coordinator'; +import { fromHexString } from '../utils'; + +import { getContract } from './contracts'; + +export interface CoordinatorRitual { + initiator: string; + dkgSize: number; + initTimestamp: number; + totalTranscripts: number; + totalAggregations: number; + publicKey: BLS12381.G1PointStructOutput; + aggregationMismatch: boolean; + aggregatedTranscript: string; +} + +export type DkgParticipant = { + provider: string; + aggregated: boolean; + decryptionRequestStaticKey: SessionStaticKey; +}; + +export class DkgCoordinatorAgent { + public static async getParticipants( + provider: ethers.providers.Provider, + ritualId: number + ): Promise { + const Coordinator = await this.connectReadOnly(provider); + const participants = await Coordinator.getParticipants(ritualId); + + return participants.map((participant) => { + return { + provider: participant.provider, + aggregated: participant.aggregated, + decryptionRequestStaticKey: SessionStaticKey.fromBytes( + fromHexString(participant.decryptionRequestStaticKey) + ), + }; + }); + } + + public static async getRitual( + provider: ethers.providers.Provider, + ritualId: number + ): Promise { + const Coordinator = await this.connectReadOnly(provider); + return Coordinator.rituals(ritualId); + } + + private static async connectReadOnly(provider: ethers.providers.Provider) { + return await this.connect(provider); + } + + private static async connect( + provider: ethers.providers.Provider, + signer?: ethers.providers.JsonRpcSigner + ): Promise { + const network = await provider.getNetwork(); + const contractAddress = getContract(network.chainId, 'COORDINATOR'); + return Coordinator__factory.connect(contractAddress, signer ?? provider); + } +} diff --git a/src/agents/subscription-manager.ts b/src/agents/subscription-manager.ts index 53bb61685..ac8a5a3c5 100644 --- a/src/agents/subscription-manager.ts +++ b/src/agents/subscription-manager.ts @@ -11,9 +11,9 @@ import { } from '../../types/ethers-contracts'; import { ChecksumAddress } from '../types'; -import { DEFAULT_WAIT_N_CONFIRMATIONS, getContracts } from './contracts'; +import { DEFAULT_WAIT_N_CONFIRMATIONS, getContract } from './contracts'; -export class SubscriptionManagerAgent { +export class PreSubscriptionManagerAgent { public static async createPolicy( web3Provider: ethers.providers.Web3Provider, valueInWei: BigNumber, @@ -76,7 +76,10 @@ export class SubscriptionManagerAgent { signer?: ethers.providers.JsonRpcSigner ): Promise { const network = await provider.getNetwork(); - const contractAddress = getContracts(network.chainId).SUBSCRIPTION_MANAGER; + const contractAddress = getContract( + network.chainId, + 'SUBSCRIPTION_MANAGER' + ); return SubscriptionManager__factory.connect( contractAddress, signer ?? provider diff --git a/src/characters/bob.ts b/src/characters/bob.ts index 5d4c67101..1ee8606af 100644 --- a/src/characters/bob.ts +++ b/src/characters/bob.ts @@ -27,11 +27,11 @@ export class RemoteBob { const dk = decryptingKey instanceof PublicKey ? decryptingKey - : PublicKey.fromBytes(decryptingKey); + : PublicKey.fromCompressedBytes(decryptingKey); const vk = verifyingKey instanceof PublicKey ? verifyingKey - : PublicKey.fromBytes(verifyingKey); + : PublicKey.fromCompressedBytes(verifyingKey); return new RemoteBob(dk, vk); } } diff --git a/src/characters/cbd-recipient.ts b/src/characters/cbd-recipient.ts new file mode 100644 index 000000000..8a97e2eda --- /dev/null +++ b/src/characters/cbd-recipient.ts @@ -0,0 +1,223 @@ +import { + Ciphertext, + Context, + DecryptionSharePrecomputed, + DecryptionShareSimple, + decryptWithSharedSecret, + EncryptedThresholdDecryptionRequest, + EncryptedThresholdDecryptionResponse, + SessionSharedSecret, + SessionStaticSecret, + ThresholdDecryptionRequest, +} from '@nucypher/nucypher-core'; +import { ethers } from 'ethers'; + +import { DkgCoordinatorAgent, DkgParticipant } from '../agents/coordinator'; +import { ConditionExpression } from '../conditions'; +import { + DkgRitual, + FerveoVariant, + getCombineDecryptionSharesFunction, + getVariantClass, +} from '../dkg'; +import { fromJSON, toJSON } from '../utils'; + +import { Porter } from './porter'; + +export type CbdTDecDecrypterJSON = { + porterUri: string; + ritualId: number; + threshold: number; +}; + +export class CbdTDecDecrypter { + // private readonly verifyingKey: Keyring; + + private constructor( + private readonly porter: Porter, + private readonly ritualId: number, + private readonly threshold: number + ) {} + + public static create(porterUri: string, dkgRitual: DkgRitual) { + return new CbdTDecDecrypter( + new Porter(porterUri), + dkgRitual.id, + dkgRitual.threshold + ); + } + + // Retrieve and decrypt ciphertext using provider and condition expression + public async retrieveAndDecrypt( + provider: ethers.providers.Web3Provider, + conditionExpr: ConditionExpression, + variant: FerveoVariant, + ciphertext: Ciphertext + ): Promise { + const decryptionShares = await this.retrieve( + provider, + conditionExpr, + variant, + ciphertext + ); + + const combineDecryptionSharesFn = + getCombineDecryptionSharesFunction(variant); + const sharedSecret = combineDecryptionSharesFn(decryptionShares); + return decryptWithSharedSecret( + ciphertext, + conditionExpr.asAad(), + sharedSecret + ); + } + + // Retrieve decryption shares + public async retrieve( + provider: ethers.providers.Web3Provider, + conditionExpr: ConditionExpression, + variant: number, + ciphertext: Ciphertext + ): Promise { + const dkgParticipants = await DkgCoordinatorAgent.getParticipants( + provider, + this.ritualId + ); + const contextStr = await conditionExpr.buildContext(provider).toJson(); + const { sharedSecrets, encryptedRequests } = this.makeDecryptionRequests( + this.ritualId, + variant, + ciphertext, + conditionExpr, + contextStr, + dkgParticipants + ); + + const { encryptedResponses, errors } = await this.porter.cbdDecrypt( + encryptedRequests, + this.threshold + ); + if (Object.keys(encryptedResponses).length < this.threshold) { + throw new Error( + `CBD decryption failed with errors: ${JSON.stringify(errors)}` + ); + } + + return this.makeDecryptionShares( + encryptedResponses, + sharedSecrets, + variant, + this.ritualId + ); + } + + private makeDecryptionShares( + encryptedResponses: Record, + sessionSharedSecret: Record, + variant: number, + expectedRitualId: number + ) { + const decryptedResponses = Object.entries(encryptedResponses).map( + ([ursula, response]) => response.decrypt(sessionSharedSecret[ursula]) + ); + + const ritualIds = decryptedResponses.map(({ ritualId }) => ritualId); + if (ritualIds.some((ritualId) => ritualId !== expectedRitualId)) { + throw new Error( + `Ritual id mismatch. Expected ${expectedRitualId}, got ${ritualIds}` + ); + } + + const decryptionShares = decryptedResponses.map( + ({ decryptionShare }) => decryptionShare + ); + + const DecryptionShareType = getVariantClass(variant); + return decryptionShares.map((share) => + DecryptionShareType.fromBytes(share) + ); + } + + private makeDecryptionRequests( + ritualId: number, + variant: number, + ciphertext: Ciphertext, + conditionExpr: ConditionExpression, + contextStr: string, + dkgParticipants: Array + ): { + sharedSecrets: Record; + encryptedRequests: Record; + } { + const decryptionRequest = new ThresholdDecryptionRequest( + ritualId, + variant, + ciphertext, + conditionExpr.toWASMConditions(), + new Context(contextStr) + ); + + const ephemeralSessionKey = this.makeSessionKey(); + + // Compute shared secrets for each participant + const sharedSecrets: Record = + Object.fromEntries( + dkgParticipants.map(({ provider, decryptionRequestStaticKey }) => { + const sharedSecret = ephemeralSessionKey.deriveSharedSecret( + decryptionRequestStaticKey + ); + return [provider, sharedSecret]; + }) + ); + + // Create encrypted requests for each participant + const encryptedRequests: Record< + string, + EncryptedThresholdDecryptionRequest + > = Object.fromEntries( + Object.entries(sharedSecrets).map(([provider, sessionSharedSecret]) => { + const encryptedRequest = decryptionRequest.encrypt( + sessionSharedSecret, + ephemeralSessionKey.publicKey() + ); + return [provider, encryptedRequest]; + }) + ); + + return { sharedSecrets, encryptedRequests }; + } + + private makeSessionKey() { + // Moving to a separate function to make it easier to mock + return SessionStaticSecret.random(); + } + + public toObj(): CbdTDecDecrypterJSON { + return { + porterUri: this.porter.porterUrl.toString(), + ritualId: this.ritualId, + threshold: this.threshold, + }; + } + + public toJSON(): string { + return toJSON(this.toObj()); + } + + public static fromObj({ + porterUri, + ritualId, + threshold, + }: CbdTDecDecrypterJSON) { + return new CbdTDecDecrypter(new Porter(porterUri), ritualId, threshold); + } + + public static fromJSON(json: string) { + return CbdTDecDecrypter.fromObj(fromJSON(json)); + } + + public equals(other: CbdTDecDecrypter): boolean { + return ( + this.porter.porterUrl.toString() === other.porter.porterUrl.toString() + ); + } +} diff --git a/src/characters/enrico.ts b/src/characters/enrico.ts index bf79b269b..17c6ff358 100644 --- a/src/characters/enrico.ts +++ b/src/characters/enrico.ts @@ -1,20 +1,27 @@ -import { MessageKit, PublicKey, SecretKey } from '@nucypher/nucypher-core'; +import { + Ciphertext, + DkgPublicKey, + ferveoEncrypt, + MessageKit, + PublicKey, + SecretKey, +} from '@nucypher/nucypher-core'; +import { ConditionExpression } from '../conditions'; import { Keyring } from '../keyring'; -import { ConditionSet } from '../policies/conditions'; import { toBytes } from '../utils'; export class Enrico { - public readonly policyEncryptingKey: PublicKey; + public readonly encryptingKey: PublicKey | DkgPublicKey; private readonly keyring: Keyring; - public conditions?: ConditionSet; + public conditions?: ConditionExpression; constructor( - policyEncryptingKey: PublicKey, + encryptingKey: PublicKey | DkgPublicKey, verifyingKey?: SecretKey, - conditions?: ConditionSet + conditions?: ConditionExpression ) { - this.policyEncryptingKey = policyEncryptingKey; + this.encryptingKey = encryptingKey; this.keyring = new Keyring(verifyingKey ?? SecretKey.random()); this.conditions = conditions; } @@ -23,17 +30,47 @@ export class Enrico { return this.keyring.publicKey; } - public encryptMessage( + public encryptMessagePre( plaintext: Uint8Array | string, - currentConditions?: ConditionSet + withConditions?: ConditionExpression ): MessageKit { - if (!currentConditions) { - currentConditions = this.conditions; + if (!withConditions) { + withConditions = this.conditions; } + + if (!(this.encryptingKey instanceof PublicKey)) { + throw new Error('Wrong key type. Use encryptMessageCbd instead.'); + } + return new MessageKit( - this.policyEncryptingKey, + this.encryptingKey, + plaintext instanceof Uint8Array ? plaintext : toBytes(plaintext), + withConditions ? withConditions.toWASMConditions() : null + ); + } + + public encryptMessageCbd( + plaintext: Uint8Array | string, + withConditions?: ConditionExpression + ): { ciphertext: Ciphertext; aad: Uint8Array } { + if (!withConditions) { + withConditions = this.conditions; + } + + if (!withConditions) { + throw new Error('Conditions are required for CBD encryption.'); + } + + if (!(this.encryptingKey instanceof DkgPublicKey)) { + throw new Error('Wrong key type. Use encryptMessagePre instead.'); + } + + const aad = withConditions.asAad(); + const ciphertext = ferveoEncrypt( plaintext instanceof Uint8Array ? plaintext : toBytes(plaintext), - currentConditions ? currentConditions.toWASMConditions() : null + aad, + this.encryptingKey ); + return { ciphertext, aad }; } } diff --git a/src/characters/porter.ts b/src/characters/porter.ts index 7834ab491..1bcc6aa41 100644 --- a/src/characters/porter.ts +++ b/src/characters/porter.ts @@ -1,5 +1,7 @@ import { CapsuleFrag, + EncryptedThresholdDecryptionRequest, + EncryptedThresholdDecryptionResponse, PublicKey, RetrievalKit, TreasureMap, @@ -7,10 +9,12 @@ import { import axios, { AxiosResponse } from 'axios'; import qs from 'qs'; -import { ConditionContext } from '../policies/conditions'; +import { ConditionContext } from '../conditions'; import { Base64EncodedBytes, ChecksumAddress, HexEncodedBytes } from '../types'; import { fromBase64, fromHexString, toBase64, toHexString } from '../utils'; +// /get_ursulas + export type Ursula = { readonly checksumAddress: ChecksumAddress; readonly uri: string; @@ -29,13 +33,15 @@ type UrsulaResponse = { readonly encrypting_key: HexEncodedBytes; }; -export type GetUrsulasResponse = { +export type GetUrsulasResult = { readonly result: { readonly ursulas: readonly UrsulaResponse[]; }; readonly version: string; }; +// /retrieve_cfrags + type PostRetrieveCFragsRequest = { readonly treasure_map: Base64EncodedBytes; readonly retrieval_kits: readonly Base64EncodedBytes[]; @@ -45,7 +51,7 @@ type PostRetrieveCFragsRequest = { readonly context?: string; }; -type PostRetrieveCFragsResult = { +type PostRetrieveCFragsResponse = { readonly result: { readonly retrieval_results: readonly { readonly cfrags: { @@ -59,9 +65,36 @@ type PostRetrieveCFragsResult = { readonly version: string; }; -export type RetrieveCFragsResponse = { - cFrags: Record; - errors: Record; +export type RetrieveCFragsResult = { + readonly cFrags: Record; + readonly errors: Record; +}; + +// /cbd_decrypt + +type PostCbdDecryptRequest = { + readonly threshold: number; + readonly encrypted_decryption_requests: Record< + ChecksumAddress, + Base64EncodedBytes + >; +}; + +type PostCbdDecryptResponse = { + result: { + decryption_results: { + encrypted_decryption_responses: Record< + ChecksumAddress, + Base64EncodedBytes + >; + errors: Record; + }; + }; +}; + +export type CbdDecryptResult = { + encryptedResponses: Record; + errors: Record; }; export class Porter { @@ -81,7 +114,7 @@ export class Porter { exclude_ursulas: excludeUrsulas, include_ursulas: includeUrsulas, }; - const resp: AxiosResponse = await axios.get( + const resp: AxiosResponse = await axios.get( new URL('/get_ursulas', this.porterUrl).toString(), { params, @@ -93,7 +126,9 @@ export class Porter { return resp.data.result.ursulas.map((u: UrsulaResponse) => ({ checksumAddress: u.checksum_address, uri: u.uri, - encryptingKey: PublicKey.fromBytes(fromHexString(u.encrypting_key)), + encryptingKey: PublicKey.fromCompressedBytes( + fromHexString(u.encrypting_key) + ), })); } @@ -104,19 +139,19 @@ export class Porter { bobEncryptingKey: PublicKey, bobVerifyingKey: PublicKey, conditionsContext?: ConditionContext - ): Promise { + ): Promise { const context = conditionsContext ? await conditionsContext.toJson() : undefined; const data: PostRetrieveCFragsRequest = { treasure_map: toBase64(treasureMap.toBytes()), retrieval_kits: retrievalKits.map((rk) => toBase64(rk.toBytes())), - alice_verifying_key: toHexString(aliceVerifyingKey.toBytes()), - bob_encrypting_key: toHexString(bobEncryptingKey.toBytes()), - bob_verifying_key: toHexString(bobVerifyingKey.toBytes()), + alice_verifying_key: toHexString(aliceVerifyingKey.toCompressedBytes()), + bob_encrypting_key: toHexString(bobEncryptingKey.toCompressedBytes()), + bob_verifying_key: toHexString(bobVerifyingKey.toCompressedBytes()), context, }; - const resp: AxiosResponse = await axios.post( + const resp: AxiosResponse = await axios.post( new URL('/retrieve_cfrags', this.porterUrl).toString(), data ); @@ -130,4 +165,40 @@ export class Porter { return { cFrags, errors }; }); } + + public async cbdDecrypt( + encryptedRequests: Record, + threshold: number + ): Promise { + const data: PostCbdDecryptRequest = { + encrypted_decryption_requests: Object.fromEntries( + Object.entries(encryptedRequests).map(([ursula, encryptedRequest]) => [ + ursula, + toBase64(encryptedRequest.toBytes()), + ]) + ), + threshold, + }; + const resp: AxiosResponse = await axios.post( + new URL('/cbd_decrypt', this.porterUrl).toString(), + data + ); + + const { encrypted_decryption_responses, errors } = + resp.data.result.decryption_results; + + const decryptionResponses = Object.entries( + encrypted_decryption_responses + ).map(([address, encryptedResponseBase64]) => { + const encryptedResponse = EncryptedThresholdDecryptionResponse.fromBytes( + fromBase64(encryptedResponseBase64) + ); + return [address, encryptedResponse]; + }); + const encryptedResponses: Record< + string, + EncryptedThresholdDecryptionResponse + > = Object.fromEntries(decryptionResponses); + return { encryptedResponses, errors }; + } } diff --git a/src/characters/universal-bob.ts b/src/characters/pre-recipient.ts similarity index 65% rename from src/characters/universal-bob.ts rename to src/characters/pre-recipient.ts index be8b6afc6..ae0fc8cda 100644 --- a/src/characters/universal-bob.ts +++ b/src/characters/pre-recipient.ts @@ -8,15 +8,15 @@ import { } from '@nucypher/nucypher-core'; import { ethers } from 'ethers'; +import { Condition, ConditionContext } from '../conditions'; import { Keyring } from '../keyring'; import { PolicyMessageKit } from '../kits/message'; import { RetrievalResult } from '../kits/retrieval'; -import { ConditionSet } from '../policies/conditions'; -import { base64ToU8Receiver, u8ToBase64Replacer, zip } from '../utils'; +import { base64ToU8Receiver, bytesEquals, toJSON, zip } from '../utils'; import { Porter } from './porter'; -type decrypterJSON = { +export type PreTDecDecrypterJSON = { porterUri: string; policyEncryptingKeyBytes: Uint8Array; encryptedTreasureMapBytes: Uint8Array; @@ -24,22 +24,31 @@ type decrypterJSON = { bobSecretKeyBytes: Uint8Array; }; -export class tDecDecrypter { - private readonly porter: Porter; - private readonly keyring: Keyring; +export class PreTDecDecrypter { // private readonly verifyingKey: Keyring; constructor( - porterUri: string, + private readonly porter: Porter, + private readonly keyring: Keyring, private readonly policyEncryptingKey: PublicKey, - readonly encryptedTreasureMap: EncryptedTreasureMap, private readonly publisherVerifyingKey: PublicKey, - secretKey: SecretKey - // verifyingKey: SecretKey - ) { - this.porter = new Porter(porterUri); - this.keyring = new Keyring(secretKey); - // this.verifyingKey = new Keyring(verifyingKey); + private readonly encryptedTreasureMap: EncryptedTreasureMap + ) {} + + public static create( + porterUri: string, + secretKey: SecretKey, + policyEncryptingKey: PublicKey, + publisherVerifyingKey: PublicKey, + encryptedTreasureMap: EncryptedTreasureMap + ): PreTDecDecrypter { + return new PreTDecDecrypter( + new Porter(porterUri), + new Keyring(secretKey), + policyEncryptingKey, + publisherVerifyingKey, + encryptedTreasureMap + ); } public get decryptingKey(): PublicKey { @@ -97,8 +106,11 @@ export class tDecDecrypter { .map((condition) => JSON.parse(condition.toString())) .reduce((acc: Record[], val) => acc.concat(val), []); - const conditionContext = - ConditionSet.fromList(conditions).buildContext(provider); + const conditionsList = conditions.map((ele: Record) => { + return Condition.fromObj(ele); + }); + + const conditionContext = new ConditionContext(conditionsList, provider); const policyMessageKits = messageKits.map((mk) => PolicyMessageKit.fromMessageKit( @@ -137,38 +149,52 @@ export class tDecDecrypter { }); } - public toObj(): decrypterJSON { + public toObj(): PreTDecDecrypterJSON { return { porterUri: this.porter.porterUrl.toString(), - policyEncryptingKeyBytes: this.policyEncryptingKey.toBytes(), + policyEncryptingKeyBytes: this.policyEncryptingKey.toCompressedBytes(), encryptedTreasureMapBytes: this.encryptedTreasureMap.toBytes(), - publisherVerifyingKeyBytes: this.publisherVerifyingKey.toBytes(), - bobSecretKeyBytes: this.keyring.secretKey.toSecretBytes(), + publisherVerifyingKeyBytes: + this.publisherVerifyingKey.toCompressedBytes(), + bobSecretKeyBytes: this.keyring.secretKey.toBEBytes(), }; } public toJSON(): string { - return JSON.stringify(this.toObj(), u8ToBase64Replacer); + return toJSON(this.toObj()); } - private static fromObj({ + public static fromObj({ porterUri, policyEncryptingKeyBytes, encryptedTreasureMapBytes, publisherVerifyingKeyBytes, bobSecretKeyBytes, - }: decrypterJSON) { - return new tDecDecrypter( - porterUri, - PublicKey.fromBytes(policyEncryptingKeyBytes), - EncryptedTreasureMap.fromBytes(encryptedTreasureMapBytes), - PublicKey.fromBytes(publisherVerifyingKeyBytes), - SecretKey.fromBytes(bobSecretKeyBytes) + }: PreTDecDecrypterJSON) { + return new PreTDecDecrypter( + new Porter(porterUri), + new Keyring(SecretKey.fromBEBytes(bobSecretKeyBytes)), + PublicKey.fromCompressedBytes(policyEncryptingKeyBytes), + PublicKey.fromCompressedBytes(publisherVerifyingKeyBytes), + EncryptedTreasureMap.fromBytes(encryptedTreasureMapBytes) ); } public static fromJSON(json: string) { const config = JSON.parse(json, base64ToU8Receiver); - return tDecDecrypter.fromObj(config); + return PreTDecDecrypter.fromObj(config); + } + + public equals(other: PreTDecDecrypter): boolean { + return ( + this.porter.porterUrl.toString() === other.porter.porterUrl.toString() && + this.policyEncryptingKey.equals(other.policyEncryptingKey) && + // TODO: Replace with `equals` after https://github.com/nucypher/nucypher-core/issues/56 is fixed + bytesEquals( + this.encryptedTreasureMap.toBytes(), + other.encryptedTreasureMap.toBytes() + ) && + this.publisherVerifyingKey.equals(other.publisherVerifyingKey) + ); } } diff --git a/src/conditions/base/condition.ts b/src/conditions/base/condition.ts new file mode 100644 index 000000000..f4caa12c2 --- /dev/null +++ b/src/conditions/base/condition.ts @@ -0,0 +1,44 @@ +import Joi from 'joi'; + +import { objectEquals } from '../../utils'; + +type Map = Record; + +export class Condition { + public readonly schema = Joi.object(); + public readonly defaults: Map = {}; + + constructor(private readonly value: Record = {}) {} + + public validate(override: Map = {}) { + const newValue = { + ...this.defaults, + ...this.value, + ...override, + }; + return this.schema.validate(newValue); + } + + public toObj(): Map { + const { error, value } = this.validate(this.value); + if (error) { + throw `Invalid condition: ${error.message}`; + } + return { + ...value, + }; + } + + public static fromObj( + // We disable the eslint rule here because we have to pass args to the constructor + // eslint-disable-next-line @typescript-eslint/no-explicit-any + this: new (...args: any[]) => T, + obj: Map + ): T { + return new this(obj); + } + + public equals(other: Condition) { + return objectEquals(this, other); + } +} diff --git a/src/conditions/base/contract.ts b/src/conditions/base/contract.ts new file mode 100644 index 000000000..83a13b6ae --- /dev/null +++ b/src/conditions/base/contract.ts @@ -0,0 +1,59 @@ +import Joi from 'joi'; + +import { ETH_ADDRESS_REGEXP } from '../const'; + +import { RpcCondition, rpcConditionRecord } from './rpc'; + +export const STANDARD_CONTRACT_TYPES = ['ERC20', 'ERC721']; + +const functionAbiVariable = Joi.object({ + internalType: Joi.string(), // TODO is this needed? + name: Joi.string().required(), + type: Joi.string().required(), +}); + +const functionAbiSchema = Joi.object({ + name: Joi.string().required(), + type: Joi.string().valid('function').required(), + inputs: Joi.array().items(functionAbiVariable), + outputs: Joi.array().items(functionAbiVariable), + // TODO: Should we restrict this to 'view'? + stateMutability: Joi.string(), +}).custom((functionAbi, helper) => { + // Validate method name + const method = helper.state.ancestors[0].method; + if (functionAbi.name !== method) { + return helper.message({ + custom: '"method" must be the same as "functionAbi.name"', + }); + } + + // Validate nr of parameters + const parameters = helper.state.ancestors[0].parameters; + if (functionAbi.inputs?.length !== parameters.length) { + return helper.message({ + custom: '"parameters" must have the same length as "functionAbi.inputs"', + }); + } + + return functionAbi; +}); + +export const contractConditionRecord: Record = { + ...rpcConditionRecord, + contractAddress: Joi.string().pattern(ETH_ADDRESS_REGEXP).required(), + standardContractType: Joi.string() + .valid(...STANDARD_CONTRACT_TYPES) + .optional(), + method: Joi.string().required(), + functionAbi: functionAbiSchema.optional(), + parameters: Joi.array().required(), +}; + +export const contractConditionSchema = Joi.object(contractConditionRecord) + // At most one of these keys needs to be present + .xor('standardContractType', 'functionAbi'); + +export class ContractCondition extends RpcCondition { + public readonly schema = contractConditionSchema; +} diff --git a/src/conditions/base/index.ts b/src/conditions/base/index.ts new file mode 100644 index 000000000..805717e01 --- /dev/null +++ b/src/conditions/base/index.ts @@ -0,0 +1,4 @@ +export { Condition } from './condition'; +export { ContractCondition } from './contract'; +export { RpcCondition } from './rpc'; +export { TimeCondition } from './time'; diff --git a/src/conditions/base/return-value.ts b/src/conditions/base/return-value.ts new file mode 100644 index 000000000..544033cdc --- /dev/null +++ b/src/conditions/base/return-value.ts @@ -0,0 +1,29 @@ +import Joi from 'joi'; + +import { ETH_ADDRESS_REGEXP, USER_ADDRESS_PARAM } from '../const'; + +const COMPARATORS = ['==', '>', '<', '>=', '<=', '!=']; + +export interface ReturnValueTestConfig { + index?: number; + comparator: string; + value: string | number; +} + +export const returnValueTestSchema: Joi.ObjectSchema = + Joi.object({ + index: Joi.number().optional(), + comparator: Joi.string() + .valid(...COMPARATORS) + .required(), + value: Joi.alternatives( + Joi.string(), + Joi.number(), + Joi.boolean() + ).required(), + }); + +export const ethAddressOrUserAddressSchema = Joi.alternatives( + Joi.string().pattern(ETH_ADDRESS_REGEXP), + USER_ADDRESS_PARAM +); diff --git a/src/conditions/base/rpc.ts b/src/conditions/base/rpc.ts new file mode 100644 index 000000000..27ed5f0b7 --- /dev/null +++ b/src/conditions/base/rpc.ts @@ -0,0 +1,39 @@ +import Joi from 'joi'; + +import { SUPPORTED_CHAINS } from '../const'; + +import { Condition } from './condition'; +import { + ethAddressOrUserAddressSchema, + returnValueTestSchema, +} from './return-value'; + +const rpcMethodSchemas: Record = { + eth_getBalance: Joi.array().items(ethAddressOrUserAddressSchema).required(), + balanceOf: Joi.array().items(ethAddressOrUserAddressSchema).required(), +}; + +const makeParameters = () => + Joi.array().when('method', { + switch: Object.keys(rpcMethodSchemas).map((method) => ({ + is: method, + then: rpcMethodSchemas[method], + })), + }); + +export const rpcConditionRecord = { + chain: Joi.number() + .valid(...SUPPORTED_CHAINS) + .required(), + method: Joi.string() + .valid(...Object.keys(rpcMethodSchemas)) + .required(), + parameters: makeParameters(), + returnValueTest: returnValueTestSchema.required(), +}; + +export const rpcConditionSchema = Joi.object(rpcConditionRecord); + +export class RpcCondition extends Condition { + public readonly schema = rpcConditionSchema; +} diff --git a/src/conditions/base/time.ts b/src/conditions/base/time.ts new file mode 100644 index 000000000..4f4671dd0 --- /dev/null +++ b/src/conditions/base/time.ts @@ -0,0 +1,23 @@ +import Joi from 'joi'; + +import { omit } from '../../utils'; + +import { RpcCondition, rpcConditionRecord } from './rpc'; + +export const BLOCKTIME_METHOD = 'blocktime'; + +export const timeConditionRecord: Record = { + // TimeCondition is an RpcCondition with the method set to 'blocktime' and no parameters + ...omit(rpcConditionRecord, ['parameters']), + method: Joi.string().valid(BLOCKTIME_METHOD).required(), +}; + +export const timeConditionSchema = Joi.object(timeConditionRecord); + +export class TimeCondition extends RpcCondition { + public readonly defaults: Record = { + method: BLOCKTIME_METHOD, + }; + + public readonly schema = timeConditionSchema; +} diff --git a/src/conditions/compound-condition.ts b/src/conditions/compound-condition.ts new file mode 100644 index 000000000..3b35f675a --- /dev/null +++ b/src/conditions/compound-condition.ts @@ -0,0 +1,31 @@ +import Joi from 'joi'; + +import { Condition } from './base'; +import { contractConditionSchema } from './base/contract'; +import { rpcConditionSchema } from './base/rpc'; +import { timeConditionSchema } from './base/time'; + +const OR_OPERATOR = 'or'; +const AND_OPERATOR = 'and'; + +const LOGICAL_OPERATORS = [AND_OPERATOR, OR_OPERATOR]; + +export const compoundConditionSchema = Joi.object({ + operator: Joi.string() + .valid(...LOGICAL_OPERATORS) + .required(), + operands: Joi.array() + .min(2) + .items( + rpcConditionSchema, + timeConditionSchema, + contractConditionSchema, + Joi.link('#compoundCondition') + ) + .required() + .valid(), +}).id('compoundCondition'); + +export class CompoundCondition extends Condition { + public readonly schema = compoundConditionSchema; +} diff --git a/src/conditions/condition-expr.ts b/src/conditions/condition-expr.ts new file mode 100644 index 000000000..5cc032c5e --- /dev/null +++ b/src/conditions/condition-expr.ts @@ -0,0 +1,103 @@ +import { Conditions as WASMConditions } from '@nucypher/nucypher-core'; +import { ethers } from 'ethers'; +import { SemVer } from 'semver'; + +import { objectEquals, toBytes, toJSON } from '../utils'; + +import { + Condition, + ContractCondition, + RpcCondition, + TimeCondition, +} from './base'; +import { BLOCKTIME_METHOD } from './base/time'; +import { CompoundCondition } from './compound-condition'; +import { ConditionContext } from './context'; + +export type ConditionExpressionJSON = { + version: string; + condition: Record; +}; + +export class ConditionExpression { + static VERSION = '1.0.0'; + + constructor( + public readonly condition: Condition, + public readonly version: string = ConditionExpression.VERSION + ) {} + + public toObj(): ConditionExpressionJSON { + const conditionData = this.condition.toObj(); + return { + version: this.version, + condition: conditionData, + }; + } + + public static fromObj(obj: ConditionExpressionJSON): ConditionExpression { + const receivedVersion = new SemVer(obj.version); + const currentVersion = new SemVer(ConditionExpression.VERSION); + if (receivedVersion.major > currentVersion.major) { + throw new Error( + `Version provided, ${obj.version}, is incompatible with current version, ${ConditionExpression.VERSION}` + ); + } + + const underlyingConditionData = obj.condition; + let condition: Condition | undefined; + + if (underlyingConditionData.operator) { + condition = new CompoundCondition(underlyingConditionData); + } else if (underlyingConditionData.method) { + if (underlyingConditionData.method === BLOCKTIME_METHOD) { + condition = new TimeCondition(underlyingConditionData); + } else if (underlyingConditionData.contractAddress) { + condition = new ContractCondition(underlyingConditionData); + } else if ( + (underlyingConditionData.method as string).startsWith('eth_') + ) { + condition = new RpcCondition(underlyingConditionData); + } + } + + if (!condition) { + throw new Error( + `Invalid condition: unrecognized condition data ${JSON.stringify( + underlyingConditionData + )}` + ); + } + + return new ConditionExpression(condition, obj.version); + } + + public toJson(): string { + return toJSON(this.toObj()); + } + + public static fromJSON(json: string): ConditionExpression { + return ConditionExpression.fromObj(JSON.parse(json)); + } + + public toWASMConditions(): WASMConditions { + return new WASMConditions(toJSON(this.toObj())); + } + + public buildContext( + provider: ethers.providers.Web3Provider + ): ConditionContext { + return new ConditionContext([this.condition], provider); + } + + public asAad(): Uint8Array { + return toBytes(this.toJson()); + } + + public equals(other: ConditionExpression): boolean { + return ( + this.version === other.version && + objectEquals(this.condition.toObj(), other.condition.toObj()) + ); + } +} diff --git a/src/conditions/const.ts b/src/conditions/const.ts new file mode 100644 index 000000000..19f336649 --- /dev/null +++ b/src/conditions/const.ts @@ -0,0 +1,12 @@ +import { ChainId } from '../types'; + +export const SUPPORTED_CHAINS = [ + ChainId.MAINNET, + ChainId.GOERLI, + ChainId.POLYGON, + ChainId.MUMBAI, +]; + +export const USER_ADDRESS_PARAM = ':userAddress'; + +export const ETH_ADDRESS_REGEXP = new RegExp('^0x[a-fA-F0-9]{40}$'); diff --git a/src/conditions/context/context.ts b/src/conditions/context/context.ts new file mode 100644 index 000000000..fcf9939c3 --- /dev/null +++ b/src/conditions/context/context.ts @@ -0,0 +1,108 @@ +import { Conditions as WASMConditions } from '@nucypher/nucypher-core'; +import { ethers } from 'ethers'; + +import { fromJSON, toJSON } from '../../utils'; +import { Condition } from '../base'; +import { USER_ADDRESS_PARAM } from '../const'; + +import { TypedSignature, WalletAuthenticationProvider } from './providers'; + +export type CustomContextParam = string | number | boolean; +export type ContextParam = CustomContextParam | TypedSignature; + +export const RESERVED_CONTEXT_PARAMS = [USER_ADDRESS_PARAM]; +export const CONTEXT_PARAM_PREFIX = ':'; + +export class ConditionContext { + private readonly walletAuthProvider: WalletAuthenticationProvider; + + constructor( + private readonly conditions: ReadonlyArray, + // TODO: We don't always need a web3 provider, only in cases where some specific context parameters are used + // TODO: Consider making this optional or introducing a different pattern to handle that + private readonly web3Provider: ethers.providers.Web3Provider, + public readonly customParameters: Record = {} + ) { + Object.keys(customParameters).forEach((key) => { + if (RESERVED_CONTEXT_PARAMS.includes(key)) { + throw new Error( + `Cannot use reserved parameter name ${key} as custom parameter` + ); + } + if (!key.startsWith(CONTEXT_PARAM_PREFIX)) { + throw new Error( + `Custom parameter ${key} must start with ${CONTEXT_PARAM_PREFIX}` + ); + } + }); + this.walletAuthProvider = new WalletAuthenticationProvider(web3Provider); + } + + public toObj = async (): Promise> => { + // First, we want to find all the parameters we need to add + const requestedParameters = new Set(); + + // Search conditions for parameters + const conditions = this.conditions.map((cnd) => cnd.toObj()); + const conditionsToCheck = fromJSON( + new WASMConditions(toJSON(conditions)).toString() + ); + for (const cond of conditionsToCheck) { + // Check return value test + const rvt = cond.returnValueTest.value; + if (typeof rvt === 'string' && rvt.startsWith(CONTEXT_PARAM_PREFIX)) { + requestedParameters.add(rvt); + } + + // Check condition parameters + for (const param of cond.parameters ?? []) { + if ( + typeof param === 'string' && + param.startsWith(CONTEXT_PARAM_PREFIX) + ) { + requestedParameters.add(param); + } + } + } + + // Now, we can safely add all the parameters + const parameters: Record = {}; + + // Fill in predefined context parameters + if (requestedParameters.has(USER_ADDRESS_PARAM)) { + parameters[USER_ADDRESS_PARAM] = + await this.walletAuthProvider.getOrCreateWalletSignature(); + // Remove from requested parameters + requestedParameters.delete(USER_ADDRESS_PARAM); + } + + // Fill in custom parameters + for (const key in this.customParameters) { + parameters[key] = this.customParameters[key]; + } + + // Ok, so at this point we should have all the parameters we need + // If we don't, we have a problem and we should throw + const missingParameters = Array.from(requestedParameters).filter( + (key) => !parameters[key] + ); + if (missingParameters.length > 0) { + throw new Error( + `Missing custom context parameter(s): ${missingParameters.join(', ')}` + ); + } + + return parameters; + }; + + public toJson = async (): Promise => { + const parameters = await this.toObj(); + return toJSON(parameters); + }; + + public withCustomParams = ( + params: Record + ): ConditionContext => { + return new ConditionContext(this.conditions, this.web3Provider, params); + }; +} diff --git a/src/conditions/context/index.ts b/src/conditions/context/index.ts new file mode 100644 index 000000000..72a893ff3 --- /dev/null +++ b/src/conditions/context/index.ts @@ -0,0 +1,2 @@ +export { ConditionContext } from './context'; +export type { CustomContextParam } from './context'; diff --git a/src/conditions/context/providers.ts b/src/conditions/context/providers.ts new file mode 100644 index 000000000..9b8db518e --- /dev/null +++ b/src/conditions/context/providers.ts @@ -0,0 +1,126 @@ +import { ethers } from 'ethers'; +import { utils as ethersUtils } from 'ethers/lib/ethers'; + +import { Eip712TypedData, FormattedTypedData } from '../../web3'; + +export interface TypedSignature { + signature: string; + typedData: Eip712TypedData; + address: string; +} + +interface ChainData { + blockHash: string; + chainId: number; + blockNumber: number; +} + +export class WalletAuthenticationProvider { + private walletSignature?: Record; + + constructor(private readonly web3Provider: ethers.providers.Web3Provider) {} + + public async getOrCreateWalletSignature(): Promise { + const address = await this.web3Provider.getSigner().getAddress(); + const storageKey = `wallet-signature-${address}`; + + // If we have a signature in localStorage, return it + const isLocalStorage = typeof localStorage !== 'undefined'; + if (isLocalStorage) { + const maybeSignature = localStorage.getItem(storageKey); + if (maybeSignature) { + return JSON.parse(maybeSignature); + } + } + + // If not, try returning from memory + const maybeSignature = this.walletSignature?.[address]; + if (maybeSignature) { + if (isLocalStorage) { + localStorage.setItem(storageKey, maybeSignature); + } + return JSON.parse(maybeSignature); + } + + // If at this point we didn't return, we need to create a new signature + const typedSignature = await this.createWalletSignature(); + + // Persist where you can + if (isLocalStorage) { + localStorage.setItem(storageKey, JSON.stringify(typedSignature)); + } + if (!this.walletSignature) { + this.walletSignature = {}; + } + this.walletSignature[address] = JSON.stringify(typedSignature); + return typedSignature; + } + + private async createWalletSignature(): Promise { + // Ensure freshness of the signature + const { blockNumber, blockHash, chainId } = await this.getChainData(); + const address = await this.web3Provider.getSigner().getAddress(); + const signatureText = `I'm the owner of address ${address} as of block number ${blockNumber}`; + const salt = ethersUtils.hexlify(ethersUtils.randomBytes(32)); + + const typedData: Eip712TypedData = { + types: { + Wallet: [ + { name: 'address', type: 'address' }, + { name: 'signatureText', type: 'string' }, + { name: 'blockNumber', type: 'uint256' }, + { name: 'blockHash', type: 'bytes32' }, + ], + }, + domain: { + name: 'cbd', + version: '1', + chainId, + salt, + }, + message: { + address, + signatureText, + blockNumber, + blockHash, + }, + }; + const signature = await this.web3Provider + .getSigner() + ._signTypedData(typedData.domain, typedData.types, typedData.message); + + const formattedTypedData: FormattedTypedData = { + ...typedData, + primaryType: 'Wallet', + types: { + ...typedData.types, + EIP712Domain: [ + { + name: 'name', + type: 'string', + }, + { + name: 'version', + type: 'string', + }, + { + name: 'chainId', + type: 'uint256', + }, + { + name: 'salt', + type: 'bytes32', + }, + ], + }, + }; + return { signature, typedData: formattedTypedData, address }; + } + + private async getChainData(): Promise { + const blockNumber = await this.web3Provider.getBlockNumber(); + const blockHash = (await this.web3Provider.getBlock(blockNumber)).hash; + const chainId = (await this.web3Provider.getNetwork()).chainId; + return { blockNumber, blockHash, chainId }; + } +} diff --git a/src/conditions/index.ts b/src/conditions/index.ts new file mode 100644 index 000000000..2d5661fdb --- /dev/null +++ b/src/conditions/index.ts @@ -0,0 +1,10 @@ +import * as base from './base'; +import * as predefined from './predefined'; + +export { predefined, base }; +export { Condition } from './base/condition'; +export type { ConditionExpressionJSON } from './condition-expr'; +export { ConditionExpression } from './condition-expr'; +export { CompoundCondition } from './compound-condition'; +export type { CustomContextParam } from './context'; +export { ConditionContext } from './context'; diff --git a/src/conditions/predefined/erc721.ts b/src/conditions/predefined/erc721.ts new file mode 100644 index 000000000..beed9a5ce --- /dev/null +++ b/src/conditions/predefined/erc721.ts @@ -0,0 +1,28 @@ +import { ContractCondition } from '../base'; +import { USER_ADDRESS_PARAM } from '../const'; + +export class ERC721Ownership extends ContractCondition { + public readonly defaults = { + method: 'ownerOf', + parameters: [], + standardContractType: 'ERC721', + returnValueTest: { + index: 0, + comparator: '==', + value: USER_ADDRESS_PARAM, + }, + }; +} + +export class ERC721Balance extends ContractCondition { + public readonly defaults = { + method: 'balanceOf', + parameters: [USER_ADDRESS_PARAM], + standardContractType: 'ERC721', + returnValueTest: { + index: 0, + comparator: '>', + value: '0', + }, + }; +} diff --git a/src/conditions/predefined/index.ts b/src/conditions/predefined/index.ts new file mode 100644 index 000000000..2c08b2da4 --- /dev/null +++ b/src/conditions/predefined/index.ts @@ -0,0 +1 @@ +export { ERC721Balance, ERC721Ownership } from './erc721'; diff --git a/src/config.ts b/src/config.ts index 32b969429..1b59d0c4e 100644 --- a/src/config.ts +++ b/src/config.ts @@ -11,6 +11,14 @@ const CONFIGS: { readonly [key in ChainId]: Configuration } = { [ChainId.MUMBAI]: { porterUri: 'https://porter-tapir.nucypher.community', }, + [ChainId.GOERLI]: { + // TODO: Confirm this is correct + porterUri: 'https://porter-tapir.nucypher.community', + }, + [ChainId.MAINNET]: { + // TODO: Confirm this is correct + porterUri: 'https://porter.nucypher.io/', + }, }; export const defaultConfiguration = (chainId: number): Configuration => { diff --git a/src/dkg.ts b/src/dkg.ts new file mode 100644 index 000000000..f0ee81e41 --- /dev/null +++ b/src/dkg.ts @@ -0,0 +1,129 @@ +import { + combineDecryptionSharesPrecomputed, + combineDecryptionSharesSimple, + DecryptionSharePrecomputed, + DecryptionShareSimple, + DkgPublicKey, + SharedSecret, +} from '@nucypher/nucypher-core'; +import { ethers } from 'ethers'; + +import { DkgCoordinatorAgent } from './agents/coordinator'; +import { bytesEquals, fromHexString } from './utils'; + +// TODO: Expose from @nucypher/nucypher-core +export enum FerveoVariant { + Simple = 0, + Precomputed = 1, +} + +export function getVariantClass( + variant: FerveoVariant +): typeof DecryptionShareSimple | typeof DecryptionSharePrecomputed { + switch (variant) { + case FerveoVariant.Simple: + return DecryptionShareSimple; + case FerveoVariant.Precomputed: + return DecryptionSharePrecomputed; + default: + throw new Error(`Invalid FerveoVariant: ${variant}`); + } +} + +export function getCombineDecryptionSharesFunction( + variant: FerveoVariant +): ( + shares: DecryptionShareSimple[] | DecryptionSharePrecomputed[] +) => SharedSecret { + switch (variant) { + case FerveoVariant.Simple: + return combineDecryptionSharesSimple; + case FerveoVariant.Precomputed: + return combineDecryptionSharesPrecomputed; + default: + throw new Error(`Invalid FerveoVariant: ${variant}`); + } +} + +export interface DkgRitualJSON { + id: number; + dkgPublicKey: Uint8Array; + threshold: number; +} + +export class DkgRitual { + constructor( + public readonly id: number, + public readonly dkgPublicKey: DkgPublicKey, + public readonly threshold: number + ) {} + + public toObj(): DkgRitualJSON { + return { + id: this.id, + dkgPublicKey: this.dkgPublicKey.toBytes(), + threshold: this.threshold, + }; + } + + public static fromObj({ + id, + dkgPublicKey, + threshold, + }: DkgRitualJSON): DkgRitual { + return new DkgRitual(id, DkgPublicKey.fromBytes(dkgPublicKey), threshold); + } + + public equals(other: DkgRitual): boolean { + return ( + this.id === other.id && + // TODO: Replace with `equals` after https://github.com/nucypher/nucypher-core/issues/56 is fixed + bytesEquals(this.dkgPublicKey.toBytes(), other.dkgPublicKey.toBytes()) && + this.threshold === other.threshold + ); + } +} + +export class DkgClient { + constructor(private readonly provider: ethers.providers.Web3Provider) {} + + // TODO: Update API: Replace with getExistingRitual and support ritualId in Strategy + public async initializeRitual(ritualParams: { + shares: number; + threshold: number; + }): Promise { + const ritualId = 2; + const ritual = await DkgCoordinatorAgent.getRitual(this.provider, ritualId); + const dkgPkBytes = new Uint8Array([ + ...fromHexString(ritual.publicKey.word0), + ...fromHexString(ritual.publicKey.word1), + ]); + + return { + id: ritualId, + dkgPublicKey: DkgPublicKey.fromBytes(dkgPkBytes), + threshold: ritualParams.threshold, + } as DkgRitual; + } + + // TODO: Without Validator public key in Coordinator, we cannot verify the + // transcript. We need to add it to the Coordinator (nucypher-contracts #77). + // public async verifyRitual(ritualId: number): Promise { + // const ritual = await DkgCoordinatorAgent.getRitual(this.provider, ritualId); + // const participants = await DkgCoordinatorAgent.getParticipants( + // this.provider, + // ritualId + // ); + // + // const validatorMessages = participants.map((p) => { + // const validatorAddress = EthereumAddress.fromString(p.provider); + // const publicKey = FerveoPublicKey.fromBytes(fromHexString(p.???)); + // const validator = new Validator(validatorAddress, publicKey); + // const transcript = Transcript.fromBytes(fromHexString(p.transcript)); + // return new ValidatorMessage(validator, transcript); + // }); + // const aggregate = new AggregatedTranscript(validatorMessages); + // + // return aggregate.verify(ritual.dkgSize, validatorMessages); + // } +} diff --git a/src/index.ts b/src/index.ts index 5aa9d2005..b8caa482b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,28 +1,42 @@ +// Characters export { Alice } from './characters/alice'; export { Bob, RemoteBob } from './characters/bob'; export { Enrico } from './characters/enrico'; -export { tDecDecrypter } from './characters/universal-bob'; -export { +export { PreTDecDecrypter } from './characters/pre-recipient'; +export { Porter } from './characters/porter'; + +// Policies +export type { BlockchainPolicyParameters, EnactedPolicy, - PreEnactedPolicy, } from './policies/policy'; -export { Porter } from './characters/porter'; +export { PreEnactedPolicy } from './policies/policy'; + +// Keyring export { Keyring } from './keyring'; -export { Configuration, defaultConfiguration } from './config'; -export { RevocationKit } from './kits/revocation'; + +// Configuration +export type { Configuration } from './config'; +export { defaultConfiguration } from './config'; + +// Kits export { PolicyMessageKit } from './kits/message'; -export { - Conditions, - ConditionSet, - ConditionContext, - Operator, - Condition, -} from './policies/conditions'; +// Conditions +import type { CustomContextParam } from './conditions'; +import * as conditions from './conditions'; +// TODO: Not sure how to re-export this type from the conditions module +export { conditions, CustomContextParam }; + +// DKG +export { FerveoVariant } from './dkg'; + +// SDK export { Cohort } from './sdk/cohort'; -export { DeployedStrategy, RevokedStrategy, Strategy } from './sdk/strategy'; +export { DeployedPreStrategy, PreStrategy } from './sdk/strategy/pre-strategy'; +export { DeployedCbdStrategy, CbdStrategy } from './sdk/strategy/cbd-strategy'; +// Re-exports export { PublicKey, SecretKey, @@ -31,4 +45,5 @@ export { Signer, TreasureMap, MessageKit, + Ciphertext, } from '@nucypher/nucypher-core'; diff --git a/src/keyring.ts b/src/keyring.ts index 4e0f06b99..4b769b95e 100644 --- a/src/keyring.ts +++ b/src/keyring.ts @@ -55,7 +55,7 @@ export class Keyring { private getSecretKeyFromLabel(label: string): SecretKey { return SecretKeyFactory.fromSecureRandomness( - this.secretKey.toSecretBytes() + this.secretKey.toBEBytes() ).makeKey(toBytes(label)); } diff --git a/src/kits/revocation.ts b/src/kits/revocation.ts deleted file mode 100644 index 9e34a77f0..000000000 --- a/src/kits/revocation.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { RevocationOrder, Signer, TreasureMap } from '@nucypher/nucypher-core'; - -export class RevocationKit { - public revocationOrder: RevocationOrder | null; - - // ideally underlying rust should throw an error if the treasure map is not signed by the signer - constructor(treasureMap: TreasureMap, signer: Signer) { - this.revocationOrder = treasureMap.makeRevocationOrders(signer); - } -} diff --git a/src/policies/conditions.ts b/src/policies/conditions.ts deleted file mode 100644 index 80ac8258c..000000000 --- a/src/policies/conditions.ts +++ /dev/null @@ -1,467 +0,0 @@ -import { Conditions as WASMConditions } from '@nucypher/nucypher-core'; -import { ethers, utils as ethersUtils } from 'ethers'; -import Joi, { ValidationError } from 'joi'; - -import { Eip712TypedData, FormattedTypedData } from '../web3'; - -export class Operator { - static readonly LOGICAL_OPERATORS: ReadonlyArray = ['and', 'or']; - - public constructor(public readonly operator: string) { - if (!Operator.LOGICAL_OPERATORS.includes(operator)) { - throw `"${operator}" is not a valid operator`; - } - this.operator = operator; - } - - toObj() { - return { operator: this.operator }; - } - - static fromObj(obj: Record) { - return new Operator(obj.operator); - } - - public static AND() { - return new Operator('and'); - } - - public static OR() { - return new Operator('or'); - } -} - -export class ConditionSet { - constructor( - public readonly conditions: ReadonlyArray - ) {} - - public validate() { - if (this.conditions.length % 2 === 0) { - throw new Error( - 'conditions must be odd length, ever other element being an operator' - ); - } - this.conditions.forEach((cnd: Condition | Operator, index) => { - if (index % 2 && cnd.constructor.name !== 'Operator') - throw new Error( - `${index} element must be an Operator; Got ${cnd.constructor.name}.` - ); - if (!(index % 2) && cnd.constructor.name === 'Operator') - throw new Error( - `${index} element must be a Condition; Got ${cnd.constructor.name}.` - ); - }); - return true; - } - - public toList() { - return this.conditions.map((cnd) => { - return cnd.toObj(); - }); - } - - public static fromList(list: ReadonlyArray>) { - return new ConditionSet( - list.map((ele: Record) => { - if ('operator' in ele) return Operator.fromObj(ele); - return Condition.fromObj(ele); - }) - ); - } - - public toJson() { - return JSON.stringify(this.toList()); - } - - public static fromJSON(json: string) { - return ConditionSet.fromList(JSON.parse(json)); - } - - public toWASMConditions() { - return new WASMConditions(this.toJson()); - } - - public buildContext( - provider: ethers.providers.Web3Provider - ): ConditionContext { - return new ConditionContext(this.toWASMConditions(), provider); - } -} - -export class Condition { - public static readonly COMPARATOR_OPERATORS = [ - '==', - '>', - '<', - '>=', - '<=', - '!=', - ]; - - public static readonly SUPPORTED_CHAINS = [ - 1, // ethereum/mainnet - 5, // ethereum/goerli - 137, // polygon/mainnet - 80001, // polygon/mumbai - ]; - - public readonly schema = Joi.object(); - public readonly defaults = {}; - private validationError?: ValidationError; - - constructor(private readonly value: Record = {}) {} - - public get error(): string | undefined { - return this.validationError?.message; - } - - protected makeReturnValueTest() { - return Joi.object({ - comparator: Joi.string() - .valid(...Condition.COMPARATOR_OPERATORS) - .required(), - value: Joi.alternatives(Joi.string(), Joi.number()).required(), - }); - } - - public toObj(): Record { - const { error, value } = this.validate(); - if (error) { - throw Error(error.message); - } - return value; - } - - public static fromObj(obj: Record) { - return new Condition(obj); - } - - public validate(data: Record = {}) { - const newValue = Object.assign(this.defaults, this.value, data); - return this.schema.validate(newValue); - } - - public getContextParameters(): string[] { - // Check all the places where context parameters may be hiding - const asObject = this.toObj(); - let paramsToCheck: string[] = []; - - // They may be hiding in the method parameters - const method = asObject['method'] as string; - if (method) { - const contextParams = RpcCondition.CONTEXT_PARAMETERS_PER_METHOD[method]; - paramsToCheck = [...(contextParams ?? [])]; - } - - // Or in the ReturnValue test - const returnValueTest = asObject['returnValueTest'] as Record< - string, - string - >; - if (returnValueTest) { - paramsToCheck.push(returnValueTest['value']); - } - - // Merge & deduplicate found context parameters - paramsToCheck = [ - ...paramsToCheck, - ...((asObject['parameters'] as string[]) ?? []), - ]; - const withoutDuplicates = new Set( - paramsToCheck.filter((p) => paramsToCheck.includes(p)) - ); - return [...withoutDuplicates]; - } -} - -// A helper method for making complex Joi types -// It says "allow these `types` when `parent` value is given" -const makeGuard = ( - schema: Joi.StringSchema | Joi.ArraySchema, - types: Record, - parent: string -) => { - Object.entries(types).forEach(([key, value]) => { - schema = schema.when(parent, { - is: key, - then: value, - }); - }); - return schema; -}; - -class TimelockCondition extends Condition { - public static readonly CONDITION_TYPE = 'timelock'; - - defaults = { - method: 'timelock', - }; - - public readonly schema = Joi.object({ - returnValueTest: this.makeReturnValueTest(), - method: 'timelock', - }); -} - -class RpcCondition extends Condition { - public static readonly CONDITION_TYPE = 'rpc'; - public static readonly RPC_METHODS = ['eth_getBalance', 'balanceOf']; - public static readonly PARAMETERS_PER_METHOD: Record = { - eth_getBalance: ['address'], - balanceOf: ['address'], - }; - public static readonly CONTEXT_PARAMETERS_PER_METHOD: Record< - string, - string[] - > = { - eth_getBalance: [':userAddress'], - balanceOf: [':userAddress'], - }; - - public readonly schema = Joi.object({ - chain: Joi.number() - .valid(...Condition.SUPPORTED_CHAINS) - .required(), - method: Joi.string() - .valid(...RpcCondition.RPC_METHODS) - .required(), - parameters: Joi.array().required(), - returnValueTest: this.makeReturnValueTest(), - }); - - public getContextParameters = (): string[] => { - const asObject = this.toObj(); - - const method = asObject['method'] as string; - const parameters = (asObject['parameters'] ?? []) as string[]; - - const context = RpcCondition.CONTEXT_PARAMETERS_PER_METHOD[method]; - const returnValueTest = asObject['returnValueTest'] as Record< - string, - string - >; - - const maybeParams = [...(context ?? []), returnValueTest['value']]; - return parameters.filter((p) => maybeParams.includes(p)); - }; -} - -class EvmCondition extends Condition { - public static readonly CONDITION_TYPE = 'evm'; - public static readonly STANDARD_CONTRACT_TYPES = [ - 'ERC20', - 'ERC721', - // 'ERC1155', // TODO(#131) - ]; - public static readonly METHODS_PER_CONTRACT_TYPE: Record = { - ERC20: ['balanceOf'], - ERC721: ['balanceOf', 'ownerOf'], - ERC1155: ['balanceOf'], - }; - public static readonly PARAMETERS_PER_METHOD: Record = { - balanceOf: ['address'], - ownerOf: ['tokenId'], - }; - public static readonly CONTEXT_PARAMETERS_PER_METHOD: Record< - string, - string[] - > = { - balanceOf: [':userAddress'], - ownerOf: [':userAddress'], - }; - - private makeMethod = () => - makeGuard( - Joi.string(), - EvmCondition.METHODS_PER_CONTRACT_TYPE, - 'standardContractType' - ); - - public readonly schema = Joi.object({ - contractAddress: Joi.string() - .pattern(new RegExp('^0x[a-fA-F0-9]{40}$')) - .required(), - chain: Joi.string() - .valid(...Condition.SUPPORTED_CHAINS) - .required(), - standardContractType: Joi.string() - .valid(...EvmCondition.STANDARD_CONTRACT_TYPES) - .optional(), - functionAbi: Joi.object().optional(), - method: this.makeMethod().required(), - parameters: Joi.array().required(), - returnValueTest: this.makeReturnValueTest(), - }) - // At most one of these keys needs to be present - .xor('standardContractType', 'functionAbi'); -} - -class ERC721Ownership extends EvmCondition { - readonly defaults = { - method: 'ownerOf', - parameters: [], - standardContractType: 'ERC721', - returnValueTest: { - comparator: '==', - value: ':userAddress', - }, - }; -} - -class ERC721Balance extends EvmCondition { - readonly defaults = { - method: 'balanceOf', - parameters: [':userAddress'], - standardContractType: 'ERC721', - returnValueTest: { - comparator: '>', - value: '0', - }, - }; -} - -interface TypedSignature { - signature: string; - typedData: Eip712TypedData; - address: string; -} - -export class ConditionContext { - private walletSignature?: Record; - - constructor( - private readonly conditions: WASMConditions, - private readonly web3Provider: ethers.providers.Web3Provider - ) {} - - public async getOrCreateWalletSignature(): Promise { - const address = await this.web3Provider.getSigner().getAddress(); - const storageKey = `wallet-signature-${address}`; - - // If we have a signature in localStorage, return it - const isLocalStorage = typeof localStorage !== 'undefined'; - if (isLocalStorage) { - const maybeSignature = localStorage.getItem(storageKey); - if (maybeSignature) { - return JSON.parse(maybeSignature); - } - } - - // If not, try returning from memory - const maybeSignature = this.walletSignature?.[address]; - if (maybeSignature) { - if (isLocalStorage) { - localStorage.setItem(storageKey, maybeSignature); - } - return JSON.parse(maybeSignature); - } - - // If at this point we didn't return, we need to create a new signature - const typedSignature = await this.createWalletSignature(); - - // Persist where you can - if (isLocalStorage) { - localStorage.setItem(storageKey, JSON.stringify(typedSignature)); - } - if (!this.walletSignature) { - this.walletSignature = {}; - } - this.walletSignature[address] = JSON.stringify(typedSignature); - return typedSignature; - } - - private async createWalletSignature(): Promise { - // Ensure freshness of the signature - const { blockNumber, blockHash, chainId } = await this.getChainData(); - const address = await this.web3Provider.getSigner().getAddress(); - const signatureText = `I'm the owner of address ${address} as of block number ${blockNumber}`; - const salt = ethersUtils.hexlify(ethersUtils.randomBytes(32)); - - const typedData: Eip712TypedData = { - types: { - Wallet: [ - { name: 'address', type: 'address' }, - { name: 'signatureText', type: 'string' }, - { name: 'blockNumber', type: 'uint256' }, - { name: 'blockHash', type: 'bytes32' }, - ], - }, - domain: { - name: 'tDec', - version: '1', - chainId, - salt, - }, - message: { - address, - signatureText, - blockNumber, - blockHash, - }, - }; - const signature = await this.web3Provider - .getSigner() - ._signTypedData(typedData.domain, typedData.types, typedData.message); - - const formattedTypedData: FormattedTypedData = { - ...typedData, - primaryType: 'Wallet', - types: { - ...typedData.types, - EIP712Domain: [ - { - name: 'name', - type: 'string', - }, - { - name: 'version', - type: 'string', - }, - { - name: 'chainId', - type: 'uint256', - }, - { - name: 'salt', - type: 'bytes32', - }, - ], - }, - }; - return { signature, typedData: formattedTypedData, address }; - } - - private async getChainData() { - const blockNumber = await this.web3Provider.getBlockNumber(); - const blockHash = (await this.web3Provider.getBlock(blockNumber)).hash; - const chainId = (await this.web3Provider.getNetwork()).chainId; - return { blockNumber, blockHash, chainId }; - } - - public toJson = async (): Promise => { - const userAddressParam = this.conditions - .toString() - .includes(':userAddress'); - if (!userAddressParam) { - return JSON.stringify({}); - } - const typedSignature = await this.getOrCreateWalletSignature(); - const payload = { ':userAddress': typedSignature }; - return JSON.stringify(payload); - }; -} - -const OR = new Operator('or'); -const AND = new Operator('and'); - -export const Conditions = { - ERC721Ownership, - ERC721Balance, - EvmCondition, - TimelockCondition, - RpcCondition, - Condition, - OR, - AND, -}; diff --git a/src/policies/policy.ts b/src/policies/policy.ts index 54d95719e..1ccca6a90 100644 --- a/src/policies/policy.ts +++ b/src/policies/policy.ts @@ -7,11 +7,10 @@ import { VerifiedKeyFrag, } from '@nucypher/nucypher-core'; -import { SubscriptionManagerAgent } from '../agents/subscription-manager'; +import { PreSubscriptionManagerAgent } from '../agents/subscription-manager'; import { Alice } from '../characters/alice'; import { RemoteBob } from '../characters/bob'; import { Ursula } from '../characters/porter'; -// import { RevocationKit } from '../kits/revocation'; import { toBytes, toEpoch, zip } from '../utils'; import { toCanonicalAddress } from '../web3'; @@ -20,8 +19,7 @@ export type EnactedPolicy = { readonly label: string; readonly policyKey: PublicKey; readonly encryptedTreasureMap: EncryptedTreasureMap; - // readonly revocationKit: RevocationKit; - readonly aliceVerifyingKey: Uint8Array; + readonly aliceVerifyingKey: PublicKey; readonly size: number; readonly startTimestamp: Date; readonly endTimestamp: Date; @@ -45,8 +43,7 @@ export class PreEnactedPolicy implements IPreEnactedPolicy { public readonly label: string, public readonly policyKey: PublicKey, public readonly encryptedTreasureMap: EncryptedTreasureMap, - // public readonly revocationKit: RevocationKit, - public readonly aliceVerifyingKey: Uint8Array, + public readonly aliceVerifyingKey: PublicKey, public readonly size: number, public readonly startTimestamp: Date, public readonly endTimestamp: Date @@ -64,13 +61,13 @@ export class PreEnactedPolicy implements IPreEnactedPolicy { const startTimestamp = toEpoch(this.startTimestamp); const endTimestamp = toEpoch(this.endTimestamp); const ownerAddress = await publisher.web3Provider.getSigner().getAddress(); - const value = await SubscriptionManagerAgent.getPolicyCost( + const value = await PreSubscriptionManagerAgent.getPolicyCost( publisher.web3Provider, this.size, startTimestamp, endTimestamp ); - const tx = await SubscriptionManagerAgent.createPolicy( + const tx = await PreSubscriptionManagerAgent.createPolicy( publisher.web3Provider, value, this.id.toBytes(), @@ -130,8 +127,7 @@ export class BlockchainPolicy { this.label, this.delegatingKey, encryptedTreasureMap, - // revocationKit, - this.publisher.verifyingKey.toBytes(), + this.publisher.verifyingKey, this.shares, this.startDate, this.endDate diff --git a/src/sdk/cohort.ts b/src/sdk/cohort.ts index 02bc45bd4..8571f3816 100644 --- a/src/sdk/cohort.ts +++ b/src/sdk/cohort.ts @@ -1,5 +1,6 @@ import { Porter } from '../characters/porter'; import { ChecksumAddress } from '../types'; +import { objectEquals } from '../utils'; export type CohortConfiguration = { readonly threshold: number; @@ -70,4 +71,8 @@ export class Cohort { porterUri: this.configuration.porterUri, }; } + + public equals(other: Cohort): boolean { + return objectEquals(this.toObj(), other.toObj()); + } } diff --git a/src/sdk/strategy.ts b/src/sdk/strategy.ts deleted file mode 100644 index 15190f8b8..000000000 --- a/src/sdk/strategy.ts +++ /dev/null @@ -1,248 +0,0 @@ -import { - EncryptedTreasureMap, - HRAC, - PublicKey, - SecretKey, -} from '@nucypher/nucypher-core'; -import { ethers } from 'ethers'; - -import { Alice } from '../characters/alice'; -import { Bob } from '../characters/bob'; -import { Enrico } from '../characters/enrico'; -import { tDecDecrypter } from '../characters/universal-bob'; -import { ConditionSet } from '../policies/conditions'; -import { EnactedPolicy, EnactedPolicyJSON } from '../policies/policy'; -import { base64ToU8Receiver, u8ToBase64Replacer } from '../utils'; - -import { Cohort, CohortJSON } from './cohort'; - -type StrategyJSON = { - cohort: CohortJSON; - aliceSecretKeyBytes: Uint8Array; - bobSecretKeyBytes: Uint8Array; - conditionSet?: ConditionSet; - startDate: Date; - endDate: Date; -}; - -type DeployedStrategyJSON = { - policy: EnactedPolicyJSON; - cohortConfig: CohortJSON; - bobSecretKeyBytes: Uint8Array; - conditionSet?: ConditionSet; -}; - -export class Strategy { - private constructor( - public readonly cohort: Cohort, - private readonly aliceSecretKey: SecretKey, - private readonly bobSecretKey: SecretKey, - private readonly startDate: Date, - private readonly endDate: Date, - private readonly conditionSet?: ConditionSet - ) {} - - public static create( - cohort: Cohort, - conditionSet?: ConditionSet, - aliceSecretKey?: SecretKey, - bobSecretKey?: SecretKey, - startDate?: Date, - endDate?: Date - ) { - if (!aliceSecretKey) { - aliceSecretKey = SecretKey.random(); - } - if (!bobSecretKey) { - bobSecretKey = SecretKey.random(); - } - if (!startDate) { - startDate = new Date(Date.now()); - } - if (!endDate) { - endDate = new Date(Date.now() + 1000 * 60 * 60 * 24 * 30); - } - return new Strategy( - cohort, - aliceSecretKey, - bobSecretKey, - startDate, - endDate, - conditionSet - ); - } - - public async deploy( - label: string, - provider: ethers.providers.Web3Provider - ): Promise { - const porterUri = this.cohort.configuration.porterUri; - const configuration = { porterUri }; - const alice = Alice.fromSecretKey( - configuration, - this.aliceSecretKey, - provider - ); - const bob = new Bob(configuration, this.bobSecretKey); - const policyParams = { - bob, - label, - threshold: this.cohort.configuration.threshold, - shares: this.cohort.configuration.shares, - startDate: this.startDate, - endDate: this.endDate, - }; - const policy = await alice.grant(policyParams, this.cohort.ursulaAddresses); - const encrypter = new Enrico( - policy.policyKey, - undefined, - this.conditionSet - ); - - const decrypter = new tDecDecrypter( - this.cohort.configuration.porterUri, - policy.policyKey, - policy.encryptedTreasureMap, - alice.verifyingKey, - this.bobSecretKey - ); - return new DeployedStrategy( - label, - this.cohort, - policy, - encrypter, - decrypter, - this.bobSecretKey, - this.conditionSet - ); - } - - public static fromJSON(json: string) { - const config = JSON.parse(json, base64ToU8Receiver); - return Strategy.fromObj(config); - } - - public toJSON() { - return JSON.stringify(this.toObj(), u8ToBase64Replacer); - } - - private static fromObj({ - cohort, - aliceSecretKeyBytes, - bobSecretKeyBytes, - conditionSet, - startDate, - endDate, - }: StrategyJSON) { - return new Strategy( - Cohort.fromObj(cohort), - SecretKey.fromBytes(aliceSecretKeyBytes), - SecretKey.fromBytes(bobSecretKeyBytes), - startDate, - endDate, - conditionSet - ); - } - - public toObj(): StrategyJSON { - return { - cohort: this.cohort.toObj(), - aliceSecretKeyBytes: this.aliceSecretKey.toSecretBytes(), - bobSecretKeyBytes: this.bobSecretKey.toSecretBytes(), - conditionSet: this.conditionSet, - startDate: this.startDate, - endDate: this.endDate, - }; - } -} - -export class DeployedStrategy { - constructor( - public label: string, - public cohort: Cohort, - public policy: EnactedPolicy, - public encrypter: Enrico, - public decrypter: tDecDecrypter, - private bobSecretKey: SecretKey, - public conditionSet?: ConditionSet - ) {} - - public static fromJSON(json: string) { - const config = JSON.parse(json, base64ToU8Receiver); - return DeployedStrategy.fromObj(config); - } - - public toJSON() { - return JSON.stringify(this.toObj(), u8ToBase64Replacer); - } - - private static fromObj({ - policy, - cohortConfig, - bobSecretKeyBytes, - conditionSet, - }: DeployedStrategyJSON) { - const id = HRAC.fromBytes(policy.id); - const policyKey = PublicKey.fromBytes(policy.policyKey); - const encryptedTreasureMap = EncryptedTreasureMap.fromBytes( - policy.encryptedTreasureMap - ); - const aliceVerifyingKey = PublicKey.fromBytes(policy.aliceVerifyingKey); - const newPolicy = { - id, - label: policy.label, - policyKey, - encryptedTreasureMap, - aliceVerifyingKey: aliceVerifyingKey.toBytes(), - size: policy.size, - startTimestamp: policy.startTimestamp, - endTimestamp: policy.endTimestamp, - txHash: policy.txHash, - }; - const bobSecretKey = SecretKey.fromBytes(bobSecretKeyBytes); - const label = newPolicy.label; - const cohort = Cohort.fromObj(cohortConfig); - const encrypter = new Enrico(newPolicy.policyKey, undefined, conditionSet); - - const decrypter = new tDecDecrypter( - cohort.configuration.porterUri, - policyKey, - encryptedTreasureMap, - aliceVerifyingKey, - bobSecretKey - ); - return new DeployedStrategy( - label, - cohort, - newPolicy, - encrypter, - decrypter, - bobSecretKey, - conditionSet - ); - } - - private toObj(): DeployedStrategyJSON { - const policy = { - ...this.policy, - id: this.policy.id.toBytes(), - policyKey: this.policy.policyKey.toBytes(), - encryptedTreasureMap: this.policy.encryptedTreasureMap.toBytes(), - }; - return { - policy, - cohortConfig: this.cohort.toObj(), - bobSecretKeyBytes: this.bobSecretKey.toSecretBytes(), - conditionSet: this.conditionSet, - }; - } -} - -export class RevokedStrategy { - constructor( - public label: string, - public policy: EnactedPolicy, - public encrypter: Enrico, - public decrypter: tDecDecrypter - ) {} -} diff --git a/src/sdk/strategy/cbd-strategy.ts b/src/sdk/strategy/cbd-strategy.ts new file mode 100644 index 000000000..0632eeaef --- /dev/null +++ b/src/sdk/strategy/cbd-strategy.ts @@ -0,0 +1,114 @@ +import { DkgPublicKey } from '@nucypher/nucypher-core'; +import { ethers } from 'ethers'; + +import { bytesEqual } from '../../../test/utils'; +import { + CbdTDecDecrypter, + CbdTDecDecrypterJSON, +} from '../../characters/cbd-recipient'; +import { Enrico } from '../../characters/enrico'; +import { ConditionExpression, ConditionExpressionJSON } from '../../conditions'; +import { DkgClient, DkgRitual } from '../../dkg'; +import { fromJSON, toJSON } from '../../utils'; +import { Cohort, CohortJSON } from '../cohort'; + +export type CbdStrategyJSON = { + cohort: CohortJSON; + conditionExpr?: ConditionExpressionJSON | undefined; +}; + +export type DeployedStrategyJSON = { + decrypter: CbdTDecDecrypterJSON; + dkgPublicKey: Uint8Array; +}; + +export class CbdStrategy { + private constructor(public readonly cohort: Cohort) {} + + public static create(cohort: Cohort) { + return new CbdStrategy(cohort); + } + + public async deploy( + provider: ethers.providers.Web3Provider + ): Promise { + const dkgRitualParams = { + threshold: this.cohort.configuration.threshold, + shares: this.cohort.configuration.shares, + }; + const dkgClient = new DkgClient(provider); + const dkgRitual = await dkgClient.initializeRitual(dkgRitualParams); + return DeployedCbdStrategy.create(this.cohort, dkgRitual); + } + + public static fromJSON(json: string) { + return CbdStrategy.fromObj(fromJSON(json)); + } + + public toJSON() { + return toJSON(this.toObj()); + } + + public static fromObj({ cohort }: CbdStrategyJSON) { + return new CbdStrategy(Cohort.fromObj(cohort)); + } + + public toObj(): CbdStrategyJSON { + return { + cohort: this.cohort.toObj(), + }; + } + + public equals(other: CbdStrategy) { + return this.cohort.equals(other.cohort); + } +} + +export class DeployedCbdStrategy { + private constructor( + public readonly decrypter: CbdTDecDecrypter, + public readonly dkgPublicKey: DkgPublicKey + ) {} + + public static create(cohort: Cohort, dkgRitual: DkgRitual) { + const decrypter = CbdTDecDecrypter.create( + cohort.configuration.porterUri, + dkgRitual + ); + return new DeployedCbdStrategy(decrypter, dkgRitual.dkgPublicKey); + } + + public makeEncrypter(conditionExpr: ConditionExpression): Enrico { + return new Enrico(this.dkgPublicKey, undefined, conditionExpr); + } + + public static fromJSON(json: string) { + const config = fromJSON(json); + return DeployedCbdStrategy.fromObj(config); + } + + public toJSON() { + return toJSON(this.toObj()); + } + + private static fromObj({ decrypter, dkgPublicKey }: DeployedStrategyJSON) { + return new DeployedCbdStrategy( + CbdTDecDecrypter.fromObj(decrypter), + DkgPublicKey.fromBytes(dkgPublicKey) + ); + } + + public toObj(): DeployedStrategyJSON { + return { + decrypter: this.decrypter.toObj(), + dkgPublicKey: this.dkgPublicKey.toBytes(), + }; + } + + public equals(other: DeployedCbdStrategy) { + return ( + this.decrypter.equals(other.decrypter) && + bytesEqual(this.dkgPublicKey.toBytes(), other.dkgPublicKey.toBytes()) + ); + } +} diff --git a/src/sdk/strategy/pre-strategy.ts b/src/sdk/strategy/pre-strategy.ts new file mode 100644 index 000000000..acc6d997f --- /dev/null +++ b/src/sdk/strategy/pre-strategy.ts @@ -0,0 +1,207 @@ +import { PublicKey, SecretKey } from '@nucypher/nucypher-core'; +import { ethers } from 'ethers'; + +import { Alice } from '../../characters/alice'; +import { Bob } from '../../characters/bob'; +import { Enrico } from '../../characters/enrico'; +import { + PreTDecDecrypter, + PreTDecDecrypterJSON, +} from '../../characters/pre-recipient'; +import { ConditionExpression } from '../../conditions'; +import { EnactedPolicy } from '../../policies/policy'; +import { base64ToU8Receiver, bytesEquals, toJSON } from '../../utils'; +import { Cohort, CohortJSON } from '../cohort'; + +export type PreStrategyJSON = { + cohort: CohortJSON; + aliceSecretKeyBytes: Uint8Array; + bobSecretKeyBytes: Uint8Array; + startDate: Date; + endDate: Date; +}; + +export type DeployedPreStrategyJSON = { + cohortConfig: CohortJSON; + decrypterJSON: PreTDecDecrypterJSON; + policyKeyBytes: Uint8Array; +}; + +export class PreStrategy { + private constructor( + public readonly cohort: Cohort, + private readonly aliceSecretKey: SecretKey, + private readonly bobSecretKey: SecretKey, + private readonly startDate: Date, + private readonly endDate: Date + ) {} + + public static create( + cohort: Cohort, + aliceSecretKey?: SecretKey, + bobSecretKey?: SecretKey, + startDate?: Date, + endDate?: Date + ) { + if (!aliceSecretKey) { + aliceSecretKey = SecretKey.random(); + } + if (!bobSecretKey) { + bobSecretKey = SecretKey.random(); + } + if (!startDate) { + startDate = new Date(Date.now()); + } + if (!endDate) { + endDate = new Date(Date.now() + 1000 * 60 * 60 * 24 * 30); + } + return new PreStrategy( + cohort, + aliceSecretKey, + bobSecretKey, + startDate, + endDate + ); + } + + public async deploy( + label: string, + provider: ethers.providers.Web3Provider + ): Promise { + const porterUri = this.cohort.configuration.porterUri; + const configuration = { porterUri }; + const alice = Alice.fromSecretKey( + configuration, + this.aliceSecretKey, + provider + ); + const bob = new Bob(configuration, this.bobSecretKey); + const policyParams = { + bob, + label, + threshold: this.cohort.configuration.threshold, + shares: this.cohort.configuration.shares, + startDate: this.startDate, + endDate: this.endDate, + }; + const policy = await alice.grant(policyParams, this.cohort.ursulaAddresses); + return DeployedPreStrategy.create(this.cohort, policy, this.bobSecretKey); + } + + public static fromJSON(json: string) { + const config = JSON.parse(json, base64ToU8Receiver); + config.startDate = new Date(config.startDate); + config.endDate = new Date(config.endDate); + return PreStrategy.fromObj(config); + } + + public toJSON() { + return toJSON(this.toObj()); + } + + public static fromObj({ + cohort, + aliceSecretKeyBytes, + bobSecretKeyBytes, + startDate, + endDate, + }: PreStrategyJSON) { + return new PreStrategy( + Cohort.fromObj(cohort), + SecretKey.fromBEBytes(aliceSecretKeyBytes), + SecretKey.fromBEBytes(bobSecretKeyBytes), + new Date(startDate), + new Date(endDate) + ); + } + + public toObj(): PreStrategyJSON { + return { + cohort: this.cohort.toObj(), + aliceSecretKeyBytes: this.aliceSecretKey.toBEBytes(), + bobSecretKeyBytes: this.bobSecretKey.toBEBytes(), + startDate: this.startDate, + endDate: this.endDate, + }; + } + + public equals(other: PreStrategy) { + return ( + this.cohort.equals(other.cohort) && + // TODO: Replace with `equals` after https://github.com/nucypher/nucypher-core/issues/56 is fixed + bytesEquals( + this.aliceSecretKey.toBEBytes(), + other.aliceSecretKey.toBEBytes() + ) && + bytesEquals( + this.bobSecretKey.toBEBytes(), + other.bobSecretKey.toBEBytes() + ) && + this.startDate.toString() === other.startDate.toString() && + this.endDate.toString() === other.endDate.toString() + ); + } +} + +export class DeployedPreStrategy { + private constructor( + public readonly cohort: Cohort, + public readonly decrypter: PreTDecDecrypter, + public readonly policyKey: PublicKey + ) {} + + public static create( + cohort: Cohort, + policy: EnactedPolicy, + bobSecretKey: SecretKey + ) { + const decrypter = PreTDecDecrypter.create( + cohort.configuration.porterUri, + bobSecretKey, + policy.policyKey, + policy.aliceVerifyingKey, + policy.encryptedTreasureMap + ); + return new DeployedPreStrategy(cohort, decrypter, policy.policyKey); + } + + public makeEncrypter(conditionExpr: ConditionExpression): Enrico { + return new Enrico(this.policyKey, undefined, conditionExpr); + } + + public static fromJSON(json: string) { + const config = JSON.parse(json, base64ToU8Receiver); + return DeployedPreStrategy.fromObj(config); + } + + public toJSON() { + return toJSON(this.toObj()); + } + + public static fromObj({ + cohortConfig, + decrypterJSON, + policyKeyBytes, + }: DeployedPreStrategyJSON) { + const cohort = Cohort.fromObj(cohortConfig); + const decrypter = PreTDecDecrypter.fromObj(decrypterJSON); + const policyKey = PublicKey.fromCompressedBytes(policyKeyBytes); + return new DeployedPreStrategy(cohort, decrypter, policyKey); + } + + public toObj(): DeployedPreStrategyJSON { + return { + cohortConfig: this.cohort.toObj(), + decrypterJSON: this.decrypter.toObj(), + policyKeyBytes: this.policyKey.toCompressedBytes(), + }; + } + + public equals(other: DeployedPreStrategy) { + return ( + this.cohort.equals(other.cohort) && + this.decrypter.equals(other.decrypter) && + this.policyKey.equals(other.policyKey) + ); + } +} diff --git a/src/types.ts b/src/types.ts index 876ff745b..2440dcc53 100644 --- a/src/types.ts +++ b/src/types.ts @@ -5,4 +5,6 @@ export type Base64EncodedBytes = string; export enum ChainId { POLYGON = 137, MUMBAI = 80001, + GOERLI = 5, + MAINNET = 1, } diff --git a/src/utils.ts b/src/utils.ts index c000feba2..3fc45a09a 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,7 +1,13 @@ +import deepEqual from 'deep-equal'; + +// TODO: Replace byte and hex manipulation with ethers.js export const toBytes = (str: string): Uint8Array => new TextEncoder().encode(str); export const fromHexString = (hexString: string): Uint8Array => { + if (hexString.startsWith('0x')) { + hexString = hexString.slice(2); + } const matches = hexString.match(/.{1,2}/g) ?? []; return new Uint8Array(matches.map((byte) => parseInt(byte, 16))); }; @@ -15,29 +21,59 @@ export const toBase64 = (bytes: Uint8Array): string => export const fromBase64 = (str: string): Uint8Array => Buffer.from(str, 'base64'); -export const base64ToU8Receiver = ( - _key: string, - value: string | number | Uint8Array -) => { +export const base64ToU8Receiver = (_key: string, value: unknown) => { if (typeof value === 'string' && value.startsWith('base64:')) { return fromBase64(value.split('base64:')[1]); } return value; }; -export const u8ToBase64Replacer = ( - _key: string, - value: string | number | Uint8Array -) => { +const sortedReplacer = (_key: string, value: unknown) => { + if (value instanceof Object && !(value instanceof Array)) { + return Object.keys(value) + .sort() + .reduce((sorted: Record, key) => { + sorted[key] = (value as Record)[key]; + return sorted; + }, {}); + } + + return value; +}; + +const u8ToBase64Replacer = (_key: string, value: unknown) => { if (value instanceof Uint8Array) { return `base64:${toBase64(value)}`; } return value; }; +const sortedSerializingReplacer = (_key: string, value: unknown): unknown => { + const serializedValue = u8ToBase64Replacer(_key, value); + return sortedReplacer(_key, serializedValue); +}; + +export const toJSON = (obj: unknown) => + JSON.stringify(obj, sortedSerializingReplacer); + +export const fromJSON = (json: string) => JSON.parse(json, base64ToU8Receiver); + export const zip = ( a: ReadonlyArray, b: ReadonlyArray ): ReadonlyArray => a.map((k, i) => [k, b[i]]); export const toEpoch = (date: Date) => (date.getTime() / 1000) | 0; + +export const bytesEquals = (first: Uint8Array, second: Uint8Array): boolean => + first.length === second.length && + first.every((value, index) => value === second[index]); + +export const objectEquals = (a: unknown, b: unknown, strict = true): boolean => + deepEqual(a, b, { strict }); + +export const omit = (obj: Record, keys: string[]) => { + const copy = { ...obj }; + keys.forEach((key) => delete copy[key]); + return copy; +}; diff --git a/test/acceptance/alice-grants.test.ts b/test/acceptance/alice-grants.test.ts index 3e1f661aa..a5fce2365 100644 --- a/test/acceptance/alice-grants.test.ts +++ b/test/acceptance/alice-grants.test.ts @@ -11,17 +11,17 @@ import { ChecksumAddress } from '../../src/types'; import { toBytes } from '../../src/utils'; import { bytesEqual, + fakeAlice, + fakeBob, + fakeRemoteBob, + fakeUrsulas, fromBytes, - mockAlice, - mockBob, mockEncryptTreasureMap, mockGenerateKFrags, mockGetUrsulas, mockMakeTreasureMap, mockPublishToBlockchain, - mockRemoteBob, mockRetrieveCFragsRequest, - mockUrsulas, reencryptKFrags, } from '../utils'; @@ -31,7 +31,7 @@ describe('story: alice shares message with bob through policy', () => { const shares = 3; const startDate = new Date(); const endDate = new Date(Date.now() + 60 * 1000); - const mockedUrsulas = mockUrsulas().slice(0, shares); + const mockedUrsulas = fakeUrsulas().slice(0, shares); // Intermediate variables used for mocking let encryptedTreasureMap: EncryptedTreasureMap; @@ -52,8 +52,8 @@ describe('story: alice shares message with bob through policy', () => { const makeTreasureMapSpy = mockMakeTreasureMap(); const encryptTreasureMapSpy = mockEncryptTreasureMap(); - const alice = mockAlice(); - const bob = mockRemoteBob(); + const alice = fakeAlice(); + const bob = fakeRemoteBob(); const policyParams = { bob, label, @@ -64,7 +64,12 @@ describe('story: alice shares message with bob through policy', () => { }; policy = await alice.grant(policyParams); - expect(policy.aliceVerifyingKey).toEqual(alice.verifyingKey.toBytes()); + expect( + bytesEqual( + policy.aliceVerifyingKey.toCompressedBytes(), + alice.verifyingKey.toCompressedBytes() + ) + ).toBeTruthy(); expect(policy.label).toBe(label); expect(getUrsulasSpy).toHaveBeenCalled(); expect(generateKFragsSpy).toHaveBeenCalled(); @@ -86,11 +91,11 @@ describe('story: alice shares message with bob through policy', () => { it('enrico encrypts the message', () => { const enrico = new Enrico(policyEncryptingKey); - encryptedMessage = enrico.encryptMessage(toBytes(message)); + encryptedMessage = enrico.encryptMessagePre(toBytes(message)); }); it('bob retrieves and decrypts the message', async () => { - const bob = mockBob(); + const bob = fakeBob(); const getUrsulasSpy = mockGetUrsulas(mockedUrsulas); const retrieveCFragsSpy = mockRetrieveCFragsRequest( ursulaAddresses, @@ -121,12 +126,23 @@ describe('story: alice shares message with bob through policy', () => { bobVerifyingKey_, ] = retrieveCFragsSpy.mock.calls[0]; expect( - bytesEqual(aliceVerifyingKey_.toBytes(), aliceVerifyingKey.toBytes()) + bytesEqual( + aliceVerifyingKey_.toCompressedBytes(), + aliceVerifyingKey.toCompressedBytes() + ) ); expect( - bytesEqual(bobEncryptingKey_.toBytes(), bob.decryptingKey.toBytes()) + bytesEqual( + bobEncryptingKey_.toCompressedBytes(), + bob.decryptingKey.toCompressedBytes() + ) + ); + expect( + bytesEqual( + bobVerifyingKey_.toCompressedBytes(), + bob.verifyingKey.toCompressedBytes() + ) ); - expect(bytesEqual(bobVerifyingKey_.toBytes(), bob.verifyingKey.toBytes())); const { verifiedCFrags } = reencryptKFrags( verifiedKFrags, diff --git a/test/acceptance/delay-enact.test.ts b/test/acceptance/delay-enact.test.ts index 6ca4cc623..61574df95 100644 --- a/test/acceptance/delay-enact.test.ts +++ b/test/acceptance/delay-enact.test.ts @@ -1,11 +1,12 @@ import { - mockAlice, + bytesEqual, + fakeAlice, + fakeRemoteBob, + fakeUrsulas, mockEncryptTreasureMap, mockGenerateKFrags, mockGetUrsulas, mockPublishToBlockchain, - mockRemoteBob, - mockUrsulas, } from '../utils'; describe('story: alice1 creates a policy but alice2 enacts it', () => { @@ -13,7 +14,7 @@ describe('story: alice1 creates a policy but alice2 enacts it', () => { const shares = 3; const startDate = new Date(); const endDate = new Date(Date.now() + 60 * 1000); // 60s later - const mockedUrsulas = mockUrsulas().slice(0, shares); + const mockedUrsulas = fakeUrsulas().slice(0, shares); const label = 'fake-data-label'; it('alice generates a new policy', async () => { @@ -22,9 +23,9 @@ describe('story: alice1 creates a policy but alice2 enacts it', () => { const publishToBlockchainSpy = mockPublishToBlockchain(); const encryptTreasureMapSpy = mockEncryptTreasureMap(); - const alice1 = mockAlice('fake-secret-key-32-bytes-alice-1'); - const alice2 = mockAlice('fake-secret-key-32-bytes-alice-2'); - const bob = mockRemoteBob(); + const alice1 = fakeAlice('fake-secret-key-32-bytes-alice-1'); + const alice2 = fakeAlice('fake-secret-key-32-bytes-alice-2'); + const bob = fakeRemoteBob(); const policyParams = { bob, label, @@ -37,9 +38,12 @@ describe('story: alice1 creates a policy but alice2 enacts it', () => { const preEnactedPolicy = await alice1.generatePreEnactedPolicy( policyParams ); - expect(preEnactedPolicy.aliceVerifyingKey).toEqual( - alice1.verifyingKey.toBytes() - ); + expect( + bytesEqual( + preEnactedPolicy.aliceVerifyingKey.toCompressedBytes(), + alice1.verifyingKey.toCompressedBytes() + ) + ).toBeTruthy(); expect(preEnactedPolicy.label).toBe(label); const enacted = await preEnactedPolicy.enact(alice2); diff --git a/test/docs/cbd.test.ts b/test/docs/cbd.test.ts index 650ad1f2f..cac579632 100644 --- a/test/docs/cbd.test.ts +++ b/test/docs/cbd.test.ts @@ -1,16 +1,12 @@ import { MessageKit, VerifiedKeyFrag } from '@nucypher/nucypher-core'; import { providers } from 'ethers'; -import { - Cohort, - Conditions, - ConditionSet, - SecretKey, - Strategy, -} from '../../src'; +import { Cohort, conditions, PreStrategy, SecretKey } from '../../src'; import { Ursula } from '../../src/characters/porter'; import { toBytes } from '../../src/utils'; import { + fakeUrsulas, + fakeWeb3Provider, mockDetectEthereumProvider, mockEncryptTreasureMap, mockGenerateKFrags, @@ -18,10 +14,14 @@ import { mockMakeTreasureMap, mockPublishToBlockchain, mockRetrieveCFragsRequest, - mockUrsulas, - mockWeb3Provider, } from '../utils'; +const { + predefined: { ERC721Ownership }, + base: { ContractCondition }, + ConditionExpression, +} = conditions; + describe('Get Started (CBD PoC)', () => { function mockRetrieveAndDecrypt( makeTreasureMapSpy: jest.SpyInstance, @@ -42,7 +42,7 @@ describe('Get Started (CBD PoC)', () => { it('can run the get started example', async () => { const detectEthereumProvider = mockDetectEthereumProvider(); - const mockedUrsulas = mockUrsulas(); + const mockedUrsulas = fakeUrsulas(); const getUrsulasSpy = mockGetUrsulas(mockedUrsulas); const generateKFragsSpy = mockGenerateKFrags(); const publishToBlockchainSpy = mockPublishToBlockchain(); @@ -52,7 +52,7 @@ describe('Get Started (CBD PoC)', () => { jest .spyOn(providers, 'Web3Provider') .mockImplementation(() => - mockWeb3Provider(SecretKey.random().toSecretBytes()) + fakeWeb3Provider(SecretKey.random().toBEBytes()) ); // @@ -67,20 +67,20 @@ describe('Get Started (CBD PoC)', () => { }; const newCohort = await Cohort.create(config); - // 3. Specify default Conditions - const NFTOwnership = new Conditions.ERC721Ownership({ + // 3. Specify default conditions + const NFTOwnership = new ERC721Ownership({ contractAddress: '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D', chain: 5, // Tapir network uses Görli testnet parameters: [5954], }); - const conditions = new ConditionSet([ - NFTOwnership, + const conditions = new ConditionExpression( + NFTOwnership // Other conditions can be added here - ]); + ); // 4. Build a Strategy - const newStrategy = Strategy.create(newCohort, conditions); + const newStrategy = PreStrategy.create(newCohort); const MMprovider = await detectEthereumProvider(); const mumbai = providers.getNetwork(80001); @@ -88,7 +88,7 @@ describe('Get Started (CBD PoC)', () => { const web3Provider = new providers.Web3Provider(MMprovider, mumbai); const newDeployed = await newStrategy.deploy('test', web3Provider); - // 5. Encrypt the plaintext & update Conditions + // 5. Encrypt the plaintext & update conditions const NFTBalanceConfig = { contractAddress: '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D', standardContractType: 'ERC721', @@ -100,15 +100,11 @@ describe('Get Started (CBD PoC)', () => { value: 3, }, }; - const NFTBalance = new Conditions.Condition(NFTBalanceConfig); - - const encrypter = newDeployed.encrypter; - + const NFTBalance = new ContractCondition(NFTBalanceConfig); + const newConditions = new ConditionExpression(NFTBalance); const plaintext = 'this is a secret'; - const encryptedMessageKit = encrypter.encryptMessage( - plaintext, - new ConditionSet([NFTBalance]) - ); + const encrypter = newDeployed.makeEncrypter(newConditions); + const encryptedMessageKit = encrypter.encryptMessagePre(plaintext); // Mocking - Not a part of any code example const retrieveCFragsSpy = mockRetrieveAndDecrypt( @@ -126,17 +122,15 @@ describe('Get Started (CBD PoC)', () => { // End of the code example // - const expectedAddresses = mockUrsulas().map((u) => u.checksumAddress); - const condObj = conditions.conditions[0].toObj(); + const expectedAddresses = fakeUrsulas().map((u) => u.checksumAddress); + const condObj = conditions.condition.toObj(); expect(newCohort.ursulaAddresses).toEqual(expectedAddresses); expect(condObj.parameters).toEqual([5954]); expect(condObj.chain).toEqual(5); expect(condObj.contractAddress).toEqual( '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D' ); - expect(conditions.validate()).toEqual(true); expect(publishToBlockchainSpy).toHaveBeenCalled(); - expect(newDeployed.label).toEqual('test'); expect(getUrsulasSpy).toHaveBeenCalledTimes(2); expect(generateKFragsSpy).toHaveBeenCalled(); expect(encryptTreasureMapSpy).toHaveBeenCalled(); diff --git a/test/integration/conditions.test.ts b/test/integration/conditions.test.ts deleted file mode 100644 index 5fe41aa84..000000000 --- a/test/integration/conditions.test.ts +++ /dev/null @@ -1,310 +0,0 @@ -import { SecretKey } from '@nucypher/nucypher-core'; - -import { - ConditionContext, - Conditions, - ConditionSet, - Operator, -} from '../../src'; -import { mockWeb3Provider } from '../utils'; - -describe('operator', () => { - it('should validate Operator', async () => { - const op = new Operator('or'); - expect(op.operator).toEqual('or'); - expect(() => { - new Operator('then'); - }).toThrow(); - }); -}); - -describe('conditions schema', () => { - const condition = new Conditions.ERC721Balance(); - let result = condition.validate({ - contractAddress: '0xC36442b4a4522E871399CD717aBDD847Ab11FE88', - }); - - it('should validate', async () => { - expect(result.error).toEqual(undefined); - expect(result.value.contractAddress).toEqual( - '0xC36442b4a4522E871399CD717aBDD847Ab11FE88' - ); - }); - - result = condition.validate({ chain: 5 }); - it('should update the value of "chain"', async () => { - expect(result.error).toEqual(undefined); - expect(result.value.chain).toEqual(5); - }); - - it('should validate chain id', async () => { - result = condition.validate({ chain: 10 }); - expect(result.error?.message).toEqual( - '"chain" must be one of [1, 5, 137, 80001]' - ); - }); -}); - -describe('condition set', () => { - const genuineUndead = new Conditions.ERC721Balance({ - contractAddress: '0x209e639a0EC166Ac7a1A4bA41968fa967dB30221', - }); - const gnomePals = new Conditions.ERC721Balance({ - contractAddress: '0x5dB11d7356aa4C0E85Aa5b255eC2B5F81De6d4dA', - }); - const conditions = new ConditionSet([ - genuineUndead, - Conditions.OR, - gnomePals, - ]); - - it('should validate', async () => { - expect(conditions.validate()).toEqual(true); - }); -}); - -describe('conditions set to/from json', () => { - const json = - '[{"chain":5,"method":"ownerOf","parameters":["3591"],"standardContractType":"ERC721","returnValueTest":{"comparator":"==","value":":userAddress"},"contractAddress":"0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77"}]'; - const conditionSet = ConditionSet.fromJSON(json); - - it('should be a ConditionSet', async () => { - expect(conditionSet.conditions[0].toObj().contractAddress).toEqual( - '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77' - ); - expect(conditionSet.toJson()).toEqual(json); - }); -}); - -describe('standard conditions types validation', () => { - const returnValueTest = { - comparator: '>', - value: '100', - }; - - describe('works for valid conditions', () => { - it('timelock', () => { - const timelock = new Conditions.TimelockCondition({ - returnValueTest, - }); - expect(timelock.toObj()).toEqual({ - returnValueTest, - method: 'timelock', - }); - }); - - it('rpc', () => { - const rpcCondition = { - chain: 5, - method: 'eth_getBalance', - parameters: ['0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77'], - returnValueTest, - }; - const rpc = new Conditions.RpcCondition(rpcCondition); - expect(rpc.toObj()).toEqual(rpcCondition); - }); - - it('evm', () => { - const evmCondition = { - contractAddress: '0x0000000000000000000000000000000000000000', - chain: 5, - standardContractType: 'ERC20', - method: 'balanceOf', - parameters: ['0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77'], - returnValueTest, - }; - const evm = new Conditions.EvmCondition(evmCondition); - expect(evm.toObj()).toEqual(evmCondition); - }); - }); - - describe('fails for invalid conditions', () => { - it('invalid timelock', () => { - const badTimelockCondition = { - // Intentionally replacing `returnValueTest` with an invalid test - returnValueTest: { - comparator: 'not-a-comparator', - value: '100', - }, - }; - const badTimelock = new Conditions.TimelockCondition( - badTimelockCondition - ); - expect(() => badTimelock.toObj()).toThrow( - '"returnValueTest.comparator" must be one of [==, >, <, >=, <=, !=]' - ); - const { error } = badTimelock.validate(badTimelockCondition); - expect(error?.message).toEqual( - '"returnValueTest.comparator" must be one of [==, >, <, >=, <=, !=]' - ); - }); - - it('invalid rpc', () => { - const badRpcCondition = { - chain: 5, - // Intentionally replacing `method` with an invalid method - method: 'fake_invalid_method', - parameters: ['0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77'], - returnValueTest, - }; - const badRpc = new Conditions.RpcCondition(badRpcCondition); - expect(() => badRpc.toObj()).toThrow( - '"method" must be one of [eth_getBalance, balanceOf]' - ); - const { error } = badRpc.validate(badRpcCondition); - expect(error?.message).toEqual( - '"method" must be one of [eth_getBalance, balanceOf]' - ); - }); - - it('invalid evm', () => { - const badEvmCondition = { - // Intentionally removing `contractAddress` - // contractAddress: '0x0000000000000000000000000000000000000000', - chain: 5, - standardContractType: 'ERC20', - method: 'balanceOf', - parameters: ['0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77'], - returnValueTest, - }; - const badEvm = new Conditions.EvmCondition(badEvmCondition); - expect(() => badEvm.toObj()).toThrow('"contractAddress" is required'); - const { error } = badEvm.validate(badEvmCondition); - expect(error?.message).toEqual('"contractAddress" is required'); - }); - }); -}); - -describe('produce context parameters from conditions', () => { - describe('from rpc condition', () => { - const methods = Conditions.RpcCondition.RPC_METHODS; - methods.forEach((method) => { - const contextParams = - Conditions.RpcCondition.CONTEXT_PARAMETERS_PER_METHOD[method]; - if (!contextParams) { - return; - } - contextParams.forEach((contextParam) => { - it(`produces context parameter ${contextParam} for method ${method}`, () => { - const rpcCondition = new Conditions.RpcCondition({ - chain: 5, - method, - parameters: [contextParam], - returnValueTest: { - comparator: '==', - value: contextParam, - }, - }); - const producedContextParam = rpcCondition.getContextParameters(); - expect(producedContextParam).toEqual([contextParam]); - }); - }); - }); - }); - - describe('from evm condition', () => { - Conditions.EvmCondition.STANDARD_CONTRACT_TYPES.forEach((contractType) => { - const methods = - Conditions.EvmCondition.METHODS_PER_CONTRACT_TYPE[contractType]; - if (!methods) { - return; - } - methods.forEach((method) => { - const contextParams = - Conditions.EvmCondition.CONTEXT_PARAMETERS_PER_METHOD[method]; - if (!contextParams) { - return; - } - contextParams.forEach((contextParam) => { - it(`produces context parameter ${contextParam} for method ${method}`, () => { - const evmCondition = new Conditions.EvmCondition({ - contractAddress: '0x0000000000000000000000000000000000000000', - chain: 5, - standardContractType: 'ERC20', - method: 'balanceOf', - parameters: [contextParam], - returnValueTest: { - comparator: '==', - value: contextParam, - }, - }); - const producedContextParam = evmCondition.getContextParameters(); - expect(producedContextParam).toEqual([contextParam]); - }); - }); - }); - }); - }); -}); - -describe('condition context', () => { - it('should serialize to JSON with context params', async () => { - const web3Provider = mockWeb3Provider(SecretKey.random().toSecretBytes()); - - const rpcCondition = new Conditions.RpcCondition({ - chain: 5, - method: 'eth_getBalance', - parameters: [':userAddress'], - returnValueTest: { - comparator: '==', - value: ':userAddress', - }, - }); - const conditionSet = new ConditionSet([rpcCondition]); - - const conditionContext = new ConditionContext( - conditionSet.toWASMConditions(), - web3Provider - ); - const asJson = await conditionContext.toJson(); - expect(asJson).toBeDefined(); - }); -}); - -describe('evm condition', () => { - describe('accepts either standardContractType or functionAbi but not both or none', () => { - const baseEvmCondition = { - contractAddress: '0x0000000000000000000000000000000000000000', - chain: 5, - method: 'balanceOf', - parameters: ['0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77'], - returnValueTest: { - comparator: '==', - value: ':userAddress', - }, - }; - const standardContractType = 'ERC20'; - const functionAbi = { fake_function_abi: true }; - - it('accepts standardContractType', () => { - const conditionJson = { ...baseEvmCondition, standardContractType }; - const evmCondition = new Conditions.EvmCondition(conditionJson); - expect(evmCondition.toObj()).toEqual(conditionJson); - }); - - it('accepts functionAbi', () => { - const conditionJson = { ...baseEvmCondition, functionAbi }; - const evmCondition = new Conditions.EvmCondition(conditionJson); - expect(evmCondition.toObj()).toEqual(conditionJson); - }); - - it('rejects both', () => { - const conditionJson = { - ...baseEvmCondition, - standardContractType, - functionAbi, - }; - const evmCondition = new Conditions.EvmCondition(conditionJson); - expect(() => evmCondition.toObj()).toThrow( - '"value" contains a conflict between exclusive peers [standardContractType, functionAbi]' - ); - }); - - it('rejects none', () => { - const evmCondition = new Conditions.EvmCondition(baseEvmCondition); - expect(() => evmCondition.toObj()).toThrow( - '"value" must contain at least one of [standardContractType, functionAbi]' - ); - }); - }); -}); diff --git a/test/integration/dkg-client.test.ts b/test/integration/dkg-client.test.ts new file mode 100644 index 000000000..acb8337b6 --- /dev/null +++ b/test/integration/dkg-client.test.ts @@ -0,0 +1,54 @@ +import { SecretKey } from '@nucypher/nucypher-core'; + +import { DkgCoordinatorAgent } from '../../src/agents/coordinator'; +import { + fakeCoordinatorRitual, + fakeDkgParticipants, + fakeRitualId, + fakeWeb3Provider, + mockGetParticipants, +} from '../utils'; + +jest.mock('../../src/agents/coordinator', () => ({ + DkgCoordinatorAgent: { + getRitual: () => Promise.resolve(fakeCoordinatorRitual(fakeRitualId)), + getParticipants: () => Promise.resolve(fakeDkgParticipants(fakeRitualId)), + }, +})); + +describe('DkgCoordinatorAgent', () => { + afterEach(() => { + jest.restoreAllMocks(); + }); + + it('fetches transcripts from the coordinator', async () => { + const provider = fakeWeb3Provider(SecretKey.random().toBEBytes()); + const ritual = await DkgCoordinatorAgent.getRitual(provider, fakeRitualId); + expect(ritual).toBeDefined(); + }); + + it('fetches participants from the coordinator', async () => { + const provider = fakeWeb3Provider(SecretKey.random().toBEBytes()); + const fakeParticipants = fakeDkgParticipants(fakeRitualId); + const getParticipantsSpy = mockGetParticipants( + fakeParticipants.participants + ); + const participants = await DkgCoordinatorAgent.getParticipants( + provider, + fakeRitualId + ); + expect(getParticipantsSpy).toHaveBeenCalled(); + expect(participants.length).toBeGreaterThan(0); + }); +}); + +// TODO: Fix this test after the DkgClient.verifyRitual() method is implemented +// describe('DkgClient', () => { +// it('verifies the dkg ritual', async () => { +// const provider = fakeWeb3Provider(SecretKey.random().toBEBytes()); +// +// const dkgClient = new DkgClient(provider); +// const isValid = await dkgClient.verifyRitual(fakeRitualId); +// expect(isValid).toBeTruthy(); +// }); +// }); diff --git a/test/integration/enrico.test.ts b/test/integration/enrico.test.ts index f3281b0ad..d28ea9f77 100644 --- a/test/integration/enrico.test.ts +++ b/test/integration/enrico.test.ts @@ -1,24 +1,30 @@ +// Disabling because we want to access Alice.keyring which is a private property /* eslint-disable @typescript-eslint/no-explicit-any */ -import { Conditions, ConditionSet, Enrico, PolicyMessageKit } from '../../src'; +import { conditions, Enrico, PolicyMessageKit } from '../../src'; import { RetrievalResult } from '../../src/kits/retrieval'; import { toBytes } from '../../src/utils'; import { bytesEqual, + fakeAlice, + fakeBob, fromBytes, - mockAlice, - mockBob, reencryptKFrags, } from '../utils'; +const { + predefined: { ERC721Ownership }, + ConditionExpression, +} = conditions; + describe('enrico', () => { it('alice decrypts message encrypted by enrico', async () => { const label = 'fake-label'; const message = 'fake-message'; - const alice = mockAlice(); + const alice = fakeAlice(); const policyKey = alice.getPolicyEncryptingKeyFromLabel(label); const enrico = new Enrico(policyKey); - const encrypted = enrico.encryptMessage(toBytes(message)); + const encrypted = enrico.encryptMessagePre(toBytes(message)); const aliceKeyring = (alice as any).keyring; const aliceSk = await aliceKeyring.getSecretKeyFromLabel(label); @@ -28,15 +34,15 @@ describe('enrico', () => { it('bob decrypts reencrypted message', async () => { const label = 'fake-label'; - const alice = mockAlice(); - const bob = mockBob(); + const alice = fakeAlice(); + const bob = fakeBob(); const policyEncryptingKey = alice.getPolicyEncryptingKeyFromLabel(label); const enrico = new Enrico(policyEncryptingKey); const plaintext = 'Plaintext message'; const plaintextBytes = toBytes(plaintext); - const encrypted = enrico.encryptMessage(plaintextBytes); + const encrypted = enrico.encryptMessagePre(plaintextBytes); // Alice can decrypt capsule she created const aliceSk = await (alice as any).keyring.getSecretKeyFromLabel(label); @@ -51,7 +57,9 @@ describe('enrico', () => { threshold, shares ); - expect(delegatingKey.toBytes()).toEqual(policyEncryptingKey.toBytes()); + expect(delegatingKey.toCompressedBytes()).toEqual( + policyEncryptingKey.toCompressedBytes() + ); // Bob can decrypt re-encrypted ciphertext const { verifiedCFrags } = reencryptKFrags( @@ -87,19 +95,20 @@ describe('enrico', () => { it('enrico generates a message kit with conditions', async () => { const label = 'fake-label'; const message = 'fake-message'; - const alice = mockAlice(); + const alice = fakeAlice(); const policyKey = alice.getPolicyEncryptingKeyFromLabel(label); - const ownsBufficornNFT = Conditions.ERC721Ownership.fromObj({ + const ownsBufficornNFT = ERC721Ownership.fromObj({ contractAddress: '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', parameters: [3591], + chain: 5, }); - const conditions = new ConditionSet([ownsBufficornNFT]); + const conditions = new ConditionExpression(ownsBufficornNFT); const enrico = new Enrico(policyKey, undefined, conditions); - const encrypted = enrico.encryptMessage(toBytes(message)); + const encrypted = enrico.encryptMessagePre(toBytes(message)); const aliceKeyring = (alice as any).keyring; const aliceSk = await aliceKeyring.getSecretKeyFromLabel(label); @@ -110,27 +119,27 @@ describe('enrico', () => { it('can overwrite conditions at encryption time', async () => { const label = 'fake-label'; const message = 'fake-message'; - const alice = mockAlice(); + const alice = fakeAlice(); const policyKey = alice.getPolicyEncryptingKeyFromLabel(label); - const ownsBufficornNFT = new Conditions.ERC721Ownership({ + const ownsBufficornNFT = new ERC721Ownership({ contractAddress: '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', chain: 5, parameters: [3591], }); - const ownsNonsenseNFT = new Conditions.ERC721Ownership({ + const ownsNonsenseNFT = new ERC721Ownership({ contractAddress: '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', chain: 5, parameters: [6969], }); - const conditions = new ConditionSet([ownsBufficornNFT]); - const updatedConditions = new ConditionSet([ownsNonsenseNFT]); + const conditions = new ConditionExpression(ownsBufficornNFT); + const updatedConditions = new ConditionExpression(ownsNonsenseNFT); const enrico = new Enrico(policyKey, undefined, conditions); - const encrypted = enrico.encryptMessage( + const encrypted = enrico.encryptMessagePre( toBytes(message), updatedConditions ); diff --git a/test/integration/message-kit.test.ts b/test/integration/message-kit.test.ts index c4070a0c0..16d27640b 100644 --- a/test/integration/message-kit.test.ts +++ b/test/integration/message-kit.test.ts @@ -1,10 +1,10 @@ import { MessageKit } from '../../src'; import { toBytes } from '../../src/utils'; -import { mockBob } from '../utils'; +import { fakeBob } from '../utils'; describe('message kit', () => { it('bob decrypts', () => { - const bob = mockBob(); + const bob = fakeBob(); const plaintext = toBytes('fake-message'); const messageKit = new MessageKit(bob.decryptingKey, plaintext, null); const decrypted = bob['keyring'].decrypt(messageKit); diff --git a/test/integration/pre.test.ts b/test/integration/pre.test.ts index c896c7b6c..e3087e16c 100644 --- a/test/integration/pre.test.ts +++ b/test/integration/pre.test.ts @@ -1,25 +1,24 @@ import { CapsuleFrag, reencrypt } from '@nucypher/nucypher-core'; -import { - Conditions, - ConditionSet, - Enrico, - MessageKit, - Operator, - PolicyMessageKit, -} from '../../src'; +import { conditions, Enrico, MessageKit, PolicyMessageKit } from '../../src'; +import { CompoundCondition } from '../../src/conditions'; import { RetrievalResult } from '../../src/kits/retrieval'; import { toBytes, zip } from '../../src/utils'; -import { mockAlice, mockBob, mockUrsulas, reencryptKFrags } from '../utils'; +import { fakeAlice, fakeBob, fakeUrsulas, reencryptKFrags } from '../utils'; + +const { + predefined: { ERC721Ownership }, + ConditionExpression, +} = conditions; describe('proxy reencryption', () => { const plaintext = toBytes('plaintext-message'); const threshold = 2; const shares = 3; - const ursulas = mockUrsulas().slice(0, shares); + const ursulas = fakeUrsulas().slice(0, shares); const label = 'fake-data-label'; - const alice = mockAlice(); - const bob = mockBob(); + const alice = fakeAlice(); + const bob = fakeBob(); it('verifies capsule frags', async () => { const { capsule } = new MessageKit(bob.decryptingKey, plaintext, null); @@ -55,7 +54,7 @@ describe('proxy reencryption', () => { const policyEncryptingKey = alice.getPolicyEncryptingKeyFromLabel(label); const enrico = new Enrico(policyEncryptingKey); - const encryptedMessage = enrico.encryptMessage(plaintext); + const encryptedMessage = enrico.encryptMessagePre(plaintext); const ursulaAddresses = ursulas.map((ursula) => ursula.checksumAddress); const reencrypted = verifiedKFrags.map((kFrag) => @@ -85,22 +84,25 @@ describe('proxy reencryption', () => { const policyEncryptingKey = alice.getPolicyEncryptingKeyFromLabel(label); - const genuineUndead = new Conditions.ERC721Ownership({ + const genuineUndead = new ERC721Ownership({ contractAddress: '0x209e639a0EC166Ac7a1A4bA41968fa967dB30221', chain: 1, + parameters: [1], }); - const gnomePals = new Conditions.ERC721Ownership({ + const gnomePals = new ERC721Ownership({ contractAddress: '0x5dB11d7356aa4C0E85Aa5b255eC2B5F81De6d4dA', chain: 1, + parameters: [1], }); - const conditions = new ConditionSet([ - genuineUndead, - Operator.OR(), - gnomePals, - ]); + const conditionsSet = new ConditionExpression( + new CompoundCondition({ + operator: 'or', + operands: [genuineUndead.toObj(), gnomePals.toObj()], + }) + ); - const enrico = new Enrico(policyEncryptingKey, undefined, conditions); - const encryptedMessage = enrico.encryptMessage(plaintext); + const enrico = new Enrico(policyEncryptingKey, undefined, conditionsSet); + const encryptedMessage = enrico.encryptMessagePre(plaintext); const ursulaAddresses = ursulas.map((ursula) => ursula.checksumAddress); const reencrypted = verifiedKFrags.map((kFrag) => diff --git a/test/unit/cbd-strategy.test.ts b/test/unit/cbd-strategy.test.ts new file mode 100644 index 000000000..36a8f216b --- /dev/null +++ b/test/unit/cbd-strategy.test.ts @@ -0,0 +1,176 @@ +import { SecretKey, SessionStaticSecret } from '@nucypher/nucypher-core'; + +import { conditions } from '../../src'; +import { FerveoVariant } from '../../src'; +import { CbdStrategy, DeployedCbdStrategy } from '../../src'; +import { CbdTDecDecrypter } from '../../src/characters/cbd-recipient'; +import { toBytes } from '../../src/utils'; +import { + fakeDkgFlow, + fakeDkgParticipants, + fakeDkgRitual, + fakeTDecFlow, + fakeUrsulas, + fakeWeb3Provider, + makeCohort, + mockCbdDecrypt, + mockGetParticipants, + mockGetUrsulas, + mockInitializeRitual, + mockRandomSessionStaticSecret, +} from '../utils'; + +import { aliceSecretKeyBytes } from './testVariables'; + +const { + predefined: { ERC721Ownership }, + ConditionExpression, +} = conditions; + +// Shared test variables +const aliceSecretKey = SecretKey.fromBEBytes(aliceSecretKeyBytes); +const aliceProvider = fakeWeb3Provider(aliceSecretKey.toBEBytes()); +const ownsNFT = new ERC721Ownership({ + contractAddress: '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', + parameters: [3591], + chain: 5, +}); +const conditionExpr = new ConditionExpression(ownsNFT); +const ursulas = fakeUrsulas().slice(0, 3); +const variant = FerveoVariant.Precomputed; + +const makeCbdStrategy = async () => { + const cohort = await makeCohort(ursulas); + const strategy = CbdStrategy.create(cohort); + expect(strategy.cohort).toEqual(cohort); + return strategy; +}; + +async function makeDeployedCbdStrategy() { + const strategy = await makeCbdStrategy(); + + const mockedDkg = fakeDkgFlow(variant, 0, 4, 4); + const mockedDkgRitual = fakeDkgRitual(mockedDkg, mockedDkg.threshold); + const web3Provider = fakeWeb3Provider(aliceSecretKey.toBEBytes()); + const getUrsulasSpy = mockGetUrsulas(ursulas); + const initializeRitualSpy = mockInitializeRitual(mockedDkgRitual); + const deployedStrategy = await strategy.deploy(web3Provider); + + expect(getUrsulasSpy).toHaveBeenCalled(); + expect(initializeRitualSpy).toHaveBeenCalled(); + + return { mockedDkg, deployedStrategy }; +} + +describe('CbdStrategy', () => { + afterEach(() => { + jest.restoreAllMocks(); + }); + + it('creates a strategy', async () => { + await makeCbdStrategy(); + }); + + it('can deploy and return a CbdDeployedStrategy', async () => { + await makeDeployedCbdStrategy(); + }); + + describe('serialization', () => { + it('serializes to a plain object', async () => { + const strategy = await makeCbdStrategy(); + const asObj = strategy.toObj(); + const fromObj = CbdStrategy.fromObj(asObj); + expect(fromObj.equals(strategy)).toBeTruthy(); + }); + + it('serializes to a JSON', async () => { + const strategy = await makeCbdStrategy(); + const asJson = strategy.toJSON(); + const fromJson = CbdStrategy.fromJSON(asJson); + expect(fromJson.equals(strategy)).toBeTruthy(); + }); + }); +}); + +describe('CbdDeployedStrategy', () => { + afterEach(() => { + jest.restoreAllMocks(); + }); + + it('can encrypt and decrypt', async () => { + const { mockedDkg, deployedStrategy } = await makeDeployedCbdStrategy(); + + const message = 'this is a secret'; + const { ciphertext, aad } = deployedStrategy + .makeEncrypter(conditionExpr) + .encryptMessageCbd(message); + + // Setup mocks for `retrieveAndDecrypt` + const { decryptionShares } = fakeTDecFlow({ + ...mockedDkg, + variant, + message: toBytes(message), + aad, + ciphertext, + }); + const { participantSecrets, participants } = fakeDkgParticipants( + mockedDkg.ritualId, + variant + ); + const requesterSessionKey = SessionStaticSecret.random(); + const decryptSpy = mockCbdDecrypt( + mockedDkg.ritualId, + decryptionShares, + participantSecrets, + requesterSessionKey.publicKey() + ); + const getParticipantsSpy = mockGetParticipants(participants); + const getUrsulasSpy = mockGetUrsulas(ursulas); + const sessionKeySpy = mockRandomSessionStaticSecret(requesterSessionKey); + + const decryptedMessage = + await deployedStrategy.decrypter.retrieveAndDecrypt( + aliceProvider, + conditionExpr, + variant, + ciphertext + ); + expect(getUrsulasSpy).toHaveBeenCalled(); + expect(getParticipantsSpy).toHaveBeenCalled(); + expect(sessionKeySpy).toHaveBeenCalled(); + expect(decryptSpy).toHaveBeenCalled(); + expect(decryptedMessage).toEqual(toBytes(message)); + }); + + describe('serialization', () => { + it('serializes to a plaintext object', async () => { + const { deployedStrategy } = await makeDeployedCbdStrategy(); + const asJson = deployedStrategy.toJSON(); + const fromJson = DeployedCbdStrategy.fromJSON(asJson); + expect(fromJson.equals(deployedStrategy)).toBeTruthy(); + }); + + it('serializes to a JSON', async () => { + const { deployedStrategy } = await makeDeployedCbdStrategy(); + const asJson = deployedStrategy.toJSON(); + const fromJson = DeployedCbdStrategy.fromJSON(asJson); + expect(fromJson.equals(deployedStrategy)).toBeTruthy(); + }); + }); +}); + +describe('CbdTDecDecrypter', () => { + it('serializes to a plain object', async () => { + const { deployedStrategy } = await makeDeployedCbdStrategy(); + const configObj = deployedStrategy.decrypter.toObj(); + const fromObj = CbdTDecDecrypter.fromObj(configObj); + expect(fromObj.equals(deployedStrategy.decrypter)).toBeTruthy(); + }); + + it('serializes to a JSON', async () => { + const { deployedStrategy } = await makeDeployedCbdStrategy(); + const configJSON = deployedStrategy.decrypter.toJSON(); + const fromJSON = CbdTDecDecrypter.fromJSON(configJSON); + expect(fromJSON.equals(deployedStrategy.decrypter)).toBeTruthy(); + }); +}); diff --git a/test/unit/cohort.test.ts b/test/unit/cohort.test.ts index 54ed84457..40ab18ee8 100644 --- a/test/unit/cohort.test.ts +++ b/test/unit/cohort.test.ts @@ -1,62 +1,26 @@ -import { Cohort } from '../../src/sdk/cohort'; -import { mockGetUrsulas, mockUrsulas } from '../utils'; +import { Cohort } from '../../src'; +import { fakeUrsulas, makeCohort } from '../utils'; describe('Cohort', () => { - it('can create Cohort from configuration', async () => { - const mockedUrsulas = mockUrsulas().slice(0, 3); - const getUrsulasSpy = mockGetUrsulas(mockedUrsulas); + const mockedUrsulas = fakeUrsulas().slice(0, 3); - const config = { - threshold: 2, - shares: 3, - porterUri: 'https://_this.should.crash', - }; - const testCohort = await Cohort.create(config); - - const expectedUrsulas = [ - '0x5cf1703a1c99a4b42eb056535840e93118177232', - '0x7fff551249d223f723557a96a0e1a469c79cc934', - '0x9c7c824239d3159327024459ad69bb215859bd25', - ]; - expect(getUrsulasSpy).toHaveBeenCalled(); - expect(testCohort.ursulaAddresses).toEqual(expectedUrsulas); + it('creates a Cohort', async () => { + const cohort = await makeCohort(mockedUrsulas); + const expectedUrsulas = mockedUrsulas.map((u) => u.checksumAddress); + expect(cohort.ursulaAddresses).toEqual(expectedUrsulas); }); - it('can export to JSON', async () => { - const mockedUrsulas = mockUrsulas().slice(0, 3); - const getUrsulasSpy = mockGetUrsulas(mockedUrsulas); - const config = { - threshold: 2, - shares: 3, - porterUri: 'https://_this.should.crash', - }; - const testCohort = await Cohort.create(config); - const configJSON = testCohort.toJSON(); - const expectedJSON = - '{"ursulaAddresses":["0x5cf1703a1c99a4b42eb056535840e93118177232","0x7fff551249d223f723557a96a0e1a469c79cc934","0x9c7c824239d3159327024459ad69bb215859bd25"],"threshold":2,"shares":3,"porterUri":"https://_this.should.crash"}'; - expect(getUrsulasSpy).toHaveBeenCalled(); - expect(configJSON).toEqual(expectedJSON); + it('serializes to a plain object', async () => { + const cohort = await makeCohort(mockedUrsulas); + const asObj = cohort.toObj(); + const fromObj = Cohort.fromObj(asObj); + expect(fromObj).toEqual(cohort); }); - it('can import from JSON', async () => { - const mockedUrsulas = mockUrsulas().slice(0, 3); - const getUrsulasSpy = mockGetUrsulas(mockedUrsulas); - - const configJSON = - '{"ursulaAddresses":["0x5cf1703a1c99a4b42eb056535840e93118177232","0x7fff551249d223f723557a96a0e1a469c79cc934","0x9c7c824239d3159327024459ad69bb215859bd25"],"threshold":2,"shares":3,"porterUri":"https://_this.should.crash"}'; - const testCohort = Cohort.fromJSON(configJSON); - const expectedUrsulas = [ - '0x5cf1703a1c99a4b42eb056535840e93118177232', - '0x7fff551249d223f723557a96a0e1a469c79cc934', - '0x9c7c824239d3159327024459ad69bb215859bd25', - ]; - const expectedConfiguration = { - threshold: 2, - shares: 3, - porterUri: 'https://_this.should.crash', - }; - expect(getUrsulasSpy).toHaveBeenCalled(); - expect(testCohort.ursulaAddresses).toEqual(expectedUrsulas); - expect(testCohort.configuration).toEqual(expectedConfiguration); + it('serializes to JSON', async () => { + const cohort = await makeCohort(mockedUrsulas); + const asJson = cohort.toJSON(); + const fromJson = Cohort.fromJSON(asJson); + expect(fromJson).toEqual(cohort); }); }); diff --git a/test/unit/conditions/base/condition.test.ts b/test/unit/conditions/base/condition.test.ts new file mode 100644 index 000000000..2a567434c --- /dev/null +++ b/test/unit/conditions/base/condition.test.ts @@ -0,0 +1,63 @@ +import { ContractCondition } from '../../../../src/conditions/base'; +import { + ERC721Balance, + ERC721Ownership, +} from '../../../../src/conditions/predefined'; +import { + TEST_CHAIN_ID, + TEST_CONTRACT_ADDR, + TEST_CONTRACT_ADDR_2, + testContractConditionObj, +} from '../../testVariables'; + +describe('validation', () => { + // TODO: Consider: + // Use Condition here with returnTestValue schema + // Refactor returnTestValue to be the part of the Condition + const condition = new ERC721Balance(); + + it('accepts a correct schema', async () => { + const result = condition.validate({ + contractAddress: TEST_CONTRACT_ADDR, + chain: TEST_CHAIN_ID, + }); + expect(result.error).toBeUndefined(); + expect(result.value.contractAddress).toEqual(TEST_CONTRACT_ADDR); + }); + + it('updates on a valid schema value', async () => { + const result = condition.validate({ + chain: TEST_CHAIN_ID, + contractAddress: TEST_CONTRACT_ADDR_2, + }); + expect(result.error).toBeUndefined(); + expect(result.value.chain).toEqual(TEST_CHAIN_ID); + }); + + it('rejects on an invalid schema value', async () => { + const result = condition.validate({ + chain: -1, + contractAddress: TEST_CONTRACT_ADDR, + }); + expect(result.error?.message).toEqual( + '"chain" must be one of [1, 5, 137, 80001]' + ); + }); +}); + +describe('serialization', () => { + it('serializes to a plain object', () => { + const contract = new ContractCondition(testContractConditionObj); + expect(contract.toObj()).toEqual({ + ...testContractConditionObj, + }); + }); + + it('serializes predefined conditions', () => { + const contract = new ERC721Ownership(testContractConditionObj); + expect(contract.toObj()).toEqual({ + ...contract.defaults, + ...testContractConditionObj, + }); + }); +}); diff --git a/test/unit/conditions/base/contract.test.ts b/test/unit/conditions/base/contract.test.ts new file mode 100644 index 000000000..25fdddd8b --- /dev/null +++ b/test/unit/conditions/base/contract.test.ts @@ -0,0 +1,154 @@ +import { SecretKey } from '@nucypher/nucypher-core'; + +import { + ConditionExpression, + CustomContextParam, +} from '../../../../src/conditions'; +import { ContractCondition } from '../../../../src/conditions/base'; +import { USER_ADDRESS_PARAM } from '../../../../src/conditions/const'; +import { fakeWeb3Provider } from '../../../utils'; +import { testContractConditionObj } from '../../testVariables'; + +describe('validation', () => { + it('accepts on a valid schema', () => { + const contract = new ContractCondition(testContractConditionObj); + expect(contract.toObj()).toEqual({ + ...testContractConditionObj, + }); + }); + + it('rejects an invalid schema', () => { + const badContractCondition = { + ...testContractConditionObj, + // Intentionally removing `contractAddress` + contractAddress: undefined, + }; + const badEvm = new ContractCondition(badContractCondition); + expect(() => badEvm.toObj()).toThrow( + 'Invalid condition: "contractAddress" is required' + ); + + const { error } = badEvm.validate(badContractCondition); + expect(error?.message).toEqual('"contractAddress" is required'); + }); +}); + +describe('accepts either standardContractType or functionAbi but not both or none', () => { + const standardContractType = 'ERC20'; + const functionAbi = { + inputs: [ + { + name: '_owner', + type: 'address', + }, + ], + name: 'balanceOf', + outputs: [ + { + name: 'balance', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }; + + it('accepts standardContractType', () => { + const conditionObj = { + ...testContractConditionObj, + standardContractType, + functionAbi: undefined, + }; + const contractCondition = new ContractCondition(conditionObj); + expect(contractCondition.toObj()).toEqual({ + ...conditionObj, + }); + }); + + it('accepts functionAbi', () => { + const conditionObj = { + ...testContractConditionObj, + functionAbi, + standardContractType: undefined, + }; + const contractCondition = new ContractCondition(conditionObj); + expect(contractCondition.toObj()).toEqual({ + ...conditionObj, + }); + }); + + it('rejects both', () => { + const conditionObj = { + ...testContractConditionObj, + standardContractType, + functionAbi, + }; + const contractCondition = new ContractCondition(conditionObj); + expect(() => contractCondition.toObj()).toThrow( + '"value" contains a conflict between exclusive peers [standardContractType, functionAbi]' + ); + }); + + it('rejects none', () => { + const conditionObj = { + ...testContractConditionObj, + standardContractType: undefined, + functionAbi: undefined, + }; + const contractCondition = new ContractCondition(conditionObj); + expect(() => contractCondition.toObj()).toThrow( + '"value" must contain at least one of [standardContractType, functionAbi]' + ); + }); +}); + +describe('supports custom function abi', () => { + const fakeFunctionAbi = { + name: 'myFunction', + type: 'function', + inputs: [ + { + name: 'account', + type: 'address', + }, + { + name: 'myCustomParam', + type: 'uint256', + }, + ], + outputs: [ + { + name: 'someValue', + type: 'uint256', + }, + ], + }; + const contractConditionObj = { + ...testContractConditionObj, + standardContractType: undefined, + functionAbi: fakeFunctionAbi, + method: 'myFunction', + parameters: [USER_ADDRESS_PARAM, ':customParam'], + returnValueTest: { + index: 0, + comparator: '==', + value: USER_ADDRESS_PARAM, + }, + }; + const contractCondition = new ContractCondition(contractConditionObj); + const web3Provider = fakeWeb3Provider(SecretKey.random().toBEBytes()); + const conditionExpr = new ConditionExpression(contractCondition); + const conditionContext = conditionExpr.buildContext(web3Provider); + const myCustomParam = ':customParam'; + const customParams: Record = {}; + customParams[myCustomParam] = 1234; + + it('accepts custom function abi', async () => { + const asJson = await conditionContext + .withCustomParams(customParams) + .toJson(); + expect(asJson).toBeDefined(); + expect(asJson).toContain(USER_ADDRESS_PARAM); + expect(asJson).toContain(myCustomParam); + }); +}); diff --git a/test/unit/conditions/base/rpc.test.ts b/test/unit/conditions/base/rpc.test.ts new file mode 100644 index 000000000..ccd65f63a --- /dev/null +++ b/test/unit/conditions/base/rpc.test.ts @@ -0,0 +1,29 @@ +import { RpcCondition } from '../../../../src/conditions/base'; +import { testRpcConditionObj } from '../../testVariables'; + +describe('validation', () => { + it('accepts on a valid schema', () => { + const rpc = new RpcCondition(testRpcConditionObj); + expect(rpc.toObj()).toEqual({ + ...testRpcConditionObj, + }); + }); + + it('rejects an invalid schema', () => { + const badRpcObj = { + ...testRpcConditionObj, + // Intentionally replacing `method` with an invalid method + method: 'fake_invalid_method', + }; + + const badRpc = new RpcCondition(badRpcObj); + expect(() => badRpc.toObj()).toThrow( + 'Invalid condition: "method" must be one of [eth_getBalance, balanceOf]' + ); + + const { error } = badRpc.validate(badRpcObj); + expect(error?.message).toEqual( + '"method" must be one of [eth_getBalance, balanceOf]' + ); + }); +}); diff --git a/test/unit/conditions/base/time.test.ts b/test/unit/conditions/base/time.test.ts new file mode 100644 index 000000000..a043c8eba --- /dev/null +++ b/test/unit/conditions/base/time.test.ts @@ -0,0 +1,42 @@ +import { TimeCondition } from '../../../../src/conditions/base'; + +describe('validation', () => { + const returnValueTest = { + index: 0, + comparator: '>', + value: '100', + }; + + it('accepts a valid schema', () => { + const timeCondition = new TimeCondition({ + returnValueTest, + chain: 5, + }); + expect(timeCondition.toObj()).toEqual({ + returnValueTest, + chain: 5, + method: 'blocktime', + }); + }); + + it('rejects an invalid schema', () => { + const badTimeObj = { + // Intentionally replacing `returnValueTest` with an invalid test + returnValueTest: { + ...returnValueTest, + comparator: 'not-a-comparator', + }, + chain: 5, + }; + + const badTimeCondition = new TimeCondition(badTimeObj); + expect(() => badTimeCondition.toObj()).toThrow( + 'Invalid condition: "returnValueTest.comparator" must be one of [==, >, <, >=, <=, !=]' + ); + + const { error } = badTimeCondition.validate(badTimeObj); + expect(error?.message).toEqual( + '"returnValueTest.comparator" must be one of [==, >, <, >=, <=, !=]' + ); + }); +}); diff --git a/test/unit/conditions/compound-condition.test.ts b/test/unit/conditions/compound-condition.test.ts new file mode 100644 index 000000000..396b6fddf --- /dev/null +++ b/test/unit/conditions/compound-condition.test.ts @@ -0,0 +1,85 @@ +import { CompoundCondition } from '../../../src/conditions'; +import { ERC721Ownership } from '../../../src/conditions/predefined/erc721'; +import { + testContractConditionObj, + testRpcConditionObj, + testTimeConditionObj, +} from '../testVariables'; + +describe('validate', () => { + const ownsBufficornNFT = ERC721Ownership.fromObj({ + contractAddress: '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', + parameters: [3591], + chain: 5, + }).toObj(); + + it('accepts or operator', () => { + const orCondition = new CompoundCondition({ + operator: 'or', + operands: [ownsBufficornNFT, testTimeConditionObj], + }).toObj(); + + expect(orCondition.operator).toEqual('or'); + expect(orCondition.operands).toEqual([ + ownsBufficornNFT, + testTimeConditionObj, + ]); + }); + + it('accepts and operator', () => { + const orCondition = new CompoundCondition({ + operator: 'and', + operands: [testContractConditionObj, testTimeConditionObj], + }).toObj(); + + expect(orCondition.operator).toEqual('and'); + expect(orCondition.operands).toEqual([ + testContractConditionObj, + testTimeConditionObj, + ]); + }); + + it('rejects an invalid operator', () => { + expect(() => + new CompoundCondition({ + operator: 'not-an-operator', + operands: [testRpcConditionObj, testTimeConditionObj], + }).toObj() + ).toThrow('"operator" must be one of [and, or]'); + }); + + it('rejects invalid number of operands = 0', () => { + expect(() => + new CompoundCondition({ + operator: 'or', + operands: [], + }).toObj() + ).toThrow('"operands" must contain at least 2 items'); + }); + + it('rejects invalid number of operands = 1', () => { + expect(() => + new CompoundCondition({ + operator: 'or', + operands: [testRpcConditionObj], + }).toObj() + ).toThrow('"operands" must contain at least 2 items'); + }); + + it('it allows recursive compound conditions', () => { + const compoundCondition = new CompoundCondition({ + operator: 'and', + operands: [ + testContractConditionObj, + testTimeConditionObj, + testRpcConditionObj, + { + operator: 'or', + operands: [ownsBufficornNFT, testContractConditionObj], + }, + ], + }).toObj(); + expect(compoundCondition.operator).toEqual('and'); + expect(compoundCondition.operands).toHaveLength(4); + }); +}); diff --git a/test/unit/conditions/condition-expr.test.ts b/test/unit/conditions/condition-expr.test.ts new file mode 100644 index 000000000..806269a7f --- /dev/null +++ b/test/unit/conditions/condition-expr.test.ts @@ -0,0 +1,426 @@ +import { SemVer } from 'semver'; + +import { + CompoundCondition, + ConditionExpression, +} from '../../../src/conditions'; +import { + ContractCondition, + RpcCondition, + TimeCondition, +} from '../../../src/conditions/base'; +import { USER_ADDRESS_PARAM } from '../../../src/conditions/const'; +import { ERC721Balance } from '../../../src/conditions/predefined'; +import { toJSON } from '../../../src/utils'; +import { + TEST_CHAIN_ID, + TEST_CONTRACT_ADDR, + testFunctionAbi, + testReturnValueTest, +} from '../testVariables'; +import { + testContractConditionObj, + testRpcConditionObj, + testTimeConditionObj, +} from '../testVariables'; + +describe('condition set', () => { + const erc721BalanceCondition = new ERC721Balance({ + chain: TEST_CHAIN_ID, + contractAddress: TEST_CONTRACT_ADDR, + }); + + const contractConditionNoAbi = new ContractCondition( + testContractConditionObj + ); + + const customParamKey = ':customParam'; + const contractConditionWithAbiObj = { + ...testContractConditionObj, + standardContractType: undefined, + functionAbi: testFunctionAbi, + method: testFunctionAbi.name, + parameters: [USER_ADDRESS_PARAM, customParamKey], + returnValueTest: { + ...testReturnValueTest, + }, + }; + const contractConditionWithAbi = new ContractCondition( + contractConditionWithAbiObj + ); + + const rpcCondition = new RpcCondition(testRpcConditionObj); + const timeCondition = new TimeCondition(testTimeConditionObj); + const compoundCondition = new CompoundCondition({ + operator: 'and', + operands: [ + testContractConditionObj, + testTimeConditionObj, + testRpcConditionObj, + { + operator: 'or', + operands: [testTimeConditionObj, testContractConditionObj], + }, + ], + }); + + describe('equality', () => { + const conditionExprCurrentVersion = new ConditionExpression(rpcCondition); + + it('same version and condition', async () => { + const conditionExprSameCurrentVerstion = new ConditionExpression( + rpcCondition, + ConditionExpression.VERSION + ); + expect( + conditionExprCurrentVersion.equals(conditionExprSameCurrentVerstion) + ).toBeTruthy(); + }); + + it('different minor/patch version but same condition', async () => { + const conditionExprOlderMinorVersion = new ConditionExpression( + rpcCondition, + '0.1.0' + ); + const conditionExprOlderPatchVersion = new ConditionExpression( + rpcCondition, + '0.0.1' + ); + expect( + conditionExprCurrentVersion.equals(conditionExprOlderMinorVersion) + ).not.toBeTruthy(); + expect( + conditionExprCurrentVersion.equals(conditionExprOlderPatchVersion) + ).not.toBeTruthy(); + expect( + conditionExprOlderMinorVersion.equals(conditionExprOlderPatchVersion) + ).not.toBeTruthy(); + }); + + it('minor/patch number greater than major; still older', async () => { + const conditionExprOlderMinorVersion = new ConditionExpression( + rpcCondition, + '0.9.0' + ); + const conditionExprOlderPatchVersion = new ConditionExpression( + rpcCondition, + '0.0.9' + ); + const conditionExprOlderMinorPatchVersion = new ConditionExpression( + rpcCondition, + '0.9.9' + ); + expect( + conditionExprCurrentVersion.equals(conditionExprOlderMinorVersion) + ).not.toBeTruthy(); + expect( + conditionExprCurrentVersion.equals(conditionExprOlderPatchVersion) + ).not.toBeTruthy(); + expect( + conditionExprCurrentVersion.equals(conditionExprOlderMinorPatchVersion) + ).not.toBeTruthy(); + expect( + conditionExprOlderMinorVersion.equals(conditionExprOlderPatchVersion) + ).not.toBeTruthy(); + expect( + conditionExprOlderMinorVersion.equals( + conditionExprOlderMinorPatchVersion + ) + ).not.toBeTruthy(); + expect( + conditionExprOlderPatchVersion.equals( + conditionExprOlderMinorPatchVersion + ) + ).not.toBeTruthy(); + }); + + it.each([ + erc721BalanceCondition, + contractConditionNoAbi, + contractConditionWithAbi, + timeCondition, + compoundCondition, + ])('same version but different condition', async (condition) => { + const conditionExprSameVersionDifferentCondition = + new ConditionExpression(condition); + expect( + conditionExprCurrentVersion.equals( + conditionExprSameVersionDifferentCondition + ) + ).not.toBeTruthy(); + }); + + it('same contract condition although using erc721 helper', async () => { + const erc721ConditionExpr = new ConditionExpression( + erc721BalanceCondition + ); + const erc721ConditionData = erc721BalanceCondition.toObj(); + const sameContractCondition = new ContractCondition(erc721ConditionData); + const contractConditionExpr = new ConditionExpression( + sameContractCondition + ); + expect(erc721ConditionExpr.equals(contractConditionExpr)).toBeTruthy(); + }); + }); + + describe('serialization / deserialization', () => { + it.each([ + erc721BalanceCondition, + contractConditionNoAbi, + contractConditionWithAbi, + rpcCondition, + timeCondition, + compoundCondition, + ])('serializes to and from json', async (condition) => { + const conditionExpr = new ConditionExpression(condition); + const conditionExprJson = conditionExpr.toJson(); + expect(conditionExprJson).toBeDefined(); + expect(conditionExprJson).toContain('version'); + expect(conditionExprJson).toContain(ConditionExpression.VERSION); + expect(conditionExprJson).toContain('condition'); + expect(conditionExprJson).toContain(toJSON(condition.toObj())); + + const conditionExprFromJson = + ConditionExpression.fromJSON(conditionExprJson); + expect(conditionExprFromJson).toBeDefined(); + expect(conditionExprFromJson.equals(conditionExprFromJson)).toBeTruthy(); + }); + + it('incompatible version', async () => { + const currentVersion = new SemVer(ConditionExpression.VERSION); + const invalidVersion = currentVersion.inc('major'); + expect(() => { + ConditionExpression.fromObj({ + version: invalidVersion.version, + condition: testTimeConditionObj, + }); + }).toThrow( + `Version provided, ${invalidVersion}, is incompatible with current version, ${ConditionExpression.VERSION}` + ); + }); + + it.each(['version', 'x.y', 'x.y.z', '-1,0.0', '1.0.0.0.0.0.0'])( + 'invalid versions', + async (invalidVersion) => { + expect(() => { + ConditionExpression.fromObj({ + version: invalidVersion, + condition: testTimeConditionObj, + }); + }).toThrow(`Invalid Version: ${invalidVersion}`); + } + ); + + it.each([ + // no "operator" nor "method" value + { + version: ConditionExpression.VERSION, + condition: { + randoKey: 'randoValue', + otherKey: 'otherValue', + }, + }, + // invalid "method" and no "contractAddress" + { + version: ConditionExpression.VERSION, + condition: { + method: 'doWhatIWant', + returnValueTest: { + index: 0, + comparator: '>', + value: '100', + }, + chain: 5, + }, + }, + // condition with wrong method "method" and no contract address + { + version: ConditionExpression.VERSION, + condition: { + ...testTimeConditionObj, + method: 'doWhatIWant', + }, + }, + // rpc condition (no contract address) with disallowed method + { + version: ConditionExpression.VERSION, + condition: { + ...testRpcConditionObj, + method: 'isPolicyActive', + }, + }, + ])("can't determine condition type", async (invalidCondition) => { + expect(() => { + ConditionExpression.fromObj(invalidCondition); + }).toThrow('unrecognized condition data'); + }); + + it('erc721 condition serialization', async () => { + const conditionExpr = new ConditionExpression(erc721BalanceCondition); + + const erc721BalanceConditionObj = erc721BalanceCondition.toObj(); + const conditionExprJson = conditionExpr.toJson(); + expect(conditionExprJson).toBeDefined(); + expect(conditionExprJson).toContain('chain'); + expect(conditionExprJson).toContain(TEST_CHAIN_ID.toString()); + expect(conditionExprJson).toContain('contractAddress'); + expect(conditionExprJson).toContain( + erc721BalanceConditionObj.contractAddress + ); + expect(conditionExprJson).toContain('standardContractType'); + expect(conditionExprJson).toContain('ERC721'); + expect(conditionExprJson).toContain('method'); + expect(conditionExprJson).toContain(erc721BalanceConditionObj.method); + expect(conditionExprJson).toContain('returnValueTest'); + + expect(conditionExprJson).not.toContain('functionAbi'); + expect(conditionExprJson).not.toContain('operator'); + expect(conditionExprJson).not.toContain('operands'); + + const conditionExprFromJson = + ConditionExpression.fromJSON(conditionExprJson); + expect(conditionExprFromJson).toBeDefined(); + expect(conditionExprFromJson.condition).toBeInstanceOf(ContractCondition); + }); + + it('contract condition no abi serialization', async () => { + const conditionExpr = new ConditionExpression(contractConditionNoAbi); + + const conditionExprJson = conditionExpr.toJson(); + expect(conditionExprJson).toBeDefined(); + expect(conditionExprJson).toContain('chain'); + expect(conditionExprJson).toContain(TEST_CHAIN_ID.toString()); + expect(conditionExprJson).toContain('contractAddress'); + expect(conditionExprJson).toContain( + testContractConditionObj.contractAddress + ); + expect(conditionExprJson).toContain('standardContractType'); + expect(conditionExprJson).toContain( + testContractConditionObj.standardContractType + ); + expect(conditionExprJson).toContain('method'); + expect(conditionExprJson).toContain(testContractConditionObj.method); + expect(conditionExprJson).toContain('parameters'); + expect(conditionExprJson).toContain( + testContractConditionObj.parameters[0] + ); + expect(conditionExprJson).toContain('returnValueTest'); + expect(conditionExprJson).not.toContain('functionAbi'); + expect(conditionExprJson).not.toContain('operator'); + expect(conditionExprJson).not.toContain('operands'); + + const conditionExprFromJson = + ConditionExpression.fromJSON(conditionExprJson); + expect(conditionExprFromJson).toBeDefined(); + expect(conditionExprFromJson.condition).toBeInstanceOf(ContractCondition); + }); + + it('contract condition with abi serialization', async () => { + const conditionExpr = new ConditionExpression(contractConditionWithAbi); + + const conditionExprJson = conditionExpr.toJson(); + expect(conditionExprJson).toBeDefined(); + expect(conditionExprJson).toContain('chain'); + expect(conditionExprJson).toContain(TEST_CHAIN_ID.toString()); + expect(conditionExprJson).toContain('contractAddress'); + expect(conditionExprJson).toContain( + contractConditionWithAbiObj.contractAddress + ); + expect(conditionExprJson).toContain('method'); + expect(conditionExprJson).toContain(contractConditionWithAbiObj.method); + expect(conditionExprJson).toContain('parameters'); + expect(conditionExprJson).toContain( + contractConditionWithAbiObj.parameters[0] + ); + expect(conditionExprJson).toContain( + contractConditionWithAbiObj.parameters[1] + ); + expect(conditionExprJson).toContain('returnValueTest'); + expect(conditionExprJson).toContain('functionAbi'); + + expect(conditionExprJson).not.toContain('standardContractType'); + expect(conditionExprJson).not.toContain('operator'); + expect(conditionExprJson).not.toContain('operands'); + + const conditionExprFromJson = + ConditionExpression.fromJSON(conditionExprJson); + expect(conditionExprFromJson).toBeDefined(); + expect(conditionExprFromJson.condition).toBeInstanceOf(ContractCondition); + }); + + it('time condition serialization', async () => { + const conditionExpr = new ConditionExpression(timeCondition); + + const conditionExprJson = conditionExpr.toJson(); + expect(conditionExprJson).toBeDefined(); + expect(conditionExprJson).toContain('chain'); + expect(conditionExprJson).toContain(TEST_CHAIN_ID.toString()); + expect(conditionExprJson).toContain('method'); + expect(conditionExprJson).toContain(testTimeConditionObj.method); + expect(conditionExprJson).toContain('returnValueTest'); + expect(conditionExprJson).not.toContain('parameters'); + expect(conditionExprJson).not.toContain('contractAddress'); + expect(conditionExprJson).not.toContain('standardContractType'); + expect(conditionExprJson).not.toContain('functionAbi'); + expect(conditionExprJson).not.toContain('operator'); + expect(conditionExprJson).not.toContain('operands'); + + const conditionExprFromJson = + ConditionExpression.fromJSON(conditionExprJson); + expect(conditionExprFromJson).toBeDefined(); + expect(conditionExprFromJson.condition).toBeInstanceOf(TimeCondition); + }); + + it('rpc condition serialization', async () => { + const conditionExpr = new ConditionExpression(rpcCondition); + + const conditionExprJson = conditionExpr.toJson(); + expect(conditionExprJson).toBeDefined(); + expect(conditionExprJson).toContain('chain'); + expect(conditionExprJson).toContain(TEST_CHAIN_ID.toString()); + expect(conditionExprJson).toContain('method'); + expect(conditionExprJson).toContain(testRpcConditionObj.method); + expect(conditionExprJson).toContain('parameters'); + expect(conditionExprJson).toContain(testRpcConditionObj.parameters[0]); + expect(conditionExprJson).toContain('returnValueTest'); + expect(conditionExprJson).not.toContain('contractAddress'); + expect(conditionExprJson).not.toContain('standardContractType'); + expect(conditionExprJson).not.toContain('functionAbi'); + expect(conditionExprJson).not.toContain('operator'); + expect(conditionExprJson).not.toContain('operands'); + + const conditionExprFromJson = + ConditionExpression.fromJSON(conditionExprJson); + expect(conditionExprFromJson).toBeDefined(); + expect(conditionExprFromJson.condition).toBeInstanceOf(RpcCondition); + }); + + it('compound condition serialization', async () => { + const conditionExpr = new ConditionExpression(compoundCondition); + const compoundConditionObj = compoundCondition.toObj(); + + const conditionExprJson = conditionExpr.toJson(); + expect(conditionExprJson).toContain('operator'); + expect(conditionExprJson).toContain(compoundConditionObj.operator); + expect(conditionExprJson).toContain('operands'); + + expect(conditionExprJson).toBeDefined(); + expect(conditionExprJson).toContain('chain'); + expect(conditionExprJson).toContain(TEST_CHAIN_ID.toString()); + expect(conditionExprJson).toContain('method'); + expect(conditionExprJson).toContain(testRpcConditionObj.method); + expect(conditionExprJson).toContain(testTimeConditionObj.method); + expect(conditionExprJson).toContain(testContractConditionObj.method); + expect(conditionExprJson).toContain('parameters'); + expect(conditionExprJson).toContain(testRpcConditionObj.parameters[0]); + expect(conditionExprJson).toContain( + testContractConditionObj.parameters[0] + ); + + const conditionExprFromJson = + ConditionExpression.fromJSON(conditionExprJson); + expect(conditionExprFromJson).toBeDefined(); + expect(conditionExprFromJson.condition).toBeInstanceOf(CompoundCondition); + }); + }); +}); diff --git a/test/unit/conditions/context.test.ts b/test/unit/conditions/context.test.ts new file mode 100644 index 000000000..035b704d6 --- /dev/null +++ b/test/unit/conditions/context.test.ts @@ -0,0 +1,120 @@ +import { SecretKey } from '@nucypher/nucypher-core'; + +import { CustomContextParam } from '../../../src'; +import { ConditionExpression } from '../../../src/conditions'; +import { ContractCondition, RpcCondition } from '../../../src/conditions/base'; +import { USER_ADDRESS_PARAM } from '../../../src/conditions/const'; +import { RESERVED_CONTEXT_PARAMS } from '../../../src/conditions/context/context'; +import { fakeWeb3Provider } from '../../utils'; +import { + testContractConditionObj, + testFunctionAbi, + testReturnValueTest, + testRpcConditionObj, +} from '../testVariables'; + +const web3Provider = fakeWeb3Provider(SecretKey.random().toBEBytes()); + +describe('serialization', () => { + it('serializes to json', async () => { + const rpcCondition = new RpcCondition({ + ...testRpcConditionObj, + parameters: [USER_ADDRESS_PARAM], + returnValueTest: { + index: 0, + comparator: '==', + value: USER_ADDRESS_PARAM, + }, + }); + const conditionContext = new ConditionExpression(rpcCondition).buildContext( + web3Provider + ); + const asJson = await conditionContext.toJson(); + expect(asJson).toBeDefined(); + expect(asJson).toContain(USER_ADDRESS_PARAM); + }); +}); + +describe('context parameters', () => { + const customParamKey = ':customParam'; + const customParams: Record = {}; + customParams[customParamKey] = 1234; + + const contractConditionObj = { + ...testContractConditionObj, + returnValueTest: { + ...testReturnValueTest, + value: customParamKey, + }, + }; + const contractCondition = new ContractCondition(contractConditionObj); + const conditionExpr = new ConditionExpression(contractCondition); + const conditionContext = conditionExpr.buildContext(web3Provider); + + describe('return value test', () => { + it('accepts on a custom context parameters', async () => { + const asObj = await conditionContext + .withCustomParams(customParams) + .toObj(); + expect(asObj).toBeDefined(); + expect(asObj[customParamKey]).toEqual(1234); + }); + + it('rejects on a missing custom context parameter', async () => { + await expect(conditionContext.toObj()).rejects.toThrow( + `Missing custom context parameter(s): ${customParamKey}` + ); + }); + }); + + it('rejects on using reserved context parameter', () => { + const badCustomParams: Record = {}; + RESERVED_CONTEXT_PARAMS.forEach((reservedParam) => { + badCustomParams[reservedParam] = 'this-will-throw'; + expect(() => conditionContext.withCustomParams(badCustomParams)).toThrow( + `Cannot use reserved parameter name ${reservedParam} as custom parameter` + ); + }); + }); + + describe('custom method parameters', () => { + const contractConditionObj = { + ...testContractConditionObj, + standardContractType: undefined, // We're going to use a custom function ABI + functionAbi: testFunctionAbi, + method: testFunctionAbi.name, + parameters: [USER_ADDRESS_PARAM, customParamKey], // We're going to use a custom parameter + returnValueTest: { + ...testReturnValueTest, + }, + }; + + it('rejects on a missing parameter ', async () => { + const customContractCondition = new ContractCondition({ + ...contractConditionObj, + parameters: [USER_ADDRESS_PARAM, customParamKey], + }); + const conditionContext = new ConditionExpression( + customContractCondition + ).buildContext(web3Provider); + + await expect(async () => conditionContext.toObj()).rejects.toThrow( + `Missing custom context parameter(s): ${customParamKey}` + ); + }); + + it('accepts on a hard-coded parameter', async () => { + const customContractCondition = new ContractCondition({ + ...contractConditionObj, + parameters: [USER_ADDRESS_PARAM, 100], + }); + const conditionContext = new ConditionExpression( + customContractCondition + ).buildContext(web3Provider); + + const asObj = await conditionContext.toObj(); + expect(asObj).toBeDefined(); + expect(asObj[USER_ADDRESS_PARAM]).toBeDefined(); + }); + }); +}); diff --git a/test/unit/pre-strategy.test.ts b/test/unit/pre-strategy.test.ts new file mode 100644 index 000000000..9fa599a22 --- /dev/null +++ b/test/unit/pre-strategy.test.ts @@ -0,0 +1,168 @@ +import { SecretKey, VerifiedKeyFrag } from '@nucypher/nucypher-core'; + +import { + conditions, + DeployedPreStrategy, + PreStrategy, + PreTDecDecrypter, +} from '../../src'; +import { Ursula } from '../../src/characters/porter'; +import { toBytes } from '../../src/utils'; +import { + fakeUrsulas, + fakeWeb3Provider, + makeCohort, + mockEncryptTreasureMap, + mockGenerateKFrags, + mockGetUrsulas, + mockMakeTreasureMap, + mockPublishToBlockchain, + mockRetrieveCFragsRequest, +} from '../utils'; + +import { aliceSecretKeyBytes, bobSecretKeyBytes } from './testVariables'; + +const { + predefined: { ERC721Ownership }, + ConditionExpression, +} = conditions; + +// Shared test variables +const aliceSecretKey = SecretKey.fromBEBytes(aliceSecretKeyBytes); +const bobSecretKey = SecretKey.fromBEBytes(bobSecretKeyBytes); +const aliceProvider = fakeWeb3Provider(aliceSecretKey.toBEBytes()); +const bobProvider = fakeWeb3Provider(bobSecretKey.toBEBytes()); +const ownsNFT = new ERC721Ownership({ + contractAddress: '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', + parameters: [3591], + chain: 5, +}); +const conditionExpr = new ConditionExpression(ownsNFT); +const mockedUrsulas = fakeUrsulas().slice(0, 3); + +const makePreStrategy = async () => { + const cohort = await makeCohort(mockedUrsulas); + const strategy = PreStrategy.create(cohort, aliceSecretKey, bobSecretKey); + expect(strategy.cohort).toEqual(cohort); + return strategy; +}; + +const makeDeployedPreStrategy = async () => { + const strategy = await makePreStrategy(); + const generateKFragsSpy = mockGenerateKFrags(); + const publishToBlockchainSpy = mockPublishToBlockchain(); + const makeTreasureMapSpy = mockMakeTreasureMap(); + const encryptTreasureMapSpy = mockEncryptTreasureMap(); + + const deployedStrategy = await strategy.deploy('test', aliceProvider); + + expect(generateKFragsSpy).toHaveBeenCalled(); + expect(publishToBlockchainSpy).toHaveBeenCalled(); + expect(makeTreasureMapSpy).toHaveBeenCalled(); + expect(encryptTreasureMapSpy).toHaveBeenCalled(); + + expect(deployedStrategy.cohort).toEqual(strategy.cohort); + + const ursulaAddresses = ( + makeTreasureMapSpy.mock.calls[0][0] as readonly Ursula[] + ).map((u) => u.checksumAddress); + const verifiedKFrags = makeTreasureMapSpy.mock + .calls[0][1] as readonly VerifiedKeyFrag[]; + + return { deployedStrategy, ursulaAddresses, verifiedKFrags }; +}; + +describe('PreStrategy', () => { + afterEach(() => { + jest.restoreAllMocks(); + }); + + it('creates a strategy', async () => { + await makePreStrategy(); + }); + + it('deploys a strategy', async () => { + await makeDeployedPreStrategy(); + }); + + describe('serialization', () => { + it('serializes to plain object', async () => { + const strategy = await makePreStrategy(); + const asObject = strategy.toObj(); + const fromObject = PreStrategy.fromObj(asObject); + expect(fromObject.equals(strategy)).toBeTruthy(); + }); + + it('serializes to JSON', async () => { + const strategy = await makePreStrategy(); + const asJson = strategy.toJSON(); + const fromJSON = PreStrategy.fromJSON(asJson); + expect(fromJSON.equals(strategy)).toBeTruthy(); + }); + }); +}); + +describe('PreDeployedStrategy', () => { + afterEach(() => { + jest.restoreAllMocks(); + }); + + it('encrypts and decrypts', async () => { + const { deployedStrategy, ursulaAddresses, verifiedKFrags } = + await makeDeployedPreStrategy(); + + const plaintext = 'this is a secret'; + const encryptedMessageKit = deployedStrategy + .makeEncrypter(conditionExpr) + .encryptMessagePre(plaintext); + + // Setup mocks for `retrieveAndDecrypt` + const getUrsulasSpy = mockGetUrsulas(mockedUrsulas); + const retrieveCFragsSpy = mockRetrieveCFragsRequest( + ursulaAddresses, + verifiedKFrags, + encryptedMessageKit.capsule + ); + + const decryptedMessage = + await deployedStrategy.decrypter.retrieveAndDecrypt( + [encryptedMessageKit], + bobProvider + ); + expect(getUrsulasSpy).toHaveBeenCalled(); + expect(retrieveCFragsSpy).toHaveBeenCalled(); + expect(decryptedMessage[0]).toEqual(toBytes(plaintext)); + }); + + describe('serialization', () => { + it('serializes to a plain object', async () => { + const { deployedStrategy } = await makeDeployedPreStrategy(); + const asObj = deployedStrategy.toObj(); + const fromJson = DeployedPreStrategy.fromObj(asObj); + expect(fromJson.equals(deployedStrategy)).toBeTruthy(); + }); + + it('serializes to a JSON', async () => { + const { deployedStrategy } = await makeDeployedPreStrategy(); + const asJson = deployedStrategy.toJSON(); + const fromJson = DeployedPreStrategy.fromJSON(asJson); + expect(fromJson.equals(deployedStrategy)).toBeTruthy(); + }); + }); +}); + +describe('PreTDecDecrypter', () => { + it('serializes to a plain object', async () => { + const { deployedStrategy } = await makeDeployedPreStrategy(); + const asObj = deployedStrategy.decrypter.toObj(); + const fromJson = PreTDecDecrypter.fromObj(asObj); + expect(fromJson.equals(deployedStrategy.decrypter)).toBeTruthy(); + }); + + it('serializes to JSON', async () => { + const { deployedStrategy } = await makeDeployedPreStrategy(); + const asJson = deployedStrategy.decrypter.toJSON(); + const fromJson = PreTDecDecrypter.fromJSON(asJson); + expect(fromJson.equals(deployedStrategy.decrypter)).toBeTruthy(); + }); +}); diff --git a/test/unit/ritual.test.ts b/test/unit/ritual.test.ts new file mode 100644 index 000000000..246c5a91f --- /dev/null +++ b/test/unit/ritual.test.ts @@ -0,0 +1,19 @@ +import { DkgPublicKey } from '@nucypher/nucypher-core'; + +import { fromHexString } from '../../src/utils'; + +describe('Ritual', () => { + it('deserializes pre-made dkg ritual', async () => { + const pkWord1 = fromHexString( + '9045795411ed251bf2eecc9415552c41863502a207104ef7ab482bc2364729d9' + ); + const pkWord2 = fromHexString('b99e2949cee8d888663b2995fc647fcf'); + + // We need to concat two words returned by the DKG contract + const dkgPkBytes = new Uint8Array([...pkWord1, ...pkWord2]); + expect(dkgPkBytes.length).toEqual(48); + + const dkgPk = DkgPublicKey.fromBytes(dkgPkBytes); + expect(dkgPk.toBytes()).toEqual(dkgPkBytes); + }); +}); diff --git a/test/unit/strategy.test.ts b/test/unit/strategy.test.ts deleted file mode 100644 index be450cc69..000000000 --- a/test/unit/strategy.test.ts +++ /dev/null @@ -1,240 +0,0 @@ -import { - EncryptedTreasureMap, - SecretKey, - VerifiedKeyFrag, -} from '@nucypher/nucypher-core'; - -import { - Cohort, - Conditions, - ConditionSet, - DeployedStrategy, - Strategy, - tDecDecrypter, -} from '../../src'; -import { Ursula } from '../../src/characters/porter'; -import { fromBase64, toBytes } from '../../src/utils'; -import { - mockEncryptTreasureMap, - mockGenerateKFrags, - mockGetUrsulas, - mockMakeTreasureMap, - mockPublishToBlockchain, - mockRetrieveCFragsRequest, - mockUrsulas, - mockWeb3Provider, -} from '../utils'; - -import { - aliceSecretKeyBytes, - bobSecretKeyBytes, - decrypterJSON, - deployedStrategyJSON, - encryptedTreasureMapBase64, - strategyJSON, -} from './testVariables'; - -describe('Strategy', () => { - const cohortConfig = { - threshold: 2, - shares: 3, - porterUri: 'https://_this.should.crash', - }; - const aliceSecretKey = SecretKey.fromBytes(aliceSecretKeyBytes); - const bobSecretKey = SecretKey.fromBytes(bobSecretKeyBytes); - const aliceProvider = mockWeb3Provider(aliceSecretKey.toSecretBytes()); - Date.now = jest.fn(() => 1487076708000); - - afterEach(() => { - jest.clearAllMocks(); - }); - - it('can create Strategy from configuration', async () => { - const mockedUrsulas = mockUrsulas().slice(0, 3); - const getUrsulasSpy = mockGetUrsulas(mockedUrsulas); - - const testCohort = await Cohort.create(cohortConfig); - const testStrategy = Strategy.create( - testCohort, - undefined, - aliceSecretKey, - bobSecretKey - ); - - const expectedUrsulas = [ - '0x5cf1703a1c99a4b42eb056535840e93118177232', - '0x7fff551249d223f723557a96a0e1a469c79cc934', - '0x9c7c824239d3159327024459ad69bb215859bd25', - ]; - expect(getUrsulasSpy).toHaveBeenCalled(); - expect(testStrategy.cohort.ursulaAddresses).toEqual(expectedUrsulas); - }); - - it('can export to JSON', async () => { - const testCohort = await Cohort.create(cohortConfig); - const testStrategy = Strategy.create( - testCohort, - undefined, - aliceSecretKey, - bobSecretKey - ); - - const configJSON = testStrategy.toJSON(); - expect(configJSON).toEqual(strategyJSON); - }); - - it('can import from JSON', async () => { - const testStrategy = Strategy.fromJSON(strategyJSON); - const expectedUrsulas = [ - '0x5cf1703a1c99a4b42eb056535840e93118177232', - '0x7fff551249d223f723557a96a0e1a469c79cc934', - '0x9c7c824239d3159327024459ad69bb215859bd25', - ]; - expect(testStrategy.cohort.ursulaAddresses).toEqual(expectedUrsulas); - }); - - it('can deploy and return DeployedStrategy', async () => { - const mockedUrsulas = mockUrsulas().slice(0, 3); - const getUrsulasSpy = mockGetUrsulas(mockedUrsulas); - const generateKFragsSpy = mockGenerateKFrags(); - const publishToBlockchainSpy = mockPublishToBlockchain(); - const makeTreasureMapSpy = mockMakeTreasureMap(); - const encryptTreasureMapSpy = mockEncryptTreasureMap(); - - const testCohort = await Cohort.create(cohortConfig); - const testStrategy = Strategy.create(testCohort, undefined, aliceSecretKey); - const testDeployed = await testStrategy.deploy('test', aliceProvider); - expect(getUrsulasSpy).toHaveBeenCalled(); - expect(generateKFragsSpy).toHaveBeenCalled(); - expect(publishToBlockchainSpy).toHaveBeenCalled(); - expect(encryptTreasureMapSpy).toHaveBeenCalled(); - expect(makeTreasureMapSpy).toHaveBeenCalled(); - - expect(testDeployed.label).toEqual('test'); - }); -}); - -describe('Deployed Strategy', () => { - const cohortConfig = { - threshold: 2, - shares: 3, - porterUri: 'https://_this.should.crash', - }; - const aliceSecretKey = SecretKey.fromBytes(aliceSecretKeyBytes); - const bobSecretKey = SecretKey.fromBytes(bobSecretKeyBytes); - - afterEach(() => { - jest.clearAllMocks(); - }); - - it('can export to JSON', async () => { - const aliceProvider = mockWeb3Provider(aliceSecretKey.toSecretBytes()); - const mockedUrsulas = mockUrsulas().slice(0, 3); - const getUrsulasSpy = mockGetUrsulas(mockedUrsulas); - const generateKFragsSpy = mockGenerateKFrags(); - const publishToBlockchainSpy = mockPublishToBlockchain(); - const makeTreasureMapSpy = mockMakeTreasureMap(); - const encryptTreasureMapSpy = mockEncryptTreasureMap( - EncryptedTreasureMap.fromBytes(fromBase64(encryptedTreasureMapBase64)) - ); - - const testCohort = await Cohort.create(cohortConfig); - const testStrategy = Strategy.create( - testCohort, - undefined, - aliceSecretKey, - bobSecretKey - ); - const testDeployed = await testStrategy.deploy('test', aliceProvider); - expect(getUrsulasSpy).toHaveBeenCalled(); - expect(generateKFragsSpy).toHaveBeenCalled(); - expect(publishToBlockchainSpy).toHaveBeenCalled(); - expect(makeTreasureMapSpy).toHaveBeenCalled(); - expect(encryptTreasureMapSpy).toHaveBeenCalled(); - - const configJSON = testDeployed.toJSON(); - expect(configJSON).toEqual(deployedStrategyJSON); - }); - - it('can import from JSON', async () => { - const importedStrategy = DeployedStrategy.fromJSON(deployedStrategyJSON); - const configJSON = importedStrategy.toJSON(); - expect(configJSON).toEqual(deployedStrategyJSON); - }); - - it('can encrypt and decrypt', async () => { - const aliceProvider = mockWeb3Provider(aliceSecretKey.toSecretBytes()); - const bobProvider = mockWeb3Provider(bobSecretKey.toSecretBytes()); - const mockedUrsulas = mockUrsulas().slice(0, 3); - const getUrsulasSpy = mockGetUrsulas(mockedUrsulas); - const generateKFragsSpy = mockGenerateKFrags(); - const publishToBlockchainSpy = mockPublishToBlockchain(); - const makeTreasureMapSpy = mockMakeTreasureMap(); - const encryptTreasureMapSpy = mockEncryptTreasureMap(); - - const testCohort = await Cohort.create(cohortConfig); - const testStrategy = Strategy.create( - testCohort, - undefined, - aliceSecretKey, - bobSecretKey - ); - const testDeployed = await testStrategy.deploy('test', aliceProvider); - - expect(getUrsulasSpy).toHaveBeenCalled(); - expect(generateKFragsSpy).toHaveBeenCalled(); - expect(publishToBlockchainSpy).toHaveBeenCalled(); - expect(encryptTreasureMapSpy).toHaveBeenCalled(); - expect(makeTreasureMapSpy).toHaveBeenCalled(); - - const encrypter = testDeployed.encrypter; - const decrypter = testDeployed.decrypter; - - const ownsNFT = new Conditions.ERC721Ownership({ - contractAddress: '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', - parameters: [3591], - chain: 5, - }); - - const plaintext = 'this is a secret'; - const conditions = new ConditionSet([ownsNFT]); - encrypter.conditions = conditions; - const encryptedMessageKit = encrypter.encryptMessage(plaintext); - // Setup mocks for `retrieveAndDecrypt` - const getUrsulasSpy2 = mockGetUrsulas(mockedUrsulas); - const ursulaAddresses = ( - makeTreasureMapSpy.mock.calls[0][0] as readonly Ursula[] - ).map((u) => u.checksumAddress); - const verifiedKFrags = makeTreasureMapSpy.mock - .calls[0][1] as readonly VerifiedKeyFrag[]; - const retrieveCFragsSpy = mockRetrieveCFragsRequest( - ursulaAddresses, - verifiedKFrags, - encryptedMessageKit.capsule - ); - - const decryptedMessage = await decrypter.retrieveAndDecrypt( - [encryptedMessageKit], - bobProvider - ); - expect(getUrsulasSpy2).toHaveBeenCalled(); - expect(retrieveCFragsSpy).toHaveBeenCalled(); - expect(decryptedMessage[0]).toEqual(toBytes(plaintext)); - }); -}); - -describe('tDecDecrypter', () => { - const importedStrategy = DeployedStrategy.fromJSON(deployedStrategyJSON); - - it('can export to JSON', () => { - const decrypter = importedStrategy.decrypter; - const configJSON = decrypter.toJSON(); - expect(configJSON).toEqual(decrypterJSON); - }); - - it('can import from JSON', () => { - const decrypter = tDecDecrypter.fromJSON(decrypterJSON); - const configJSON = decrypter.toJSON(); - expect(configJSON).toEqual(decrypterJSON); - }); -}); diff --git a/test/unit/testVariables.ts b/test/unit/testVariables.ts index 643c853c9..ef943513a 100644 --- a/test/unit/testVariables.ts +++ b/test/unit/testVariables.ts @@ -1,12 +1,3 @@ -export const strategyJSON = - '{"cohort":{"ursulaAddresses":["0x5cf1703a1c99a4b42eb056535840e93118177232","0x7fff551249d223f723557a96a0e1a469c79cc934","0x9c7c824239d3159327024459ad69bb215859bd25"],"threshold":2,"shares":3,"porterUri":"https://_this.should.crash"},"aliceSecretKeyBytes":"base64:N1K+vcukPJQkVi57P5jXca5W9CwX48VEBVV0H9CYWDU=","bobSecretKeyBytes":"base64:dOs3NGmtXJMdjVMaXf3/m5PlAmqwzSGoF9XpyO4LwZk=","startDate":"2017-02-14T12:51:48.000Z","endDate":"2017-03-16T12:51:48.000Z"}'; - -export const encryptedTreasureMapBase64 = - 'RU1hcAABAACSxGIDdzg9r81RRC+kQGy0C0s8LdQXwcDf+MJtuJ9+i3Zp+bICp+WRepaHInVIh7O3hiiz0Frs4Xr7sct2nNaXHrbFLgzKHdNnmhg7EIpPWs2HUJMjwh4Ny0rKVyx2/Ilvh24t5sUGtg2tnZKEMnf1Z9E8wIEv1itZmsjjXmnlrshHxPdQ/1cJneXIU+ch+n7t+BJQkOJSfLE74++KZJ+mUnPpCh8QWssHeeGNBeB2oB9CtpmcBzDoLdJJClTVte4OmADofiQ6RJswQfGCM6Gw21rJOqm5q7/6jaR47gvMlu/A94Y3WkiUAFbaGcr4vQzeAflRsR0N9LPfKIIqHfajWNCEagp0GgoaG6DsQVeEnaL7z+meg8HeQdO+m09OFh4b8Ic0m2BtYSscrlUBlU5JWrxKtLjPuxBTIQyX8FQV6gYnLyzkAEBAOgPgjuwHsTZeFUatTDYYhA/Y2hlfdmLeYW5pZ74/+uNJBof/9QB1beCn+TfrTbVyjGADn2JU8NwhnsNdDM3XFQy6WUoHLrnTs4lYj16unC7Ir6DnI6UXj84ixjli2ge8wgHpZkmQJKrMc1HvfDlM3TWG18rvEB0fE70sSMGhhegp/cjh52C3eTUACaEkO127r1kF/NjCDtbOsk9CnD2mwGyOMdr17B5TojWINwJ0SsT9gCgnZjEuxbX45NAr+M+Nz4TwbPF8ap67mj3dbGvuokNHsBfjn8YCRAIDgP83SYnR/Y4VqqKL7uzRbfmu2ljCkTohe9rJUNhwaVYpl0PODuVZQo1jAmSBZ9/HzVNbkqGwiTAtjz5CHXW7oKl8SwXiBUHXXOu0jvi8RgOP9BZeoL48sFLiSWDIxI2XAxEEuaD16vgvvthl0mxklP7R5p7vvAfAdP/lNCy28B5r7PPsXh6MmYyyaObetm2HzcJhB3sijfXHM5iEoQ41PKXRTRxrgAw1eVAjOnNW3Ld9LJEOqB6hh/U3UYUPhrXkk4kdc7EAm4gTMbq5wmEsZQRnWIn5IsBEAMFlh3z6PvtrcuwRJkIwQSF96Ai0kE776e9pjsiuEUyZFyn4wRTfg2mxdteiC4vKTBxh2BJNVxzRONtTMgcZ0JHZpCf/ZRct2Bke8F4eWn+AmtYDQEdASHnJQtjQPe5Fl5LoePZ1uIVaKgWywz6pV4zvX4hBAZ2gK/wo8hzJNRtAaKoAr8FQxG9HUlY2htZmCtI60m2a2y8Vj3IKTa2X/2PqB/OnuZEq18FCve91TmKqghCHqteB1ON6dMl+1XK4WpTlyELbha6cni8er2w4dDO+P6e40lWzQJKUlfyYfCoB8uRDCLw82a58kG80dYGZFZAmGhqItL9RC6Ofm2TBq0F+jfdSS3DVxrJG5AldhuKbIK73ojAaLV8FVjRyT6uwo6M4JAj12krCgbvOXUaHM3jT08ZFmOI0ldmzG/I6I73LHEGm7Hey6a+K4ry5EiXA+KgLMNA8pct6HihOKBws7ckClqYOos6nAyUkABpbASdfmyat8jtUNyIXprEtZr4wvB/2E011cf9EsnIVhEovpPmvMp7IdgID0Qxs219MFFr7sJ5XjHeOINA4jb6gh5r5uQzuYtpmxv7ppi8fs/x0co8pOsgHDfy4zRGDys/Z9f/QrEB6VHms9xh7Kwpp3HLAtCcEAkCg+AsnC++6VMwWwvcLbjfE2uIYsVJJ+ciX7rSYZyDzC0IayyqNJLgS30li1xPb2u5YHMA+2vzSQGx9Zae2QSXFwDQ5Qui94RfQP//x6pqZuutXI8fqGDey50DYtPYd8J6AiKcoOPBivqSTMXj2Nb9FItbDm5DYTRM7CmQkmbYLR+/hord5AFSYauEB3zsqME3vD3mBY5OvWfPqnSpUUGe2RTF+u3mtmcfptaO9fwWSr6ckBwBMB42DuoyXVuYsdXA6WCtqCjQGqCBG0qsvOJFA3Rd2q5cy4Q+V537LlOJAkhSu/9/1WDma7JbELCSq5fCl9hOVJ96c8CfJacSVhNM4LRT71qDEf9wI2AVQrjYeMGdSXDEtidXyz1oPZpCoc8mPALPLOvgwBhLYK175NteQ9GQ+9ySMI1NWBbv/FP1jwKrFtT46FdFQHKv8xc/z29muPNPmgev3ht1tvPzrrvyCtQLdASaaHTc1FlZcMlYopgOxvz8q3MUki0wjwpVudTSaowf8Bfduj3r6TSPo11+k97P49fy3LLxOsTrvVaetD0rNIs704MI0/DmNZd0FkqyX6JzFILUCZunK9azQoJX9vr9BzsQJ2r3vmlSYNA+n9C2+YIcZqE7nHjO38XTbnfCcrZvWohBZ+Q9gDWPD7Y378w3OgIrkzNEUJhFHCahLVj41l3Y3HIMI8GM98uejNjEVZLW6NEMrjhGh+aimmvgFCAIJYXFMFe8oSfeFRQBQnvOc0y+XJl5Mbm6g5oKp'; - -export const deployedStrategyJSON = - '{"policy":{"id":"base64:tKuR/HipMeU4trCdytbZCQ==","label":"test","policyKey":"base64:A/u/2+G8Hn0UPwRZqVfa41XiT/6W2+98dotTob7xKg5C","encryptedTreasureMap":"base64:RU1hcAABAACSxGIDdzg9r81RRC+kQGy0C0s8LdQXwcDf+MJtuJ9+i3Zp+bICp+WRepaHInVIh7O3hiiz0Frs4Xr7sct2nNaXHrbFLgzKHdNnmhg7EIpPWs2HUJMjwh4Ny0rKVyx2/Ilvh24t5sUGtg2tnZKEMnf1Z9E8wIEv1itZmsjjXmnlrshHxPdQ/1cJneXIU+ch+n7t+BJQkOJSfLE74++KZJ+mUnPpCh8QWssHeeGNBeB2oB9CtpmcBzDoLdJJClTVte4OmADofiQ6RJswQfGCM6Gw21rJOqm5q7/6jaR47gvMlu/A94Y3WkiUAFbaGcr4vQzeAflRsR0N9LPfKIIqHfajWNCEagp0GgoaG6DsQVeEnaL7z+meg8HeQdO+m09OFh4b8Ic0m2BtYSscrlUBlU5JWrxKtLjPuxBTIQyX8FQV6gYnLyzkAEBAOgPgjuwHsTZeFUatTDYYhA/Y2hlfdmLeYW5pZ74/+uNJBof/9QB1beCn+TfrTbVyjGADn2JU8NwhnsNdDM3XFQy6WUoHLrnTs4lYj16unC7Ir6DnI6UXj84ixjli2ge8wgHpZkmQJKrMc1HvfDlM3TWG18rvEB0fE70sSMGhhegp/cjh52C3eTUACaEkO127r1kF/NjCDtbOsk9CnD2mwGyOMdr17B5TojWINwJ0SsT9gCgnZjEuxbX45NAr+M+Nz4TwbPF8ap67mj3dbGvuokNHsBfjn8YCRAIDgP83SYnR/Y4VqqKL7uzRbfmu2ljCkTohe9rJUNhwaVYpl0PODuVZQo1jAmSBZ9/HzVNbkqGwiTAtjz5CHXW7oKl8SwXiBUHXXOu0jvi8RgOP9BZeoL48sFLiSWDIxI2XAxEEuaD16vgvvthl0mxklP7R5p7vvAfAdP/lNCy28B5r7PPsXh6MmYyyaObetm2HzcJhB3sijfXHM5iEoQ41PKXRTRxrgAw1eVAjOnNW3Ld9LJEOqB6hh/U3UYUPhrXkk4kdc7EAm4gTMbq5wmEsZQRnWIn5IsBEAMFlh3z6PvtrcuwRJkIwQSF96Ai0kE776e9pjsiuEUyZFyn4wRTfg2mxdteiC4vKTBxh2BJNVxzRONtTMgcZ0JHZpCf/ZRct2Bke8F4eWn+AmtYDQEdASHnJQtjQPe5Fl5LoePZ1uIVaKgWywz6pV4zvX4hBAZ2gK/wo8hzJNRtAaKoAr8FQxG9HUlY2htZmCtI60m2a2y8Vj3IKTa2X/2PqB/OnuZEq18FCve91TmKqghCHqteB1ON6dMl+1XK4WpTlyELbha6cni8er2w4dDO+P6e40lWzQJKUlfyYfCoB8uRDCLw82a58kG80dYGZFZAmGhqItL9RC6Ofm2TBq0F+jfdSS3DVxrJG5AldhuKbIK73ojAaLV8FVjRyT6uwo6M4JAj12krCgbvOXUaHM3jT08ZFmOI0ldmzG/I6I73LHEGm7Hey6a+K4ry5EiXA+KgLMNA8pct6HihOKBws7ckClqYOos6nAyUkABpbASdfmyat8jtUNyIXprEtZr4wvB/2E011cf9EsnIVhEovpPmvMp7IdgID0Qxs219MFFr7sJ5XjHeOINA4jb6gh5r5uQzuYtpmxv7ppi8fs/x0co8pOsgHDfy4zRGDys/Z9f/QrEB6VHms9xh7Kwpp3HLAtCcEAkCg+AsnC++6VMwWwvcLbjfE2uIYsVJJ+ciX7rSYZyDzC0IayyqNJLgS30li1xPb2u5YHMA+2vzSQGx9Zae2QSXFwDQ5Qui94RfQP//x6pqZuutXI8fqGDey50DYtPYd8J6AiKcoOPBivqSTMXj2Nb9FItbDm5DYTRM7CmQkmbYLR+/hord5AFSYauEB3zsqME3vD3mBY5OvWfPqnSpUUGe2RTF+u3mtmcfptaO9fwWSr6ckBwBMB42DuoyXVuYsdXA6WCtqCjQGqCBG0qsvOJFA3Rd2q5cy4Q+V537LlOJAkhSu/9/1WDma7JbELCSq5fCl9hOVJ96c8CfJacSVhNM4LRT71qDEf9wI2AVQrjYeMGdSXDEtidXyz1oPZpCoc8mPALPLOvgwBhLYK175NteQ9GQ+9ySMI1NWBbv/FP1jwKrFtT46FdFQHKv8xc/z29muPNPmgev3ht1tvPzrrvyCtQLdASaaHTc1FlZcMlYopgOxvz8q3MUki0wjwpVudTSaowf8Bfduj3r6TSPo11+k97P49fy3LLxOsTrvVaetD0rNIs704MI0/DmNZd0FkqyX6JzFILUCZunK9azQoJX9vr9BzsQJ2r3vmlSYNA+n9C2+YIcZqE7nHjO38XTbnfCcrZvWohBZ+Q9gDWPD7Y378w3OgIrkzNEUJhFHCahLVj41l3Y3HIMI8GM98uejNjEVZLW6NEMrjhGh+aimmvgFCAIJYXFMFe8oSfeFRQBQnvOc0y+XJl5Mbm6g5oKp","aliceVerifyingKey":"base64:A3yU8aavNj4LJ97eFAaYpU97q70oSogzBZAlo5tj/1Kj","size":3,"startTimestamp":"2017-02-14T12:51:48.000Z","endTimestamp":"2017-03-16T12:51:48.000Z","txHash":"0x1234567890123456789012345678901234567890"},"cohortConfig":{"ursulaAddresses":["0x5cf1703a1c99a4b42eb056535840e93118177232","0x7fff551249d223f723557a96a0e1a469c79cc934","0x9c7c824239d3159327024459ad69bb215859bd25"],"threshold":2,"shares":3,"porterUri":"https://_this.should.crash"},"bobSecretKeyBytes":"base64:dOs3NGmtXJMdjVMaXf3/m5PlAmqwzSGoF9XpyO4LwZk="}'; - export const aliceSecretKeyBytes = new Uint8Array([ 55, 82, 190, 189, 203, 164, 60, 148, 36, 86, 46, 123, 63, 152, 215, 113, 174, 86, 244, 44, 23, 227, 197, 68, 5, 85, 116, 31, 208, 152, 88, 53, @@ -17,5 +8,64 @@ export const bobSecretKeyBytes = new Uint8Array([ 229, 2, 106, 176, 205, 33, 168, 23, 213, 233, 200, 238, 11, 193, 153, ]); -export const decrypterJSON = - '{"porterUri":"https://_this.should.crash/","policyEncryptingKeyBytes":"base64:A/u/2+G8Hn0UPwRZqVfa41XiT/6W2+98dotTob7xKg5C","encryptedTreasureMapBytes":"base64:RU1hcAABAACSxGIDdzg9r81RRC+kQGy0C0s8LdQXwcDf+MJtuJ9+i3Zp+bICp+WRepaHInVIh7O3hiiz0Frs4Xr7sct2nNaXHrbFLgzKHdNnmhg7EIpPWs2HUJMjwh4Ny0rKVyx2/Ilvh24t5sUGtg2tnZKEMnf1Z9E8wIEv1itZmsjjXmnlrshHxPdQ/1cJneXIU+ch+n7t+BJQkOJSfLE74++KZJ+mUnPpCh8QWssHeeGNBeB2oB9CtpmcBzDoLdJJClTVte4OmADofiQ6RJswQfGCM6Gw21rJOqm5q7/6jaR47gvMlu/A94Y3WkiUAFbaGcr4vQzeAflRsR0N9LPfKIIqHfajWNCEagp0GgoaG6DsQVeEnaL7z+meg8HeQdO+m09OFh4b8Ic0m2BtYSscrlUBlU5JWrxKtLjPuxBTIQyX8FQV6gYnLyzkAEBAOgPgjuwHsTZeFUatTDYYhA/Y2hlfdmLeYW5pZ74/+uNJBof/9QB1beCn+TfrTbVyjGADn2JU8NwhnsNdDM3XFQy6WUoHLrnTs4lYj16unC7Ir6DnI6UXj84ixjli2ge8wgHpZkmQJKrMc1HvfDlM3TWG18rvEB0fE70sSMGhhegp/cjh52C3eTUACaEkO127r1kF/NjCDtbOsk9CnD2mwGyOMdr17B5TojWINwJ0SsT9gCgnZjEuxbX45NAr+M+Nz4TwbPF8ap67mj3dbGvuokNHsBfjn8YCRAIDgP83SYnR/Y4VqqKL7uzRbfmu2ljCkTohe9rJUNhwaVYpl0PODuVZQo1jAmSBZ9/HzVNbkqGwiTAtjz5CHXW7oKl8SwXiBUHXXOu0jvi8RgOP9BZeoL48sFLiSWDIxI2XAxEEuaD16vgvvthl0mxklP7R5p7vvAfAdP/lNCy28B5r7PPsXh6MmYyyaObetm2HzcJhB3sijfXHM5iEoQ41PKXRTRxrgAw1eVAjOnNW3Ld9LJEOqB6hh/U3UYUPhrXkk4kdc7EAm4gTMbq5wmEsZQRnWIn5IsBEAMFlh3z6PvtrcuwRJkIwQSF96Ai0kE776e9pjsiuEUyZFyn4wRTfg2mxdteiC4vKTBxh2BJNVxzRONtTMgcZ0JHZpCf/ZRct2Bke8F4eWn+AmtYDQEdASHnJQtjQPe5Fl5LoePZ1uIVaKgWywz6pV4zvX4hBAZ2gK/wo8hzJNRtAaKoAr8FQxG9HUlY2htZmCtI60m2a2y8Vj3IKTa2X/2PqB/OnuZEq18FCve91TmKqghCHqteB1ON6dMl+1XK4WpTlyELbha6cni8er2w4dDO+P6e40lWzQJKUlfyYfCoB8uRDCLw82a58kG80dYGZFZAmGhqItL9RC6Ofm2TBq0F+jfdSS3DVxrJG5AldhuKbIK73ojAaLV8FVjRyT6uwo6M4JAj12krCgbvOXUaHM3jT08ZFmOI0ldmzG/I6I73LHEGm7Hey6a+K4ry5EiXA+KgLMNA8pct6HihOKBws7ckClqYOos6nAyUkABpbASdfmyat8jtUNyIXprEtZr4wvB/2E011cf9EsnIVhEovpPmvMp7IdgID0Qxs219MFFr7sJ5XjHeOINA4jb6gh5r5uQzuYtpmxv7ppi8fs/x0co8pOsgHDfy4zRGDys/Z9f/QrEB6VHms9xh7Kwpp3HLAtCcEAkCg+AsnC++6VMwWwvcLbjfE2uIYsVJJ+ciX7rSYZyDzC0IayyqNJLgS30li1xPb2u5YHMA+2vzSQGx9Zae2QSXFwDQ5Qui94RfQP//x6pqZuutXI8fqGDey50DYtPYd8J6AiKcoOPBivqSTMXj2Nb9FItbDm5DYTRM7CmQkmbYLR+/hord5AFSYauEB3zsqME3vD3mBY5OvWfPqnSpUUGe2RTF+u3mtmcfptaO9fwWSr6ckBwBMB42DuoyXVuYsdXA6WCtqCjQGqCBG0qsvOJFA3Rd2q5cy4Q+V537LlOJAkhSu/9/1WDma7JbELCSq5fCl9hOVJ96c8CfJacSVhNM4LRT71qDEf9wI2AVQrjYeMGdSXDEtidXyz1oPZpCoc8mPALPLOvgwBhLYK175NteQ9GQ+9ySMI1NWBbv/FP1jwKrFtT46FdFQHKv8xc/z29muPNPmgev3ht1tvPzrrvyCtQLdASaaHTc1FlZcMlYopgOxvz8q3MUki0wjwpVudTSaowf8Bfduj3r6TSPo11+k97P49fy3LLxOsTrvVaetD0rNIs704MI0/DmNZd0FkqyX6JzFILUCZunK9azQoJX9vr9BzsQJ2r3vmlSYNA+n9C2+YIcZqE7nHjO38XTbnfCcrZvWohBZ+Q9gDWPD7Y378w3OgIrkzNEUJhFHCahLVj41l3Y3HIMI8GM98uejNjEVZLW6NEMrjhGh+aimmvgFCAIJYXFMFe8oSfeFRQBQnvOc0y+XJl5Mbm6g5oKp","publisherVerifyingKeyBytes":"base64:A3yU8aavNj4LJ97eFAaYpU97q70oSogzBZAlo5tj/1Kj","bobSecretKeyBytes":"base64:dOs3NGmtXJMdjVMaXf3/m5PlAmqwzSGoF9XpyO4LwZk="}'; +export const TEST_CONTRACT_ADDR = '0x0000000000000000000000000000000000000001'; +export const TEST_CONTRACT_ADDR_2 = + '0x0000000000000000000000000000000000000002'; +export const TEST_CHAIN_ID = 5; + +export const testReturnValueTest = { + index: 0, + comparator: '>', + value: '100', +}; + +export const testTimeConditionObj = { + returnValueTest: { + index: 0, + comparator: '>', + value: '100', + }, + method: 'blocktime', + chain: 5, +}; + +export const testRpcConditionObj = { + chain: TEST_CHAIN_ID, + method: 'eth_getBalance', + parameters: ['0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77'], + returnValueTest: testReturnValueTest, +}; + +export const testContractConditionObj = { + contractAddress: '0x0000000000000000000000000000000000000000', + chain: 5, + standardContractType: 'ERC20', + method: 'balanceOf', + parameters: ['0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77'], + returnValueTest: testReturnValueTest, +}; + +export const testFunctionAbi = { + name: 'myFunction', + type: 'function', + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'uint256', + name: 'myCustomParam', + type: 'uint256', + }, + ], + outputs: [ + { + internalType: 'uint256', + name: 'someValue', + type: 'uint256', + }, + ], + stateMutability: 'view', +}; diff --git a/test/utils.ts b/test/utils.ts index c27b5da7b..b79ca46d6 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -5,56 +5,83 @@ import { Block } from '@ethersproject/providers'; import { Capsule, CapsuleFrag, + EncryptedThresholdDecryptionResponse, EncryptedTreasureMap, + ferveoEncrypt, + PublicKey, reencrypt, SecretKey, + SessionSecretFactory, + SessionStaticKey, + SessionStaticSecret, + ThresholdDecryptionResponse, VerifiedCapsuleFrag, VerifiedKeyFrag, } from '@nucypher/nucypher-core'; +import { + AggregatedTranscript, + Ciphertext, + combineDecryptionSharesPrecomputed, + combineDecryptionSharesSimple, + DecryptionSharePrecomputed, + DecryptionShareSimple, + decryptWithSharedSecret, + Dkg, + EthereumAddress, + Keypair, + Transcript, + Validator, + ValidatorMessage, +} from '@nucypher/nucypher-core'; import axios from 'axios'; import { ethers, providers, Wallet } from 'ethers'; +import { keccak256 } from 'ethers/lib/utils'; -import { Alice, Bob, Configuration, RemoteBob } from '../src'; +import { Alice, Bob, Cohort, Configuration, RemoteBob } from '../src'; +import { DkgCoordinatorAgent, DkgParticipant } from '../src/agents/coordinator'; +import { CbdTDecDecrypter } from '../src/characters/cbd-recipient'; import { - GetUrsulasResponse, + CbdDecryptResult, + GetUrsulasResult, Porter, - RetrieveCFragsResponse, + RetrieveCFragsResult, Ursula, } from '../src/characters/porter'; +import { DkgClient, DkgRitual, FerveoVariant } from '../src/dkg'; import { BlockchainPolicy, PreEnactedPolicy } from '../src/policies/policy'; import { ChecksumAddress } from '../src/types'; import { toBytes, toHexString, zip } from '../src/utils'; -export const fromBytes = (bytes: Uint8Array): string => - new TextDecoder().decode(bytes); - export const bytesEqual = (first: Uint8Array, second: Uint8Array): boolean => first.length === second.length && first.every((value, index) => value === second[index]); +export const fromBytes = (bytes: Uint8Array): string => + new TextDecoder().decode(bytes); + const mockConfig: Configuration = { porterUri: 'https://_this_should_crash.com/', }; -export const mockBob = (): Bob => { - const secretKey = SecretKey.fromBytes( +export const fakeBob = (): Bob => { + const secretKey = SecretKey.fromBEBytes( toBytes('fake-secret-key-32-bytes-bob-xxx') ); return Bob.fromSecretKey(mockConfig, secretKey); }; -export const mockRemoteBob = (): RemoteBob => { - const { decryptingKey, verifyingKey } = mockBob(); +export const fakeRemoteBob = (): RemoteBob => { + const { decryptingKey, verifyingKey } = fakeBob(); return RemoteBob.fromKeys(decryptingKey, verifyingKey); }; -export const mockAlice = (aliceKey = 'fake-secret-key-32-bytes-alice-x') => { - const secretKey = SecretKey.fromBytes(toBytes(aliceKey)); - const provider = mockWeb3Provider(secretKey.toSecretBytes()); +export const fakeAlice = (aliceKey = 'fake-secret-key-32-bytes-alice-x') => { + const secretKey = SecretKey.fromBEBytes(toBytes(aliceKey)); + const provider = fakeWeb3Provider(secretKey.toBEBytes()); return Alice.fromSecretKey(mockConfig, secretKey, provider); }; -export const mockWeb3Provider = ( +export const fakeWeb3Provider = ( secretKeyBytes: Uint8Array, blockNumber?: number, blockTimestamp?: number @@ -65,7 +92,6 @@ export const mockWeb3Provider = ( getBlock: () => Promise.resolve(block as Block), _isProvider: true, getNetwork: () => Promise.resolve({ name: 'mockNetwork', chainId: -1 }), - request: () => '', }; const fakeSignerWithProvider = { ...new Wallet(secretKeyBytes), @@ -80,50 +106,25 @@ export const mockWeb3Provider = ( } as unknown as ethers.providers.Web3Provider; }; -export const mockUrsulas = (): readonly Ursula[] => { - return [ - { - encryptingKey: SecretKey.random().publicKey(), - checksumAddress: '0x5cF1703A1c99A4b42Eb056535840e93118177232', - uri: 'https://example.a.com:9151', - }, - { - encryptingKey: SecretKey.random().publicKey(), - checksumAddress: '0x7fff551249D223f723557a96a0e1a469C79cC934', - uri: 'https://example.b.com:9151', - }, - { - encryptingKey: SecretKey.random().publicKey(), - checksumAddress: '0x9C7C824239D3159327024459Ad69bB215859Bd25', - uri: 'https://example.c.com:9151', - }, - { - encryptingKey: SecretKey.random().publicKey(), - checksumAddress: '0x9919C9f5CbBAA42CB3bEA153E14E16F85fEA5b5D', - uri: 'https://example.d.com:9151', - }, - { - encryptingKey: SecretKey.random().publicKey(), - checksumAddress: '0xfBeb3368735B3F0A65d1F1E02bf1d188bb5F5BE6', - uri: 'https://example.e.com:9151', - }, - ].map(({ encryptingKey, checksumAddress, uri }) => { - return { - checksumAddress: checksumAddress.toLowerCase(), - encryptingKey, - uri, - }; - }); -}; +const genChecksumAddress = (i: number) => + '0x' + '0'.repeat(40 - i.toString(16).length) + i.toString(16); +const genEthAddr = (i: number) => + EthereumAddress.fromString(genChecksumAddress(i)); +export const fakeUrsulas = (): readonly Ursula[] => + [0, 1, 2, 3, 4].map((i: number) => ({ + encryptingKey: SecretKey.random().publicKey(), + checksumAddress: genChecksumAddress(i).toLowerCase(), + uri: 'https://example.a.com:9151', + })); export const mockGetUrsulas = (ursulas: readonly Ursula[]) => { - const mockPorterUrsulas = ( + const fakePorterUrsulas = ( mockUrsulas: readonly Ursula[] - ): GetUrsulasResponse => { + ): GetUrsulasResult => { return { result: { ursulas: mockUrsulas.map(({ encryptingKey, uri, checksumAddress }) => ({ - encrypting_key: toHexString(encryptingKey.toBytes()), + encrypting_key: toHexString(encryptingKey.toCompressedBytes()), uri: uri, checksum_address: checksumAddress, })), @@ -133,7 +134,7 @@ export const mockGetUrsulas = (ursulas: readonly Ursula[]) => { }; return jest.spyOn(axios, 'get').mockImplementation(async () => { - return Promise.resolve({ data: mockPorterUrsulas(ursulas) }); + return Promise.resolve({ data: fakePorterUrsulas(ursulas) }); }); }; export const mockPublishToBlockchain = () => { @@ -143,16 +144,11 @@ export const mockPublishToBlockchain = () => { .mockImplementation(async () => Promise.resolve(txHash)); }; -export const mockCFragResponse = ( +const fakeCFragResponse = ( ursulas: readonly ChecksumAddress[], verifiedKFrags: readonly VerifiedKeyFrag[], capsule: Capsule -): readonly RetrieveCFragsResponse[] => { - if (ursulas.length !== verifiedKFrags.length) { - throw new Error( - 'Number of verifiedKFrags must match the number of Ursulas' - ); - } +): readonly RetrieveCFragsResult[] => { const reencrypted = verifiedKFrags .map((kFrag) => reencrypt(capsule, kFrag)) .map((cFrag) => CapsuleFrag.fromBytes(cFrag.toBytes())); @@ -165,22 +161,22 @@ export const mockRetrieveCFragsRequest = ( verifiedKFrags: readonly VerifiedKeyFrag[], capsule: Capsule ) => { - const results = mockCFragResponse(ursulas, verifiedKFrags, capsule); + const results = fakeCFragResponse(ursulas, verifiedKFrags, capsule); return jest .spyOn(Porter.prototype, 'retrieveCFrags') .mockImplementation(() => { return Promise.resolve(results); }); }; - -export const mockRetrieveCFragsRequestThrows = () => { - return jest - .spyOn(Porter.prototype, 'retrieveCFrags') - .mockRejectedValue(new Error('fake-reencryption-request-failed-error')); -}; - -export const mockGenerateKFrags = () => { - return jest.spyOn(Alice.prototype as any, 'generateKFrags'); +export const mockGenerateKFrags = (withValue?: { + delegatingKey: PublicKey; + verifiedKFrags: VerifiedKeyFrag[]; +}) => { + const spy = jest.spyOn(Alice.prototype as any, 'generateKFrags'); + if (withValue) { + return spy.mockImplementation(() => withValue); + } + return spy; }; export const mockEncryptTreasureMap = (withValue?: EncryptedTreasureMap) => { @@ -216,3 +212,310 @@ export const mockDetectEthereumProvider = () => { return {} as unknown as providers.ExternalProvider; }); }; + +export const fakeDkgFlow = ( + variant: FerveoVariant | FerveoVariant.Precomputed, + ritualId: number, + sharesNum: number, + threshold: number +) => { + if ( + variant !== FerveoVariant.Simple && + variant !== FerveoVariant.Precomputed + ) { + throw new Error(`Invalid variant: ${variant}`); + } + const validatorKeypairs: Keypair[] = []; + const validators: Validator[] = []; + for (let i = 0; i < sharesNum; i++) { + const keypair = Keypair.random(); + validatorKeypairs.push(keypair); + const validator = new Validator(genEthAddr(i), keypair.publicKey); + validators.push(validator); + } + + // Each validator holds their own DKG instance and generates a transcript every + // validator, including themselves + const messages: ValidatorMessage[] = []; + const transcripts: Transcript[] = []; + validators.forEach((sender) => { + const dkg = new Dkg(ritualId, sharesNum, threshold, validators, sender); + const transcript = dkg.generateTranscript(); + transcripts.push(transcript); + const message = new ValidatorMessage(sender, transcript); + messages.push(message); + }); + + // Now that every validator holds a dkg instance and a transcript for every other validator, + // every validator can aggregate the transcripts + const dkg = new Dkg( + ritualId, + sharesNum, + threshold, + validators, + validators[0] + ); + + // Let's say that we've only received `threshold` transcripts + const receivedMessages = messages.slice(0, threshold); + + const serverAggregate = dkg.aggregateTranscript(receivedMessages); + expect(serverAggregate.verify(sharesNum, receivedMessages)).toBeTruthy(); + + // Client can also aggregate the transcripts and verify them + const clientAggregate = new AggregatedTranscript(receivedMessages); + expect(clientAggregate.verify(sharesNum, receivedMessages)).toBeTruthy(); + return { + ritualId, + sharesNum, + threshold, + validatorKeypairs, + validators, + transcripts, + dkg, + receivedMessages, + serverAggregate, + }; +}; + +interface FakeDkgRitualFlow { + validators: Validator[]; + validatorKeypairs: Keypair[]; + ritualId: number; + sharesNum: number; + threshold: number; + receivedMessages: ValidatorMessage[]; + variant: FerveoVariant; + ciphertext: Ciphertext; + aad: Uint8Array; + dkg: Dkg; + message: Uint8Array; +} + +export const fakeTDecFlow = ({ + validators, + validatorKeypairs, + ritualId, + sharesNum, + threshold, + receivedMessages, + variant, + ciphertext, + aad, + message, +}: FakeDkgRitualFlow) => { + // Having aggregated the transcripts, the validators can now create decryption shares + const decryptionShares: ( + | DecryptionSharePrecomputed + | DecryptionShareSimple + )[] = []; + zip(validators, validatorKeypairs).forEach(([validator, keypair]) => { + const dkg = new Dkg(ritualId, sharesNum, threshold, validators, validator); + const aggregate = dkg.aggregateTranscript(receivedMessages); + const isValid = aggregate.verify(sharesNum, receivedMessages); + if (!isValid) { + throw new Error('Transcript is invalid'); + } + + let decryptionShare; + if (variant === FerveoVariant.Precomputed) { + decryptionShare = aggregate.createDecryptionSharePrecomputed( + dkg, + ciphertext, + aad, + keypair + ); + } else { + decryptionShare = aggregate.createDecryptionShareSimple( + dkg, + ciphertext, + aad, + keypair + ); + } + decryptionShares.push(decryptionShare); + }); + + // Now, the decryption share can be used to decrypt the ciphertext + // This part is in the client API + + let sharedSecret; + if (variant === FerveoVariant.Precomputed) { + sharedSecret = combineDecryptionSharesPrecomputed(decryptionShares); + } else { + sharedSecret = combineDecryptionSharesSimple(decryptionShares); + } + + // The client should have access to the public parameters of the DKG + const plaintext = decryptWithSharedSecret(ciphertext, aad, sharedSecret); + if (!bytesEqual(plaintext, message)) { + throw new Error('Decryption failed'); + } + return { decryptionShares, sharedSecret, plaintext }; +}; + +export const fakeDkgTDecFlowE2e = ( + variant: FerveoVariant, + message = toBytes('fake-message'), + aad = toBytes('fake-aad'), + ritualId = 0, + sharesNum = 4, + threshold = 4 +) => { + const ritual = fakeDkgFlow(variant, ritualId, sharesNum, threshold); + + // In the meantime, the client creates a ciphertext and decryption request + const ciphertext = ferveoEncrypt(message, aad, ritual.dkg.publicKey()); + const { decryptionShares } = fakeTDecFlow({ + ...ritual, + variant, + ciphertext, + aad, + message, + }); + + return { + ...ritual, + message, + aad, + ciphertext, + decryptionShares, + }; +}; + +export const fakeCoordinatorRitual = ( + ritualId: number +): { + aggregationMismatch: boolean; + initTimestamp: number; + aggregatedTranscriptHash: string; + initiator: string; + dkgSize: number; + id: number; + publicKey: { word1: string; word0: string }; + totalTranscripts: number; + aggregatedTranscript: string; + publicKeyHash: string; + totalAggregations: number; +} => { + const ritual = fakeDkgTDecFlowE2e(FerveoVariant.Precomputed); + const dkgPkBytes = ritual.dkg.publicKey().toBytes(); + return { + id: ritualId, + initiator: ritual.validators[0].address.toString(), + dkgSize: ritual.sharesNum, + initTimestamp: 0, + totalTranscripts: ritual.receivedMessages.length, + totalAggregations: ritual.sharesNum, // Assuming the ritual is finished + aggregatedTranscriptHash: keccak256(ritual.serverAggregate.toBytes()), + aggregationMismatch: false, // Assuming the ritual is correct + aggregatedTranscript: toHexString(ritual.serverAggregate.toBytes()), + publicKey: { + word0: toHexString(dkgPkBytes.slice(0, 32)), + word1: toHexString(dkgPkBytes.slice(32, 48)), + }, + publicKeyHash: keccak256(ritual.dkg.publicKey().toBytes()), + }; +}; + +export const fakeDkgParticipants = ( + ritualId: number, + variant = FerveoVariant.Precomputed +): { + participants: DkgParticipant[]; + participantSecrets: Record; +} => { + const ritual = fakeDkgTDecFlowE2e(variant); + const label = toBytes(`${ritualId}`); + + const participantSecrets: Record = + Object.fromEntries( + ritual.validators.map(({ address }) => { + const participantSecret = SessionSecretFactory.random().makeKey(label); + return [address.toString(), participantSecret]; + }) + ); + + const participants: DkgParticipant[] = zip( + Object.entries(participantSecrets), + ritual.transcripts + ).map(([[address, secret], transcript]) => { + return { + provider: address, + aggregated: true, // Assuming all validators already contributed to the aggregate + transcript, + decryptionRequestStaticKey: secret.publicKey(), + } as DkgParticipant; + }); + return { participantSecrets, participants }; +}; + +export const mockGetParticipants = (participants: DkgParticipant[]) => { + return jest + .spyOn(DkgCoordinatorAgent, 'getParticipants') + .mockImplementation(() => { + return Promise.resolve(participants); + }); +}; + +export const mockCbdDecrypt = ( + ritualId: number, + decryptionShares: (DecryptionSharePrecomputed | DecryptionShareSimple)[], + participantSecrets: Record, + requesterPk: SessionStaticKey, + errors: Record = {} +) => { + const encryptedResponses: Record< + string, + EncryptedThresholdDecryptionResponse + > = Object.fromEntries( + zip(decryptionShares, Object.entries(participantSecrets)).map( + ([share, [address, secret]]) => { + const resp = new ThresholdDecryptionResponse(ritualId, share.toBytes()); + const sessionSecret = secret.deriveSharedSecret(requesterPk); + const encryptedResp = resp.encrypt(sessionSecret); + return [address, encryptedResp]; + } + ) + ); + + const result: CbdDecryptResult = { + encryptedResponses, + errors, + }; + return jest.spyOn(Porter.prototype, 'cbdDecrypt').mockImplementation(() => { + return Promise.resolve(result); + }); +}; + +export const mockRandomSessionStaticSecret = (secret: SessionStaticSecret) => { + return jest + .spyOn(CbdTDecDecrypter.prototype as any, 'makeSessionKey') + .mockImplementation(() => secret); +}; + +export const fakeRitualId = 0; + +export const fakeDkgRitual = (ritual: { dkg: Dkg }, threshold: number) => { + return new DkgRitual(fakeRitualId, ritual.dkg.publicKey(), threshold); +}; + +export const mockInitializeRitual = (fakeRitual: unknown) => { + return jest + .spyOn(DkgClient.prototype as any, 'initializeRitual') + .mockImplementation(() => { + return Promise.resolve(fakeRitual); + }); +}; + +export const makeCohort = async (ursulas: Ursula[]) => { + const getUrsulasSpy = mockGetUrsulas(ursulas); + const config = { + threshold: 2, + shares: 3, + porterUri: 'https://_this.should.crash', + }; + const cohort = await Cohort.create(config); + expect(getUrsulasSpy).toHaveBeenCalled(); + return cohort; +}; diff --git a/tsconfig.json b/tsconfig.json index 58621b182..07ea4fca0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -23,6 +23,7 @@ "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */, "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */, "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, + "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ /* Additional Checks */ "noUnusedLocals": true /* Report errors on unused locals. */, diff --git a/types/ethers-contracts/index.ts b/types/ethers-contracts/index.ts index 8bb492b58..a72a65e49 100644 --- a/types/ethers-contracts/index.ts +++ b/types/ethers-contracts/index.ts @@ -1,6 +1,8 @@ /* Autogenerated file. Do not edit manually. */ /* tslint:disable */ /* eslint-disable */ +export type { Coordinator } from "./Coordinator"; export type { SubscriptionManager } from "./SubscriptionManager"; +export { Coordinator__factory } from "./factories/Coordinator__factory"; export { SubscriptionManager__factory } from "./factories/SubscriptionManager__factory"; diff --git a/yarn.lock b/yarn.lock index bf7e3e148..567b36b42 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,12 +2,12 @@ # yarn lockfile v1 -"@ampproject/remapping@^2.1.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" - integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== dependencies: - "@jridgewell/gen-mapping" "^0.1.0" + "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" "@babel/code-frame@7.12.11": @@ -17,98 +17,102 @@ dependencies: "@babel/highlight" "^7.10.4" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" - integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.5.tgz#234d98e1551960604f1246e6475891a570ad5658" + integrity sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ== dependencies: - "@babel/highlight" "^7.18.6" + "@babel/highlight" "^7.22.5" -"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.0", "@babel/compat-data@^7.20.1": - version "7.20.1" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.1.tgz#f2e6ef7790d8c8dbf03d379502dcc246dcce0b30" - integrity sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ== +"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.5.tgz#b1f6c86a02d85d2dd3368a2b67c09add8cd0c255" + integrity sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA== "@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.18.10", "@babel/core@^7.7.2", "@babel/core@^7.8.0": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.2.tgz#8dc9b1620a673f92d3624bd926dc49a52cf25b92" - integrity sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g== - dependencies: - "@ampproject/remapping" "^2.1.0" - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.20.2" - "@babel/helper-compilation-targets" "^7.20.0" - "@babel/helper-module-transforms" "^7.20.2" - "@babel/helpers" "^7.20.1" - "@babel/parser" "^7.20.2" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.20.1" - "@babel/types" "^7.20.2" + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.5.tgz#d67d9747ecf26ee7ecd3ebae1ee22225fe902a89" + integrity sha512-SBuTAjg91A3eKOvD+bPEz3LlhHZRNu1nFOVts9lzDJTXshHTjII0BAtDS3Y2DAkdZdDKWVZGVwkDfc4Clxn1dg== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.22.5" + "@babel/generator" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.5" + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helpers" "^7.22.5" + "@babel/parser" "^7.22.5" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.5" + "@babel/types" "^7.22.5" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" - json5 "^2.2.1" + json5 "^2.2.2" semver "^6.3.0" -"@babel/generator@^7.20.1", "@babel/generator@^7.20.2", "@babel/generator@^7.7.2": - version "7.20.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.4.tgz#4d9f8f0c30be75fd90a0562099a26e5839602ab8" - integrity sha512-luCf7yk/cm7yab6CAW1aiFnmEfBJplb/JojV56MYEK7ziWfGmFlTfmL9Ehwfy4gFhbjBfWO1wj7/TuSbVNEEtA== +"@babel/generator@^7.22.5", "@babel/generator@^7.7.2": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.5.tgz#1e7bf768688acfb05cf30b2369ef855e82d984f7" + integrity sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA== dependencies: - "@babel/types" "^7.20.2" + "@babel/types" "^7.22.5" "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" -"@babel/helper-annotate-as-pure@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb" - integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== +"@babel/helper-annotate-as-pure@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" + integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg== dependencies: - "@babel/types" "^7.18.6" + "@babel/types" "^7.22.5" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz#acd4edfd7a566d1d51ea975dff38fd52906981bb" - integrity sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.5.tgz#a3f4758efdd0190d8927fcffd261755937c71878" + integrity sha512-m1EP3lVOPptR+2DwD125gziZNcmoNSHGmJROKoy87loWUQyJaVXDgpmruWqDARZSmtYQ+Dl25okU8+qhVzuykw== dependencies: - "@babel/helper-explode-assignable-expression" "^7.18.6" - "@babel/types" "^7.18.9" + "@babel/types" "^7.22.5" -"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.20.0": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz#6bf5374d424e1b3922822f1d9bdaa43b1a139d0a" - integrity sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ== +"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz#fc7319fc54c5e2fa14b2909cf3c5fd3046813e02" + integrity sha512-Ji+ywpHeuqxB8WDxraCiqR0xfhYjiDE/e6k7FuIaANnoOFxAHskHChz4vA1mJC9Lbm01s1PVAGhQY4FUKSkGZw== dependencies: - "@babel/compat-data" "^7.20.0" - "@babel/helper-validator-option" "^7.18.6" + "@babel/compat-data" "^7.22.5" + "@babel/helper-validator-option" "^7.22.5" browserslist "^4.21.3" + lru-cache "^5.1.1" semver "^6.3.0" -"@babel/helper-create-class-features-plugin@^7.18.6": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.2.tgz#3c08a5b5417c7f07b5cf3dfb6dc79cbec682e8c2" - integrity sha512-k22GoYRAHPYr9I+Gvy2ZQlAe5mGy8BqWst2wRt8cwIufWTxrsVshhIBvYNqC80N0GSFWTsqRVexOtfzlgOEDvA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-member-expression-to-functions" "^7.18.9" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-replace-supers" "^7.19.1" - "@babel/helper-split-export-declaration" "^7.18.6" +"@babel/helper-create-class-features-plugin@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.5.tgz#2192a1970ece4685fbff85b48da2c32fcb130b7c" + integrity sha512-xkb58MyOYIslxu3gKmVXmjTtUPvBU4odYzbiIQbWwLKIHCsx6UGZGX6F1IznMFVnDdirseUZopzN+ZRt8Xb33Q== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-member-expression-to-functions" "^7.22.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.5" + semver "^6.3.0" -"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz#7976aca61c0984202baca73d84e2337a5424a41b" - integrity sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw== +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.5.tgz#bb2bf0debfe39b831986a4efbf4066586819c6e4" + integrity sha512-1VpEFOIbMRaXyDeUwUfmTIxExLwQ+zkW+Bh5zXpApA3oQedBx9v/updixWxnx/bZpKw7u8VxWjb/qWpIcmPq8A== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - regexpu-core "^5.1.0" + "@babel/helper-annotate-as-pure" "^7.22.5" + regexpu-core "^5.3.1" + semver "^6.3.0" -"@babel/helper-define-polyfill-provider@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz#8612e55be5d51f0cd1f36b4a5a83924e89884b7a" - integrity sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww== +"@babel/helper-define-polyfill-provider@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.0.tgz#487053f103110f25b9755c5980e031e93ced24d8" + integrity sha512-RnanLx5ETe6aybRi1cO/edaRH+bNYWaryCEmjDDYyNr4wnSzyOp8T0dWipmqVHKEY3AbVKUom50AKSlj1zmKbg== dependencies: "@babel/helper-compilation-targets" "^7.17.7" "@babel/helper-plugin-utils" "^7.16.7" @@ -117,301 +121,179 @@ resolve "^1.14.2" semver "^6.1.2" -"@babel/helper-environment-visitor@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" - integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== - -"@babel/helper-explode-assignable-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz#41f8228ef0a6f1a036b8dfdfec7ce94f9a6bc096" - integrity sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c" - integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== - dependencies: - "@babel/template" "^7.18.10" - "@babel/types" "^7.19.0" - -"@babel/helper-hoist-variables@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" - integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-member-expression-to-functions@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz#1531661e8375af843ad37ac692c132841e2fd815" - integrity sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg== - dependencies: - "@babel/types" "^7.18.9" - -"@babel/helper-module-imports@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" - integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.19.6", "@babel/helper-module-transforms@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz#ac53da669501edd37e658602a21ba14c08748712" - integrity sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-simple-access" "^7.20.2" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/helper-validator-identifier" "^7.19.1" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.20.1" - "@babel/types" "^7.20.2" - -"@babel/helper-optimise-call-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe" - integrity sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629" - integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ== - -"@babel/helper-remap-async-to-generator@^7.18.6", "@babel/helper-remap-async-to-generator@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519" - integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-wrap-function" "^7.18.9" - "@babel/types" "^7.18.9" - -"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz#e1592a9b4b368aa6bdb8784a711e0bcbf0612b78" - integrity sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-member-expression-to-functions" "^7.18.9" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/traverse" "^7.19.1" - "@babel/types" "^7.19.0" - -"@babel/helper-simple-access@^7.19.4", "@babel/helper-simple-access@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz#0ab452687fe0c2cfb1e2b9e0015de07fc2d62dd9" - integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA== - dependencies: - "@babel/types" "^7.20.2" - -"@babel/helper-skip-transparent-expression-wrappers@^7.18.9": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz#fbe4c52f60518cab8140d77101f0e63a8a230684" - integrity sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg== - dependencies: - "@babel/types" "^7.20.0" - -"@babel/helper-split-export-declaration@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" - integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-string-parser@^7.19.4": - version "7.19.4" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" - integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== - -"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" - integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== - -"@babel/helper-validator-option@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" - integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== - -"@babel/helper-wrap-function@^7.18.9": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz#89f18335cff1152373222f76a4b37799636ae8b1" - integrity sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg== - dependencies: - "@babel/helper-function-name" "^7.19.0" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.19.0" - "@babel/types" "^7.19.0" - -"@babel/helpers@^7.20.1": - version "7.20.1" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.1.tgz#2ab7a0fcb0a03b5bf76629196ed63c2d7311f4c9" - integrity sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg== - dependencies: - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.20.1" - "@babel/types" "^7.20.0" - -"@babel/highlight@^7.10.4", "@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" - integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== - dependencies: - "@babel/helper-validator-identifier" "^7.18.6" +"@babel/helper-environment-visitor@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98" + integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== + +"@babel/helper-function-name@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be" + integrity sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ== + dependencies: + "@babel/template" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-member-expression-to-functions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.5.tgz#0a7c56117cad3372fbf8d2fb4bf8f8d64a1e76b2" + integrity sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-imports@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz#1a8f4c9f4027d23f520bd76b364d44434a72660c" + integrity sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-transforms@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz#0f65daa0716961b6e96b164034e737f60a80d2ef" + integrity sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw== + dependencies: + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/helper-optimise-call-expression@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz#f21531a9ccbff644fdd156b4077c16ff0c3f609e" + integrity sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== + +"@babel/helper-remap-async-to-generator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.5.tgz#14a38141a7bf2165ad38da61d61cf27b43015da2" + integrity sha512-cU0Sq1Rf4Z55fgz7haOakIyM7+x/uCFwXpLPaeRzfoUtAEAuUZjZvFPjL/rk5rW693dIgn2hng1W7xbT7lWT4g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-wrap-function" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/helper-replace-supers@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.5.tgz#71bc5fb348856dea9fdc4eafd7e2e49f585145dc" + integrity sha512-aLdNM5I3kdI/V9xGNyKSF3X/gTyMUBohTZ+/3QdQKAA9vxIiy12E+8E2HoOP1/DjeqU+g6as35QHJNMDDYpuCg== + dependencies: + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-member-expression-to-functions" "^7.22.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-skip-transparent-expression-wrappers@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz#007f15240b5751c537c40e77abb4e89eeaaa8847" + integrity sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-split-export-declaration@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.5.tgz#88cf11050edb95ed08d596f7a044462189127a08" + integrity sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-string-parser@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" + integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== + +"@babel/helper-validator-identifier@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" + integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== + +"@babel/helper-validator-option@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac" + integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw== + +"@babel/helper-wrap-function@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.5.tgz#44d205af19ed8d872b4eefb0d2fa65f45eb34f06" + integrity sha512-bYqLIBSEshYcYQyfks8ewYA8S30yaGSeRslcvKMvoUk6HHPySbxHq9YRi6ghhzEU+yhQv9bP/jXnygkStOcqZw== + dependencies: + "@babel/helper-function-name" "^7.22.5" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/helpers@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.5.tgz#74bb4373eb390d1ceed74a15ef97767e63120820" + integrity sha512-pSXRmfE1vzcUIDFQcSGA5Mr+GxBV9oiRKDuDxXvWQQBCh8HoIjs/2DlDB7H8smac1IVrB9/xdXj2N3Wol9Cr+Q== + dependencies: + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/highlight@^7.10.4", "@babel/highlight@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.5.tgz#aa6c05c5407a67ebce408162b7ede789b4d22031" + integrity sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw== + dependencies: + "@babel/helper-validator-identifier" "^7.22.5" chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.18.10", "@babel/parser@^7.20.1", "@babel/parser@^7.20.2": - version "7.20.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.3.tgz#5358cf62e380cf69efcb87a7bb922ff88bfac6e2" - integrity sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.5.tgz#721fd042f3ce1896238cf1b341c77eb7dee7dbea" + integrity sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q== -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2" - integrity sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ== +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz#87245a21cd69a73b0b81bcda98d443d6df08f05e" + integrity sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz#a11af19aa373d68d561f08e0a57242350ed0ec50" - integrity sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.5.tgz#fef09f9499b1f1c930da8a0c419db42167d792ca" + integrity sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" - "@babel/plugin-proposal-optional-chaining" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-transform-optional-chaining" "^7.22.5" -"@babel/plugin-proposal-async-generator-functions@^7.20.1": - version "7.20.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.1.tgz#352f02baa5d69f4e7529bdac39aaa02d41146af9" - integrity sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-remap-async-to-generator" "^7.18.9" - "@babel/plugin-syntax-async-generators" "^7.8.4" - -"@babel/plugin-proposal-class-properties@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" - integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-proposal-class-static-block@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz#8aa81d403ab72d3962fc06c26e222dacfc9b9020" - integrity sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - -"@babel/plugin-proposal-dynamic-import@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz#72bcf8d408799f547d759298c3c27c7e7faa4d94" - integrity sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - -"@babel/plugin-proposal-export-namespace-from@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz#5f7313ab348cdb19d590145f9247540e94761203" - integrity sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - -"@babel/plugin-proposal-json-strings@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz#7e8788c1811c393aff762817e7dbf1ebd0c05f0b" - integrity sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-json-strings" "^7.8.3" - -"@babel/plugin-proposal-logical-assignment-operators@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz#8148cbb350483bf6220af06fa6db3690e14b2e23" - integrity sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - -"@babel/plugin-proposal-nullish-coalescing-operator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1" - integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - -"@babel/plugin-proposal-numeric-separator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz#899b14fbafe87f053d2c5ff05b36029c62e13c75" - integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - -"@babel/plugin-proposal-object-rest-spread@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.2.tgz#a556f59d555f06961df1e572bb5eca864c84022d" - integrity sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ== - dependencies: - "@babel/compat-data" "^7.20.1" - "@babel/helper-compilation-targets" "^7.20.0" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.20.1" - -"@babel/plugin-proposal-optional-catch-binding@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz#f9400d0e6a3ea93ba9ef70b09e72dd6da638a2cb" - integrity sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - -"@babel/plugin-proposal-optional-chaining@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz#e8e8fe0723f2563960e4bf5e9690933691915993" - integrity sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - -"@babel/plugin-proposal-private-methods@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz#5209de7d213457548a98436fa2882f52f4be6bea" - integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" +"@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": + version "7.21.0-placeholder-for-preset-env.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" + integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== -"@babel/plugin-proposal-private-property-in-object@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz#a64137b232f0aca3733a67eb1a144c192389c503" - integrity sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - -"@babel/plugin-proposal-unicode-property-regex@^7.18.6", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": +"@babel/plugin-proposal-unicode-property-regex@^7.4.4": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz#af613d2cd5e643643b65cded64207b15c85cb78e" integrity sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w== @@ -461,14 +343,21 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-import-assertions@^7.20.0": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz#bb50e0d4bea0957235390641209394e87bdb9cc4" - integrity sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ== +"@babel/plugin-syntax-import-assertions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz#07d252e2aa0bc6125567f742cd58619cb14dce98" + integrity sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-import-attributes@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz#ab840248d834410b829f569f5262b9e517555ecb" + integrity sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg== dependencies: - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-syntax-import-meta@^7.8.3": +"@babel/plugin-syntax-import-meta@^7.10.4", "@babel/plugin-syntax-import-meta@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== @@ -539,294 +428,428 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-typescript@^7.7.2": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz#4e9a0cfc769c85689b77a2e642d24e9f697fc8c7" - integrity sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz#aac8d383b062c5072c647a31ef990c1d0af90272" + integrity sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ== dependencies: - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-arrow-functions@^7.18.6": +"@babel/plugin-syntax-unicode-sets-regex@^7.18.6": version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz#19063fcf8771ec7b31d742339dac62433d0611fe" - integrity sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ== + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" + integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg== dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-async-to-generator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz#ccda3d1ab9d5ced5265fdb13f1882d5476c71615" - integrity sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag== +"@babel/plugin-transform-arrow-functions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz#e5ba566d0c58a5b2ba2a8b795450641950b71958" + integrity sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw== dependencies: - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-remap-async-to-generator" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-block-scoped-functions@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz#9187bf4ba302635b9d70d986ad70f038726216a8" - integrity sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ== +"@babel/plugin-transform-async-generator-functions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.5.tgz#7336356d23380eda9a56314974f053a020dab0c3" + integrity sha512-gGOEvFzm3fWoyD5uZq7vVTD57pPJ3PczPUD/xCFGjzBpUosnklmXyKnGQbbbGs1NPNPskFex0j93yKbHt0cHyg== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.5" + "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-transform-block-scoping@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.2.tgz#f59b1767e6385c663fd0bce655db6ca9c8b236ed" - integrity sha512-y5V15+04ry69OV2wULmwhEA6jwSWXO1TwAtIwiPXcvHcoOQUqpyMVd2bDsQJMW8AurjulIyUV8kDqtjSwHy1uQ== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - -"@babel/plugin-transform-classes@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.2.tgz#c0033cf1916ccf78202d04be4281d161f6709bb2" - integrity sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-compilation-targets" "^7.20.0" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-replace-supers" "^7.19.1" - "@babel/helper-split-export-declaration" "^7.18.6" +"@babel/plugin-transform-async-to-generator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz#c7a85f44e46f8952f6d27fe57c2ed3cc084c3775" + integrity sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ== + dependencies: + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.5" + +"@babel/plugin-transform-block-scoped-functions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz#27978075bfaeb9fa586d3cb63a3d30c1de580024" + integrity sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-block-scoping@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.5.tgz#8bfc793b3a4b2742c0983fadc1480d843ecea31b" + integrity sha512-EcACl1i5fSQ6bt+YGuU/XGCeZKStLmyVGytWkpyhCLeQVA0eu6Wtiw92V+I1T/hnezUv7j74dA/Ro69gWcU+hg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-class-properties@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz#97a56e31ad8c9dc06a0b3710ce7803d5a48cca77" + integrity sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-class-static-block@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.5.tgz#3e40c46f048403472d6f4183116d5e46b1bff5ba" + integrity sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + +"@babel/plugin-transform-classes@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.5.tgz#635d4e98da741fad814984639f4c0149eb0135e1" + integrity sha512-2edQhLfibpWpsVBx2n/GKOz6JdGQvLruZQfGr9l1qes2KQaWswjBzhQF7UDUZMNaMMQeYnQzxwOMPsbYF7wqPQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.5" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz#2357a8224d402dad623caf6259b611e56aec746e" - integrity sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw== +"@babel/plugin-transform-computed-properties@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz#cd1e994bf9f316bd1c2dafcd02063ec261bb3869" + integrity sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/template" "^7.22.5" -"@babel/plugin-transform-destructuring@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.2.tgz#c23741cfa44ddd35f5e53896e88c75331b8b2792" - integrity sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw== +"@babel/plugin-transform-destructuring@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.5.tgz#d3aca7438f6c26c78cdd0b0ba920a336001b27cc" + integrity sha512-GfqcFuGW8vnEqTUBM7UtPd5A4q797LTvvwKxXTgRsFjoqaJiEg9deBG6kWeQYkVEL569NpnmpC0Pkr/8BLKGnQ== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-dotall-regex@^7.18.6", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz#b286b3e7aae6c7b861e45bed0a2fafd6b1a4fef8" - integrity sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg== +"@babel/plugin-transform-dotall-regex@^7.22.5", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz#dbb4f0e45766eb544e193fb00e65a1dd3b2a4165" + integrity sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-duplicate-keys@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz#687f15ee3cdad6d85191eb2a372c4528eaa0ae0e" - integrity sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw== +"@babel/plugin-transform-duplicate-keys@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz#b6e6428d9416f5f0bba19c70d1e6e7e0b88ab285" + integrity sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-exponentiation-operator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz#421c705f4521888c65e91fdd1af951bfefd4dacd" - integrity sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw== +"@babel/plugin-transform-dynamic-import@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.5.tgz#d6908a8916a810468c4edff73b5b75bda6ad393e" + integrity sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" -"@babel/plugin-transform-for-of@^7.18.8": - version "7.18.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz#6ef8a50b244eb6a0bdbad0c7c61877e4e30097c1" - integrity sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ== +"@babel/plugin-transform-exponentiation-operator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz#402432ad544a1f9a480da865fda26be653e48f6a" + integrity sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-function-name@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz#cc354f8234e62968946c61a46d6365440fc764e0" - integrity sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ== +"@babel/plugin-transform-export-namespace-from@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.5.tgz#57c41cb1d0613d22f548fddd8b288eedb9973a5b" + integrity sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg== dependencies: - "@babel/helper-compilation-targets" "^7.18.9" - "@babel/helper-function-name" "^7.18.9" - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-transform-literals@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz#72796fdbef80e56fba3c6a699d54f0de557444bc" - integrity sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg== +"@babel/plugin-transform-for-of@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz#ab1b8a200a8f990137aff9a084f8de4099ab173f" + integrity sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-member-expression-literals@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz#ac9fdc1a118620ac49b7e7a5d2dc177a1bfee88e" - integrity sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA== +"@babel/plugin-transform-function-name@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz#935189af68b01898e0d6d99658db6b164205c143" + integrity sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-compilation-targets" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-modules-amd@^7.19.6": - version "7.19.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.19.6.tgz#aca391801ae55d19c4d8d2ebfeaa33df5f2a2cbd" - integrity sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg== +"@babel/plugin-transform-json-strings@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.5.tgz#14b64352fdf7e1f737eed68de1a1468bd2a77ec0" + integrity sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A== dependencies: - "@babel/helper-module-transforms" "^7.19.6" - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-json-strings" "^7.8.3" -"@babel/plugin-transform-modules-commonjs@^7.19.6": - version "7.19.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.19.6.tgz#25b32feef24df8038fc1ec56038917eacb0b730c" - integrity sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ== +"@babel/plugin-transform-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz#e9341f4b5a167952576e23db8d435849b1dd7920" + integrity sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g== dependencies: - "@babel/helper-module-transforms" "^7.19.6" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-simple-access" "^7.19.4" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-modules-systemjs@^7.19.6": - version "7.19.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.6.tgz#59e2a84064b5736a4471b1aa7b13d4431d327e0d" - integrity sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ== +"@babel/plugin-transform-logical-assignment-operators@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.5.tgz#66ae5f068fd5a9a5dc570df16f56c2a8462a9d6c" + integrity sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA== dependencies: - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-module-transforms" "^7.19.6" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-validator-identifier" "^7.19.1" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-transform-modules-umd@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz#81d3832d6034b75b54e62821ba58f28ed0aab4b9" - integrity sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ== +"@babel/plugin-transform-member-expression-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz#4fcc9050eded981a468347dd374539ed3e058def" + integrity sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew== dependencies: - "@babel/helper-module-transforms" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-named-capturing-groups-regex@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz#ec7455bab6cd8fb05c525a94876f435a48128888" - integrity sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw== +"@babel/plugin-transform-modules-amd@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.22.5.tgz#4e045f55dcf98afd00f85691a68fc0780704f526" + integrity sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.19.0" - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-new-target@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz#d128f376ae200477f37c4ddfcc722a8a1b3246a8" - integrity sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw== +"@babel/plugin-transform-modules-commonjs@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz#7d9875908d19b8c0536085af7b053fd5bd651bfa" + integrity sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" -"@babel/plugin-transform-object-super@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz#fb3c6ccdd15939b6ff7939944b51971ddc35912c" - integrity sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA== +"@babel/plugin-transform-modules-systemjs@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz#18c31410b5e579a0092638f95c896c2a98a5d496" + integrity sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-replace-supers" "^7.18.6" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" -"@babel/plugin-transform-parameters@^7.20.1": - version "7.20.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.3.tgz#7b3468d70c3c5b62e46be0a47b6045d8590fb748" - integrity sha512-oZg/Fpx0YDrj13KsLyO8I/CX3Zdw7z0O9qOd95SqcoIzuqy/WTGWvePeHAnZCN54SfdyjHcb1S30gc8zlzlHcA== +"@babel/plugin-transform-modules-umd@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz#4694ae40a87b1745e3775b6a7fe96400315d4f98" + integrity sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-property-literals@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz#e22498903a483448e94e032e9bbb9c5ccbfc93a3" - integrity sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg== +"@babel/plugin-transform-named-capturing-groups-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz#67fe18ee8ce02d57c855185e27e3dc959b2e991f" + integrity sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-regenerator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz#585c66cb84d4b4bf72519a34cfce761b8676ca73" - integrity sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ== +"@babel/plugin-transform-new-target@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz#1b248acea54ce44ea06dfd37247ba089fcf9758d" + integrity sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - regenerator-transform "^0.15.0" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-reserved-words@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz#b1abd8ebf8edaa5f7fe6bbb8d2133d23b6a6f76a" - integrity sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA== +"@babel/plugin-transform-nullish-coalescing-operator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.5.tgz#f8872c65776e0b552e0849d7596cddd416c3e381" + integrity sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-transform-shorthand-properties@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz#6d6df7983d67b195289be24909e3f12a8f664dc9" - integrity sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw== +"@babel/plugin-transform-numeric-separator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.5.tgz#57226a2ed9e512b9b446517ab6fa2d17abb83f58" + integrity sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-transform-spread@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz#dd60b4620c2fec806d60cfaae364ec2188d593b6" - integrity sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w== +"@babel/plugin-transform-object-rest-spread@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz#9686dc3447df4753b0b2a2fae7e8bc33cdc1f2e1" + integrity sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ== dependencies: - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" + "@babel/compat-data" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.22.5" -"@babel/plugin-transform-sticky-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz#c6706eb2b1524028e317720339583ad0f444adcc" - integrity sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q== +"@babel/plugin-transform-object-super@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz#794a8d2fcb5d0835af722173c1a9d704f44e218c" + integrity sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.5" -"@babel/plugin-transform-template-literals@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz#04ec6f10acdaa81846689d63fae117dd9c243a5e" - integrity sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA== +"@babel/plugin-transform-optional-catch-binding@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.5.tgz#842080be3076703be0eaf32ead6ac8174edee333" + integrity sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-transform-typeof-symbol@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz#c8cea68263e45addcd6afc9091429f80925762c0" - integrity sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw== +"@babel/plugin-transform-optional-chaining@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.5.tgz#1003762b9c14295501beb41be72426736bedd1e0" + integrity sha512-AconbMKOMkyG+xCng2JogMCDcqW8wedQAqpVIL4cOSescZ7+iW8utC6YDZLMCSUIReEA733gzRSaOSXMAt/4WQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-transform-unicode-escapes@^7.18.10": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz#1ecfb0eda83d09bbcb77c09970c2dd55832aa246" - integrity sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ== +"@babel/plugin-transform-parameters@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz#c3542dd3c39b42c8069936e48717a8d179d63a18" + integrity sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-unicode-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz#194317225d8c201bbae103364ffe9e2cea36cdca" - integrity sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA== +"@babel/plugin-transform-private-methods@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz#21c8af791f76674420a147ae62e9935d790f8722" + integrity sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-private-property-in-object@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.5.tgz#07a77f28cbb251546a43d175a1dda4cf3ef83e32" + integrity sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + +"@babel/plugin-transform-property-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz#b5ddabd73a4f7f26cd0e20f5db48290b88732766" + integrity sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-regenerator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.5.tgz#cd8a68b228a5f75fa01420e8cc2fc400f0fc32aa" + integrity sha512-rR7KePOE7gfEtNTh9Qw+iO3Q/e4DEsoQ+hdvM6QUDH7JRJ5qxq5AA52ZzBWbI5i9lfNuvySgOGP8ZN7LAmaiPw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + regenerator-transform "^0.15.1" + +"@babel/plugin-transform-reserved-words@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz#832cd35b81c287c4bcd09ce03e22199641f964fb" + integrity sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-shorthand-properties@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz#6e277654be82b5559fc4b9f58088507c24f0c624" + integrity sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-spread@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz#6487fd29f229c95e284ba6c98d65eafb893fea6b" + integrity sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + +"@babel/plugin-transform-sticky-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz#295aba1595bfc8197abd02eae5fc288c0deb26aa" + integrity sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-template-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz#8f38cf291e5f7a8e60e9f733193f0bcc10909bff" + integrity sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-typeof-symbol@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz#5e2ba478da4b603af8673ff7c54f75a97b716b34" + integrity sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-escapes@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.5.tgz#ce0c248522b1cb22c7c992d88301a5ead70e806c" + integrity sha512-biEmVg1IYB/raUO5wT1tgfacCef15Fbzhkx493D3urBI++6hpJ+RFG4SrWMn0NEZLfvilqKf3QDrRVZHo08FYg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-property-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz#098898f74d5c1e86660dc112057b2d11227f1c81" + integrity sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz#ce7e7bb3ef208c4ff67e02a22816656256d7a183" + integrity sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-sets-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz#77788060e511b708ffc7d42fdfbc5b37c3004e91" + integrity sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/preset-env@^7.15.6": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.20.2.tgz#9b1642aa47bb9f43a86f9630011780dab7f86506" - integrity sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg== - dependencies: - "@babel/compat-data" "^7.20.1" - "@babel/helper-compilation-targets" "^7.20.0" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-validator-option" "^7.18.6" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.18.9" - "@babel/plugin-proposal-async-generator-functions" "^7.20.1" - "@babel/plugin-proposal-class-properties" "^7.18.6" - "@babel/plugin-proposal-class-static-block" "^7.18.6" - "@babel/plugin-proposal-dynamic-import" "^7.18.6" - "@babel/plugin-proposal-export-namespace-from" "^7.18.9" - "@babel/plugin-proposal-json-strings" "^7.18.6" - "@babel/plugin-proposal-logical-assignment-operators" "^7.18.9" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.6" - "@babel/plugin-proposal-numeric-separator" "^7.18.6" - "@babel/plugin-proposal-object-rest-spread" "^7.20.2" - "@babel/plugin-proposal-optional-catch-binding" "^7.18.6" - "@babel/plugin-proposal-optional-chaining" "^7.18.9" - "@babel/plugin-proposal-private-methods" "^7.18.6" - "@babel/plugin-proposal-private-property-in-object" "^7.18.6" - "@babel/plugin-proposal-unicode-property-regex" "^7.18.6" + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.22.5.tgz#3da66078b181f3d62512c51cf7014392c511504e" + integrity sha512-fj06hw89dpiZzGZtxn+QybifF07nNiZjZ7sazs2aVDcysAZVGjW7+7iFYxg6GLNM47R/thYfLdrXc+2f11Vi9A== + dependencies: + "@babel/compat-data" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.5" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.22.5" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.22.5" + "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-class-properties" "^7.12.13" "@babel/plugin-syntax-class-static-block" "^7.14.5" "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-import-assertions" "^7.20.0" + "@babel/plugin-syntax-import-assertions" "^7.22.5" + "@babel/plugin-syntax-import-attributes" "^7.22.5" + "@babel/plugin-syntax-import-meta" "^7.10.4" "@babel/plugin-syntax-json-strings" "^7.8.3" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" @@ -836,44 +859,61 @@ "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" "@babel/plugin-syntax-top-level-await" "^7.14.5" - "@babel/plugin-transform-arrow-functions" "^7.18.6" - "@babel/plugin-transform-async-to-generator" "^7.18.6" - "@babel/plugin-transform-block-scoped-functions" "^7.18.6" - "@babel/plugin-transform-block-scoping" "^7.20.2" - "@babel/plugin-transform-classes" "^7.20.2" - "@babel/plugin-transform-computed-properties" "^7.18.9" - "@babel/plugin-transform-destructuring" "^7.20.2" - "@babel/plugin-transform-dotall-regex" "^7.18.6" - "@babel/plugin-transform-duplicate-keys" "^7.18.9" - "@babel/plugin-transform-exponentiation-operator" "^7.18.6" - "@babel/plugin-transform-for-of" "^7.18.8" - "@babel/plugin-transform-function-name" "^7.18.9" - "@babel/plugin-transform-literals" "^7.18.9" - "@babel/plugin-transform-member-expression-literals" "^7.18.6" - "@babel/plugin-transform-modules-amd" "^7.19.6" - "@babel/plugin-transform-modules-commonjs" "^7.19.6" - "@babel/plugin-transform-modules-systemjs" "^7.19.6" - "@babel/plugin-transform-modules-umd" "^7.18.6" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.19.1" - "@babel/plugin-transform-new-target" "^7.18.6" - "@babel/plugin-transform-object-super" "^7.18.6" - "@babel/plugin-transform-parameters" "^7.20.1" - "@babel/plugin-transform-property-literals" "^7.18.6" - "@babel/plugin-transform-regenerator" "^7.18.6" - "@babel/plugin-transform-reserved-words" "^7.18.6" - "@babel/plugin-transform-shorthand-properties" "^7.18.6" - "@babel/plugin-transform-spread" "^7.19.0" - "@babel/plugin-transform-sticky-regex" "^7.18.6" - "@babel/plugin-transform-template-literals" "^7.18.9" - "@babel/plugin-transform-typeof-symbol" "^7.18.9" - "@babel/plugin-transform-unicode-escapes" "^7.18.10" - "@babel/plugin-transform-unicode-regex" "^7.18.6" + "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" + "@babel/plugin-transform-arrow-functions" "^7.22.5" + "@babel/plugin-transform-async-generator-functions" "^7.22.5" + "@babel/plugin-transform-async-to-generator" "^7.22.5" + "@babel/plugin-transform-block-scoped-functions" "^7.22.5" + "@babel/plugin-transform-block-scoping" "^7.22.5" + "@babel/plugin-transform-class-properties" "^7.22.5" + "@babel/plugin-transform-class-static-block" "^7.22.5" + "@babel/plugin-transform-classes" "^7.22.5" + "@babel/plugin-transform-computed-properties" "^7.22.5" + "@babel/plugin-transform-destructuring" "^7.22.5" + "@babel/plugin-transform-dotall-regex" "^7.22.5" + "@babel/plugin-transform-duplicate-keys" "^7.22.5" + "@babel/plugin-transform-dynamic-import" "^7.22.5" + "@babel/plugin-transform-exponentiation-operator" "^7.22.5" + "@babel/plugin-transform-export-namespace-from" "^7.22.5" + "@babel/plugin-transform-for-of" "^7.22.5" + "@babel/plugin-transform-function-name" "^7.22.5" + "@babel/plugin-transform-json-strings" "^7.22.5" + "@babel/plugin-transform-literals" "^7.22.5" + "@babel/plugin-transform-logical-assignment-operators" "^7.22.5" + "@babel/plugin-transform-member-expression-literals" "^7.22.5" + "@babel/plugin-transform-modules-amd" "^7.22.5" + "@babel/plugin-transform-modules-commonjs" "^7.22.5" + "@babel/plugin-transform-modules-systemjs" "^7.22.5" + "@babel/plugin-transform-modules-umd" "^7.22.5" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.22.5" + "@babel/plugin-transform-new-target" "^7.22.5" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.22.5" + "@babel/plugin-transform-numeric-separator" "^7.22.5" + "@babel/plugin-transform-object-rest-spread" "^7.22.5" + "@babel/plugin-transform-object-super" "^7.22.5" + "@babel/plugin-transform-optional-catch-binding" "^7.22.5" + "@babel/plugin-transform-optional-chaining" "^7.22.5" + "@babel/plugin-transform-parameters" "^7.22.5" + "@babel/plugin-transform-private-methods" "^7.22.5" + "@babel/plugin-transform-private-property-in-object" "^7.22.5" + "@babel/plugin-transform-property-literals" "^7.22.5" + "@babel/plugin-transform-regenerator" "^7.22.5" + "@babel/plugin-transform-reserved-words" "^7.22.5" + "@babel/plugin-transform-shorthand-properties" "^7.22.5" + "@babel/plugin-transform-spread" "^7.22.5" + "@babel/plugin-transform-sticky-regex" "^7.22.5" + "@babel/plugin-transform-template-literals" "^7.22.5" + "@babel/plugin-transform-typeof-symbol" "^7.22.5" + "@babel/plugin-transform-unicode-escapes" "^7.22.5" + "@babel/plugin-transform-unicode-property-regex" "^7.22.5" + "@babel/plugin-transform-unicode-regex" "^7.22.5" + "@babel/plugin-transform-unicode-sets-regex" "^7.22.5" "@babel/preset-modules" "^0.1.5" - "@babel/types" "^7.20.2" - babel-plugin-polyfill-corejs2 "^0.3.3" - babel-plugin-polyfill-corejs3 "^0.6.0" - babel-plugin-polyfill-regenerator "^0.4.1" - core-js-compat "^3.25.1" + "@babel/types" "^7.22.5" + babel-plugin-polyfill-corejs2 "^0.4.3" + babel-plugin-polyfill-corejs3 "^0.8.1" + babel-plugin-polyfill-regenerator "^0.5.0" + core-js-compat "^3.30.2" semver "^6.3.0" "@babel/preset-modules@^0.1.5": @@ -887,45 +927,50 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/runtime@^7.8.4": - version "7.20.1" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.1.tgz#1148bb33ab252b165a06698fde7576092a78b4a9" - integrity sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg== - dependencies: - regenerator-runtime "^0.13.10" - -"@babel/template@^7.18.10", "@babel/template@^7.3.3": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" - integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/parser" "^7.18.10" - "@babel/types" "^7.18.10" +"@babel/regjsgen@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" + integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/traverse@^7.19.0", "@babel/traverse@^7.19.1", "@babel/traverse@^7.20.1", "@babel/traverse@^7.7.2": - version "7.20.1" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.1.tgz#9b15ccbf882f6d107eeeecf263fbcdd208777ec8" - integrity sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.20.1" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.20.1" - "@babel/types" "^7.20.0" +"@babel/runtime@^7.8.4": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.5.tgz#8564dd588182ce0047d55d7a75e93921107b57ec" + integrity sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA== + dependencies: + regenerator-runtime "^0.13.11" + +"@babel/template@^7.22.5", "@babel/template@^7.3.3": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.5.tgz#0c8c4d944509875849bd0344ff0050756eefc6ec" + integrity sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw== + dependencies: + "@babel/code-frame" "^7.22.5" + "@babel/parser" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/traverse@^7.22.5", "@babel/traverse@^7.7.2": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.5.tgz#44bd276690db6f4940fdb84e1cb4abd2f729ccd1" + integrity sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ== + dependencies: + "@babel/code-frame" "^7.22.5" + "@babel/generator" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.5" + "@babel/parser" "^7.22.5" + "@babel/types" "^7.22.5" debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.2.tgz#67ac09266606190f496322dbaff360fdaa5e7842" - integrity sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog== +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.5", "@babel/types@^7.3.3", "@babel/types@^7.4.4": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.5.tgz#cd93eeaab025880a3a47ec881f4b096a5b786fbe" + integrity sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA== dependencies: - "@babel/helper-string-parser" "^7.19.4" - "@babel/helper-validator-identifier" "^7.19.1" + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" to-fast-properties "^2.0.0" "@bcoe/v8-coverage@^0.2.3": @@ -933,53 +978,55 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@commitlint/config-validator@^17.1.0": - version "17.1.0" - resolved "https://registry.yarnpkg.com/@commitlint/config-validator/-/config-validator-17.1.0.tgz#51d09ca53d7a0d19736abf34eb18a66efce0f97a" - integrity sha512-Q1rRRSU09ngrTgeTXHq6ePJs2KrI+axPTgkNYDWSJIuS1Op4w3J30vUfSXjwn5YEJHklK3fSqWNHmBhmTR7Vdg== +"@commitlint/config-validator@^17.4.4": + version "17.4.4" + resolved "https://registry.yarnpkg.com/@commitlint/config-validator/-/config-validator-17.4.4.tgz#d0742705719559a101d2ee49c0c514044af6d64d" + integrity sha512-bi0+TstqMiqoBAQDvdEP4AFh0GaKyLFlPPEObgI29utoKEYoPQTvF0EYqIwYYLEoJYhj5GfMIhPHJkTJhagfeg== dependencies: - "@commitlint/types" "^17.0.0" + "@commitlint/types" "^17.4.4" ajv "^8.11.0" -"@commitlint/execute-rule@^17.0.0": - version "17.0.0" - resolved "https://registry.yarnpkg.com/@commitlint/execute-rule/-/execute-rule-17.0.0.tgz#186e9261fd36733922ae617497888c4bdb6e5c92" - integrity sha512-nVjL/w/zuqjCqSJm8UfpNaw66V9WzuJtQvEnCrK4jDw6qKTmZB+1JQ8m6BQVZbNBcwfYdDNKnhIhqI0Rk7lgpQ== +"@commitlint/execute-rule@^17.4.0": + version "17.4.0" + resolved "https://registry.yarnpkg.com/@commitlint/execute-rule/-/execute-rule-17.4.0.tgz#4518e77958893d0a5835babe65bf87e2638f6939" + integrity sha512-LIgYXuCSO5Gvtc0t9bebAMSwd68ewzmqLypqI2Kke1rqOqqDbMpYcYfoPfFlv9eyLIh4jocHWwCK5FS7z9icUA== "@commitlint/load@>6.1.1": - version "17.2.0" - resolved "https://registry.yarnpkg.com/@commitlint/load/-/load-17.2.0.tgz#11c9fb23a967ff1507a28931c91aae7f978ea4ae" - integrity sha512-HDD57qSqNrk399R4TIjw31AWBG8dBjNj1MrDKZKmC/wvimtnIFlqzcu1+sxfXIOHj/+M6tcMWDtvknGUd7SU+g== - dependencies: - "@commitlint/config-validator" "^17.1.0" - "@commitlint/execute-rule" "^17.0.0" - "@commitlint/resolve-extends" "^17.1.0" - "@commitlint/types" "^17.0.0" - "@types/node" "^14.0.0" + version "17.5.0" + resolved "https://registry.yarnpkg.com/@commitlint/load/-/load-17.5.0.tgz#be45dbbb50aaf5eb7e8e940e1e0d6171d1426bab" + integrity sha512-l+4W8Sx4CD5rYFsrhHH8HP01/8jEP7kKf33Xlx2Uk2out/UKoKPYMOIRcDH5ppT8UXLMV+x6Wm5osdRKKgaD1Q== + dependencies: + "@commitlint/config-validator" "^17.4.4" + "@commitlint/execute-rule" "^17.4.0" + "@commitlint/resolve-extends" "^17.4.4" + "@commitlint/types" "^17.4.4" + "@types/node" "*" chalk "^4.1.0" - cosmiconfig "^7.0.0" + cosmiconfig "^8.0.0" cosmiconfig-typescript-loader "^4.0.0" - lodash "^4.17.19" + lodash.isplainobject "^4.0.6" + lodash.merge "^4.6.2" + lodash.uniq "^4.5.0" resolve-from "^5.0.0" ts-node "^10.8.1" - typescript "^4.6.4" + typescript "^4.6.4 || ^5.0.0" -"@commitlint/resolve-extends@^17.1.0": - version "17.1.0" - resolved "https://registry.yarnpkg.com/@commitlint/resolve-extends/-/resolve-extends-17.1.0.tgz#7cf04fa13096c8a6544a4af13321fdf8d0d50694" - integrity sha512-jqKm00LJ59T0O8O4bH4oMa4XyJVEOK4GzH8Qye9XKji+Q1FxhZznxMV/bDLyYkzbTodBt9sL0WLql8wMtRTbqQ== +"@commitlint/resolve-extends@^17.4.4": + version "17.4.4" + resolved "https://registry.yarnpkg.com/@commitlint/resolve-extends/-/resolve-extends-17.4.4.tgz#8f931467dea8c43b9fe38373e303f7c220de6fdc" + integrity sha512-znXr1S0Rr8adInptHw0JeLgumS11lWbk5xAWFVno+HUFVN45875kUtqjrI6AppmD3JI+4s0uZlqqlkepjJd99A== dependencies: - "@commitlint/config-validator" "^17.1.0" - "@commitlint/types" "^17.0.0" + "@commitlint/config-validator" "^17.4.4" + "@commitlint/types" "^17.4.4" import-fresh "^3.0.0" - lodash "^4.17.19" + lodash.mergewith "^4.6.2" resolve-from "^5.0.0" resolve-global "^1.0.0" -"@commitlint/types@^17.0.0": - version "17.0.0" - resolved "https://registry.yarnpkg.com/@commitlint/types/-/types-17.0.0.tgz#3b4604c1a0f06c340ce976e6c6903d4f56e3e690" - integrity sha512-hBAw6U+SkAT5h47zDMeOu3HSiD0SODw4Aq7rRNh1ceUmL7GyLKYhPbUvlRWqZ65XjBLPHZhFyQlRaPNz8qvUyQ== +"@commitlint/types@^17.4.4": + version "17.4.4" + resolved "https://registry.yarnpkg.com/@commitlint/types/-/types-17.4.4.tgz#1416df936e9aad0d6a7bbc979ecc31e55dade662" + integrity sha512-amRN8tRLYOsxRr6mTnGGGvB5EmW/4DDjLMgiwK3CCVEmN6Sr/6xePGEpWaspKkckILuUORCwe6VfDBw6uj4axQ== dependencies: chalk "^4.1.0" @@ -1574,38 +1621,40 @@ "@types/yargs" "^16.0.0" chalk "^4.0.0" -"@jridgewell/gen-mapping@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" - integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== - dependencies: - "@jridgewell/set-array" "^1.0.0" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@jridgewell/gen-mapping@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" - integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== dependencies: "@jridgewell/set-array" "^1.0.1" "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/resolve-uri@3.1.0", "@jridgewell/resolve-uri@^3.0.3": +"@jridgewell/resolve-uri@3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== -"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + +"@jridgewell/set-array@^1.0.1": version "1.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== -"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": +"@jridgewell/sourcemap-codec@1.4.14": version "1.4.14" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + "@jridgewell/trace-mapping@0.3.9": version "0.3.9" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" @@ -1614,10 +1663,10 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@jridgewell/trace-mapping@^0.3.9": - version "0.3.17" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" - integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== +"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.18" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz#25783b2086daf6ff1dcb53c9249ae480e4dd4cd6" + integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== dependencies: "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" @@ -1643,10 +1692,10 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@nucypher/nucypher-core@0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@nucypher/nucypher-core/-/nucypher-core-0.4.0.tgz#1388abde9de61ed848959b86bc96e3d12ef97ae4" - integrity sha512-Pu4tRCwf7lnhZSoMjp889uTIUM7bNmYEe05TOOCuMYbJKmQWe7tYKeH0+rflUBISzGtMx2+xDe2CYYTyEGkvSw== +"@nucypher/nucypher-core@^0.10.0": + version "0.10.0" + resolved "https://registry.yarnpkg.com/@nucypher/nucypher-core/-/nucypher-core-0.10.0.tgz#95ba3805fa0c01510e9e012d65b735e97bd6ff08" + integrity sha512-7ZbFIZbAIO8UU++0tGhZEP8z1m4Vj5b/4+c9opBXXK88GZ7DFjdNWeTJWOCwLK3fMSpQJcUmkkqfsUd+PfGa9A== "@sideway/address@^4.1.3": version "4.1.4" @@ -1655,10 +1704,10 @@ dependencies: "@hapi/hoek" "^9.0.0" -"@sideway/formula@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.0.tgz#fe158aee32e6bd5de85044be615bc08478a0a13c" - integrity sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg== +"@sideway/formula@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.1.tgz#80fcbcbaf7ce031e0ef2dd29b1bfc7c3f583611f" + integrity sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg== "@sideway/pinpoint@^2.0.0": version "2.0.0" @@ -1666,9 +1715,9 @@ integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== "@sinonjs/commons@^1.7.0": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.5.tgz#e280c94c95f206dcfd5aca00a43f2156b758c764" - integrity sha512-rTpCA0wG1wUxglBSFdMMY0oTrKYvgf4fNgv/sXbfCVAdf+FnPBdKJR/7XbpTCwbCrvCbdPYnlWaUUYz4V2fPDA== + version "1.8.6" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.6.tgz#80c516a4dc264c2a69115e7578d62581ff455ed9" + integrity sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ== dependencies: type-detect "4.0.8" @@ -1718,9 +1767,9 @@ integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== "@tsconfig/node16@^1.0.2": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e" - integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== + version "1.0.4" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== "@typechain/ethers-v5@^9.0.0": version "9.0.0" @@ -1731,12 +1780,12 @@ ts-essentials "^7.0.1" "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": - version "7.1.20" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.20.tgz#e168cdd612c92a2d335029ed62ac94c95b362359" - integrity sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ== + version "7.20.1" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.1.tgz#916ecea274b0c776fec721e333e55762d3a9614b" + integrity sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw== dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" "@types/babel__generator" "*" "@types/babel__template" "*" "@types/babel__traverse" "*" @@ -1757,16 +1806,21 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.18.2" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.2.tgz#235bf339d17185bdec25e024ca19cce257cc7309" - integrity sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg== + version "7.20.1" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.1.tgz#dd6f1d2411ae677dcb2db008c962598be31d6acf" + integrity sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg== dependencies: - "@babel/types" "^7.3.0" + "@babel/types" "^7.20.7" + +"@types/deep-equal@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/deep-equal/-/deep-equal-1.0.1.tgz#71cfabb247c22bcc16d536111f50c0ed12476b03" + integrity sha512-mMUu4nWHLBlHtxXY17Fg6+ucS/MnndyOWyOe7MmwkoMYxvfQU2ajtRaEvqSUv+aVkMqH/C0NCI8UoVfRNQ10yg== "@types/graceful-fs@^4.1.2": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" - integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== + version "4.1.6" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae" + integrity sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw== dependencies: "@types/node" "*" @@ -1798,9 +1852,9 @@ pretty-format "^26.0.0" "@types/json-schema@^7.0.7": - version "7.0.11" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" - integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== + version "7.0.12" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" + integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== "@types/json5@^0.0.29": version "0.0.29" @@ -1813,35 +1867,30 @@ integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== "@types/node@*": - version "18.11.9" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.9.tgz#02d013de7058cea16d36168ef2fc653464cfbad4" - integrity sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg== - -"@types/node@^14.0.0": - version "14.18.33" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.33.tgz#8c29a0036771569662e4635790ffa9e057db379b" - integrity sha512-qelS/Ra6sacc4loe/3MSjXNL1dNQ/GjxNHVzuChwMfmk7HuycRLVQN2qNY3XahK+fZc5E2szqQSKUyAF0E+2bg== + version "20.3.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.3.2.tgz#fa6a90f2600e052a03c18b8cb3fd83dd4e599898" + integrity sha512-vOBLVQeCQfIcF/2Y7eKFTqrMnizK5lRNQ7ykML/5RuwVXVWxYkgwS7xbt4B6fKCUPgbSL5FSsjHQpaGQP/dQmw== "@types/normalize-package-data@^2.4.0": version "2.4.1" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== -"@types/parse-json@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" - integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== - "@types/prettier@^2.1.1", "@types/prettier@^2.1.5": - version "2.7.1" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.1.tgz#dfd20e2dc35f027cdd6c1908e80a5ddc7499670e" - integrity sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow== + version "2.7.3" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" + integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== "@types/qs@^6.9.7": version "6.9.7" resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== +"@types/semver@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" + integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== + "@types/stack-utils@^2.0.0": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" @@ -1853,16 +1902,16 @@ integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== "@types/yargs@^15.0.0": - version "15.0.14" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.14.tgz#26d821ddb89e70492160b66d10a0eb6df8f6fb06" - integrity sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ== + version "15.0.15" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.15.tgz#e609a2b1ef9e05d90489c2f5f45bbfb2be092158" + integrity sha512-IziEYMU9XoVj8hWg7k+UJrXALkGFjWJhn5QFEv9q4p+v40oZhSuC135M38st8XPjICL7Ey4TV64ferBGUoJhBg== dependencies: "@types/yargs-parser" "*" "@types/yargs@^16.0.0": - version "16.0.4" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.4.tgz#26aad98dd2c2a38e421086ea9ad42b9e51642977" - integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw== + version "16.0.5" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.5.tgz#12cc86393985735a283e387936398c2f9e5f88e3" + integrity sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ== dependencies: "@types/yargs-parser" "*" @@ -1978,9 +2027,9 @@ acorn@^7.1.1, acorn@^7.4.0: integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== acorn@^8.2.4, acorn@^8.4.1: - version "8.8.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" - integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== + version "8.9.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.9.0.tgz#78a16e3b2bcc198c10822786fa6679e245db5b59" + integrity sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ== add-stream@^1.0.0: version "1.0.0" @@ -2010,9 +2059,9 @@ ajv@^6.10.0, ajv@^6.12.4: uri-js "^4.2.2" ajv@^8.0.1, ajv@^8.11.0: - version "8.11.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.2.tgz#aecb20b50607acf2569b6382167b65a96008bb78" - integrity sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg== + version "8.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== dependencies: fast-deep-equal "^3.1.1" json-schema-traverse "^1.0.0" @@ -2056,9 +2105,9 @@ ansi-styles@^5.0.0: integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== anymatch@^3.0.3: - version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" - integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== dependencies: normalize-path "^3.0.0" picomatch "^2.0.4" @@ -2075,6 +2124,11 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + array-back@^3.0.1, array-back@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" @@ -2085,12 +2139,20 @@ array-back@^4.0.1, array-back@^4.0.2: resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.2.tgz#8004e999a6274586beeb27342168652fdb89fa1e" integrity sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg== +array-buffer-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" + integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== + dependencies: + call-bind "^1.0.2" + is-array-buffer "^3.0.1" + array-ify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" integrity sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng== -array-includes@^3.1.4: +array-includes@^3.1.6: version "3.1.6" resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.6.tgz#9e9e720e194f198266ba9e18c29e6a9b0e4b225f" integrity sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw== @@ -2118,7 +2180,7 @@ array-uniq@^1.0.1: resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== -array.prototype.flat@^1.2.5: +array.prototype.flat@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2" integrity sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA== @@ -2128,6 +2190,16 @@ array.prototype.flat@^1.2.5: es-abstract "^1.20.4" es-shim-unscopables "^1.0.0" +array.prototype.flatmap@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz#1aae7903c2100433cb8261cd4ed310aab5c4a183" + integrity sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + es-shim-unscopables "^1.0.0" + arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" @@ -2155,6 +2227,11 @@ at-least-node@^1.0.0: resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + axios@^0.21.1: version "0.21.4" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" @@ -2197,29 +2274,29 @@ babel-plugin-jest-hoist@^27.5.1: "@types/babel__core" "^7.0.0" "@types/babel__traverse" "^7.0.6" -babel-plugin-polyfill-corejs2@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz#5d1bd3836d0a19e1b84bbf2d9640ccb6f951c122" - integrity sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q== +babel-plugin-polyfill-corejs2@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.3.tgz#75044d90ba5043a5fb559ac98496f62f3eb668fd" + integrity sha512-bM3gHc337Dta490gg+/AseNB9L4YLHxq1nGKZZSHbhXv4aTYU2MD2cjza1Ru4S6975YLTaL1K8uJf6ukJhhmtw== dependencies: "@babel/compat-data" "^7.17.7" - "@babel/helper-define-polyfill-provider" "^0.3.3" + "@babel/helper-define-polyfill-provider" "^0.4.0" semver "^6.1.1" -babel-plugin-polyfill-corejs3@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz#56ad88237137eade485a71b52f72dbed57c6230a" - integrity sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA== +babel-plugin-polyfill-corejs3@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.1.tgz#39248263c38191f0d226f928d666e6db1b4b3a8a" + integrity sha512-ikFrZITKg1xH6pLND8zT14UPgjKHiGLqex7rGEZCH2EvhsneJaJPemmpQaIZV5AL03II+lXylw3UmddDK8RU5Q== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.3" - core-js-compat "^3.25.1" + "@babel/helper-define-polyfill-provider" "^0.4.0" + core-js-compat "^3.30.1" -babel-plugin-polyfill-regenerator@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz#390f91c38d90473592ed43351e801a9d3e0fd747" - integrity sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw== +babel-plugin-polyfill-regenerator@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.0.tgz#e7344d88d9ef18a3c47ded99362ae4a757609380" + integrity sha512-hDJtKjMLVa7Z+LwnTCxoDLQj6wdc+B8dun7ayF2fYieI6OzfuvcLMB32ihJZ4UhCBwNYGl5bg/x/P9cMdnkc2g== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.3" + "@babel/helper-define-polyfill-provider" "^0.4.0" babel-preset-current-node-syntax@^1.0.0: version "1.0.1" @@ -2313,15 +2390,15 @@ browser-process-hrtime@^1.0.0: resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== -browserslist@^4.21.3, browserslist@^4.21.4: - version "4.21.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" - integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== +browserslist@^4.21.3, browserslist@^4.21.5: + version "4.21.9" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.9.tgz#e11bdd3c313d7e2a9e87e8b4b0c7872b13897635" + integrity sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg== dependencies: - caniuse-lite "^1.0.30001400" - electron-to-chromium "^1.4.251" - node-releases "^2.0.6" - update-browserslist-db "^1.0.9" + caniuse-lite "^1.0.30001503" + electron-to-chromium "^1.4.431" + node-releases "^2.0.12" + update-browserslist-db "^1.0.11" bs-logger@0.x: version "0.2.6" @@ -2387,10 +2464,10 @@ camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001400: - version "1.0.30001431" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001431.tgz#e7c59bd1bc518fae03a4656be442ce6c4887a795" - integrity sha512-zBUoFU0ZcxpvSt9IU66dXVT/3ctO1cy4y9cscs1szkPlcWb6pasYM144GqrUygUbT+k7cmUCW61cvskjcv0enQ== +caniuse-lite@^1.0.30001503: + version "1.0.30001508" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001508.tgz#4461bbc895c692a96da399639cc1e146e7302a33" + integrity sha512-sdQZOJdmt3GJs1UMNpCCCyeuS2IEGLXnHyAo9yIO5JJDjbjoVRij4M1qep6P6gFpptD1PqIYgzM+gwJbOi92mw== chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" @@ -2420,14 +2497,14 @@ chardet@^0.7.0: integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== ci-info@^3.2.0: - version "3.6.1" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.6.1.tgz#7594f1c95cb7fdfddee7af95a13af7dbc67afdcf" - integrity sha512-up5ggbaDqOqJ4UqLKZ2naVkyqSJQgJi5lwD6b6mM748ysrghDBX0bx/qJTUHzw7zu6Mq4gycviSF5hJnwceD8w== + version "3.8.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" + integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== cjs-module-lexer@^1.0.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" - integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== cli-cursor@^3.1.0: version "3.1.0" @@ -2437,9 +2514,9 @@ cli-cursor@^3.1.0: restore-cursor "^3.1.0" cli-spinners@^2.5.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.7.0.tgz#f815fd30b5f9eaac02db604c7a231ed7cb2f797a" - integrity sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw== + version "2.9.0" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.0.tgz#5881d0ad96381e117bbe07ad91f2008fe6ffd8db" + integrity sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g== cli-width@^3.0.0: version "3.0.0" @@ -2527,9 +2604,9 @@ commander@^2.18.0: integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== commitizen@^4.0.3: - version "4.2.5" - resolved "https://registry.yarnpkg.com/commitizen/-/commitizen-4.2.5.tgz#48e5a5c28334c6e8ed845cc24fc9f072efd3961e" - integrity sha512-9sXju8Qrz1B4Tw7kC5KhnvwYQN88qs2zbiB8oyMsnXZyJ24PPGiNM3nHr73d32dnE3i8VJEXddBFIbOgYSEXtQ== + version "4.3.0" + resolved "https://registry.yarnpkg.com/commitizen/-/commitizen-4.3.0.tgz#0d056c542a2d2b1f9b9aba981aa32575b2849924" + integrity sha512-H0iNtClNEhT0fotHvGV3E9tDejDeS04sN1veIebsKYGMuGscFaswRoYJKmT3eW85eIJAs0F28bG2+a/9wCOfPw== dependencies: cachedir "2.3.0" cz-conventional-changelog "3.3.0" @@ -2539,10 +2616,10 @@ commitizen@^4.0.3: find-root "1.1.0" fs-extra "9.1.0" glob "7.2.3" - inquirer "8.2.4" + inquirer "8.2.5" is-utf8 "^0.2.1" lodash "4.17.21" - minimist "1.2.6" + minimist "1.2.7" strip-bom "4.0.0" strip-json-comments "3.1.1" @@ -2747,12 +2824,12 @@ convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== -core-js-compat@^3.25.1: - version "3.26.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.26.1.tgz#0e710b09ebf689d719545ac36e49041850f943df" - integrity sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A== +core-js-compat@^3.30.1, core-js-compat@^3.30.2: + version "3.31.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.31.0.tgz#4030847c0766cc0e803dcdfb30055d7ef2064bf1" + integrity sha512-hM7YCu1cU6Opx7MXNu0NuumM0ezNeAeRKadixyiQELWY3vT3De9S4J5ZBMraWV2vZnrE1Cirl0GtFtDtMUXzPw== dependencies: - browserslist "^4.21.4" + browserslist "^4.21.5" core-util-is@~1.0.0: version "1.0.3" @@ -2760,20 +2837,19 @@ core-util-is@~1.0.0: integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== cosmiconfig-typescript-loader@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.2.0.tgz#a3cfd0dd9dac86be7dbe5f53eb46ad03abdf417b" - integrity sha512-NkANeMnaHrlaSSlpKGyvn2R4rqUDeE/9E5YHx+b4nwo0R8dZyAqcih8/gxpCZvqWP9Vf6xuLpMSzSgdVEIM78g== + version "4.3.0" + resolved "https://registry.yarnpkg.com/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.3.0.tgz#c4259ce474c9df0f32274ed162c0447c951ef073" + integrity sha512-NTxV1MFfZDLPiBMjxbHRwSh5LaLcPMwNdCutmnHJCKoVnlvldPWlllonKwrsRJ5pYZBIBGRWWU2tfvzxgeSW5Q== -cosmiconfig@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" - integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== +cosmiconfig@^8.0.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.2.0.tgz#f7d17c56a590856cd1e7cee98734dca272b0d8fd" + integrity sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ== dependencies: - "@types/parse-json" "^4.0.0" import-fresh "^3.2.1" + js-yaml "^4.1.0" parse-json "^5.0.0" path-type "^4.0.0" - yaml "^1.10.0" create-require@^1.1.0: version "1.1.1" @@ -2857,13 +2933,6 @@ debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: dependencies: ms "2.1.2" -debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" @@ -2885,15 +2954,39 @@ decamelize@^1.1.0, decamelize@^1.2.0: integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== decimal.js@^10.2.1: - version "10.4.2" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.2.tgz#0341651d1d997d86065a2ce3a441fbd0d8e8b98e" - integrity sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA== + version "10.4.3" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" + integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== dedent@0.7.0, dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== +deep-equal@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.1.tgz#c72ab22f3a7d3503a4ca87dde976fe9978816739" + integrity sha512-lKdkdV6EOGoVn65XaOsPdH4rMxTZOnmFyuIkMjM1i5HHCbfjC97dawgTAy0deYNfuqUqW+Q5VrVaQYtUpSd6yQ== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.2" + es-get-iterator "^1.1.3" + get-intrinsic "^1.2.0" + is-arguments "^1.1.1" + is-array-buffer "^3.0.2" + is-date-object "^1.0.5" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + isarray "^2.0.5" + object-is "^1.1.5" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.5.0" + side-channel "^1.0.4" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.1" + which-typed-array "^1.1.9" + deep-extend@~0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -2905,9 +2998,9 @@ deep-is@^0.1.3, deep-is@~0.1.3: integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== deepmerge@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" - integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== defaults@^1.0.3: version "1.0.4" @@ -2916,10 +3009,10 @@ defaults@^1.0.3: dependencies: clone "^1.0.2" -define-properties@^1.1.3, define-properties@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" - integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== +define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" + integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== dependencies: has-property-descriptors "^1.0.0" object-keys "^1.1.1" @@ -3002,10 +3095,10 @@ dotgitignore@^2.1.0: find-up "^3.0.0" minimatch "^3.0.4" -electron-to-chromium@^1.4.251: - version "1.4.284" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592" - integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA== +electron-to-chromium@^1.4.431: + version "1.4.441" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.441.tgz#94dd9c1cbf081d83f032a4f1cd9f787e21fc24ce" + integrity sha512-LlCgQ8zgYZPymf5H4aE9itwiIWH4YlCiv1HFLmmcBeFYi5E+3eaIFnjHzYtcFQbaKfAW+CqZ9pgxo33DZuoqPg== elliptic@6.5.4: version "6.5.4" @@ -3050,34 +3143,68 @@ error-ex@^1.3.1: is-arrayish "^0.2.1" es-abstract@^1.19.0, es-abstract@^1.20.4: - version "1.20.4" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.4.tgz#1d103f9f8d78d4cf0713edcd6d0ed1a46eed5861" - integrity sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA== + version "1.21.2" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.2.tgz#a56b9695322c8a185dc25975aa3b8ec31d0e7eff" + integrity sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg== dependencies: + array-buffer-byte-length "^1.0.0" + available-typed-arrays "^1.0.5" call-bind "^1.0.2" + es-set-tostringtag "^2.0.1" es-to-primitive "^1.2.1" - function-bind "^1.1.1" function.prototype.name "^1.1.5" - get-intrinsic "^1.1.3" + get-intrinsic "^1.2.0" get-symbol-description "^1.0.0" + globalthis "^1.0.3" + gopd "^1.0.1" has "^1.0.3" has-property-descriptors "^1.0.0" + has-proto "^1.0.1" has-symbols "^1.0.3" - internal-slot "^1.0.3" + internal-slot "^1.0.5" + is-array-buffer "^3.0.2" is-callable "^1.2.7" is-negative-zero "^2.0.2" is-regex "^1.1.4" is-shared-array-buffer "^1.0.2" is-string "^1.0.7" + is-typed-array "^1.1.10" is-weakref "^1.0.2" - object-inspect "^1.12.2" + object-inspect "^1.12.3" object-keys "^1.1.1" object.assign "^4.1.4" regexp.prototype.flags "^1.4.3" safe-regex-test "^1.0.0" - string.prototype.trimend "^1.0.5" - string.prototype.trimstart "^1.0.5" + string.prototype.trim "^1.2.7" + string.prototype.trimend "^1.0.6" + string.prototype.trimstart "^1.0.6" + typed-array-length "^1.0.4" unbox-primitive "^1.0.2" + which-typed-array "^1.1.9" + +es-get-iterator@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz#3ef87523c5d464d41084b2c3c9c214f1199763d6" + integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + has-symbols "^1.0.3" + is-arguments "^1.1.1" + is-map "^2.0.2" + is-set "^2.0.2" + is-string "^1.0.7" + isarray "^2.0.5" + stop-iteration-iterator "^1.0.0" + +es-set-tostringtag@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" + integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== + dependencies: + get-intrinsic "^1.1.3" + has "^1.0.3" + has-tostringtag "^1.0.0" es-shim-unscopables@^1.0.0: version "1.0.0" @@ -3134,18 +3261,19 @@ eslint-config-prettier@^6.11.0: dependencies: get-stdin "^6.0.0" -eslint-import-resolver-node@^0.3.6: - version "0.3.6" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" - integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== +eslint-import-resolver-node@^0.3.7: + version "0.3.7" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz#83b375187d412324a1963d84fa664377a23eb4d7" + integrity sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA== dependencies: debug "^3.2.7" - resolve "^1.20.0" + is-core-module "^2.11.0" + resolve "^1.22.1" -eslint-module-utils@^2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz#4f3e41116aaf13a20792261e61d3a2e7e0583974" - integrity sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA== +eslint-module-utils@^2.7.4: + version "2.8.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" + integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== dependencies: debug "^3.2.7" @@ -3158,22 +3286,24 @@ eslint-plugin-eslint-comments@^3.2.0: ignore "^5.0.5" eslint-plugin-import@^2.22.0: - version "2.26.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz#f812dc47be4f2b72b478a021605a59fc6fe8b88b" - integrity sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA== + version "2.27.5" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz#876a6d03f52608a3e5bb439c2550588e51dd6c65" + integrity sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow== dependencies: - array-includes "^3.1.4" - array.prototype.flat "^1.2.5" - debug "^2.6.9" + array-includes "^3.1.6" + array.prototype.flat "^1.3.1" + array.prototype.flatmap "^1.3.1" + debug "^3.2.7" doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.6" - eslint-module-utils "^2.7.3" + eslint-import-resolver-node "^0.3.7" + eslint-module-utils "^2.7.4" has "^1.0.3" - is-core-module "^2.8.1" + is-core-module "^2.11.0" is-glob "^4.0.3" minimatch "^3.1.2" - object.values "^1.1.5" - resolve "^1.22.0" + object.values "^1.1.6" + resolve "^1.22.1" + semver "^6.3.0" tsconfig-paths "^3.14.1" eslint-scope@^5.1.1: @@ -3269,9 +3399,9 @@ esprima@^4.0.0, esprima@^4.0.1: integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== dependencies: estraverse "^5.1.0" @@ -3406,9 +3536,9 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== dependencies: reusify "^1.0.4" @@ -3551,6 +3681,13 @@ follow-redirects@^1.14.0: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + form-data@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" @@ -3618,7 +3755,7 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== -functions-have-names@^1.2.2: +functions-have-names@^1.2.2, functions-have-names@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== @@ -3633,13 +3770,14 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" - integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" + integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== dependencies: function-bind "^1.1.1" has "^1.0.3" + has-proto "^1.0.1" has-symbols "^1.0.3" get-package-type@^0.1.0: @@ -3747,9 +3885,9 @@ glob@7.2.3, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glo path-is-absolute "^1.0.0" glob@^8.0.3: - version "8.0.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-8.0.3.tgz#415c6eb2deed9e502c68fa44a272e6da6eeca42e" - integrity sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ== + version "8.1.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" + integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -3790,12 +3928,19 @@ globals@^11.1.0: integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== globals@^13.6.0, globals@^13.9.0: - version "13.17.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.17.0.tgz#902eb1e680a41da93945adbdcb5a9f361ba69bd4" - integrity sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw== + version "13.20.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" + integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== dependencies: type-fest "^0.20.2" +globalthis@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" + integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== + dependencies: + define-properties "^1.1.3" + globby@^11.0.3: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" @@ -3819,10 +3964,17 @@ globby@^6.1.0: pify "^2.0.0" pinkie-promise "^2.0.0" +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.9: - version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== handlebars@^4.7.7: version "4.7.7" @@ -3863,6 +4015,11 @@ has-property-descriptors@^1.0.0: dependencies: get-intrinsic "^1.1.1" +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" @@ -3975,9 +4132,9 @@ ignore@^4.0.6: integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== ignore@^5.0.5, ignore@^5.1.8, ignore@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" - integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== import-fresh@^3.0.0, import-fresh@^3.2.1: version "3.3.0" @@ -4023,10 +4180,10 @@ ini@^1.3.2, ini@^1.3.4: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== -inquirer@8.2.4: - version "8.2.4" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.4.tgz#ddbfe86ca2f67649a67daa6f1051c128f684f0b4" - integrity sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg== +inquirer@8.2.5: + version "8.2.5" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.5.tgz#d8654a7542c35a9b9e069d27e2df4858784d54f8" + integrity sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ== dependencies: ansi-escapes "^4.2.1" chalk "^4.1.1" @@ -4044,15 +4201,32 @@ inquirer@8.2.4: through "^2.3.6" wrap-ansi "^7.0.0" -internal-slot@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" - integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== +internal-slot@^1.0.4, internal-slot@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" + integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== dependencies: - get-intrinsic "^1.1.0" + get-intrinsic "^1.2.0" has "^1.0.3" side-channel "^1.0.4" +is-arguments@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" + integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.0" + is-typed-array "^1.1.10" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -4073,19 +4247,19 @@ is-boolean-object@^1.1.0: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-callable@^1.1.4, is-callable@^1.2.7: +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== -is-core-module@^2.5.0, is-core-module@^2.8.1, is-core-module@^2.9.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" - integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== +is-core-module@^2.11.0, is-core-module@^2.5.0: + version "2.12.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" + integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg== dependencies: has "^1.0.3" -is-date-object@^1.0.1: +is-date-object@^1.0.1, is-date-object@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== @@ -4124,6 +4298,11 @@ is-interactive@^1.0.0: resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== +is-map@^2.0.1, is-map@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" + integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== + is-negative-zero@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" @@ -4164,6 +4343,11 @@ is-regex@^1.1.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" +is-set@^2.0.1, is-set@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" + integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== + is-shared-array-buffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" @@ -4197,6 +4381,17 @@ is-text-path@^1.0.1: dependencies: text-extensions "^1.0.0" +is-typed-array@^1.1.10, is-typed-array@^1.1.9: + version "1.1.10" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" + integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + is-typedarray@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" @@ -4212,6 +4407,11 @@ is-utf8@^0.2.1: resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" integrity sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q== +is-weakmap@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" + integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== + is-weakref@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" @@ -4219,6 +4419,14 @@ is-weakref@^1.0.2: dependencies: call-bind "^1.0.2" +is-weakset@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.2.tgz#4569d67a747a1ce5a994dfd4ef6dcea76e7c0a1d" + integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + is-windows@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -4231,6 +4439,11 @@ is-wsl@^2.1.1: dependencies: is-docker "^2.0.0" +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -4523,9 +4736,9 @@ jest-mock@^27.5.1: "@types/node" "*" jest-pnp-resolver@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" - integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== + version "1.2.3" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" + integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== jest-regex-util@^27.5.1: version "27.5.1" @@ -4704,14 +4917,14 @@ jest@^27.0.6: jest-cli "^27.5.1" joi@^17.7.0: - version "17.7.0" - resolved "https://registry.yarnpkg.com/joi/-/joi-17.7.0.tgz#591a33b1fe1aca2bc27f290bcad9b9c1c570a6b3" - integrity sha512-1/ugc8djfn93rTE3WRKdCzGGt/EtiYKxITMO4Wiv6q5JL1gl9ePt4kBsl1S499nbosspfctIQTpYIhSmHA3WAg== + version "17.9.2" + resolved "https://registry.yarnpkg.com/joi/-/joi-17.9.2.tgz#8b2e4724188369f55451aebd1d0b1d9482470690" + integrity sha512-Itk/r+V4Dx0V3c7RLFdRh12IOjySm2/WGPMubBT92cQvRfYZhPM2W0hZlctjj72iES8jsRCwp7S/cRmWBnJ4nw== dependencies: "@hapi/hoek" "^9.0.0" "@hapi/topo" "^5.0.0" "@sideway/address" "^4.1.3" - "@sideway/formula" "^3.0.0" + "@sideway/formula" "^3.0.1" "@sideway/pinpoint" "^2.0.0" js-sha3@0.8.0, js-sha3@^0.8.0: @@ -4732,6 +4945,13 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + jsdom@^16.6.0: version "16.7.0" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" @@ -4805,12 +5025,12 @@ json-stringify-safe@^5.0.1: resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== -json5@2.x, json5@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" - integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== +json5@2.x, json5@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== -json5@^1.0.1: +json5@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== @@ -4939,6 +5159,11 @@ lodash.ismatch@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" integrity sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g== +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== + lodash.map@^4.5.1: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" @@ -4954,12 +5179,22 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash.mergewith@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55" + integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ== + lodash.truncate@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== -lodash@4.17.21, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.7.0: +lodash.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== + +lodash@4.17.21, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.21, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -4977,6 +5212,13 @@ longest@^2.0.1: resolved "https://registry.yarnpkg.com/longest/-/longest-2.0.1.tgz#781e183296aa94f6d4d916dc335d0d17aefa23f8" integrity sha512-Ajzxb8CM6WAnFjgiloPsI3bF+WCxcvhdIG3KNA2KN962+tdBsHcuQ4k4qX/EcS/2CRkcc0iAkR956Nib6aXU/Q== +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -5019,9 +5261,9 @@ map-obj@^4.0.0: integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ== marked@^4.0.16: - version "4.2.2" - resolved "https://registry.yarnpkg.com/marked/-/marked-4.2.2.tgz#1d2075ad6cdfe42e651ac221c32d949a26c0672a" - integrity sha512-JjBTFTAvuTgANXx82a5vzK9JLSMoV6V3LBVn4Uhdso6t7vXrGx7g1Cd2r6NYSsxrYbQGFCMqBDhFHyK5q2UvcQ== + version "4.3.0" + resolved "https://registry.yarnpkg.com/marked/-/marked-4.3.0.tgz#796362821b019f734054582038b116481b456cf3" + integrity sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A== memorystream@^0.3.1: version "0.3.1" @@ -5125,9 +5367,9 @@ minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: brace-expansion "^1.1.7" minimatch@^5.0.1, minimatch@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7" - integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg== + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== dependencies: brace-expansion "^2.0.1" @@ -5140,16 +5382,16 @@ minimist-options@4.1.0, minimist-options@^4.0.2: is-plain-obj "^1.1.0" kind-of "^6.0.3" -minimist@1.2.6: - version "1.2.6" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" - integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== - -minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: +minimist@1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== +minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + mkdirp@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" @@ -5160,11 +5402,6 @@ modify-values@^1.0.0: resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" @@ -5200,10 +5437,10 @@ node-int64@^0.4.0: resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== -node-releases@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" - integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== +node-releases@^2.0.12: + version "2.0.12" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.12.tgz#35627cc224a23bfb06fb3380f2b3afaaa7eb1039" + integrity sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ== normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: version "2.5.0" @@ -5253,19 +5490,27 @@ npm-run-path@^4.0.1: path-key "^3.0.0" nwsapi@^2.2.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.2.tgz#e5418863e7905df67d51ec95938d67bf801f0bb0" - integrity sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw== + version "2.2.5" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.5.tgz#a52744c61b3889dd44b0a158687add39b8d935e2" + integrity sha512-6xpotnECFy/og7tKSBVmUNft7J3jyXAka4XvG6AUhFWRz+Q/Ljus7znJAA3bxColfQLdS+XsjoodtJfCgeTEFQ== object-assign@^4.0.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== -object-inspect@^1.12.2, object-inspect@^1.9.0: - version "1.12.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" - integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== +object-inspect@^1.12.3, object-inspect@^1.9.0: + version "1.12.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" + integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== + +object-is@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" object-keys@^1.1.1: version "1.1.1" @@ -5282,7 +5527,7 @@ object.assign@^4.1.4: has-symbols "^1.0.3" object-keys "^1.1.1" -object.values@^1.1.5: +object.values@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.6.tgz#4abbaa71eba47d63589d402856f908243eea9b1d" integrity sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw== @@ -5547,9 +5792,9 @@ pinkie@^2.0.0: integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== pirates@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" - integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== + version "4.0.6" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== pkg-dir@^4.1.0, pkg-dir@^4.2.0: version "4.2.0" @@ -5569,9 +5814,9 @@ prelude-ls@~1.1.2: integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== prettier@^2.1.1, prettier@^2.1.2: - version "2.7.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64" - integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g== + version "2.8.8" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== pretty-format@^26.0.0, pretty-format@^26.6.2: version "26.6.2" @@ -5616,9 +5861,9 @@ psl@^1.1.33: integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + version "2.3.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== q@^1.5.1: version "1.5.1" @@ -5626,9 +5871,9 @@ q@^1.5.1: integrity sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw== qs@^6.10.1: - version "6.11.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" - integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + version "6.11.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" + integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== dependencies: side-channel "^1.0.4" @@ -5689,18 +5934,18 @@ read-pkg@^5.2.0: type-fest "^0.6.0" readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stream@^3.4.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== dependencies: inherits "^2.0.3" string_decoder "^1.1.1" util-deprecate "^1.0.1" readable-stream@~2.3.6: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -5740,48 +5985,43 @@ regenerate@^1.4.2: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== -regenerator-runtime@^0.13.10: - version "0.13.10" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz#ed07b19616bcbec5da6274ebc75ae95634bfc2ee" - integrity sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw== +regenerator-runtime@^0.13.11: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== -regenerator-transform@^0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.0.tgz#cbd9ead5d77fae1a48d957cf889ad0586adb6537" - integrity sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg== +regenerator-transform@^0.15.1: + version "0.15.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.1.tgz#f6c4e99fc1b4591f780db2586328e4d9a9d8dc56" + integrity sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg== dependencies: "@babel/runtime" "^7.8.4" -regexp.prototype.flags@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" - integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== +regexp.prototype.flags@^1.4.3, regexp.prototype.flags@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz#fe7ce25e7e4cca8db37b6634c8a2c7009199b9cb" + integrity sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA== dependencies: call-bind "^1.0.2" - define-properties "^1.1.3" - functions-have-names "^1.2.2" + define-properties "^1.2.0" + functions-have-names "^1.2.3" regexpp@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== -regexpu-core@^5.1.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.2.1.tgz#a69c26f324c1e962e9ffd0b88b055caba8089139" - integrity sha512-HrnlNtpvqP1Xkb28tMhBUO2EbyUHdQlsnlAhzWcwHy8WJR53UWr7/MAvqrsQKMbV4qdpv03oTMG8iIhfsPFktQ== +regexpu-core@^5.3.1: + version "5.3.2" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.3.2.tgz#11a2b06884f3527aec3e93dbbf4a3b958a95546b" + integrity sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ== dependencies: + "@babel/regjsgen" "^0.8.0" regenerate "^1.4.2" regenerate-unicode-properties "^10.1.0" - regjsgen "^0.7.1" regjsparser "^0.9.1" unicode-match-property-ecmascript "^2.0.0" - unicode-match-property-value-ecmascript "^2.0.0" - -regjsgen@^0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.7.1.tgz#ee5ef30e18d3f09b7c369b76e7c2373ed25546f6" - integrity sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA== + unicode-match-property-value-ecmascript "^2.1.0" regjsparser@^0.9.1: version "0.9.1" @@ -5838,16 +6078,16 @@ resolve-global@^1.0.0: global-dirs "^0.1.1" resolve.exports@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" - integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== + version "1.1.1" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.1.tgz#05cfd5b3edf641571fd46fa608b610dda9ead999" + integrity sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ== -resolve@^1.10.0, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.22.0: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== +resolve@^1.10.0, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.22.1: + version "1.22.2" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" + integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== dependencies: - is-core-module "^2.9.0" + is-core-module "^2.11.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" @@ -5884,9 +6124,9 @@ run-parallel@^1.1.9: queue-microtask "^1.2.2" rxjs@^7.5.5: - version "7.5.7" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.7.tgz#2ec0d57fdc89ece220d2e702730ae8f1e49def39" - integrity sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA== + version "7.8.1" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== dependencies: tslib "^2.1.0" @@ -5931,10 +6171,10 @@ scrypt-js@3.0.1: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@7.x, semver@^7.1.1, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: - version "7.3.8" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" - integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== +semver@7.x, semver@^7.1.1, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.5.2: + version "7.5.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" + integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== dependencies: lru-cache "^6.0.0" @@ -5968,9 +6208,9 @@ shebang-regex@^3.0.0: integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== shell-quote@^1.6.1: - version "1.7.4" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.4.tgz#33fe15dee71ab2a81fcbd3a52106c5cfb9fb75d8" - integrity sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw== + version "1.8.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" + integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== shiki@^0.10.1: version "0.10.1" @@ -6033,9 +6273,9 @@ source-map@^0.7.3: integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + version "3.2.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" + integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== dependencies: spdx-expression-parse "^3.0.0" spdx-license-ids "^3.0.0" @@ -6054,9 +6294,9 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.12" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz#69077835abe2710b65f03969898b6637b505a779" - integrity sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA== + version "3.0.13" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz#7189a474c46f8d47c7b0da4b987bb45e908bd2d5" + integrity sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w== split2@^3.0.0: version "3.2.2" @@ -6104,6 +6344,13 @@ standard-version@^9.0.0: stringify-package "^1.0.1" yargs "^16.0.0" +stop-iteration-iterator@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz#6a60be0b4ee757d1ed5254858ec66b10c49285e4" + integrity sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ== + dependencies: + internal-slot "^1.0.4" + string-format@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/string-format/-/string-format-2.0.0.tgz#f2df2e7097440d3b65de31b6d40d54c96eaffb9b" @@ -6135,7 +6382,16 @@ string.prototype.padend@^3.0.0: define-properties "^1.1.4" es-abstract "^1.20.4" -string.prototype.trimend@^1.0.5: +string.prototype.trim@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz#a68352740859f6893f14ce3ef1bb3037f7a90533" + integrity sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +string.prototype.trimend@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ== @@ -6144,7 +6400,7 @@ string.prototype.trimend@^1.0.5: define-properties "^1.1.4" es-abstract "^1.20.4" -string.prototype.trimstart@^1.0.5: +string.prototype.trimstart@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4" integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== @@ -6325,9 +6581,9 @@ text-table@^0.2.0: integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== throat@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" - integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== + version "6.0.2" + resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.2.tgz#51a3fbb5e11ae72e2cf74861ed5c8020f89f29fe" + integrity sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ== through2@^2.0.0: version "2.0.5" @@ -6382,9 +6638,9 @@ token-types@^2.0.0: ieee754 "^1.2.1" tough-cookie@^4.0.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874" - integrity sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ== + version "4.1.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf" + integrity sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw== dependencies: psl "^1.1.33" punycode "^2.1.1" @@ -6411,9 +6667,9 @@ trim-repeated@^1.0.0: escape-string-regexp "^1.0.2" ts-command-line-args@^2.2.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/ts-command-line-args/-/ts-command-line-args-2.3.1.tgz#b6188e42efc6cf7a8898e438a873fbb15505ddd6" - integrity sha512-FR3y7pLl/fuUNSmnPhfLArGqRrpojQgIEEOVzYx9DhTmfIN7C9RWSfpkJEF4J+Gk7aVx5pak8I7vWZsaN4N84g== + version "2.5.1" + resolved "https://registry.yarnpkg.com/ts-command-line-args/-/ts-command-line-args-2.5.1.tgz#e64456b580d1d4f6d948824c274cf6fa5f45f7f0" + integrity sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw== dependencies: chalk "^4.1.0" command-line-args "^5.1.1" @@ -6459,20 +6715,20 @@ ts-node@^10.8.1: yn "3.1.1" ts-unused-exports@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/ts-unused-exports/-/ts-unused-exports-8.0.0.tgz#6dd15ff26286e0b7e5663cda3b98c77ea6f3ffe7" - integrity sha512-gylHFyJqC80PSb4zy35KTckykEW1vmKjnOHjBeX9iKBo4b/SzqQIcXXbYSuif4YMgNm6ewFF62VM1C9z0bGZPw== + version "8.0.5" + resolved "https://registry.yarnpkg.com/ts-unused-exports/-/ts-unused-exports-8.0.5.tgz#43b1ac25822ec9445b5fc3e57862c0d1f23471cb" + integrity sha512-ewEHxTtQsYQFQCI12CnMx8D0xxn1/Uui1Wr5jbiX4me+4LlSiOGvt4mGz0hxtIC3eElVaLrKEPbeT3TPrm4JvA== dependencies: chalk "^4.0.0" tsconfig-paths "^3.9.0" tsconfig-paths@^3.14.1, tsconfig-paths@^3.9.0: - version "3.14.1" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" - integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== + version "3.14.2" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088" + integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g== dependencies: "@types/json5" "^0.0.29" - json5 "^1.0.1" + json5 "^1.0.2" minimist "^1.2.6" strip-bom "^3.0.0" @@ -6482,9 +6738,9 @@ tslib@^1.8.1: integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslib@^2.1.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" - integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== + version "2.6.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3" + integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA== tsutils@^3.21.0: version "3.21.0" @@ -6558,6 +6814,15 @@ typechain@^7.0.0: ts-command-line-args "^2.2.0" ts-essentials "^7.0.1" +typed-array-length@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" + integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + is-typed-array "^1.1.9" + typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" @@ -6586,15 +6851,15 @@ typedoc@^0.22.11: minimatch "^5.1.0" shiki "^0.10.1" -typescript@^4.6.4: - version "4.8.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6" - integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== +"typescript@^4.6.4 || ^5.0.0": + version "5.1.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.3.tgz#8d84219244a6b40b6fb2b33cc1c062f715b9e826" + integrity sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw== typescript@^4.7.0: - version "4.9.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.3.tgz#3aea307c1746b8c384435d8ac36b8a2e580d85db" - integrity sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA== + version "4.9.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" + integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== typical@^4.0.0: version "4.0.0" @@ -6634,10 +6899,10 @@ unicode-match-property-ecmascript@^2.0.0: unicode-canonical-property-names-ecmascript "^2.0.0" unicode-property-aliases-ecmascript "^2.0.0" -unicode-match-property-value-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" - integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== +unicode-match-property-value-ecmascript@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz#cb5fffdcd16a05124f5a4b0bf7c3770208acbbe0" + integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== unicode-property-aliases-ecmascript@^2.0.0: version "2.1.0" @@ -6659,10 +6924,10 @@ universalify@^2.0.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== -update-browserslist-db@^1.0.9: - version "1.0.10" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" - integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== +update-browserslist-db@^1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" + integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== dependencies: escalade "^3.1.1" picocolors "^1.0.0" @@ -6720,9 +6985,9 @@ validate-npm-package-license@^3.0.1: spdx-expression-parse "^3.0.0" vscode-oniguruma@^1.6.1: - version "1.6.2" - resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz#aeb9771a2f1dbfc9083c8a7fdd9cccaa3f386607" - integrity sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA== + version "1.7.0" + resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz#439bfad8fe71abd7798338d1cd3dc53a8beea94b" + integrity sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA== vscode-textmate@5.2.0: version "5.2.0" @@ -6799,6 +7064,28 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" +which-collection@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" + integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== + dependencies: + is-map "^2.0.1" + is-set "^2.0.1" + is-weakmap "^2.0.1" + is-weakset "^2.0.1" + +which-typed-array@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" + integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + is-typed-array "^1.1.10" + which@^1.2.14, which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -6885,16 +7172,16 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yaml@^1.10.0: - version "1.10.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== - yargs-parser@20.x, yargs-parser@^20.2.2, yargs-parser@^20.2.3: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"