diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..87902af --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,42 @@ + +# Changelog + +## 0.4.1 + +- Add configuration for more compatibility +- Bump dependencies + +## 0.4.0 + +- Change secp256k1 library to [noble-curves](https://github.com/paulmillr/noble-curves), which is [audited](https://github.com/paulmillr/noble-curves/tree/main/audit) +- Change hash library to [noble-hashes](https://github.com/paulmillr/noble-hashes) +- Change test library to [jest](https://jestjs.io/) +- Bump dependencies +- Drop Node 14 support + +## 0.3.1 ~ 0.3.17 + +- Support Node 18, 20 +- Drop Node 10, 12 support +- Bump dependencies +- Update documentation +- Extract constant variables and rename some parameters + +## 0.3.0 + +- API change: `encrypt/decrypt` now can take both hex `string` and `Buffer` + +## 0.2.0 + +- API change: use `HKDF-sha256` to derive shared keys instead of `sha256` +- Bump dependencies +- Update documentation + +## 0.1.1 ~ 0.1.5 + +- Bump dependencies +- Update documentation + +## 0.1.0 + +- First beta version release diff --git a/README.md b/README.md index 5ba8cb8..ef7f9d0 100644 --- a/README.md +++ b/README.md @@ -89,39 +89,29 @@ readonly uncompressed: Buffer; readonly compressed: Buffer; ``` -## Release Notes +## Configuration -### 0.4.0 +Ephemeral key format in the payload and shared key in the key derivation can be configured as compressed or uncompressed format. -- Change secp256k1 library to [noble-curves](https://github.com/paulmillr/noble-curves), which is [audited](https://github.com/paulmillr/noble-curves/tree/main/audit) -- Change hash library to [noble-hashes](https://github.com/paulmillr/noble-hashes) -- Change test library to [jest](https://jestjs.io/) -- Bump dependencies -- Drop Node 14 support +```ts +class Config { + isEphemeralKeyCompressed: boolean = false; + isHkdfKeyCompressed: boolean = false; + symmetricAlgorithm: Algorithm = "aes-256-gcm"; // currently we only support aes-256-gcm + symmetricNonceLength: NonceLength = 16; +} -### 0.3.1 ~ 0.3.17 - -- Support Node 18, 20 -- Drop Node 10, 12 support -- Bump dependencies -- Update documentation -- Extract constant variables and rename some parameters - -### 0.3.0 - -- API change: `encrypt/decrypt` now can take both hex `string` and `Buffer` +export const ECIES_CONFIG = new Config(); +``` -### 0.2.0 +For example, if you set `isEphemeralKeyCompressed = true`, the payload would be like: `33 Bytes + AES` instead of `65 Bytes + AES`. -- API change: use `HKDF-sha256` to derive shared keys instead of `sha256` -- Bump dependencies -- Update documentation +If you set `isHkdfKeyCompressed = true`, the hkdf key would be derived from `ephemeral public key (compressed) + shared public key (compressed)` instead of `ephemeral public key (uncompressed) + shared public key (uncompressed)`. -### 0.1.1 ~ 0.1.5 +If you set `symmetricNonceLength = 12`, then the nonce of aes-256-gcm would be 12 bytes. -- Bump dependencies -- Update documentation +For compatibility, make sure different applications share the same configuration. -### 0.1.0 +## Changelog -- First beta version release +See [CHANGELOG.md](./CHANGELOG.md) diff --git a/package.json b/package.json index 6892ed5..21bf22f 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,9 @@ "email": "to.be.impressive@gmail.com", "url": "https://github.com/kigawas" }, + "engines": { + "node": ">=16.0.0" + }, "keywords": [ "secp256k1", "crypto", @@ -29,15 +32,15 @@ "type": "git", "url": "https://github.com/ecies/js.git" }, - "version": "0.4.0", + "version": "0.4.1", "dependencies": { "@noble/curves": "^1.1.0" }, "devDependencies": { "@types/jest": "^29.5.2", - "@types/node": "^20.3.2", + "@types/node": "^20.4.2", "axios": "^1.4.0", - "jest": "^29.5.0", + "jest": "^29.6.1", "ts-jest": "^29.1.0", "ts-node": "^10.9.1", "typescript": "^5.1.5" diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 0000000..447217b --- /dev/null +++ b/src/config.ts @@ -0,0 +1,22 @@ +import { COMPRESSED_PUBLIC_KEY_SIZE, UNCOMPRESSED_PUBLIC_KEY_SIZE } from "./consts"; + +export type SymmetricAlgorithm = "aes-256-gcm"; +export type NonceLength = 12 | 16 | 24; // bytes + +class Config { + isEphemeralKeyCompressed: boolean = false; + isHkdfKeyCompressed: boolean = false; + symmetricAlgorithm: SymmetricAlgorithm = "aes-256-gcm"; + symmetricNonceLength: NonceLength = 16; +} + +export const ECIES_CONFIG = new Config(); + +export const isEphemeralKeyCompressed = () => ECIES_CONFIG.isEphemeralKeyCompressed; +export const isHkdfKeyCompressed = () => ECIES_CONFIG.isHkdfKeyCompressed; +export const ephemeralKeySize = () => + ECIES_CONFIG.isEphemeralKeyCompressed + ? COMPRESSED_PUBLIC_KEY_SIZE + : UNCOMPRESSED_PUBLIC_KEY_SIZE; +export const symmetricAlgorithm = () => ECIES_CONFIG.symmetricAlgorithm; +export const symmetricNonceLength = () => ECIES_CONFIG.symmetricNonceLength; diff --git a/src/consts.ts b/src/consts.ts index 2d6ceb9..8c81b98 100644 --- a/src/consts.ts +++ b/src/consts.ts @@ -1,6 +1,6 @@ +export const COMPRESSED_PUBLIC_KEY_SIZE = 33; export const UNCOMPRESSED_PUBLIC_KEY_SIZE = 65; -export const AES_IV_LENGTH = 16; -export const AES_TAG_LENGTH = 16; -export const AES_IV_PLUS_TAG_LENGTH = AES_IV_LENGTH + AES_TAG_LENGTH; +export const ETH_PUBLIC_KEY_SIZE = 64; export const SECRET_KEY_LENGTH = 32; export const ONE = BigInt(1); +export const AEAD_TAG_LENGTH = 16; diff --git a/src/index.ts b/src/index.ts index 8ed71ff..e90cece 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -import { UNCOMPRESSED_PUBLIC_KEY_SIZE } from "./consts"; +import { ephemeralKeySize, isEphemeralKeyCompressed } from "./config"; import { PrivateKey, PublicKey } from "./keys"; import { aesDecrypt, aesEncrypt, decodeHex, getValidSecret, remove0x } from "./utils"; @@ -12,7 +12,12 @@ export function encrypt(receiverRawPK: string | Buffer, msg: Buffer): Buffer { const aesKey = ephemeralKey.encapsulate(receiverPK); const encrypted = aesEncrypt(aesKey, msg); - return Buffer.concat([ephemeralKey.publicKey.uncompressed, encrypted]); + + if (isEphemeralKeyCompressed()) { + return Buffer.concat([ephemeralKey.publicKey.compressed, encrypted]); + } else { + return Buffer.concat([ephemeralKey.publicKey.uncompressed, encrypted]); + } } export function decrypt(receiverRawSK: string | Buffer, msg: Buffer): Buffer { @@ -21,8 +26,9 @@ export function decrypt(receiverRawSK: string | Buffer, msg: Buffer): Buffer { ? new PrivateKey(receiverRawSK) : PrivateKey.fromHex(receiverRawSK); - const senderPubkey = new PublicKey(msg.subarray(0, UNCOMPRESSED_PUBLIC_KEY_SIZE)); - const encrypted = msg.subarray(UNCOMPRESSED_PUBLIC_KEY_SIZE); + const keySize = ephemeralKeySize(); + const senderPubkey = new PublicKey(msg.subarray(0, keySize)); + const encrypted = msg.subarray(keySize); const aesKey = senderPubkey.decapsulate(receiverSK); return aesDecrypt(aesKey, encrypted); } diff --git a/src/keys/PrivateKey.ts b/src/keys/PrivateKey.ts index c3c4945..296a8c9 100644 --- a/src/keys/PrivateKey.ts +++ b/src/keys/PrivateKey.ts @@ -1,7 +1,12 @@ -import { secp256k1 } from "@noble/curves/secp256k1"; -import { hkdf } from "@noble/hashes/hkdf"; -import { sha256 } from "@noble/hashes/sha256"; -import { decodeHex, getValidSecret } from "../utils"; +import { isHkdfKeyCompressed } from "../config"; +import { + decodeHex, + deriveKey, + getPublicKey, + getSharedPoint, + getValidSecret, + isValidPrivateKey, +} from "../utils"; import PublicKey from "./PublicKey"; export default class PrivateKey { @@ -13,11 +18,11 @@ export default class PrivateKey { public readonly publicKey: PublicKey; constructor(secret?: Buffer) { - this.secret = secret || getValidSecret(); - if (!secp256k1.utils.isValidPrivateKey(this.secret)) { + this.secret = secret === undefined ? getValidSecret() : secret; + if (!isValidPrivateKey(this.secret)) { throw new Error("Invalid private key"); } - this.publicKey = new PublicKey(Buffer.from(secp256k1.getPublicKey(this.secret))); + this.publicKey = new PublicKey(getPublicKey(this.secret)); } public toHex(): string { @@ -25,12 +30,18 @@ export default class PrivateKey { } public encapsulate(pub: PublicKey): Buffer { - const master = Buffer.concat([this.publicKey.uncompressed, this.multiply(pub)]); - return Buffer.from(hkdf(sha256, master, undefined, undefined, 32)); + let master: Buffer; + + if (isHkdfKeyCompressed()) { + master = Buffer.concat([this.publicKey.compressed, this.multiply(pub, true)]); + } else { + master = Buffer.concat([this.publicKey.uncompressed, this.multiply(pub, false)]); + } + return deriveKey(master); } - public multiply(pub: PublicKey): Buffer { - return Buffer.from(secp256k1.getSharedSecret(this.secret, pub.compressed, false)); + public multiply(pub: PublicKey, compressed: boolean = false): Buffer { + return getSharedPoint(this.secret, pub.compressed, compressed); } public equals(other: PrivateKey): boolean { diff --git a/src/keys/PublicKey.ts b/src/keys/PublicKey.ts index 081a548..5cd9f2e 100644 --- a/src/keys/PublicKey.ts +++ b/src/keys/PublicKey.ts @@ -1,14 +1,12 @@ -import { secp256k1 } from "@noble/curves/secp256k1"; -import { hkdf } from "@noble/hashes/hkdf"; -import { sha256 } from "@noble/hashes/sha256"; -import { ONE, UNCOMPRESSED_PUBLIC_KEY_SIZE } from "../consts"; -import { decodeHex } from "../utils"; +import { isHkdfKeyCompressed } from "../config"; +import { ETH_PUBLIC_KEY_SIZE, ONE } from "../consts"; +import { decodeHex, deriveKey, getSharedPoint } from "../utils"; import PrivateKey from "./PrivateKey"; export default class PublicKey { public static fromHex(hex: string): PublicKey { const decoded = decodeHex(hex); - if (decoded.length === UNCOMPRESSED_PUBLIC_KEY_SIZE - 1) { + if (decoded.length === ETH_PUBLIC_KEY_SIZE) { // eth public key const prefix: Buffer = Buffer.from([0x04]); const fixed: Buffer = Buffer.concat([prefix, decoded]); @@ -21,8 +19,8 @@ export default class PublicKey { public readonly compressed: Buffer; constructor(buffer: Buffer) { - this.uncompressed = Buffer.from(secp256k1.getSharedSecret(ONE, buffer, false)); - this.compressed = Buffer.from(secp256k1.getSharedSecret(ONE, buffer, true)); + this.uncompressed = getSharedPoint(ONE, buffer, false); + this.compressed = getSharedPoint(ONE, buffer, true); } public toHex(compressed: boolean = true): string { @@ -34,8 +32,14 @@ export default class PublicKey { } public decapsulate(priv: PrivateKey): Buffer { - const master = Buffer.concat([this.uncompressed, priv.multiply(this)]); - return Buffer.from(hkdf(sha256, master, undefined, undefined, 32)); + let master: Buffer; + + if (isHkdfKeyCompressed()) { + master = Buffer.concat([this.compressed, priv.multiply(this, true)]); + } else { + master = Buffer.concat([this.uncompressed, priv.multiply(this, false)]); + } + return deriveKey(master); } public equals(other: PublicKey): boolean { diff --git a/src/utils.ts b/src/utils.ts deleted file mode 100644 index 314cf67..0000000 --- a/src/utils.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { secp256k1 } from "@noble/curves/secp256k1"; -import { createCipheriv, createDecipheriv, randomBytes } from "crypto"; - -import { AES_IV_LENGTH, AES_IV_PLUS_TAG_LENGTH, SECRET_KEY_LENGTH } from "./consts"; - -export function remove0x(hex: string): string { - if (hex.startsWith("0x") || hex.startsWith("0X")) { - return hex.slice(2); - } - return hex; -} - -export function decodeHex(hex: string): Buffer { - return Buffer.from(remove0x(hex), "hex"); -} - -export function getValidSecret(): Buffer { - let key: Buffer; - do { - key = randomBytes(SECRET_KEY_LENGTH); - } while (!secp256k1.utils.isValidPrivateKey(key)); - return key; -} - -export function aesEncrypt(key: Buffer, plainText: Buffer): Buffer { - const nonce = randomBytes(AES_IV_LENGTH); - const cipher = createCipheriv("aes-256-gcm", key, nonce); - const encrypted = Buffer.concat([cipher.update(plainText), cipher.final()]); - const tag = cipher.getAuthTag(); - return Buffer.concat([nonce, tag, encrypted]); -} - -export function aesDecrypt(key: Buffer, cipherText: Buffer): Buffer { - const nonce = cipherText.subarray(0, AES_IV_LENGTH); - const tag = cipherText.subarray(AES_IV_LENGTH, AES_IV_PLUS_TAG_LENGTH); - const ciphered = cipherText.subarray(AES_IV_PLUS_TAG_LENGTH); - const decipher = createDecipheriv("aes-256-gcm", key, nonce); - decipher.setAuthTag(tag); - return Buffer.concat([decipher.update(ciphered), decipher.final()]); -} diff --git a/src/utils/elliptic.ts b/src/utils/elliptic.ts new file mode 100644 index 0000000..93ad8d8 --- /dev/null +++ b/src/utils/elliptic.ts @@ -0,0 +1,28 @@ +import { secp256k1 } from "@noble/curves/secp256k1"; +import { randomBytes } from "crypto"; + +import { SECRET_KEY_LENGTH } from "../consts"; + +export function isValidPrivateKey(secret: Buffer) { + return secp256k1.utils.isValidPrivateKey(secret); +} + +export function getValidSecret(): Buffer { + let key: Buffer; + do { + key = randomBytes(SECRET_KEY_LENGTH); + } while (!isValidPrivateKey(key)); + return key; +} + +export function getPublicKey(secret: Buffer): Buffer { + return Buffer.from(secp256k1.getPublicKey(secret)); +} + +export function getSharedPoint( + skRaw: Buffer | bigint, + pkRaw: Buffer, + compressed: boolean +): Buffer { + return Buffer.from(secp256k1.getSharedSecret(skRaw, pkRaw, compressed)); +} diff --git a/src/utils/hex.ts b/src/utils/hex.ts new file mode 100644 index 0000000..6176416 --- /dev/null +++ b/src/utils/hex.ts @@ -0,0 +1,10 @@ +export function remove0x(hex: string): string { + if (hex.startsWith("0x") || hex.startsWith("0X")) { + return hex.slice(2); + } + return hex; +} + +export function decodeHex(hex: string): Buffer { + return Buffer.from(remove0x(hex), "hex"); +} diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 0000000..8cf12f1 --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,3 @@ +export * from "./elliptic"; +export * from "./hex"; +export * from "./symmetric"; diff --git a/src/utils/symmetric.ts b/src/utils/symmetric.ts new file mode 100644 index 0000000..be94908 --- /dev/null +++ b/src/utils/symmetric.ts @@ -0,0 +1,49 @@ +import { hkdf } from "@noble/hashes/hkdf"; +import { sha256 } from "@noble/hashes/sha256"; +import { createCipheriv, createDecipheriv, randomBytes } from "crypto"; + +import { + NonceLength, + SymmetricAlgorithm, + symmetricAlgorithm, + symmetricNonceLength, +} from "../config"; +import { AEAD_TAG_LENGTH } from "../consts"; + +function _aesEncrypt( + key: Buffer, + plainText: Buffer, + algorithm: SymmetricAlgorithm, + nonceLength: NonceLength +): Buffer { + const nonce = randomBytes(nonceLength); + const cipher = createCipheriv(algorithm, key, nonce); + const encrypted = Buffer.concat([cipher.update(plainText), cipher.final()]); + const tag = cipher.getAuthTag(); + return Buffer.concat([nonce, tag, encrypted]); +} + +function _aesDecrypt( + key: Buffer, + cipherText: Buffer, + algorithm: SymmetricAlgorithm, + nonceLength: NonceLength +): Buffer { + const nonce = cipherText.subarray(0, nonceLength); + const tag = cipherText.subarray(nonceLength, nonceLength + AEAD_TAG_LENGTH); + const ciphered = cipherText.subarray(nonceLength + AEAD_TAG_LENGTH); + const decipher = createDecipheriv(algorithm, key, nonce); + decipher.setAuthTag(tag); + return Buffer.concat([decipher.update(ciphered), decipher.final()]); +} + +export function aesEncrypt(key: Buffer, plainText: Buffer): Buffer { + return _aesEncrypt(key, plainText, symmetricAlgorithm(), symmetricNonceLength()); +} + +export function aesDecrypt(key: Buffer, cipherText: Buffer): Buffer { + return _aesDecrypt(key, cipherText, symmetricAlgorithm(), symmetricNonceLength()); +} +export function deriveKey(master: Buffer) { + return Buffer.from(hkdf(sha256, master, undefined, undefined, 32)); +} diff --git a/tests/crypt.test.ts b/tests/crypt.test.ts index 1b532c6..54f3eec 100644 --- a/tests/crypt.test.ts +++ b/tests/crypt.test.ts @@ -1,55 +1,41 @@ -import axios from "axios"; -import { randomBytes } from "crypto"; -import { stringify } from "querystring"; - +import { ECIES_CONFIG } from "../src/config"; import { decrypt, encrypt } from "../src/index"; import { PrivateKey, PublicKey } from "../src/keys"; -import { aesDecrypt, aesEncrypt, decodeHex } from "../src/utils"; -const PYTHON_BACKEND = "https://eciespydemo-1-d5397785.deta.app/"; -const TEXT = "helloworld"; +const TEXT = "helloworld🌍"; + +function check(sk: PrivateKey, compressed: boolean = false) { + if (compressed) { + const encrypted = encrypt(sk.publicKey.compressed, Buffer.from(TEXT)); + expect(decrypt(sk.secret, encrypted).toString()).toBe(TEXT); + } else { + const encrypted = encrypt(sk.publicKey.uncompressed, Buffer.from(TEXT)); + expect(decrypt(sk.secret, encrypted).toString()).toBe(TEXT); + } +} +function checkHex(sk: PrivateKey) { + const encrypted = encrypt(sk.publicKey.toHex(), Buffer.from(TEXT)); + expect(decrypt(sk.secret, encrypted).toString()).toBe(TEXT); +} describe("test encrypt and decrypt", () => { - it("tests aes with random key", () => { - const key = randomBytes(32); - const data = Buffer.from("this is a test"); - expect(data.equals(aesDecrypt(key, aesEncrypt(key, data)))).toBe(true); - }); - - it("tests aes decrypt with known key and TEXT", () => { - const key = Buffer.from( - decodeHex("0000000000000000000000000000000000000000000000000000000000000000") - ); - const nonce = Buffer.from(decodeHex("f3e1ba810d2c8900b11312b7c725565f")); - const tag = Buffer.from(decodeHex("ec3b71e17c11dbe31484da9450edcf6c")); - const encrypted = Buffer.from(decodeHex("02d2ffed93b856f148b9")); - - const data = Buffer.concat([nonce, tag, encrypted]); - const decrypted = aesDecrypt(key, data); - expect(decrypted.toString()).toBe(TEXT); - }); - it("tests encrypt/decrypt buffer", () => { const prv1 = new PrivateKey(); - const encrypted1 = encrypt(prv1.publicKey.uncompressed, Buffer.from(TEXT)); - expect(decrypt(prv1.secret, encrypted1).toString()).toBe(TEXT); + check(prv1); const prv2 = new PrivateKey(); - const encrypted2 = encrypt(prv2.publicKey.compressed, Buffer.from(TEXT)); - expect(decrypt(prv2.secret, encrypted2).toString()).toBe(TEXT); + check(prv2, true); }); it("tests encrypt/decrypt hex", () => { const prv1 = new PrivateKey(); - const encrypted1 = encrypt(prv1.publicKey.toHex(), Buffer.from(TEXT)); - expect(decrypt(prv1.toHex(), encrypted1).toString()).toBe(TEXT); + checkHex(prv1); const prv2 = new PrivateKey(); - const encrypted2 = encrypt(prv2.publicKey.toHex(), Buffer.from(TEXT)); - expect(decrypt(prv2.toHex(), encrypted2).toString()).toBe(TEXT); + checkHex(prv2); }); - it("tests sk pk", () => { + it("tests known sk pk", () => { const sk = PrivateKey.fromHex( "5b5b1a0ff51e4350badd6f58d9e6fa6f57fbdbde6079d12901770dda3b803081" ); @@ -60,28 +46,12 @@ describe("test encrypt and decrypt", () => { expect(decrypt(sk.toHex(), enc).toString()).toBe(TEXT); }); - it("tests encrypt/decrypt against python version", async () => { - const prv = new PrivateKey(); - let res = await axios.post( - PYTHON_BACKEND, - stringify({ - data: TEXT, - pub: prv.publicKey.toHex(), - }) - ); - const encryptedKnown = Buffer.from(decodeHex(res.data)); - const decrypted = decrypt(prv.toHex(), encryptedKnown); + it("tests ephemeral key config", () => { + ECIES_CONFIG.isEphemeralKeyCompressed = true; - expect(decrypted.toString()).toEqual(TEXT); + const prv1 = new PrivateKey(); + check(prv1); - const encrypted = encrypt(prv.publicKey.toHex(), Buffer.from(TEXT)); - res = await axios.post( - PYTHON_BACKEND, - stringify({ - data: encrypted.toString("hex"), - prv: prv.toHex(), - }) - ); - expect(TEXT).toEqual(res.data); + ECIES_CONFIG.isEphemeralKeyCompressed = false; }); }); diff --git a/tests/integration.test.ts b/tests/integration.test.ts new file mode 100644 index 0000000..63805c1 --- /dev/null +++ b/tests/integration.test.ts @@ -0,0 +1,40 @@ +import axios from "axios"; +import { stringify } from "querystring"; + +import { decrypt, encrypt } from "../src/index"; +import { PrivateKey } from "../src/keys"; +import { decodeHex } from "../src/utils"; + +const PYTHON_BACKEND = "https://eciespydemo-1-d5397785.deta.app/"; + +const TEXT = "helloworld🌍"; + +describe("test encrypt and decrypt", () => { + const prv = new PrivateKey(); + + it("tests encryption against python version", async () => { + const res = await axios.post( + PYTHON_BACKEND, + stringify({ + data: TEXT, + pub: prv.publicKey.toHex(), + }) + ); + const encryptedKnown = Buffer.from(decodeHex(res.data)); + const decrypted = decrypt(prv.toHex(), encryptedKnown); + + expect(decrypted.toString()).toEqual(TEXT); + }); + + it("tests decryption against python version", async () => { + const encrypted = encrypt(prv.publicKey.toHex(), Buffer.from(TEXT)); + const res = await axios.post( + PYTHON_BACKEND, + stringify({ + data: encrypted.toString("hex"), + prv: prv.toHex(), + }) + ); + expect(TEXT).toEqual(res.data); + }); +}); diff --git a/tests/keys.test.ts b/tests/keys.test.ts index 4cc788a..77c9712 100644 --- a/tests/keys.test.ts +++ b/tests/keys.test.ts @@ -1,3 +1,4 @@ +import { ECIES_CONFIG } from "../src/config"; import { PrivateKey, PublicKey } from "../src/keys"; import { decodeHex } from "../src/utils"; @@ -6,6 +7,19 @@ const PUB_HEX = "0x98afe4f150642cd05cc9d2fa36458ce0a58567daeaf5fde7333ba9b403011140" + "a4e28911fcf83ab1f457a30b4959efc4b9306f514a4c3711a16a80e3b47eb58b"; +function checkHkdf(k1: PrivateKey, k2: PrivateKey, knownHex: string) { + const derived1 = k1.encapsulate(k2.publicKey); + const derived2 = k1.publicKey.decapsulate(k2); + const knownDerived = Buffer.from(decodeHex(knownHex)); + expect(derived1.equals(knownDerived)).toBe(true); + expect(derived2.equals(knownDerived)).toBe(true); +} + +const two = Buffer.from(new Uint8Array(32)); +two[31] = 2; +const three = Buffer.from(new Uint8Array(32)); +three[31] = 3; + describe("test keys", () => { it("tests invalid", () => { // 0 < private key < group order int @@ -15,6 +29,7 @@ describe("test keys", () => { const groupOrderIntAdd1 = "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142"; + expect(() => PrivateKey.fromHex(groupOrderIntAdd1)).toThrow(Error); expect(() => PrivateKey.fromHex("0")).toThrow(Error); @@ -44,21 +59,28 @@ describe("test keys", () => { }); it("tests multiply and hkdf", () => { - const two = Buffer.from(new Uint8Array(32)); - two[31] = 2; - const three = Buffer.from(new Uint8Array(32)); - three[31] = 3; - const k1 = new PrivateKey(two); const k2 = new PrivateKey(three); + expect(k1.multiply(k2.publicKey).equals(k2.multiply(k1.publicKey))).toBe(true); - const derived = k1.encapsulate(k2.publicKey); - const anotherDerived = k1.publicKey.decapsulate(k2); - const knownDerived = Buffer.from( - decodeHex("6f982d63e8590c9d9b5b4c1959ff80315d772edd8f60287c9361d548d5200f82") + checkHkdf( + k1, + k2, + "6f982d63e8590c9d9b5b4c1959ff80315d772edd8f60287c9361d548d5200f82" + ); + }); + + it("tests hkdf config", () => { + const k1 = new PrivateKey(two); + const k2 = new PrivateKey(three); + + ECIES_CONFIG.isHkdfKeyCompressed = true; + checkHkdf( + k1, + k2, + "b192b226edb3f02da11ef9c6ce4afe1c7e40be304e05ae3b988f4834b1cb6c69" ); - expect(derived.equals(knownDerived)).toBe(true); - expect(anotherDerived.equals(knownDerived)).toBe(true); + ECIES_CONFIG.isHkdfKeyCompressed = false; }); }); diff --git a/tests/util.test.ts b/tests/util.test.ts deleted file mode 100644 index 4cd88cb..0000000 --- a/tests/util.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { secp256k1 } from "@noble/curves/secp256k1"; - -import { decodeHex, getValidSecret, remove0x } from "../src/utils"; - -describe("test string <-> buffer utils ", () => { - it("should remove 0x", () => { - expect(remove0x("0x0011")).toBe("0011"); - expect(remove0x("0011")).toBe("0011"); - expect(remove0x("0X0022")).toBe("0022"); - expect(remove0x("0022")).toBe("0022"); - }); - - it("should generate valid secret", () => { - const key = getValidSecret(); - expect(secp256k1.utils.isValidPrivateKey(key)).toBe(true); - }); - - it("should convert hex to buffer", () => { - const decoded = decodeHex("0x0011"); - expect(decoded.equals(Buffer.from([0, 0x11]))).toBe(true); - }); -}); diff --git a/tests/utils.test.ts b/tests/utils.test.ts new file mode 100644 index 0000000..e779d9b --- /dev/null +++ b/tests/utils.test.ts @@ -0,0 +1,65 @@ +import { randomBytes } from "crypto"; + +import { ECIES_CONFIG } from "../src/config"; +import { + aesDecrypt, + aesEncrypt, + decodeHex, + getValidSecret, + isValidPrivateKey, + remove0x, +} from "../src/utils"; + +const TEXT = "helloworld🌍"; + +describe("test hex utils", () => { + it("should remove 0x", () => { + expect(remove0x("0011")).toBe("0011"); + expect(remove0x("0022")).toBe("0022"); + expect(remove0x("0x0011")).toBe("0011"); + expect(remove0x("0X0022")).toBe("0022"); + }); + + it("should convert hex to buffer", () => { + const decoded = decodeHex("0x0011"); + expect(decoded).toEqual(Buffer.from([0, 0x11])); + }); +}); + +describe("test elliptic utils", () => { + it("should generate valid secret", () => { + const key = getValidSecret(); + expect(isValidPrivateKey(key)).toBe(true); + }); +}); + +describe("test symmetric utils", () => { + it("tests aes with random key", () => { + const key = randomBytes(32); + const data = Buffer.from(TEXT); + expect(data).toEqual(aesDecrypt(key, aesEncrypt(key, data))); + }); + + it("tests aes decrypt with known key", () => { + const key = Buffer.from( + decodeHex("0000000000000000000000000000000000000000000000000000000000000000") + ); + const nonce = Buffer.from(decodeHex("0xf3e1ba810d2c8900b11312b7c725565f")); + const tag = Buffer.from(decodeHex("0Xec3b71e17c11dbe31484da9450edcf6c")); + const encrypted = Buffer.from(decodeHex("02d2ffed93b856f148b9")); + + const data = Buffer.concat([nonce, tag, encrypted]); + const decrypted = aesDecrypt(key, data); + expect(decrypted.toString()).toBe("helloworld"); + }); + + it("tests aes nonce length config", () => { + ECIES_CONFIG.symmetricNonceLength = 12; + + const key = randomBytes(32); + const data = Buffer.from(TEXT); + expect(data.equals(aesDecrypt(key, aesEncrypt(key, data)))).toBe(true); + + ECIES_CONFIG.symmetricNonceLength = 16; + }); +}); diff --git a/yarn.lock b/yarn.lock index 4cd9e94..4fa6e9a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17,52 +17,52 @@ dependencies: "@babel/highlight" "^7.22.5" -"@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/compat-data@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.9.tgz#71cdb00a1ce3a329ce4cbec3a44f9fef35669730" + integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ== "@babel/core@^7.11.6", "@babel/core@^7.12.3": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.5.tgz#d67d9747ecf26ee7ecd3ebae1ee22225fe902a89" - integrity sha512-SBuTAjg91A3eKOvD+bPEz3LlhHZRNu1nFOVts9lzDJTXshHTjII0BAtDS3Y2DAkdZdDKWVZGVwkDfc4Clxn1dg== + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.9.tgz#bd96492c68822198f33e8a256061da3cf391f58f" + integrity sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w== 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/generator" "^7.22.9" + "@babel/helper-compilation-targets" "^7.22.9" + "@babel/helper-module-transforms" "^7.22.9" + "@babel/helpers" "^7.22.6" + "@babel/parser" "^7.22.7" "@babel/template" "^7.22.5" - "@babel/traverse" "^7.22.5" + "@babel/traverse" "^7.22.8" "@babel/types" "^7.22.5" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.2" - semver "^6.3.0" + semver "^6.3.1" -"@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== +"@babel/generator@^7.22.7", "@babel/generator@^7.22.9", "@babel/generator@^7.7.2": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.9.tgz#572ecfa7a31002fa1de2a9d91621fd895da8493d" + integrity sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw== dependencies: "@babel/types" "^7.22.5" "@jridgewell/gen-mapping" "^0.3.2" "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" -"@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== +"@babel/helper-compilation-targets@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.9.tgz#f9d0a7aaaa7cd32a3f31c9316a69f5a9bcacb892" + integrity sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw== dependencies: - "@babel/compat-data" "^7.22.5" + "@babel/compat-data" "^7.22.9" "@babel/helper-validator-option" "^7.22.5" - browserslist "^4.21.3" + browserslist "^4.21.9" lru-cache "^5.1.1" - semver "^6.3.0" + semver "^6.3.1" "@babel/helper-environment-visitor@^7.22.5": version "7.22.5" @@ -91,19 +91,16 @@ 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== +"@babel/helper-module-transforms@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz#92dfcb1fbbb2bc62529024f72d942a8c97142129" + integrity sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ== 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-split-export-declaration" "^7.22.6" "@babel/helper-validator-identifier" "^7.22.5" - "@babel/template" "^7.22.5" - "@babel/traverse" "^7.22.5" - "@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.22.5", "@babel/helper-plugin-utils@^7.8.0": version "7.22.5" @@ -117,10 +114,10 @@ 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== +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== dependencies: "@babel/types" "^7.22.5" @@ -139,13 +136,13 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac" integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw== -"@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== +"@babel/helpers@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.6.tgz#8e61d3395a4f0c5a8060f309fb008200969b5ecd" + integrity sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA== dependencies: "@babel/template" "^7.22.5" - "@babel/traverse" "^7.22.5" + "@babel/traverse" "^7.22.6" "@babel/types" "^7.22.5" "@babel/highlight@^7.22.5": @@ -157,10 +154,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@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/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.5", "@babel/parser@^7.22.7": + version "7.22.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.7.tgz#df8cf085ce92ddbdbf668a7f186ce848c9036cae" + integrity sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q== "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" @@ -269,18 +266,18 @@ "@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== +"@babel/traverse@^7.22.6", "@babel/traverse@^7.22.8": + version "7.22.8" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.8.tgz#4d4451d31bc34efeae01eac222b514a77aa4000e" + integrity sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw== dependencies: "@babel/code-frame" "^7.22.5" - "@babel/generator" "^7.22.5" + "@babel/generator" "^7.22.7" "@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/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.22.7" "@babel/types" "^7.22.5" debug "^4.1.0" globals "^11.1.0" @@ -322,28 +319,28 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.5.0.tgz#593a6c5c0d3f75689835f1b3b4688c4f8544cb57" - integrity sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ== +"@jest/console@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.6.1.tgz#b48ba7b9c34b51483e6d590f46e5837f1ab5f639" + integrity sha512-Aj772AYgwTSr5w8qnyoJ0eDYvN6bMsH3ORH1ivMotrInHLKdUz6BDlaEXHdM6kODaBIkNIyQGzsMvRdOv7VG7Q== dependencies: - "@jest/types" "^29.5.0" + "@jest/types" "^29.6.1" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^29.5.0" - jest-util "^29.5.0" + jest-message-util "^29.6.1" + jest-util "^29.6.1" slash "^3.0.0" -"@jest/core@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.5.0.tgz#76674b96904484e8214614d17261cc491e5f1f03" - integrity sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ== - dependencies: - "@jest/console" "^29.5.0" - "@jest/reporters" "^29.5.0" - "@jest/test-result" "^29.5.0" - "@jest/transform" "^29.5.0" - "@jest/types" "^29.5.0" +"@jest/core@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.6.1.tgz#fac0d9ddf320490c93356ba201451825231e95f6" + integrity sha512-CcowHypRSm5oYQ1obz1wfvkjZZ2qoQlrKKvlfPwh5jUXVU12TWr2qMeH8chLMuTFzHh5a1g2yaqlqDICbr+ukQ== + dependencies: + "@jest/console" "^29.6.1" + "@jest/reporters" "^29.6.1" + "@jest/test-result" "^29.6.1" + "@jest/transform" "^29.6.1" + "@jest/types" "^29.6.1" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" @@ -351,81 +348,81 @@ exit "^0.1.2" graceful-fs "^4.2.9" jest-changed-files "^29.5.0" - jest-config "^29.5.0" - jest-haste-map "^29.5.0" - jest-message-util "^29.5.0" + jest-config "^29.6.1" + jest-haste-map "^29.6.1" + jest-message-util "^29.6.1" jest-regex-util "^29.4.3" - jest-resolve "^29.5.0" - jest-resolve-dependencies "^29.5.0" - jest-runner "^29.5.0" - jest-runtime "^29.5.0" - jest-snapshot "^29.5.0" - jest-util "^29.5.0" - jest-validate "^29.5.0" - jest-watcher "^29.5.0" + jest-resolve "^29.6.1" + jest-resolve-dependencies "^29.6.1" + jest-runner "^29.6.1" + jest-runtime "^29.6.1" + jest-snapshot "^29.6.1" + jest-util "^29.6.1" + jest-validate "^29.6.1" + jest-watcher "^29.6.1" micromatch "^4.0.4" - pretty-format "^29.5.0" + pretty-format "^29.6.1" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.5.0.tgz#9152d56317c1fdb1af389c46640ba74ef0bb4c65" - integrity sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ== +"@jest/environment@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.6.1.tgz#ee358fff2f68168394b4a50f18c68278a21fe82f" + integrity sha512-RMMXx4ws+Gbvw3DfLSuo2cfQlK7IwGbpuEWXCqyYDcqYTI+9Ju3a5hDnXaxjNsa6uKh9PQF2v+qg+RLe63tz5A== dependencies: - "@jest/fake-timers" "^29.5.0" - "@jest/types" "^29.5.0" + "@jest/fake-timers" "^29.6.1" + "@jest/types" "^29.6.1" "@types/node" "*" - jest-mock "^29.5.0" + jest-mock "^29.6.1" -"@jest/expect-utils@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.5.0.tgz#f74fad6b6e20f924582dc8ecbf2cb800fe43a036" - integrity sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg== +"@jest/expect-utils@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.6.1.tgz#ab83b27a15cdd203fe5f68230ea22767d5c3acc5" + integrity sha512-o319vIf5pEMx0LmzSxxkYYxo4wrRLKHq9dP1yJU7FoPTB0LfAKSz8SWD6D/6U3v/O52t9cF5t+MeJiRsfk7zMw== dependencies: jest-get-type "^29.4.3" -"@jest/expect@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.5.0.tgz#80952f5316b23c483fbca4363ce822af79c38fba" - integrity sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g== +"@jest/expect@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.6.1.tgz#fef18265188f6a97601f1ea0a2912d81a85b4657" + integrity sha512-N5xlPrAYaRNyFgVf2s9Uyyvr795jnB6rObuPx4QFvNJz8aAjpZUDfO4bh5G/xuplMID8PrnuF1+SfSyDxhsgYg== dependencies: - expect "^29.5.0" - jest-snapshot "^29.5.0" + expect "^29.6.1" + jest-snapshot "^29.6.1" -"@jest/fake-timers@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.5.0.tgz#d4d09ec3286b3d90c60bdcd66ed28d35f1b4dc2c" - integrity sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg== +"@jest/fake-timers@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.6.1.tgz#c773efddbc61e1d2efcccac008139f621de57c69" + integrity sha512-RdgHgbXyosCDMVYmj7lLpUwXA4c69vcNzhrt69dJJdf8azUrpRh3ckFCaTPNjsEeRi27Cig0oKDGxy5j7hOgHg== dependencies: - "@jest/types" "^29.5.0" + "@jest/types" "^29.6.1" "@sinonjs/fake-timers" "^10.0.2" "@types/node" "*" - jest-message-util "^29.5.0" - jest-mock "^29.5.0" - jest-util "^29.5.0" + jest-message-util "^29.6.1" + jest-mock "^29.6.1" + jest-util "^29.6.1" -"@jest/globals@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.5.0.tgz#6166c0bfc374c58268677539d0c181f9c1833298" - integrity sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ== +"@jest/globals@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.6.1.tgz#c8a8923e05efd757308082cc22893d82b8aa138f" + integrity sha512-2VjpaGy78JY9n9370H8zGRCFbYVWwjY6RdDMhoJHa1sYfwe6XM/azGN0SjY8kk7BOZApIejQ1BFPyH7FPG0w3A== dependencies: - "@jest/environment" "^29.5.0" - "@jest/expect" "^29.5.0" - "@jest/types" "^29.5.0" - jest-mock "^29.5.0" + "@jest/environment" "^29.6.1" + "@jest/expect" "^29.6.1" + "@jest/types" "^29.6.1" + jest-mock "^29.6.1" -"@jest/reporters@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.5.0.tgz#985dfd91290cd78ddae4914ba7921bcbabe8ac9b" - integrity sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA== +"@jest/reporters@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.6.1.tgz#3325a89c9ead3cf97ad93df3a427549d16179863" + integrity sha512-9zuaI9QKr9JnoZtFQlw4GREQbxgmNYXU6QuWtmuODvk5nvPUeBYapVR/VYMyi2WSx3jXTLJTJji8rN6+Cm4+FA== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^29.5.0" - "@jest/test-result" "^29.5.0" - "@jest/transform" "^29.5.0" - "@jest/types" "^29.5.0" - "@jridgewell/trace-mapping" "^0.3.15" + "@jest/console" "^29.6.1" + "@jest/test-result" "^29.6.1" + "@jest/transform" "^29.6.1" + "@jest/types" "^29.6.1" + "@jridgewell/trace-mapping" "^0.3.18" "@types/node" "*" chalk "^4.0.0" collect-v8-coverage "^1.0.0" @@ -437,77 +434,77 @@ istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.1.3" - jest-message-util "^29.5.0" - jest-util "^29.5.0" - jest-worker "^29.5.0" + jest-message-util "^29.6.1" + jest-util "^29.6.1" + jest-worker "^29.6.1" slash "^3.0.0" string-length "^4.0.1" strip-ansi "^6.0.0" v8-to-istanbul "^9.0.1" -"@jest/schemas@^29.4.3": - version "29.4.3" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.4.3.tgz#39cf1b8469afc40b6f5a2baaa146e332c4151788" - integrity sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg== +"@jest/schemas@^29.6.0": + version "29.6.0" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.0.tgz#0f4cb2c8e3dca80c135507ba5635a4fd755b0040" + integrity sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ== dependencies: - "@sinclair/typebox" "^0.25.16" + "@sinclair/typebox" "^0.27.8" -"@jest/source-map@^29.4.3": - version "29.4.3" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.4.3.tgz#ff8d05cbfff875d4a791ab679b4333df47951d20" - integrity sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w== +"@jest/source-map@^29.6.0": + version "29.6.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.6.0.tgz#bd34a05b5737cb1a99d43e1957020ac8e5b9ddb1" + integrity sha512-oA+I2SHHQGxDCZpbrsCQSoMLb3Bz547JnM+jUr9qEbuw0vQlWZfpPS7CO9J7XiwKicEz9OFn/IYoLkkiUD7bzA== dependencies: - "@jridgewell/trace-mapping" "^0.3.15" + "@jridgewell/trace-mapping" "^0.3.18" callsites "^3.0.0" graceful-fs "^4.2.9" -"@jest/test-result@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.5.0.tgz#7c856a6ca84f45cc36926a4e9c6b57f1973f1408" - integrity sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ== +"@jest/test-result@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.6.1.tgz#850e565a3f58ee8ca6ec424db00cb0f2d83c36ba" + integrity sha512-Ynr13ZRcpX6INak0TPUukU8GWRfm/vAytE3JbJNGAvINySWYdfE7dGZMbk36oVuK4CigpbhMn8eg1dixZ7ZJOw== dependencies: - "@jest/console" "^29.5.0" - "@jest/types" "^29.5.0" + "@jest/console" "^29.6.1" + "@jest/types" "^29.6.1" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.5.0.tgz#34d7d82d3081abd523dbddc038a3ddcb9f6d3cc4" - integrity sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ== +"@jest/test-sequencer@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.6.1.tgz#e3e582ee074dd24ea9687d7d1aaf05ee3a9b068e" + integrity sha512-oBkC36PCDf/wb6dWeQIhaviU0l5u6VCsXa119yqdUosYAt7/FbQU2M2UoziO3igj/HBDEgp57ONQ3fm0v9uyyg== dependencies: - "@jest/test-result" "^29.5.0" + "@jest/test-result" "^29.6.1" graceful-fs "^4.2.9" - jest-haste-map "^29.5.0" + jest-haste-map "^29.6.1" slash "^3.0.0" -"@jest/transform@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.5.0.tgz#cf9c872d0965f0cbd32f1458aa44a2b1988b00f9" - integrity sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw== +"@jest/transform@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.6.1.tgz#acb5606019a197cb99beda3c05404b851f441c92" + integrity sha512-URnTneIU3ZjRSaf906cvf6Hpox3hIeJXRnz3VDSw5/X93gR8ycdfSIEy19FlVx8NFmpN7fe3Gb1xF+NjXaQLWg== dependencies: "@babel/core" "^7.11.6" - "@jest/types" "^29.5.0" - "@jridgewell/trace-mapping" "^0.3.15" + "@jest/types" "^29.6.1" + "@jridgewell/trace-mapping" "^0.3.18" babel-plugin-istanbul "^6.1.1" chalk "^4.0.0" convert-source-map "^2.0.0" fast-json-stable-stringify "^2.1.0" graceful-fs "^4.2.9" - jest-haste-map "^29.5.0" + jest-haste-map "^29.6.1" jest-regex-util "^29.4.3" - jest-util "^29.5.0" + jest-util "^29.6.1" micromatch "^4.0.4" pirates "^4.0.4" slash "^3.0.0" write-file-atomic "^4.0.2" -"@jest/types@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.5.0.tgz#f59ef9b031ced83047c67032700d8c807d6e1593" - integrity sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog== +"@jest/types@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.1.tgz#ae79080278acff0a6af5eb49d063385aaa897bf2" + integrity sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw== dependencies: - "@jest/schemas" "^29.4.3" + "@jest/schemas" "^29.6.0" "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" "@types/node" "*" @@ -556,7 +553,7 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.15", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@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== @@ -576,10 +573,10 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== -"@sinclair/typebox@^0.25.16": - version "0.25.24" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718" - integrity sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ== +"@sinclair/typebox@^0.27.8": + version "0.27.8" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" + integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== "@sinonjs/commons@^3.0.0": version "3.0.0" @@ -675,17 +672,17 @@ "@types/istanbul-lib-report" "*" "@types/jest@^29.5.2": - version "29.5.2" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.2.tgz#86b4afc86e3a8f3005b297ed8a72494f89e6395b" - integrity sha512-mSoZVJF5YzGVCk+FsDxzDuH7s+SCkzrgKZzf0Z0T2WudhBUPoF6ktoTPC4R0ZoCPCV5xUvuU6ias5NvxcBcMMg== + version "29.5.3" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.3.tgz#7a35dc0044ffb8b56325c6802a4781a626b05777" + integrity sha512-1Nq7YrO/vJE/FYnqYyw0FS8LdrjExSgIiHyKg7xPpn+yi8Q4huZryKnkJatN1ZRH89Kw2v33/8ZMB7DuZeSLlA== dependencies: expect "^29.0.0" pretty-format "^29.0.0" -"@types/node@*", "@types/node@^20.3.2": - version "20.3.3" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.3.3.tgz#329842940042d2b280897150e023e604d11657d6" - integrity sha512-wheIYdr4NYML61AjC8MKj/2jrR/kDQri/CIpVoZwldwhnIrD/j9jIU5bJ8yBKuB2VhpFV7Ab6G2XkBjv9r9Zzw== +"@types/node@*", "@types/node@^20.4.2": + version "20.4.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.2.tgz#129cc9ae69f93824f92fac653eebfb4812ab4af9" + integrity sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw== "@types/prettier@^2.1.5": version "2.7.3" @@ -715,9 +712,9 @@ acorn-walk@^8.1.1: integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== acorn@^8.4.1: - version "8.9.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.9.0.tgz#78a16e3b2bcc198c10822786fa6679e245db5b59" - integrity sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ== + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== ansi-escapes@^4.2.1: version "4.3.2" @@ -784,12 +781,12 @@ axios@^1.4.0: form-data "^4.0.0" proxy-from-env "^1.1.0" -babel-jest@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.5.0.tgz#3fe3ddb109198e78b1c88f9ebdecd5e4fc2f50a5" - integrity sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q== +babel-jest@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.6.1.tgz#a7141ad1ed5ec50238f3cd36127636823111233a" + integrity sha512-qu+3bdPEQC6KZSPz+4Fyjbga5OODNcp49j6GKzG1EKbkfyJBxEYGVUmVGpwCSeGouG52R4EgYMLb6p9YeEEQ4A== dependencies: - "@jest/transform" "^29.5.0" + "@jest/transform" "^29.6.1" "@types/babel__core" "^7.1.14" babel-plugin-istanbul "^6.1.1" babel-preset-jest "^29.5.0" @@ -864,7 +861,7 @@ braces@^3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.21.3: +browserslist@^4.21.9: version "4.21.9" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.9.tgz#e11bdd3c313d7e2a9e87e8b4b0c7872b13897635" integrity sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg== @@ -909,9 +906,9 @@ camelcase@^6.2.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001503: - version "1.0.30001509" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001509.tgz#2b7ad5265392d6d2de25cd8776d1ab3899570d14" - integrity sha512-2uDDk+TRiTX5hMcUYT/7CSyzMZxjfGu0vAUjS2g0LSD8UoXOv0LtpH4LxGMemsiPq6LCVIUjNwVM0erkOkGCDA== + version "1.0.30001516" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001516.tgz#621b1be7d85a8843ee7d210fd9d87b52e3daab3a" + integrity sha512-Wmec9pCBY8CWbmI4HsjBeQLqDTqV91nFVR83DnZpYyRnPI1wePDsTg0bGLPC5VU/3OIZV1fmxEea1b+tFKe86g== chalk@^2.0.0: version "2.4.2" @@ -960,9 +957,9 @@ co@^4.6.0: integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== collect-v8-coverage@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" - integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== + version "1.0.2" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" + integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== color-convert@^1.9.0: version "1.9.3" @@ -1062,9 +1059,9 @@ diff@^4.0.1: integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== electron-to-chromium@^1.4.431: - version "1.4.447" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.447.tgz#ac69d3a7b3713e9ae94bb30ba65c3114e4d76a38" - integrity sha512-sxX0LXh+uL41hSJsujAN86PjhrV/6c79XmpY0TvjZStV6VxIgarf8SRkUoUTuYmFcZQTemsoqo8qXOGw5npWfw== + version "1.4.461" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.461.tgz#6b14af66042732bf883ab63a4d82cac8f35eb252" + integrity sha512-1JkvV2sgEGTDXjdsaQCeSwYYuhLRphRpc+g6EHTFELJXEiznLt3/0pZ9JuAOQ5p2rI3YxKTbivtvajirIfhrEQ== emittery@^0.13.1: version "0.13.1" @@ -1123,16 +1120,17 @@ exit@^0.1.2: resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== -expect@^29.0.0, expect@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-29.5.0.tgz#68c0509156cb2a0adb8865d413b137eeaae682f7" - integrity sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg== +expect@^29.0.0, expect@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.6.1.tgz#64dd1c8f75e2c0b209418f2b8d36a07921adfdf1" + integrity sha512-XEdDLonERCU1n9uR56/Stx9OqojaLAQtZf9PrCHH9Hl8YXiEIka3H4NXJ3NOIBmQJTg7+j7buh34PMHfJujc8g== dependencies: - "@jest/expect-utils" "^29.5.0" + "@jest/expect-utils" "^29.6.1" + "@types/node" "*" jest-get-type "^29.4.3" - jest-matcher-utils "^29.5.0" - jest-message-util "^29.5.0" - jest-util "^29.5.0" + jest-matcher-utils "^29.6.1" + jest-message-util "^29.6.1" + jest-util "^29.6.1" fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.1.0: version "2.1.0" @@ -1372,87 +1370,87 @@ jest-changed-files@^29.5.0: execa "^5.0.0" p-limit "^3.1.0" -jest-circus@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.5.0.tgz#b5926989449e75bff0d59944bae083c9d7fb7317" - integrity sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA== +jest-circus@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.6.1.tgz#861dab37e71a89907d1c0fabc54a0019738ed824" + integrity sha512-tPbYLEiBU4MYAL2XoZme/bgfUeotpDBd81lgHLCbDZZFaGmECk0b+/xejPFtmiBP87GgP/y4jplcRpbH+fgCzQ== dependencies: - "@jest/environment" "^29.5.0" - "@jest/expect" "^29.5.0" - "@jest/test-result" "^29.5.0" - "@jest/types" "^29.5.0" + "@jest/environment" "^29.6.1" + "@jest/expect" "^29.6.1" + "@jest/test-result" "^29.6.1" + "@jest/types" "^29.6.1" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" dedent "^0.7.0" is-generator-fn "^2.0.0" - jest-each "^29.5.0" - jest-matcher-utils "^29.5.0" - jest-message-util "^29.5.0" - jest-runtime "^29.5.0" - jest-snapshot "^29.5.0" - jest-util "^29.5.0" + jest-each "^29.6.1" + jest-matcher-utils "^29.6.1" + jest-message-util "^29.6.1" + jest-runtime "^29.6.1" + jest-snapshot "^29.6.1" + jest-util "^29.6.1" p-limit "^3.1.0" - pretty-format "^29.5.0" + pretty-format "^29.6.1" pure-rand "^6.0.0" slash "^3.0.0" stack-utils "^2.0.3" -jest-cli@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.5.0.tgz#b34c20a6d35968f3ee47a7437ff8e53e086b4a67" - integrity sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw== +jest-cli@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.6.1.tgz#99d9afa7449538221c71f358f0fdd3e9c6e89f72" + integrity sha512-607dSgTA4ODIN6go9w6xY3EYkyPFGicx51a69H7yfvt7lN53xNswEVLovq+E77VsTRi5fWprLH0yl4DJgE8Ing== dependencies: - "@jest/core" "^29.5.0" - "@jest/test-result" "^29.5.0" - "@jest/types" "^29.5.0" + "@jest/core" "^29.6.1" + "@jest/test-result" "^29.6.1" + "@jest/types" "^29.6.1" chalk "^4.0.0" exit "^0.1.2" graceful-fs "^4.2.9" import-local "^3.0.2" - jest-config "^29.5.0" - jest-util "^29.5.0" - jest-validate "^29.5.0" + jest-config "^29.6.1" + jest-util "^29.6.1" + jest-validate "^29.6.1" prompts "^2.0.1" yargs "^17.3.1" -jest-config@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.5.0.tgz#3cc972faec8c8aaea9ae158c694541b79f3748da" - integrity sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA== +jest-config@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.6.1.tgz#d785344509065d53a238224c6cdc0ed8e2f2f0dd" + integrity sha512-XdjYV2fy2xYixUiV2Wc54t3Z4oxYPAELUzWnV6+mcbq0rh742X2p52pii5A3oeRzYjLnQxCsZmp0qpI6klE2cQ== dependencies: "@babel/core" "^7.11.6" - "@jest/test-sequencer" "^29.5.0" - "@jest/types" "^29.5.0" - babel-jest "^29.5.0" + "@jest/test-sequencer" "^29.6.1" + "@jest/types" "^29.6.1" + babel-jest "^29.6.1" chalk "^4.0.0" ci-info "^3.2.0" deepmerge "^4.2.2" glob "^7.1.3" graceful-fs "^4.2.9" - jest-circus "^29.5.0" - jest-environment-node "^29.5.0" + jest-circus "^29.6.1" + jest-environment-node "^29.6.1" jest-get-type "^29.4.3" jest-regex-util "^29.4.3" - jest-resolve "^29.5.0" - jest-runner "^29.5.0" - jest-util "^29.5.0" - jest-validate "^29.5.0" + jest-resolve "^29.6.1" + jest-runner "^29.6.1" + jest-util "^29.6.1" + jest-validate "^29.6.1" micromatch "^4.0.4" parse-json "^5.2.0" - pretty-format "^29.5.0" + pretty-format "^29.6.1" slash "^3.0.0" strip-json-comments "^3.1.1" -jest-diff@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.5.0.tgz#e0d83a58eb5451dcc1fa61b1c3ee4e8f5a290d63" - integrity sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw== +jest-diff@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.6.1.tgz#13df6db0a89ee6ad93c747c75c85c70ba941e545" + integrity sha512-FsNCvinvl8oVxpNLttNQX7FAq7vR+gMDGj90tiP7siWw1UdakWUGqrylpsYrpvj908IYckm5Y0Q7azNAozU1Kg== dependencies: chalk "^4.0.0" diff-sequences "^29.4.3" jest-get-type "^29.4.3" - pretty-format "^29.5.0" + pretty-format "^29.6.1" jest-docblock@^29.4.3: version "29.4.3" @@ -1461,94 +1459,94 @@ jest-docblock@^29.4.3: dependencies: detect-newline "^3.0.0" -jest-each@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.5.0.tgz#fc6e7014f83eac68e22b7195598de8554c2e5c06" - integrity sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA== +jest-each@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.6.1.tgz#975058e5b8f55c6780beab8b6ab214921815c89c" + integrity sha512-n5eoj5eiTHpKQCAVcNTT7DRqeUmJ01hsAL0Q1SMiBHcBcvTKDELixQOGMCpqhbIuTcfC4kMfSnpmDqRgRJcLNQ== dependencies: - "@jest/types" "^29.5.0" + "@jest/types" "^29.6.1" chalk "^4.0.0" jest-get-type "^29.4.3" - jest-util "^29.5.0" - pretty-format "^29.5.0" + jest-util "^29.6.1" + pretty-format "^29.6.1" -jest-environment-node@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.5.0.tgz#f17219d0f0cc0e68e0727c58b792c040e332c967" - integrity sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw== +jest-environment-node@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.6.1.tgz#08a122dece39e58bc388da815a2166c58b4abec6" + integrity sha512-ZNIfAiE+foBog24W+2caIldl4Irh8Lx1PUhg/GZ0odM1d/h2qORAsejiFc7zb+SEmYPn1yDZzEDSU5PmDkmVLQ== dependencies: - "@jest/environment" "^29.5.0" - "@jest/fake-timers" "^29.5.0" - "@jest/types" "^29.5.0" + "@jest/environment" "^29.6.1" + "@jest/fake-timers" "^29.6.1" + "@jest/types" "^29.6.1" "@types/node" "*" - jest-mock "^29.5.0" - jest-util "^29.5.0" + jest-mock "^29.6.1" + jest-util "^29.6.1" jest-get-type@^29.4.3: version "29.4.3" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5" integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg== -jest-haste-map@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.5.0.tgz#69bd67dc9012d6e2723f20a945099e972b2e94de" - integrity sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA== +jest-haste-map@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.6.1.tgz#62655c7a1c1b349a3206441330fb2dbdb4b63803" + integrity sha512-0m7f9PZXxOCk1gRACiVgX85knUKPKLPg4oRCjLoqIm9brTHXaorMA0JpmtmVkQiT8nmXyIVoZd/nnH1cfC33ig== dependencies: - "@jest/types" "^29.5.0" + "@jest/types" "^29.6.1" "@types/graceful-fs" "^4.1.3" "@types/node" "*" anymatch "^3.0.3" fb-watchman "^2.0.0" graceful-fs "^4.2.9" jest-regex-util "^29.4.3" - jest-util "^29.5.0" - jest-worker "^29.5.0" + jest-util "^29.6.1" + jest-worker "^29.6.1" micromatch "^4.0.4" walker "^1.0.8" optionalDependencies: fsevents "^2.3.2" -jest-leak-detector@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz#cf4bdea9615c72bac4a3a7ba7e7930f9c0610c8c" - integrity sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow== +jest-leak-detector@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.6.1.tgz#66a902c81318e66e694df7d096a95466cb962f8e" + integrity sha512-OrxMNyZirpOEwkF3UHnIkAiZbtkBWiye+hhBweCHkVbCgyEy71Mwbb5zgeTNYWJBi1qgDVfPC1IwO9dVEeTLwQ== dependencies: jest-get-type "^29.4.3" - pretty-format "^29.5.0" + pretty-format "^29.6.1" -jest-matcher-utils@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz#d957af7f8c0692c5453666705621ad4abc2c59c5" - integrity sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw== +jest-matcher-utils@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.6.1.tgz#6c60075d84655d6300c5d5128f46531848160b53" + integrity sha512-SLaztw9d2mfQQKHmJXKM0HCbl2PPVld/t9Xa6P9sgiExijviSp7TnZZpw2Fpt+OI3nwUO/slJbOfzfUMKKC5QA== dependencies: chalk "^4.0.0" - jest-diff "^29.5.0" + jest-diff "^29.6.1" jest-get-type "^29.4.3" - pretty-format "^29.5.0" + pretty-format "^29.6.1" -jest-message-util@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.5.0.tgz#1f776cac3aca332ab8dd2e3b41625435085c900e" - integrity sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA== +jest-message-util@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.6.1.tgz#d0b21d87f117e1b9e165e24f245befd2ff34ff8d" + integrity sha512-KoAW2zAmNSd3Gk88uJ56qXUWbFk787QKmjjJVOjtGFmmGSZgDBrlIL4AfQw1xyMYPNVD7dNInfIbur9B2rd/wQ== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^29.5.0" + "@jest/types" "^29.6.1" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" graceful-fs "^4.2.9" micromatch "^4.0.4" - pretty-format "^29.5.0" + pretty-format "^29.6.1" slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.5.0.tgz#26e2172bcc71d8b0195081ff1f146ac7e1518aed" - integrity sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw== +jest-mock@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.6.1.tgz#049ee26aea8cbf54c764af649070910607316517" + integrity sha512-brovyV9HBkjXAEdRooaTQK42n8usKoSRR3gihzUpYeV/vwqgSoNfrksO7UfSACnPmxasO/8TmHM3w9Hp3G1dgw== dependencies: - "@jest/types" "^29.5.0" + "@jest/types" "^29.6.1" "@types/node" "*" - jest-util "^29.5.0" + jest-util "^29.6.1" jest-pnp-resolver@^1.2.2: version "1.2.3" @@ -1560,170 +1558,168 @@ jest-regex-util@^29.4.3: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.4.3.tgz#a42616141e0cae052cfa32c169945d00c0aa0bb8" integrity sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg== -jest-resolve-dependencies@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.5.0.tgz#f0ea29955996f49788bf70996052aa98e7befee4" - integrity sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg== +jest-resolve-dependencies@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.1.tgz#b85b06670f987a62515bbf625d54a499e3d708f5" + integrity sha512-BbFvxLXtcldaFOhNMXmHRWx1nXQO5LoXiKSGQcA1LxxirYceZT6ch8KTE1bK3X31TNG/JbkI7OkS/ABexVahiw== dependencies: jest-regex-util "^29.4.3" - jest-snapshot "^29.5.0" + jest-snapshot "^29.6.1" -jest-resolve@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.5.0.tgz#b053cc95ad1d5f6327f0ac8aae9f98795475ecdc" - integrity sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w== +jest-resolve@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.6.1.tgz#4c3324b993a85e300add2f8609f51b80ddea39ee" + integrity sha512-AeRkyS8g37UyJiP9w3mmI/VXU/q8l/IH52vj/cDAyScDcemRbSBhfX/NMYIGilQgSVwsjxrCHf3XJu4f+lxCMg== dependencies: chalk "^4.0.0" graceful-fs "^4.2.9" - jest-haste-map "^29.5.0" + jest-haste-map "^29.6.1" jest-pnp-resolver "^1.2.2" - jest-util "^29.5.0" - jest-validate "^29.5.0" + jest-util "^29.6.1" + jest-validate "^29.6.1" resolve "^1.20.0" resolve.exports "^2.0.0" slash "^3.0.0" -jest-runner@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.5.0.tgz#6a57c282eb0ef749778d444c1d758c6a7693b6f8" - integrity sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ== - dependencies: - "@jest/console" "^29.5.0" - "@jest/environment" "^29.5.0" - "@jest/test-result" "^29.5.0" - "@jest/transform" "^29.5.0" - "@jest/types" "^29.5.0" +jest-runner@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.6.1.tgz#54557087e7972d345540d622ab5bfc3d8f34688c" + integrity sha512-tw0wb2Q9yhjAQ2w8rHRDxteryyIck7gIzQE4Reu3JuOBpGp96xWgF0nY8MDdejzrLCZKDcp8JlZrBN/EtkQvPQ== + dependencies: + "@jest/console" "^29.6.1" + "@jest/environment" "^29.6.1" + "@jest/test-result" "^29.6.1" + "@jest/transform" "^29.6.1" + "@jest/types" "^29.6.1" "@types/node" "*" chalk "^4.0.0" emittery "^0.13.1" graceful-fs "^4.2.9" jest-docblock "^29.4.3" - jest-environment-node "^29.5.0" - jest-haste-map "^29.5.0" - jest-leak-detector "^29.5.0" - jest-message-util "^29.5.0" - jest-resolve "^29.5.0" - jest-runtime "^29.5.0" - jest-util "^29.5.0" - jest-watcher "^29.5.0" - jest-worker "^29.5.0" + jest-environment-node "^29.6.1" + jest-haste-map "^29.6.1" + jest-leak-detector "^29.6.1" + jest-message-util "^29.6.1" + jest-resolve "^29.6.1" + jest-runtime "^29.6.1" + jest-util "^29.6.1" + jest-watcher "^29.6.1" + jest-worker "^29.6.1" p-limit "^3.1.0" source-map-support "0.5.13" -jest-runtime@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.5.0.tgz#c83f943ee0c1da7eb91fa181b0811ebd59b03420" - integrity sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw== - dependencies: - "@jest/environment" "^29.5.0" - "@jest/fake-timers" "^29.5.0" - "@jest/globals" "^29.5.0" - "@jest/source-map" "^29.4.3" - "@jest/test-result" "^29.5.0" - "@jest/transform" "^29.5.0" - "@jest/types" "^29.5.0" +jest-runtime@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.6.1.tgz#8a0fc9274ef277f3d70ba19d238e64334958a0dc" + integrity sha512-D6/AYOA+Lhs5e5il8+5pSLemjtJezUr+8zx+Sn8xlmOux3XOqx4d8l/2udBea8CRPqqrzhsKUsN/gBDE/IcaPQ== + dependencies: + "@jest/environment" "^29.6.1" + "@jest/fake-timers" "^29.6.1" + "@jest/globals" "^29.6.1" + "@jest/source-map" "^29.6.0" + "@jest/test-result" "^29.6.1" + "@jest/transform" "^29.6.1" + "@jest/types" "^29.6.1" "@types/node" "*" chalk "^4.0.0" cjs-module-lexer "^1.0.0" collect-v8-coverage "^1.0.0" glob "^7.1.3" graceful-fs "^4.2.9" - jest-haste-map "^29.5.0" - jest-message-util "^29.5.0" - jest-mock "^29.5.0" + jest-haste-map "^29.6.1" + jest-message-util "^29.6.1" + jest-mock "^29.6.1" jest-regex-util "^29.4.3" - jest-resolve "^29.5.0" - jest-snapshot "^29.5.0" - jest-util "^29.5.0" + jest-resolve "^29.6.1" + jest-snapshot "^29.6.1" + jest-util "^29.6.1" slash "^3.0.0" strip-bom "^4.0.0" -jest-snapshot@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.5.0.tgz#c9c1ce0331e5b63cd444e2f95a55a73b84b1e8ce" - integrity sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g== +jest-snapshot@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.6.1.tgz#0d083cb7de716d5d5cdbe80d598ed2fbafac0239" + integrity sha512-G4UQE1QQ6OaCgfY+A0uR1W2AY0tGXUPQpoUClhWHq1Xdnx1H6JOrC2nH5lqnOEqaDgbHFgIwZ7bNq24HpB180A== dependencies: "@babel/core" "^7.11.6" "@babel/generator" "^7.7.2" "@babel/plugin-syntax-jsx" "^7.7.2" "@babel/plugin-syntax-typescript" "^7.7.2" - "@babel/traverse" "^7.7.2" "@babel/types" "^7.3.3" - "@jest/expect-utils" "^29.5.0" - "@jest/transform" "^29.5.0" - "@jest/types" "^29.5.0" - "@types/babel__traverse" "^7.0.6" + "@jest/expect-utils" "^29.6.1" + "@jest/transform" "^29.6.1" + "@jest/types" "^29.6.1" "@types/prettier" "^2.1.5" babel-preset-current-node-syntax "^1.0.0" chalk "^4.0.0" - expect "^29.5.0" + expect "^29.6.1" graceful-fs "^4.2.9" - jest-diff "^29.5.0" + jest-diff "^29.6.1" jest-get-type "^29.4.3" - jest-matcher-utils "^29.5.0" - jest-message-util "^29.5.0" - jest-util "^29.5.0" + jest-matcher-utils "^29.6.1" + jest-message-util "^29.6.1" + jest-util "^29.6.1" natural-compare "^1.4.0" - pretty-format "^29.5.0" - semver "^7.3.5" + pretty-format "^29.6.1" + semver "^7.5.3" -jest-util@^29.0.0, jest-util@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.5.0.tgz#24a4d3d92fc39ce90425311b23c27a6e0ef16b8f" - integrity sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ== +jest-util@^29.0.0, jest-util@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.6.1.tgz#c9e29a87a6edbf1e39e6dee2b4689b8a146679cb" + integrity sha512-NRFCcjc+/uO3ijUVyNOQJluf8PtGCe/W6cix36+M3cTFgiYqFOOW5MgN4JOOcvbUhcKTYVd1CvHz/LWi8d16Mg== dependencies: - "@jest/types" "^29.5.0" + "@jest/types" "^29.6.1" "@types/node" "*" chalk "^4.0.0" ci-info "^3.2.0" graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-validate@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.5.0.tgz#8e5a8f36178d40e47138dc00866a5f3bd9916ffc" - integrity sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ== +jest-validate@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.6.1.tgz#765e684af6e2c86dce950aebefbbcd4546d69f7b" + integrity sha512-r3Ds69/0KCN4vx4sYAbGL1EVpZ7MSS0vLmd3gV78O+NAx3PDQQukRU5hNHPXlyqCgFY8XUk7EuTMLugh0KzahA== dependencies: - "@jest/types" "^29.5.0" + "@jest/types" "^29.6.1" camelcase "^6.2.0" chalk "^4.0.0" jest-get-type "^29.4.3" leven "^3.1.0" - pretty-format "^29.5.0" + pretty-format "^29.6.1" -jest-watcher@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.5.0.tgz#cf7f0f949828ba65ddbbb45c743a382a4d911363" - integrity sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA== +jest-watcher@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.6.1.tgz#7c0c43ddd52418af134c551c92c9ea31e5ec942e" + integrity sha512-d4wpjWTS7HEZPaaj8m36QiaP856JthRZkrgcIY/7ISoUWPIillrXM23WPboZVLbiwZBt4/qn2Jke84Sla6JhFA== dependencies: - "@jest/test-result" "^29.5.0" - "@jest/types" "^29.5.0" + "@jest/test-result" "^29.6.1" + "@jest/types" "^29.6.1" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" emittery "^0.13.1" - jest-util "^29.5.0" + jest-util "^29.6.1" string-length "^4.0.1" -jest-worker@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.5.0.tgz#bdaefb06811bd3384d93f009755014d8acb4615d" - integrity sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA== +jest-worker@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.6.1.tgz#64b015f0e985ef3a8ad049b61fe92b3db74a5319" + integrity sha512-U+Wrbca7S8ZAxAe9L6nb6g8kPdia5hj32Puu5iOqBCMTMWFHXuK6dOV2IFrpedbTV8fjMFLdWNttQTBL6u2MRA== dependencies: "@types/node" "*" - jest-util "^29.5.0" + jest-util "^29.6.1" merge-stream "^2.0.0" supports-color "^8.0.0" -jest@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-29.5.0.tgz#f75157622f5ce7ad53028f2f8888ab53e1f1f24e" - integrity sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ== +jest@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest/-/jest-29.6.1.tgz#74be1cb719c3abe439f2d94aeb18e6540a5b02ad" + integrity sha512-Nirw5B4nn69rVUZtemCQhwxOBhm0nsp3hmtF4rzCeWD7BkjAXRIji7xWQfnTNbz9g0aVsBX6aZK3n+23LM6uDw== dependencies: - "@jest/core" "^29.5.0" - "@jest/types" "^29.5.0" + "@jest/core" "^29.6.1" + "@jest/types" "^29.6.1" import-local "^3.0.2" - jest-cli "^29.5.0" + jest-cli "^29.6.1" js-tokens@^4.0.0: version "4.0.0" @@ -1866,9 +1862,9 @@ node-int64@^0.4.0: integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== 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== + version "2.0.13" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" + integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== normalize-path@^3.0.0: version "3.0.0" @@ -1974,12 +1970,12 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -pretty-format@^29.0.0, pretty-format@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.5.0.tgz#283134e74f70e2e3e7229336de0e4fce94ccde5a" - integrity sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw== +pretty-format@^29.0.0, pretty-format@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.6.1.tgz#ec838c288850b7c4f9090b867c2d4f4edbfb0f3e" + integrity sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog== dependencies: - "@jest/schemas" "^29.4.3" + "@jest/schemas" "^29.6.0" ansi-styles "^5.0.0" react-is "^18.0.0" @@ -2037,15 +2033,15 @@ resolve@^1.20.0: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -semver@^6.0.0, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.5, semver@^7.5.3: - version "7.5.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" - integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== +semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0"