From 5099e4aacbb5a73238c2af4b517cac5801c9e872 Mon Sep 17 00:00:00 2001 From: cfaur09 Date: Tue, 15 Oct 2024 12:24:12 +0300 Subject: [PATCH 01/25] e.g commit --- src/common/api-config/entities/status-checker-thresholds.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common/api-config/entities/status-checker-thresholds.ts b/src/common/api-config/entities/status-checker-thresholds.ts index e9b17b316..f7f0bb15c 100644 --- a/src/common/api-config/entities/status-checker-thresholds.ts +++ b/src/common/api-config/entities/status-checker-thresholds.ts @@ -11,4 +11,5 @@ export class StatusCheckerThresholds { public tokenAccounts: number = 0; public tokenTransactions: number = 0; public nodeValidators: number = 0; + } From b35b11849348fe9ef89d20ba64f4c61266a027b0 Mon Sep 17 00:00:00 2001 From: Catalin Faur <52102171+cfaur09@users.noreply.github.com> Date: Wed, 27 Nov 2024 14:39:25 +0200 Subject: [PATCH 02/25] [temp] - add support for prefix ESDT (#1348) * add cacheDuration * add support for NftSubType * Update elastic.indexer.helper.ts * Update nft.filter.ts * Update nft.controller.ts * add filter.type on collection elastic * add subType even for SFT * fix mex.token.charts.spec.ts * Update nft.controller.ts * revert changes * add subType filter * add collections subType filter * add address collection roles subType * add subType filter for roles/collections count * add accounts/nfts subType filter * add accounts/collection subType Filter * add support for prefix ESDT * add cacheDuration * accept 3 - * include account sov tokens * Update account.controller.ts * add condition for 3 || 4 - * small fixes * temp skip tests * [wip] integrate new nestjs sdk * Revert "Merge branch 'refs/heads/feat/sovereign' into temp-support-for-sov-prefix" This reverts commit dd61d4eeed4883d13633fedd1ec2dd9de27e43e5, reversing changes made to 8cdc6f6427df0db407864dff0fac88b8512aa4bf. * fix * npmjs deps * fix dependency * bugfixes * fixes after review * remove console logs * ticker fixes --------- Co-authored-by: tanghel Co-authored-by: bogdan-rosianu Co-authored-by: bogdan-rosianu <51945539+bogdan-rosianu@users.noreply.github.com> --- package-lock.json | 86 +++++++++---------- package.json | 16 ++-- .../entities/status-checker-thresholds.ts | 1 - .../collections/collection.controller.ts | 2 +- .../collections/collection.service.ts | 11 ++- src/endpoints/esdt/esdt.address.service.ts | 37 ++++++-- src/endpoints/nfts/nft.controller.ts | 16 ++-- src/endpoints/nfts/nft.service.ts | 8 +- src/endpoints/tokens/token.controller.ts | 63 +------------- src/endpoints/tokens/token.service.ts | 29 +++++-- .../collections.controller.spec.ts | 2 +- 11 files changed, 125 insertions(+), 146 deletions(-) diff --git a/package-lock.json b/package-lock.json index cc4cceef8..3a4c41132 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,14 +16,14 @@ "@golevelup/nestjs-rabbitmq": "^4.0.0", "@multiversx/sdk-core": "^13.2.2", "@multiversx/sdk-data-api-client": "^0.7.0", - "@multiversx/sdk-nestjs-auth": "4.0.1", - "@multiversx/sdk-nestjs-cache": "4.0.1", - "@multiversx/sdk-nestjs-common": "4.0.1", - "@multiversx/sdk-nestjs-elastic": "^4.0.1", - "@multiversx/sdk-nestjs-http": "4.0.1", - "@multiversx/sdk-nestjs-monitoring": "4.0.1", - "@multiversx/sdk-nestjs-rabbitmq": "4.0.1", - "@multiversx/sdk-nestjs-redis": "4.0.1", + "@multiversx/sdk-nestjs-auth": "4.1.0-beta.0", + "@multiversx/sdk-nestjs-cache": "4.1.0-beta.0", + "@multiversx/sdk-nestjs-common": "4.1.0-beta.0", + "@multiversx/sdk-nestjs-elastic": "4.1.0-beta.0", + "@multiversx/sdk-nestjs-http": "4.1.0-beta.0", + "@multiversx/sdk-nestjs-monitoring": "4.1.0-beta.0", + "@multiversx/sdk-nestjs-rabbitmq": "4.1.0-beta.0", + "@multiversx/sdk-nestjs-redis": "4.1.0-beta.0", "@multiversx/sdk-wallet": "^4.0.0", "@nestjs/apollo": "12.0.11", "@nestjs/common": "10.2.0", @@ -3263,9 +3263,9 @@ "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" }, "node_modules/@multiversx/sdk-nestjs-auth": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-auth/-/sdk-nestjs-auth-4.0.1.tgz", - "integrity": "sha512-sPZeaoN/dT8v0Dj7ZPocjqOuoXD0CqD1VQnA5MNZvubuUZ9iMb65zpaQvyh+hhwUth4hST6IkT49K7zyf6G3gg==", + "version": "4.1.0-beta.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-auth/-/sdk-nestjs-auth-4.1.0-beta.0.tgz", + "integrity": "sha512-cqk8LJgvcUBbQucbGhRRgkBxqmDWEfKtRzv9AVyKKi2PBaFEUWkXcNkNUpHwHsPxd/zMZpVTUy0U+CIZ3ugBKA==", "dependencies": { "@multiversx/sdk-core": "^13.4.1", "@multiversx/sdk-native-auth-server": "^1.0.19", @@ -3273,9 +3273,9 @@ "jsonwebtoken": "^9.0.0" }, "peerDependencies": { - "@multiversx/sdk-nestjs-cache": "^4.0.0", - "@multiversx/sdk-nestjs-common": "^4.0.0", - "@multiversx/sdk-nestjs-monitoring": "^4.0.0", + "@multiversx/sdk-nestjs-cache": "^4.1.0-beta.0", + "@multiversx/sdk-nestjs-common": "^4.1.0-beta.0", + "@multiversx/sdk-nestjs-monitoring": "^4.1.0-beta.0", "@nestjs/common": "^10.x" } }, @@ -3301,9 +3301,9 @@ } }, "node_modules/@multiversx/sdk-nestjs-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-cache/-/sdk-nestjs-cache-4.0.1.tgz", - "integrity": "sha512-k4mmz8+zD/G2AvxGsZFkclywGL2laXaeUlyzVvWh/OcfAMZ4Mwf7ToSq18aOaT5p7m6nv3Q7s4kar4aRaNTCHg==", + "version": "4.1.0-beta.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-cache/-/sdk-nestjs-cache-4.1.0-beta.0.tgz", + "integrity": "sha512-v7D3hW3pNeGYl/MBeRXx+ccXlIBxzebStY51kusoRq/p3bjzXe1u6+YNHpY1FMDedk/IQXyYhS7TO49K0PsDgw==", "dependencies": { "lru-cache": "^8.0.4", "moment": "^2.29.4", @@ -3312,9 +3312,9 @@ "uuid": "^8.3.2" }, "peerDependencies": { - "@multiversx/sdk-nestjs-common": "^4.0.0", - "@multiversx/sdk-nestjs-monitoring": "^4.0.0", - "@multiversx/sdk-nestjs-redis": "^4.0.0", + "@multiversx/sdk-nestjs-common": "^4.1.0-beta.0", + "@multiversx/sdk-nestjs-monitoring": "^4.1.0-beta.0", + "@multiversx/sdk-nestjs-redis": "^4.1.0-beta.0", "@nestjs/common": "^10.x", "@nestjs/core": "^10.x" } @@ -3336,9 +3336,9 @@ } }, "node_modules/@multiversx/sdk-nestjs-common": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-common/-/sdk-nestjs-common-4.0.1.tgz", - "integrity": "sha512-vhSM6aClBJ7WxUQPCTjqjwmvLU4i6/BjjGglTuF+yABiuu2UjL5brqcdrkHLh9aCeJwzH85wsRD78CEiOjVgcg==", + "version": "4.1.0-beta.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-common/-/sdk-nestjs-common-4.1.0-beta.0.tgz", + "integrity": "sha512-GG/9IPJp72wdeAPR7hO4q7Ao8dulYGqfp+lM6WBhPTmqq9a58AH1BPc34l/6eG8p8h1ZI4g8ZzNn9YIGabY+qw==", "dependencies": { "@multiversx/sdk-core": "^13.4.1", "@multiversx/sdk-network-providers": "^2.6.0", @@ -3347,7 +3347,7 @@ "winston": "^3.7.2" }, "peerDependencies": { - "@multiversx/sdk-nestjs-monitoring": "^4.0.0", + "@multiversx/sdk-nestjs-monitoring": "^4.1.0-beta.0", "@nestjs/common": "^10.x", "@nestjs/config": "^3.x", "@nestjs/core": "^10.x", @@ -3363,34 +3363,34 @@ } }, "node_modules/@multiversx/sdk-nestjs-elastic": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-elastic/-/sdk-nestjs-elastic-4.0.1.tgz", - "integrity": "sha512-Ol/65Q1FzbZCLuGFgW5v3Q9Xy0ftpwKnCjP0iz3bIlxO5rEbWwLaUe5qvH5vKSi10FQ0QrcJXA0DmYM7nKmF4A==", + "version": "4.1.0-beta.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-elastic/-/sdk-nestjs-elastic-4.1.0-beta.0.tgz", + "integrity": "sha512-6TcaulRYtFxQjCHWIq1JYBnvhYa/W8ID/kWUPb+mhf64DD72zR633LiG1hachQqDbV87sz6bHhYrmVSaQm0QOg==", "peerDependencies": { - "@multiversx/sdk-nestjs-http": "^4.0.0", + "@multiversx/sdk-nestjs-http": "^4.1.0-beta.0", "@nestjs/common": "^10.x" } }, "node_modules/@multiversx/sdk-nestjs-http": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-http/-/sdk-nestjs-http-4.0.1.tgz", - "integrity": "sha512-2cq9Jmgihf6+UQ1sa7SYSCzca+PhFuxfuXJgRs/UKr11OPe11g2XNkFunTHHFTzbbmsQMVSpvdYW0i6auJQCUQ==", + "version": "4.1.0-beta.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-http/-/sdk-nestjs-http-4.1.0-beta.0.tgz", + "integrity": "sha512-sOiMsMUhcsVSySjeskVu6+ZNzbKzam9e8NODXWXWQ2KkdmsA6PW20feisln8efu0J6OHSqTboVdXi2mHnAhPIQ==", "dependencies": { "@multiversx/sdk-native-auth-client": "^1.0.9", "agentkeepalive": "^4.3.0", "axios": "^1.7.4" }, "peerDependencies": { - "@multiversx/sdk-nestjs-common": "^4.0.0", - "@multiversx/sdk-nestjs-monitoring": "^4.0.0", + "@multiversx/sdk-nestjs-common": "^4.1.0-beta.0", + "@multiversx/sdk-nestjs-monitoring": "^4.1.0-beta.0", "@nestjs/common": "^10.x", "@nestjs/core": "^10.x" } }, "node_modules/@multiversx/sdk-nestjs-monitoring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-monitoring/-/sdk-nestjs-monitoring-4.0.1.tgz", - "integrity": "sha512-TfWFrD0crVgWQ3lUhBNzwi/h1I8PiOjsCUyhyqg6amzCQiAMO1AuIKeLkfnaN8VyQb8x/OxMnhFrosaDGpp9Wg==", + "version": "4.1.0-beta.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-monitoring/-/sdk-nestjs-monitoring-4.1.0-beta.0.tgz", + "integrity": "sha512-1j+1PxCdKv5rh6pULVXeepUhf8HTln5oZV8EMCcrusSWS/azMoYmH9cK+p2S8XgL5zHfUNwJLFMiufQpY/MlNA==", "dependencies": { "prom-client": "^14.0.1", "winston": "^3.7.2", @@ -3401,15 +3401,15 @@ } }, "node_modules/@multiversx/sdk-nestjs-rabbitmq": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-rabbitmq/-/sdk-nestjs-rabbitmq-4.0.1.tgz", - "integrity": "sha512-NvAixK0idJn3WNlSBQMTsaKz/n64zbME0z0sLnI1OEUV1j25GQwaHRElnrv7TcduJtz9mwieIcC75+fp5Tedxg==", + "version": "4.1.0-beta.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-rabbitmq/-/sdk-nestjs-rabbitmq-4.1.0-beta.0.tgz", + "integrity": "sha512-KoQoHkQzPSP8XZSBbI03zoS96quhBCOj/IsmlJ29Fpvot/6Rl2RQ95lRzcIucIaBhUB9sI13AHUEC47uW/ScTA==", "dependencies": { "@golevelup/nestjs-rabbitmq": "4.0.0", "uuid": "^8.3.2" }, "peerDependencies": { - "@multiversx/sdk-nestjs-common": "^4.0.0", + "@multiversx/sdk-nestjs-common": "^4.1.0-beta.0", "@nestjs/common": "^10.x" } }, @@ -3496,9 +3496,9 @@ } }, "node_modules/@multiversx/sdk-nestjs-redis": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-redis/-/sdk-nestjs-redis-4.0.1.tgz", - "integrity": "sha512-Gq4DNnB3AIWCLDyBhmeKZS4notwjcLmiOvU8mNek3/FLrZgo8+DIOuIsMhuxp4GrzivpOj3eiza29RgvcGe+PA==", + "version": "4.1.0-beta.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-redis/-/sdk-nestjs-redis-4.1.0-beta.0.tgz", + "integrity": "sha512-Hm/zRf7U8LmzAGMhlGd8LfPx+f3/e9kPJzjztiGFer5Hv6IAOgzGTLBGiTWo7+LbI0ekLkDd+vo0pAHI4GROgQ==", "dependencies": { "ioredis": "^5.2.3" }, diff --git a/package.json b/package.json index b3db082c8..7365df6ba 100644 --- a/package.json +++ b/package.json @@ -83,14 +83,14 @@ "@golevelup/nestjs-rabbitmq": "^4.0.0", "@multiversx/sdk-core": "^13.2.2", "@multiversx/sdk-data-api-client": "^0.7.0", - "@multiversx/sdk-nestjs-auth": "4.0.1", - "@multiversx/sdk-nestjs-cache": "4.0.1", - "@multiversx/sdk-nestjs-common": "4.0.1", - "@multiversx/sdk-nestjs-elastic": "^4.0.1", - "@multiversx/sdk-nestjs-http": "4.0.1", - "@multiversx/sdk-nestjs-monitoring": "4.0.1", - "@multiversx/sdk-nestjs-rabbitmq": "4.0.1", - "@multiversx/sdk-nestjs-redis": "4.0.1", + "@multiversx/sdk-nestjs-auth": "4.1.0-beta.0", + "@multiversx/sdk-nestjs-cache": "4.1.0-beta.0", + "@multiversx/sdk-nestjs-common": "4.1.0-beta.0", + "@multiversx/sdk-nestjs-elastic": "4.1.0-beta.0", + "@multiversx/sdk-nestjs-http": "4.1.0-beta.0", + "@multiversx/sdk-nestjs-monitoring": "4.1.0-beta.0", + "@multiversx/sdk-nestjs-rabbitmq": "4.1.0-beta.0", + "@multiversx/sdk-nestjs-redis": "4.1.0-beta.0", "@multiversx/sdk-wallet": "^4.0.0", "@nestjs/apollo": "12.0.11", "@nestjs/common": "10.2.0", diff --git a/src/common/api-config/entities/status-checker-thresholds.ts b/src/common/api-config/entities/status-checker-thresholds.ts index f7f0bb15c..e9b17b316 100644 --- a/src/common/api-config/entities/status-checker-thresholds.ts +++ b/src/common/api-config/entities/status-checker-thresholds.ts @@ -11,5 +11,4 @@ export class StatusCheckerThresholds { public tokenAccounts: number = 0; public tokenTransactions: number = 0; public nodeValidators: number = 0; - } diff --git a/src/endpoints/collections/collection.controller.ts b/src/endpoints/collections/collection.controller.ts index 039ccd434..e81e8c614 100644 --- a/src/endpoints/collections/collection.controller.ts +++ b/src/endpoints/collections/collection.controller.ts @@ -7,7 +7,7 @@ import { Nft } from "../nfts/entities/nft"; import { NftService } from "../nfts/nft.service"; import { NftFilter } from "../nfts/entities/nft.filter"; import { NftQueryOptions } from "../nfts/entities/nft.query.options"; -import { ParseAddressPipe, ParseArrayPipe, ParseCollectionPipe, ParseBoolPipe, ParseEnumArrayPipe, ParseIntPipe, ApplyComplexity, ParseAddressArrayPipe, ParseBlockHashPipe, ParseEnumPipe, ParseRecordPipe, ParseNftArrayPipe, ParseCollectionArrayPipe } from '@multiversx/sdk-nestjs-common'; +import { ParseAddressPipe, ParseArrayPipe, ParseCollectionPipe, ParseBoolPipe, ParseEnumArrayPipe, ParseIntPipe, ApplyComplexity, ParseAddressArrayPipe, ParseBlockHashPipe, ParseEnumPipe, ParseRecordPipe, ParseCollectionArrayPipe, ParseNftArrayPipe } from '@multiversx/sdk-nestjs-common'; import { QueryPagination } from "src/common/entities/query.pagination"; import { CollectionFilter } from "./entities/collection.filter"; import { CollectionAccount } from "./entities/collection.account"; diff --git a/src/endpoints/collections/collection.service.ts b/src/endpoints/collections/collection.service.ts index ecff14fd2..8e5e79133 100644 --- a/src/endpoints/collections/collection.service.ts +++ b/src/endpoints/collections/collection.service.ts @@ -131,8 +131,14 @@ export class CollectionService { // @ts-ignore nftCollection.type = collectionProperties.type; nftCollection.name = collectionProperties.name; - nftCollection.collection = collectionIdentifier.split('-').slice(0, 2).join('-'); - nftCollection.ticker = collectionIdentifier.split('-')[0]; + if (TokenUtils.isSovereignIdentifier(collectionIdentifier)) { + nftCollection.collection = collectionIdentifier.split('-').slice(0, 3).join('-'); + nftCollection.ticker = collectionIdentifier.split('-')[1]; + } else { + nftCollection.collection = collectionIdentifier.split('-').slice(0, 2).join('-'); + nftCollection.ticker = collectionIdentifier.split('-')[0]; + } + nftCollection.canFreeze = collectionProperties.canFreeze; nftCollection.canWipe = collectionProperties.canWipe; nftCollection.canPause = collectionProperties.canPause; @@ -147,7 +153,6 @@ export class CollectionService { } nftCollection.assets = collectionsAssets[collectionIdentifier]; - nftCollection.ticker = nftCollection.assets ? collectionIdentifier.split('-')[0] : nftCollection.collection; nftCollections.push(nftCollection); } diff --git a/src/endpoints/esdt/esdt.address.service.ts b/src/endpoints/esdt/esdt.address.service.ts index 817598c2c..514ce0641 100644 --- a/src/endpoints/esdt/esdt.address.service.ts +++ b/src/endpoints/esdt/esdt.address.service.ts @@ -16,7 +16,7 @@ import { NftCollectionWithRoles } from "../collections/entities/nft.collection.w import { CollectionService } from "../collections/collection.service"; import { CollectionFilter } from "../collections/entities/collection.filter"; import { CollectionRoles } from "../tokens/entities/collection.roles"; -import { AddressUtils, BinaryUtils, OriginLogger } from '@multiversx/sdk-nestjs-common'; +import { AddressUtils, BinaryUtils, OriginLogger, TokenUtils } from '@multiversx/sdk-nestjs-common'; import { ApiUtils } from "@multiversx/sdk-nestjs-http"; import { MetricsService } from "@multiversx/sdk-nestjs-monitoring"; import { CacheService } from "@multiversx/sdk-nestjs-cache"; @@ -41,7 +41,7 @@ export class EsdtAddressService { private readonly nftExtendedAttributesService: NftExtendedAttributesService, @Inject(forwardRef(() => CollectionService)) private readonly collectionService: CollectionService, - private readonly assetsService: AssetsService + private readonly assetsService: AssetsService, ) { this.NFT_THUMBNAIL_PREFIX = this.apiConfigService.getExternalMediaUrl() + '/nfts/asset'; } @@ -210,11 +210,21 @@ export class EsdtAddressService { private async getNftsForAddressFromGateway(address: string, filter: NftFilter, pagination: QueryPagination): Promise { let esdts: Record = {}; + let collection: string | undefined; + let nonceHex: string | undefined; if (filter.identifiers && filter.identifiers.length === 1) { const identifier = filter.identifiers[0]; - const collection = identifier.split('-').slice(0, 2).join('-'); - const nonceHex = identifier.split('-')[2]; + + const splitIdentifierParts = identifier.split('-'); + if (TokenUtils.isSovereignIdentifier(identifier)) { + collection = splitIdentifierParts.slice(0, 3).join('-'); + nonceHex = splitIdentifierParts[3]; + } else { + collection = splitIdentifierParts.slice(0, 2).join('-'); + nonceHex = splitIdentifierParts[2]; + } + const nonceNumeric = BinaryUtils.hexToNumber(nonceHex); let result: any; @@ -239,7 +249,11 @@ export class EsdtAddressService { esdts = await this.getAllEsdtsForAddressFromGateway(address); } - const nfts: GatewayNft[] = Object.values(esdts).map(x => x as any).filter(x => x.tokenIdentifier.split('-').length === 3); + const nfts: GatewayNft[] = Object.values(esdts).map(x => x as any).filter(x => { + const isSovereignIdentifier = TokenUtils.isSovereignIdentifier(x.tokenIdentifier); + const numParts = x.tokenIdentifier.split('-').length; + return (!isSovereignIdentifier && numParts === 3) || (isSovereignIdentifier && numParts === 4); + }); const collator = new Intl.Collator('en', { sensitivity: 'base' }); nfts.sort((a: GatewayNft, b: GatewayNft) => collator.compare(a.tokenIdentifier, b.tokenIdentifier)); @@ -255,7 +269,12 @@ export class EsdtAddressService { for (const dataSourceNft of nfts) { const nft = new NftAccount(); nft.identifier = dataSourceNft.tokenIdentifier; - nft.collection = dataSourceNft.tokenIdentifier.split('-').slice(0, 2).join('-'); + const splitTokenIdentifierParts = dataSourceNft.tokenIdentifier.split('-'); + if (TokenUtils.isSovereignIdentifier(dataSourceNft.tokenIdentifier)) { + nft.collection = splitTokenIdentifierParts.slice(0, 3).join('-'); + } else { + nft.collection = splitTokenIdentifierParts.slice(0, 2).join('-'); + } nft.nonce = dataSourceNft.nonce; nft.creator = dataSourceNft.creator; nft.royalties = Number(dataSourceNft.royalties) / 100; // 10.000 => 100% @@ -394,6 +413,12 @@ export class EsdtAddressService { nfts = nfts.filter(x => nftSubTypes.includes(x.subType)); } + if (filter.subType) { + const nftSubTypes = filter.subType ?? []; + + nfts = nfts.filter(x => nftSubTypes.includes(x.subType)); + } + if (filter.collection) { nfts = nfts.filter(x => x.collection === filter.collection); } diff --git a/src/endpoints/nfts/nft.controller.ts b/src/endpoints/nfts/nft.controller.ts index 539d1797e..e97cb7cc9 100644 --- a/src/endpoints/nfts/nft.controller.ts +++ b/src/endpoints/nfts/nft.controller.ts @@ -194,7 +194,7 @@ export class NftController { @ApiOkResponse({ type: Nft }) @ApiNotFoundResponse({ description: 'Token not found' }) async getNft( - @Param('identifier', ParseNftPipe) identifier: string + @Param('identifier') identifier: string ): Promise { const token = await this.nftService.getSingleNft(identifier); if (token === undefined) { @@ -232,7 +232,7 @@ export class NftController { @ApiOkResponse({ type: NftSupply }) @ApiNotFoundResponse({ description: 'Token not found' }) async getNftSupply( - @Param('identifier', ParseNftPipe) identifier: string + @Param('identifier') identifier: string ): Promise<{ supply: string; }> { const totalSupply = await this.nftService.getNftSupply(identifier); if (!totalSupply) { @@ -249,7 +249,7 @@ export class NftController { @ApiQuery({ name: 'from', description: 'Number of items to skip for the result set', required: false }) @ApiQuery({ name: 'size', description: 'Number of items to retrieve', required: false }) async getNftAccounts( - @Param('identifier', ParseNftPipe) identifier: string, + @Param('identifier') identifier: string, @Query('from', new DefaultValuePipe(0), ParseIntPipe) from: number, @Query('size', new DefaultValuePipe(25), ParseIntPipe) size: number, ): Promise { @@ -265,7 +265,7 @@ export class NftController { @ApiOperation({ summary: 'NFT accounts count', description: 'Returns number of addresses that hold balances for a specific Non-Fungible / Semi-Fungible / MetaESDT token' }) @ApiOkResponse({ type: Number }) async getNftAccountsCount( - @Param('identifier', ParseNftPipe) identifier: string + @Param('identifier') identifier: string ): Promise { const ownersCount = await this.nftService.getNftOwnersCount(identifier); if (ownersCount === undefined) { @@ -298,7 +298,7 @@ export class NftController { @ApiQuery({ name: 'withScamInfo', description: 'Returns scam information', required: false, type: Boolean }) @ApiQuery({ name: 'withUsername', description: 'Integrates username in assets for all addresses present in the transactions', required: false, type: Boolean }) async getNftTransactions( - @Param('identifier', ParseNftPipe) identifier: string, + @Param('identifier') identifier: string, @Query('from', new DefaultValuePipe(0), ParseIntPipe) from: number, @Query('size', new DefaultValuePipe(25), ParseIntPipe) size: number, @Query('sender', ParseAddressPipe) sender?: string, @@ -350,7 +350,7 @@ export class NftController { @ApiQuery({ name: 'before', description: 'Before timestamp', required: false }) @ApiQuery({ name: 'after', description: 'After timestamp', required: false }) async getNftTransactionsCount( - @Param('identifier', ParseNftPipe) identifier: string, + @Param('identifier') identifier: string, @Query('sender', ParseAddressPipe) sender?: string, @Query('receiver', ParseAddressArrayPipe) receiver?: string[], @Query('senderShard', ParseIntPipe) senderShard?: number, @@ -400,7 +400,7 @@ export class NftController { @ApiQuery({ name: 'withScamInfo', description: 'Returns scam information', required: false, type: Boolean }) @ApiQuery({ name: 'withUsername', description: 'Integrates username in assets for all addresses present in the transfers', required: false, type: Boolean }) async getNftTransfers( - @Param('identifier', ParseNftPipe) identifier: string, + @Param('identifier') identifier: string, @Query('from', new DefaultValuePipe(0), ParseIntPipe) from: number, @Query('size', new DefaultValuePipe(25), ParseIntPipe) size: number, @Query('sender', ParseAddressPipe) sender?: string, @@ -452,7 +452,7 @@ export class NftController { @ApiQuery({ name: 'before', description: 'Before timestamp', required: false }) @ApiQuery({ name: 'after', description: 'After timestamp', required: false }) async getNftTransfersCount( - @Param('identifier', ParseNftPipe) identifier: string, + @Param('identifier') identifier: string, @Query('sender', ParseAddressPipe) sender?: string, @Query('receiver', ParseAddressArrayPipe) receiver?: string[], @Query('senderShard', ParseIntPipe) senderShard?: number, diff --git a/src/endpoints/nfts/nft.service.ts b/src/endpoints/nfts/nft.service.ts index 1c357d8ef..f6e774295 100644 --- a/src/endpoints/nfts/nft.service.ts +++ b/src/endpoints/nfts/nft.service.ts @@ -203,10 +203,6 @@ export class NftService { async getSingleNft(identifier: string): Promise { const nfts = await this.getNftsInternal(new QueryPagination({ from: 0, size: 1 }), new NftFilter(), identifier); - if (!TokenUtils.isNft(identifier)) { - return undefined; - } - if (nfts.length === 0) { return undefined; } @@ -280,7 +276,7 @@ export class NftService { } async isNft(identifier: string): Promise { - if (identifier.split('-').length !== 3) { + if (!TokenUtils.isNft(identifier)) { return false; } @@ -565,7 +561,7 @@ export class NftService { } async getNftSupply(identifier: string): Promise { - if (identifier.split('-').length !== 3) { + if (!TokenUtils.isNft(identifier)) { return undefined; } diff --git a/src/endpoints/tokens/token.controller.ts b/src/endpoints/tokens/token.controller.ts index d206e9c16..17bb0f338 100644 --- a/src/endpoints/tokens/token.controller.ts +++ b/src/endpoints/tokens/token.controller.ts @@ -17,7 +17,7 @@ import { QueryPagination } from "src/common/entities/query.pagination"; import { TokenFilter } from "./entities/token.filter"; import { TransactionFilter } from "../transactions/entities/transaction.filter"; import { TransactionQueryOptions } from "../transactions/entities/transactions.query.options"; -import { ParseAddressPipe, ParseBlockHashPipe, ParseBoolPipe, ParseEnumPipe, ParseIntPipe, ParseArrayPipe, ParseTokenPipe, ParseAddressArrayPipe, ApplyComplexity, ParseEnumArrayPipe } from "@multiversx/sdk-nestjs-common"; +import { ParseAddressPipe, ParseBlockHashPipe, ParseBoolPipe, ParseEnumPipe, ParseIntPipe, ParseArrayPipe, ParseAddressArrayPipe, ApplyComplexity, ParseEnumArrayPipe, ParseTokenPipe } from "@multiversx/sdk-nestjs-common"; import { TransactionDetailed } from "../transactions/entities/transaction.detailed"; import { Response } from "express"; import { TokenType } from "src/common/indexer/entities"; @@ -136,11 +136,6 @@ export class TokenController { @Param('identifier', ParseTokenPipe) identifier: string, @Query('denominated', new ParseBoolPipe) denominated?: boolean, ): Promise { - const isToken = await this.tokenService.isToken(identifier); - if (!isToken) { - throw new HttpException('Token not found', HttpStatus.NOT_FOUND); - } - const getSupplyResult = await this.tokenService.getTokenSupply(identifier, { denominated }); if (!getSupplyResult) { throw new NotFoundException('Token not found'); @@ -160,11 +155,6 @@ export class TokenController { @Query('from', new DefaultValuePipe(0), ParseIntPipe) from: number, @Query("size", new DefaultValuePipe(25), ParseIntPipe) size: number ): Promise { - const isToken = await this.tokenService.isToken(identifier); - if (!isToken) { - throw new HttpException('Token not found', HttpStatus.NOT_FOUND); - } - const accounts = await this.tokenService.getTokenAccounts(new QueryPagination({ from, size }), identifier); if (!accounts) { throw new NotFoundException('Token not found'); @@ -180,11 +170,6 @@ export class TokenController { async getTokenAccountsCount( @Param('identifier', ParseTokenPipe) identifier: string, ): Promise { - const isToken = await this.tokenService.isToken(identifier); - if (!isToken) { - throw new HttpException('Token not found', HttpStatus.NOT_FOUND); - } - const count = await this.tokenService.getTokenAccountsCount(identifier); if (count === undefined) { throw new NotFoundException('Token not found'); @@ -245,12 +230,6 @@ export class TokenController { @Query('withActionTransferValue', ParseBoolPipe) withActionTransferValue?: boolean, ) { const options = TransactionQueryOptions.applyDefaultOptions(size, { withScResults, withOperations, withLogs, withScamInfo, withUsername, withBlockInfo, withActionTransferValue }); - - const isToken = await this.tokenService.isToken(identifier); - if (!isToken) { - throw new NotFoundException('Token not found'); - } - return await this.transactionService.getTransactions(new TransactionFilter({ sender, receivers: receiver, @@ -300,11 +279,6 @@ export class TokenController { @Query('after', ParseIntPipe) after?: number, @Query('round', ParseIntPipe) round?: number, ) { - const isToken = await this.tokenService.isToken(identifier); - if (!isToken) { - throw new NotFoundException('Token not found'); - } - return await this.transactionService.getTransactionCount(new TransactionFilter({ sender, receivers: receiver, @@ -327,11 +301,6 @@ export class TokenController { async getTokenRoles( @Param('identifier', ParseTokenPipe) identifier: string, ): Promise { - const isToken = await this.tokenService.isToken(identifier); - if (!isToken) { - throw new HttpException('Token not found', HttpStatus.NOT_FOUND); - } - const roles = await this.tokenService.getTokenRoles(identifier); if (!roles) { throw new HttpException('Token roles not found', HttpStatus.NOT_FOUND); @@ -348,11 +317,6 @@ export class TokenController { @Param('identifier', ParseTokenPipe) identifier: string, @Param('address', ParseAddressPipe) address: string, ): Promise { - const isToken = await this.tokenService.isToken(identifier); - if (!isToken) { - throw new NotFoundException('Token not found'); - } - const roles = await this.tokenService.getTokenRolesForIdentifierAndAddress(identifier, address); if (!roles) { throw new NotFoundException('Token not found'); @@ -406,11 +370,6 @@ export class TokenController { @Query('withBlockInfo', new ParseBoolPipe) withBlockInfo?: boolean, @Query('withActionTransferValue', ParseBoolPipe) withActionTransferValue?: boolean, ): Promise { - const isToken = await this.tokenService.isToken(identifier); - if (!isToken) { - throw new NotFoundException('Token not found'); - } - const options = TransactionQueryOptions.applyDefaultOptions(size, { withScamInfo, withUsername, withBlockInfo, withActionTransferValue }); return await this.transferService.getTransfers(new TransactionFilter({ @@ -462,11 +421,6 @@ export class TokenController { @Query('after', ParseIntPipe) after?: number, @Query('round', ParseIntPipe) round?: number, ): Promise { - const isToken = await this.tokenService.isToken(identifier); - if (!isToken) { - throw new NotFoundException('Token not found'); - } - return await this.transferService.getTransfersCount(new TransactionFilter({ senders: sender, receivers: receiver, @@ -499,11 +453,6 @@ export class TokenController { @Query('after', ParseIntPipe) after?: number, @Query('round', ParseIntPipe) round?: number, ): Promise { - const isToken = await this.tokenService.isToken(identifier); - if (!isToken) { - throw new NotFoundException('Token not found'); - } - return await this.transferService.getTransfersCount(new TransactionFilter({ senders: sender, receivers: receiver, @@ -525,11 +474,6 @@ export class TokenController { @Param('identifier', ParseTokenPipe) identifier: string, @Res() response: Response ): Promise { - const isToken = await this.tokenService.isToken(identifier); - if (!isToken) { - throw new NotFoundException('Token not found'); - } - const url = await this.tokenService.getLogoPng(identifier); if (url === undefined) { throw new NotFoundException('Assets not found'); @@ -543,11 +487,6 @@ export class TokenController { @Param('identifier', ParseTokenPipe) identifier: string, @Res() response: Response ): Promise { - const isToken = await this.tokenService.isToken(identifier); - if (!isToken) { - throw new NotFoundException('Token not found'); - } - const url = await this.tokenService.getLogoSvg(identifier); if (url === undefined) { throw new NotFoundException('Assets not found'); diff --git a/src/endpoints/tokens/token.service.ts b/src/endpoints/tokens/token.service.ts index 107f371c5..3b7df3bf8 100644 --- a/src/endpoints/tokens/token.service.ts +++ b/src/endpoints/tokens/token.service.ts @@ -107,12 +107,17 @@ export class TokenService { } normalizeIdentifierCase(identifier: string): string { - const [ticker, randomSequence] = identifier.split("-"); - if (!ticker || !randomSequence) { + const isSovereignIdentifier = TokenUtils.isSovereignIdentifier(identifier); + const parts = identifier.split("-"); + if (parts.length < 2) { return identifier.toUpperCase(); } - return `${ticker.toUpperCase()}-${randomSequence.toLowerCase()}`; + if (isSovereignIdentifier) { + return `${parts[0].toLowerCase()}-${parts[1].toUpperCase()}-${parts[2].toLowerCase()}`; + } else { + return `${parts[0].toUpperCase()}-${parts[1].toLowerCase()}`; + } } async getTokens(queryPagination: QueryPagination, filter: TokenFilter): Promise { @@ -130,8 +135,14 @@ export class TokenService { } applyTickerFromAssets(token: Token) { + const splitParts = token.identifier.split('-'); + const isSovereignIdentifier = TokenUtils.isSovereignIdentifier(token.identifier); if (token.assets) { - token.ticker = token.identifier.split('-')[0]; + if (isSovereignIdentifier) { + token.ticker = splitParts[1]; + } else { + token.ticker = splitParts[0]; + } } else { token.ticker = token.identifier; } @@ -386,7 +397,6 @@ export class TokenService { async getAllTokensForAddress(address: string, filter: TokenFilter): Promise { const tokens = await this.getFilteredTokens(filter); - const tokensIndexed: { [index: string]: Token } = {}; for (const token of tokens) { tokensIndexed[token.identifier] = token; @@ -397,7 +407,12 @@ export class TokenService { const tokensWithBalance: TokenWithBalance[] = []; for (const tokenIdentifier of Object.keys(esdts)) { - const identifier = tokenIdentifier.split('-').slice(0, 2).join('-'); + let identifier = ''; + if (TokenUtils.isSovereignIdentifier(tokenIdentifier)) { + identifier = tokenIdentifier.split('-').slice(0, 3).join('-'); + } else { + identifier = tokenIdentifier.split('-').slice(0, 2).join('-'); + } const esdt = esdts[tokenIdentifier]; const token = tokensIndexed[identifier]; @@ -609,7 +624,7 @@ export class TokenService { } async getTokenProperties(identifier: string): Promise { - if (identifier.split('-').length !== 2) { + if (!TokenUtils.isCollection(identifier)) { return undefined; } diff --git a/src/test/unit/controllers/collections.controller.spec.ts b/src/test/unit/controllers/collections.controller.spec.ts index 2ffef1f26..f89e1758e 100644 --- a/src/test/unit/controllers/collections.controller.spec.ts +++ b/src/test/unit/controllers/collections.controller.spec.ts @@ -447,7 +447,7 @@ describe('CollectionController', () => { expect(collectionServiceMocks.getNftCollection).toHaveBeenCalled(); }); - it('should should throw collection validation pipe if given collection is not a valid collection', async () => { + it('should throw collection validation pipe if given collection is not a valid collection', async () => { collectionServiceMocks.getNftCollection.mockReturnValue({}); const collection = 'TEST-5409d3-Test'; From 057fc6495861229eb75fb230827d2ae21a52d177 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Wed, 11 Dec 2024 11:06:39 +0200 Subject: [PATCH 03/25] fix bls cache --- src/endpoints/bls/bls.service.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/endpoints/bls/bls.service.ts b/src/endpoints/bls/bls.service.ts index 313e9aaa1..27f06bb73 100644 --- a/src/endpoints/bls/bls.service.ts +++ b/src/endpoints/bls/bls.service.ts @@ -12,19 +12,17 @@ export class BlsService { ) { } public async getPublicKeys(shard: number, epoch: number): Promise { - return await this.cachingService.getOrSet( + const cachedValue = await this.cachingService.getOrSet( CacheInfo.ShardAndEpochBlses(shard, epoch).key, async () => await this.getPublicKeysRaw(shard, epoch), - CacheInfo.ShardAndEpochBlses(shard, epoch).ttl + CacheInfo.ShardAndEpochBlses(shard, epoch).ttl, ); + + return cachedValue ? cachedValue : []; } - private async getPublicKeysRaw(shard: number, epoch: number): Promise { - const publicKeys = await this.indexerService.getPublicKeys(shard, epoch); - if (publicKeys) { - return publicKeys; - } - return []; + private async getPublicKeysRaw(shard: number, epoch: number): Promise { + return await this.indexerService.getPublicKeys(shard, epoch); } async getBlsIndex(bls: string, shardId: number, epoch: number): Promise { From 290f30a3cff03a668c440d695ee9a110a73a912e Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Wed, 11 Dec 2024 12:15:29 +0200 Subject: [PATCH 04/25] fix bls cache --- src/endpoints/blocks/block.service.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/endpoints/blocks/block.service.ts b/src/endpoints/blocks/block.service.ts index 3b8418655..735dbdacf 100644 --- a/src/endpoints/blocks/block.service.ts +++ b/src/endpoints/blocks/block.service.ts @@ -84,10 +84,11 @@ export class BlockService { let { proposer, validators } = item; let blses: any = await this.cachingService.getLocal(CacheInfo.ShardAndEpochBlses(shardId, epoch).key); - if (!blses) { + if (!blses || blses.length === 0) { blses = await this.blsService.getPublicKeys(shardId, epoch); - - await this.cachingService.setLocal(CacheInfo.ShardAndEpochBlses(shardId, epoch).key, blses, CacheInfo.ShardAndEpochBlses(shardId, epoch).ttl); + if (blses.length > 0) { + await this.cachingService.setLocal(CacheInfo.ShardAndEpochBlses(shardId, epoch).key, blses, CacheInfo.ShardAndEpochBlses(shardId, epoch).ttl); + } } proposer = blses[proposer]; From 4c79f87e55e43a87d487d218e58fd5c48239e064 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Tue, 21 Jan 2025 16:40:32 +0200 Subject: [PATCH 05/25] API-417: added withCrossChainTransfers filter --- .../indexer/elastic/elastic.indexer.helper.ts | 18 +++++++++++++++--- src/endpoints/accounts/account.controller.ts | 7 ++++++- .../entities/transaction.filter.ts | 1 + .../transactions/transaction.controller.ts | 14 +++++++++++--- src/test/unit/services/bls.spec.ts | 8 -------- 5 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/common/indexer/elastic/elastic.indexer.helper.ts b/src/common/indexer/elastic/elastic.indexer.helper.ts index 0369f02f3..d2001a0d0 100644 --- a/src/common/indexer/elastic/elastic.indexer.helper.ts +++ b/src/common/indexer/elastic/elastic.indexer.helper.ts @@ -25,6 +25,7 @@ export class ElasticIndexerHelper { private nonFungibleEsdtTypes: NftType[] = [NftType.NonFungibleESDT, NftType.NonFungibleESDTv2, NftType.DynamicNonFungibleESDT]; private semiFungibleEsdtTypes: NftType[] = [NftType.SemiFungibleESDT, NftType.DynamicSemiFungibleESDT]; private metaEsdtTypes: NftType[] = [NftType.MetaESDT, NftType.DynamicMetaESDT]; + private crossChainTransferSenderShard = 4294967293; constructor( private readonly apiConfigService: ApiConfigService, @@ -529,16 +530,27 @@ export class ElasticIndexerHelper { let elasticQuery = ElasticQuery.create(); if (!filter.withRelayedScresults) { - elasticQuery = elasticQuery.withMustMatchCondition('type', 'normal'); + if (!filter.withCrossChainTransfers) { + elasticQuery = elasticQuery.withMustMatchCondition('type', 'normal'); + } else { + elasticQuery = elasticQuery.withShouldCondition([ + QueryType.Match('type', 'normal'), + QueryType.Match('senderShard', this.crossChainTransferSenderShard), + ]); + } } else { - elasticQuery = elasticQuery.withShouldCondition([ + const shouldConditions = [ QueryType.Match('type', 'normal'), QueryType.Must([ QueryType.Exists('relayerAddr'), QueryType.Match('type', 'unsigned'), new ScriptQuery(`doc['originalTxHash'].size() > 0 && doc['prevTxHash'].size() > 0 && doc['originalTxHash'].value == doc['prevTxHash'].value`), ]), - ]); + ]; + if (filter.withCrossChainTransfers) { + shouldConditions.push(QueryType.Match('senderShard', this.crossChainTransferSenderShard)); + } + elasticQuery = elasticQuery.withShouldCondition(shouldConditions); } elasticQuery = elasticQuery.withMustMatchCondition('senderShard', filter.senderShard) diff --git a/src/endpoints/accounts/account.controller.ts b/src/endpoints/accounts/account.controller.ts index 979378ecf..26adf168f 100644 --- a/src/endpoints/accounts/account.controller.ts +++ b/src/endpoints/accounts/account.controller.ts @@ -879,6 +879,7 @@ export class AccountController { @ApiQuery({ name: 'isRelayed', description: 'Returns isRelayed transactions details', required: false, type: Boolean }) @ApiQuery({ name: 'withActionTransferValue', description: 'Returns value in USD and EGLD for transferred tokens within the action attribute', required: false }) @ApiQuery({ name: 'withRelayedScresults', description: 'If set to true, will include smart contract results that resemble relayed transactions', required: false, type: Boolean }) + @ApiQuery({ name: 'withCrossChainTransfers', description: 'If set to true, will include cross chain transfer transactions', required: false, type: Boolean }) async getAccountTransactions( @Param('address', ParseAddressPipe) address: string, @Query('from', new DefaultValuePipe(0), ParseIntPipe) from: number, @@ -907,6 +908,7 @@ export class AccountController { @Query('isRelayed', ParseBoolPipe) isRelayed?: boolean, @Query('withActionTransferValue', ParseBoolPipe) withActionTransferValue?: boolean, @Query('withRelayedScresults', ParseBoolPipe) withRelayedScresults?: boolean, + @Query('withCrossChainTransfers', ParseBoolPipe) withCrossChainTransfers?: boolean, ) { const options = TransactionQueryOptions.applyDefaultOptions(size, { withScResults, withOperations, withLogs, withScamInfo, withUsername, withBlockInfo, withActionTransferValue }); @@ -927,6 +929,7 @@ export class AccountController { isRelayed, round, withRelayedScresults, + withCrossChainTransfers, }); TransactionFilter.validate(transactionFilter, size); return await this.transactionService.getTransactions(transactionFilter, new QueryPagination({ from, size }), options, address, fields); @@ -950,6 +953,7 @@ export class AccountController { @ApiQuery({ name: 'senderOrReceiver', description: 'One address that current address interacted with', required: false }) @ApiQuery({ name: 'isRelayed', description: 'Returns isRelayed transactions details', required: false, type: Boolean }) @ApiQuery({ name: 'withRelayedScresults', description: 'If set to true, will include smart contract results that resemble relayed transactions', required: false, type: Boolean }) + @ApiQuery({ name: 'withCrossChainTransfers', description: 'If set to true, will include cross chain transfer transactions', required: false, type: Boolean }) async getAccountTransactionsCount( @Param('address', ParseAddressPipe) address: string, @Query('sender', ParseAddressPipe) sender?: string, @@ -967,7 +971,7 @@ export class AccountController { @Query('senderOrReceiver', ParseAddressPipe) senderOrReceiver?: string, @Query('isRelayed', ParseBoolPipe) isRelayed?: boolean, @Query('withRelayedScresults', ParseBoolPipe) withRelayedScresults?: boolean, - + @Query('withCrossChainTransfers', ParseBoolPipe) withCrossChainTransfers?: boolean, ): Promise { return await this.transactionService.getTransactionCount(new TransactionFilter({ @@ -986,6 +990,7 @@ export class AccountController { isRelayed, round, withRelayedScresults, + withCrossChainTransfers, }), address); } diff --git a/src/endpoints/transactions/entities/transaction.filter.ts b/src/endpoints/transactions/entities/transaction.filter.ts index e20cc08bb..c7d9aa0f4 100644 --- a/src/endpoints/transactions/entities/transaction.filter.ts +++ b/src/endpoints/transactions/entities/transaction.filter.ts @@ -29,6 +29,7 @@ export class TransactionFilter { withRefunds?: boolean; withRelayedScresults?: boolean; withTxsRelayedByAddress?: boolean; + withCrossChainTransfers?: boolean; constructor(init?: Partial) { Object.assign(this, init); diff --git a/src/endpoints/transactions/transaction.controller.ts b/src/endpoints/transactions/transaction.controller.ts index aa0bbbb15..274e1722d 100644 --- a/src/endpoints/transactions/transaction.controller.ts +++ b/src/endpoints/transactions/transaction.controller.ts @@ -51,6 +51,7 @@ export class TransactionController { @ApiQuery({ name: 'isRelayed', description: 'Returns relayed transactions details', required: false, type: Boolean }) @ApiQuery({ name: 'withActionTransferValue', description: 'Returns value in USD and EGLD for transferred tokens within the action attribute', required: false }) @ApiQuery({ name: 'withRelayedScresults', description: 'If set to true, will include smart contract results that resemble relayed transactions', required: false, type: Boolean }) + @ApiQuery({ name: 'withCrossChainTransfers', description: 'If set to true, will include cross chain transfer transactions', required: false, type: Boolean }) getTransactions( @Query('from', new DefaultValuePipe(0), ParseIntPipe) from: number, @Query('size', new DefaultValuePipe(25), ParseIntPipe) size: number, @@ -79,6 +80,7 @@ export class TransactionController { @Query('isRelayed', ParseBoolPipe) isRelayed?: boolean, @Query('withActionTransferValue', ParseBoolPipe) withActionTransferValue?: boolean, @Query('withRelayedScresults', ParseBoolPipe) withRelayedScresults?: boolean, + @Query('withCrossChainTransfers', ParseBoolPipe) withCrossChainTransfers?: boolean, ) { const options = TransactionQueryOptions.applyDefaultOptions(size, { withScResults, withOperations, withLogs, withScamInfo, withUsername, withBlockInfo, withActionTransferValue }); @@ -99,7 +101,8 @@ export class TransactionController { relayer, isRelayed, round, - withRelayedScresults: withRelayedScresults, + withRelayedScresults, + withCrossChainTransfers, }); TransactionFilter.validate(transactionFilter, size); return this.transactionService.getTransactions(transactionFilter, @@ -129,6 +132,7 @@ export class TransactionController { @ApiQuery({ name: 'isRelayed', description: 'Returns relayed transactions details', required: false, type: Boolean }) @ApiQuery({ name: 'relayer', description: 'Filter by a relayer address', required: false }) @ApiQuery({ name: 'withRelayedScresults', description: 'If set to true, will include smart contract results that resemble relayed transactions', required: false, type: Boolean }) + @ApiQuery({ name: 'withCrossChainTransfers', description: 'If set to true, will include cross chain transfer transactions', required: false, type: Boolean }) getTransactionCount( @Query('sender', ParseAddressAndMetachainPipe) sender?: string, @Query('receiver', ParseAddressArrayPipe) receiver?: string[], @@ -146,6 +150,7 @@ export class TransactionController { @Query('relayer', ParseAddressPipe) relayer?: string, @Query('isRelayed', ParseBoolPipe) isRelayed?: boolean, @Query('withRelayedScresults', ParseBoolPipe) withRelayedScresults?: boolean, + @Query('withCrossChainTransfers', ParseBoolPipe) withCrossChainTransfers?: boolean, ): Promise { return this.transactionService.getTransactionCount(new TransactionFilter({ sender, @@ -163,7 +168,8 @@ export class TransactionController { relayer, isRelayed, round, - withRelayedScresults: withRelayedScresults, + withRelayedScresults, + withCrossChainTransfers, })); } @@ -186,6 +192,7 @@ export class TransactionController { @Query('relayer', ParseAddressPipe) relayer?: string, @Query('isRelayed', ParseBoolPipe) isRelayed?: boolean, @Query('withRelayedScresults', ParseBoolPipe) withRelayedScresults?: boolean, + @Query('withCrossChainTransfers', ParseBoolPipe) withCrossChainTransfers?: boolean, ): Promise { return this.transactionService.getTransactionCount(new TransactionFilter({ sender, @@ -203,7 +210,8 @@ export class TransactionController { isRelayed, relayer, round, - withRelayedScresults: withRelayedScresults, + withRelayedScresults, + withCrossChainTransfers, })); } diff --git a/src/test/unit/services/bls.spec.ts b/src/test/unit/services/bls.spec.ts index 2f6544bbf..0141fe8d1 100644 --- a/src/test/unit/services/bls.spec.ts +++ b/src/test/unit/services/bls.spec.ts @@ -100,14 +100,6 @@ describe('BlsService', () => { }); describe('getPublicKeysRaw', () => { - it('should return empty array if getPublicKeys returns undefined', async () => { - jest.spyOn(indexerService, 'getPublicKeys').mockResolvedValue(undefined); - - const result = await blsService['getPublicKeysRaw'](0, 1); - - expect(result).toEqual([]); - }); - it('should return public keys if getPublicKeys returns an array', async () => { const publicKeys = ['publicKey1', 'publicKey2']; jest.spyOn(indexerService, 'getPublicKeys').mockResolvedValue(publicKeys); From 060ad1a15c43ed4a5ef07c8f1bb1cc46759877c6 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Wed, 22 Jan 2025 11:47:13 +0200 Subject: [PATCH 06/25] extract cross chain transfers metadata --- .../transaction.action.service.ts | 49 ++++++++++++++++--- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/src/endpoints/transactions/transaction-action/transaction.action.service.ts b/src/endpoints/transactions/transaction-action/transaction.action.service.ts index 2f24be389..d6fcfa0d0 100644 --- a/src/endpoints/transactions/transaction-action/transaction.action.service.ts +++ b/src/endpoints/transactions/transaction-action/transaction.action.service.ts @@ -10,13 +10,14 @@ import { TransactionActionEsdtNftRecognizerService } from "./recognizers/esdt/tr import { TokenTransferService } from "src/endpoints/tokens/token.transfer.service"; import { TransactionType } from "src/endpoints/transactions/entities/transaction.type"; import { MetabondingActionRecognizerService } from "./recognizers/mex/mex.metabonding.action.recognizer.service"; -import { AddressUtils, BinaryUtils, StringUtils } from "@multiversx/sdk-nestjs-common"; -import { OriginLogger } from "@multiversx/sdk-nestjs-common"; +import { AddressUtils, BinaryUtils, OriginLogger, StringUtils } from "@multiversx/sdk-nestjs-common"; +import { TokenTransferProperties } from "../../tokens/entities/token.transfer.properties"; @Injectable() export class TransactionActionService { private recognizers: TransactionActionRecognizerInterface[] = []; private readonly logger = new OriginLogger(TransactionActionService.name); + private readonly esdtSystemAccountAddress = 'erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u'; constructor( private readonly mexRecognizer: TransactionActionMexRecognizerService, @@ -170,8 +171,15 @@ export class TransactionActionService { } private async getMultiTransferMetadata(metadata: TransactionMetadata, applyValue: boolean = false): Promise { + /* + sovereign cross chain transfer example: MultiESDTNFTTransfer@02@4147452d626532353731@@01314fb37062980000@42474431362d633437663436@@5d894a4a3a220000 + regular chain example: MultiESDTNFTTransfer@0000000000000000050000b4c094947e427d79931a8bad81316b797d238cdb3f@02@4c524f4e452d633133303234@@036f5933a0d19ae387@524f4e452d626232653639@@04493d2ce61b650000@6164644c6971756964697479@01@01 + */ + const isSovereignCrossChainTransfer = metadata.sender === this.esdtSystemAccountAddress; if (metadata.sender !== metadata.receiver) { - return undefined; + if (!isSovereignCrossChainTransfer) { + return undefined; + } } if (metadata.functionName !== 'MultiESDTNFTTransfer') { @@ -183,12 +191,22 @@ export class TransactionActionService { return undefined; } - if (!AddressUtils.isValidHexAddress(args[0])) { + if (!AddressUtils.isValidHexAddress(args[0]) && !isSovereignCrossChainTransfer) { return undefined; } - const receiver = AddressUtils.bech32Encode(args[0]); - const transferCount = BinaryUtils.hexToNumber(args[1]); + let receiver: string; + if (!isSovereignCrossChainTransfer) { + receiver = AddressUtils.bech32Encode(args[0]); + } else { + receiver = metadata.receiver; + } + + let transferCountIndex = 1; + if (isSovereignCrossChainTransfer) { + transferCountIndex = 0; + } + const transferCount = BinaryUtils.hexToNumber(args[transferCountIndex]); const result = new TransactionMetadata(); if (!result.transfers) { @@ -196,14 +214,19 @@ export class TransactionActionService { } let index = 2; + if (isSovereignCrossChainTransfer) { + index = 1; + } for (let i = 0; i < transferCount; i++) { const identifier = BinaryUtils.hexToString(args[index++]); const nonce = args[index++]; const value = this.parseValueFromMultiTransferValueArg(args[index++]); + let validProperties = false; if (nonce && nonce !== "00") { const properties = await this.tokenTransferService.getTokenTransferProperties({ identifier, nonce }); if (properties) { + validProperties = true; result.transfers.push({ value, properties, @@ -212,12 +235,26 @@ export class TransactionActionService { } else { const properties = await this.tokenTransferService.getTokenTransferProperties({ identifier, timestamp: metadata.timestamp, value: value.toString(), applyValue }); if (properties) { + validProperties = true; result.transfers.push({ value, properties, }); } } + + // TODO: might remove this after token details are indexed inside sovereign es + if (!validProperties) { // missing token details (decimals for example. extract transfer info - best effort) + result.transfers.push({ + value, + properties: new TokenTransferProperties({ + decimals: 18, + identifier, + ticker: identifier, + token: identifier, + }), + }); + } } result.sender = metadata.sender; From e0f2fefdc88b95092ef6b7d499e2b79f86e5231b Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Wed, 22 Jan 2025 13:27:07 +0200 Subject: [PATCH 07/25] fix --- .../entities/transaction.metadata.ts | 1 + .../transaction-action/transaction.action.service.ts | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/endpoints/transactions/transaction-action/entities/transaction.metadata.ts b/src/endpoints/transactions/transaction-action/entities/transaction.metadata.ts index 75646f4d0..55d45bc22 100644 --- a/src/endpoints/transactions/transaction-action/entities/transaction.metadata.ts +++ b/src/endpoints/transactions/transaction-action/entities/transaction.metadata.ts @@ -11,6 +11,7 @@ export class TransactionMetadata { receiver: string = ''; value: BigInt = BigInt(0); functionName?: string; + senderShard?: number = -1; functionArgs: string[] = []; timestamp: number = 0; transfers?: TransactionMetadataTransfer[]; diff --git a/src/endpoints/transactions/transaction-action/transaction.action.service.ts b/src/endpoints/transactions/transaction-action/transaction.action.service.ts index d6fcfa0d0..c3e494fa0 100644 --- a/src/endpoints/transactions/transaction-action/transaction.action.service.ts +++ b/src/endpoints/transactions/transaction-action/transaction.action.service.ts @@ -17,7 +17,7 @@ import { TokenTransferProperties } from "../../tokens/entities/token.transfer.pr export class TransactionActionService { private recognizers: TransactionActionRecognizerInterface[] = []; private readonly logger = new OriginLogger(TransactionActionService.name); - private readonly esdtSystemAccountAddress = 'erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u'; + private crossChainTransferSenderShard = 4294967293; constructor( private readonly mexRecognizer: TransactionActionMexRecognizerService, @@ -46,6 +46,9 @@ export class TransactionActionService { } async getTransactionAction(transaction: Transaction, applyValue: boolean = false): Promise { + if (transaction.txHash === '8537cde573855199b4bd2e01c4c6792c52f6cfaf2416e476b7ef32d4131c3f5a') { + console.log('aqui'); + } const metadata = await this.getTransactionMetadata(transaction, applyValue); const recognizers = await this.getRecognizers(); @@ -87,6 +90,9 @@ export class TransactionActionService { metadata.receiver = transaction.receiver; metadata.timestamp = transaction.timestamp; metadata.value = BigInt(transaction.value); + if (transaction.senderShard !== undefined) { + metadata.senderShard = transaction.senderShard; + } if (transaction.data) { const decodedData = BinaryUtils.base64Decode(transaction.data); @@ -175,7 +181,7 @@ export class TransactionActionService { sovereign cross chain transfer example: MultiESDTNFTTransfer@02@4147452d626532353731@@01314fb37062980000@42474431362d633437663436@@5d894a4a3a220000 regular chain example: MultiESDTNFTTransfer@0000000000000000050000b4c094947e427d79931a8bad81316b797d238cdb3f@02@4c524f4e452d633133303234@@036f5933a0d19ae387@524f4e452d626232653639@@04493d2ce61b650000@6164644c6971756964697479@01@01 */ - const isSovereignCrossChainTransfer = metadata.sender === this.esdtSystemAccountAddress; + const isSovereignCrossChainTransfer = metadata.senderShard === this.crossChainTransferSenderShard; if (metadata.sender !== metadata.receiver) { if (!isSovereignCrossChainTransfer) { return undefined; From e66b2c53682d6d980d35e890d103b2a73b5372da Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Wed, 22 Jan 2025 13:46:17 +0200 Subject: [PATCH 08/25] extra check --- .../transaction-action/transaction.action.service.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/endpoints/transactions/transaction-action/transaction.action.service.ts b/src/endpoints/transactions/transaction-action/transaction.action.service.ts index c3e494fa0..7a64cfb62 100644 --- a/src/endpoints/transactions/transaction-action/transaction.action.service.ts +++ b/src/endpoints/transactions/transaction-action/transaction.action.service.ts @@ -137,7 +137,8 @@ export class TransactionActionService { try { if (transaction.type === TransactionType.SmartContractResult) { if (metadata.functionName === 'MultiESDTNFTTransfer' && - metadata.functionArgs.length > 0 + metadata.functionArgs.length > 0 && + metadata.senderShard !== this.crossChainTransferSenderShard ) { // if the first argument has up to 4 hex chars (meaning it will contain up to 65536 transfers) // then we insert the address as the first parameter. otherwise we assume that the address From b217596c11cbbb1f87c8d9471fa1812a2d2b3159 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Wed, 22 Jan 2025 15:05:58 +0200 Subject: [PATCH 09/25] remove console log --- .../transaction-action/transaction.action.service.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/endpoints/transactions/transaction-action/transaction.action.service.ts b/src/endpoints/transactions/transaction-action/transaction.action.service.ts index 7a64cfb62..e5c3000f7 100644 --- a/src/endpoints/transactions/transaction-action/transaction.action.service.ts +++ b/src/endpoints/transactions/transaction-action/transaction.action.service.ts @@ -46,9 +46,6 @@ export class TransactionActionService { } async getTransactionAction(transaction: Transaction, applyValue: boolean = false): Promise { - if (transaction.txHash === '8537cde573855199b4bd2e01c4c6792c52f6cfaf2416e476b7ef32d4131c3f5a') { - console.log('aqui'); - } const metadata = await this.getTransactionMetadata(transaction, applyValue); const recognizers = await this.getRecognizers(); From 66f8374d0995b595155ba71a4f9acdeaf2156660 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Thu, 30 Jan 2025 14:04:06 +0200 Subject: [PATCH 10/25] fixes after review --- config/config.devnet-old.yaml | 1 + config/config.devnet.yaml | 1 + config/config.e2e-mocked.mainnet.yaml | 1 + config/config.e2e.mainnet.yaml | 1 + config/config.mainnet.yaml | 1 + config/config.placeholder.yaml | 1 + config/config.testnet.yaml | 1 + src/common/api-config/api.config.service.ts | 9 +++++++++ src/common/indexer/elastic/elastic.indexer.helper.ts | 5 ++--- src/endpoints/tokens/token.controller.ts | 6 ++++++ .../transaction-action/transaction.action.service.ts | 7 ++++--- src/test/unit/services/bls.spec.ts | 8 ++++++++ 12 files changed, 36 insertions(+), 6 deletions(-) diff --git a/config/config.devnet-old.yaml b/config/config.devnet-old.yaml index b066116c1..b57e84e0e 100644 --- a/config/config.devnet-old.yaml +++ b/config/config.devnet-old.yaml @@ -1,5 +1,6 @@ network: 'devnet-old' metaChainShardId: 4294967295 +crossChainSenderShardId: 4294967293 api: public: true private: true diff --git a/config/config.devnet.yaml b/config/config.devnet.yaml index 48ee28c9e..f5fd9befc 100644 --- a/config/config.devnet.yaml +++ b/config/config.devnet.yaml @@ -1,5 +1,6 @@ network: 'devnet' metaChainShardId: 4294967295 +crossChainSenderShardId: 4294967293 api: public: true publicPort: 3001 diff --git a/config/config.e2e-mocked.mainnet.yaml b/config/config.e2e-mocked.mainnet.yaml index f2ffbd055..e848cd20b 100644 --- a/config/config.e2e-mocked.mainnet.yaml +++ b/config/config.e2e-mocked.mainnet.yaml @@ -1,5 +1,6 @@ network: 'mainnet' metaChainShardId: 4294967295 +crossChainSenderShardId: 4294967293 api: public: true private: true diff --git a/config/config.e2e.mainnet.yaml b/config/config.e2e.mainnet.yaml index 558ff31af..ed101f9da 100644 --- a/config/config.e2e.mainnet.yaml +++ b/config/config.e2e.mainnet.yaml @@ -1,5 +1,6 @@ network: 'mainnet' metaChainShardId: 4294967295 +crossChainSenderShardId: 4294967293 api: public: true private: true diff --git a/config/config.mainnet.yaml b/config/config.mainnet.yaml index 0cd7f9202..ecea5b5d9 100644 --- a/config/config.mainnet.yaml +++ b/config/config.mainnet.yaml @@ -1,5 +1,6 @@ network: 'mainnet' metaChainShardId: 4294967295 +crossChainSenderShardId: 4294967293 api: public: true publicPort: 3001 diff --git a/config/config.placeholder.yaml b/config/config.placeholder.yaml index e764432d9..2ca6f4e39 100644 --- a/config/config.placeholder.yaml +++ b/config/config.placeholder.yaml @@ -1,5 +1,6 @@ network: 'DAPP_CONFIG' metaChainShardId: 4294967295 +crossChainSenderShardId: 4294967293 api: public: true publicPort: 3001 diff --git a/config/config.testnet.yaml b/config/config.testnet.yaml index 13f244dc4..16c13888b 100644 --- a/config/config.testnet.yaml +++ b/config/config.testnet.yaml @@ -1,5 +1,6 @@ network: 'testnet' metaChainShardId: 4294967295 +crossChainSenderShardId: 4294967293 api: public: true publicPort: 3001 diff --git a/src/common/api-config/api.config.service.ts b/src/common/api-config/api.config.service.ts index caa42d10b..71a972595 100644 --- a/src/common/api-config/api.config.service.ts +++ b/src/common/api-config/api.config.service.ts @@ -550,6 +550,15 @@ export class ApiConfigService { return metaChainShardId; } + getCrossChainSenderShardId(): number { + const crossChainSenderShardId = this.configService.get('crossChainSenderShardId'); + if (crossChainSenderShardId === undefined) { + throw new Error('No crossChainSenderShardId present'); + } + + return crossChainSenderShardId; + } + getRateLimiterSecret(): string | undefined { return this.configService.get('rateLimiterSecret'); } diff --git a/src/common/indexer/elastic/elastic.indexer.helper.ts b/src/common/indexer/elastic/elastic.indexer.helper.ts index d2001a0d0..16b1d80ee 100644 --- a/src/common/indexer/elastic/elastic.indexer.helper.ts +++ b/src/common/indexer/elastic/elastic.indexer.helper.ts @@ -25,7 +25,6 @@ export class ElasticIndexerHelper { private nonFungibleEsdtTypes: NftType[] = [NftType.NonFungibleESDT, NftType.NonFungibleESDTv2, NftType.DynamicNonFungibleESDT]; private semiFungibleEsdtTypes: NftType[] = [NftType.SemiFungibleESDT, NftType.DynamicSemiFungibleESDT]; private metaEsdtTypes: NftType[] = [NftType.MetaESDT, NftType.DynamicMetaESDT]; - private crossChainTransferSenderShard = 4294967293; constructor( private readonly apiConfigService: ApiConfigService, @@ -535,7 +534,7 @@ export class ElasticIndexerHelper { } else { elasticQuery = elasticQuery.withShouldCondition([ QueryType.Match('type', 'normal'), - QueryType.Match('senderShard', this.crossChainTransferSenderShard), + QueryType.Match('senderShard', this.apiConfigService.getCrossChainSenderShardId()), ]); } } else { @@ -548,7 +547,7 @@ export class ElasticIndexerHelper { ]), ]; if (filter.withCrossChainTransfers) { - shouldConditions.push(QueryType.Match('senderShard', this.crossChainTransferSenderShard)); + shouldConditions.push(QueryType.Match('senderShard', this.apiConfigService.getCrossChainSenderShardId())); } elasticQuery = elasticQuery.withShouldCondition(shouldConditions); } diff --git a/src/endpoints/tokens/token.controller.ts b/src/endpoints/tokens/token.controller.ts index 1814d4097..ac40c72b8 100644 --- a/src/endpoints/tokens/token.controller.ts +++ b/src/endpoints/tokens/token.controller.ts @@ -205,6 +205,7 @@ export class TokenController { @ApiQuery({ name: 'withBlockInfo', description: 'Returns sender / receiver block details', required: false, type: Boolean }) @ApiQuery({ name: 'withActionTransferValue', description: 'Returns value in USD and EGLD for transferred tokens within the action attribute', required: false }) @ApiQuery({ name: 'withRelayedScresults', description: 'If set to true, will include smart contract results that resemble relayed transactions', required: false, type: Boolean }) + @ApiQuery({ name: 'withCrossChainTransfers', description: 'If set to true, will include cross chain transfer transactions', required: false, type: Boolean }) async getTokenTransactions( @Param('identifier', ParseTokenPipe) identifier: string, @Query('from', new DefaultValuePipe(0), ParseIntPipe) from: number, @@ -230,6 +231,7 @@ export class TokenController { @Query('withBlockInfo', ParseBoolPipe) withBlockInfo?: boolean, @Query('withActionTransferValue', ParseBoolPipe) withActionTransferValue?: boolean, @Query('withRelayedScresults', ParseBoolPipe) withRelayedScresults?: boolean, + @Query('withCrossChainTransfers', ParseBoolPipe) withCrossChainTransfers?: boolean, ) { const options = TransactionQueryOptions.applyDefaultOptions(size, { withScResults, withOperations, withLogs, withScamInfo, withUsername, withBlockInfo, withActionTransferValue }); @@ -253,6 +255,7 @@ export class TokenController { order, round, withRelayedScresults, + withCrossChainTransfers, }); TransactionFilter.validate(transactionFilter, size); @@ -280,6 +283,7 @@ export class TokenController { @ApiQuery({ name: 'after', description: 'After timestamp', required: false }) @ApiQuery({ name: 'round', description: 'Filter by round number', required: false }) @ApiQuery({ name: 'withRelayedScresults', description: 'If set to true, will include smart contract results that resemble relayed transactions', required: false, type: Boolean }) + @ApiQuery({ name: 'withCrossChainTransfers', description: 'If set to true, will include cross chain transfer transactions', required: false, type: Boolean }) async getTokenTransactionsCount( @Param('identifier', ParseTokenPipe) identifier: string, @Query('sender', ParseAddressPipe) sender?: string, @@ -293,6 +297,7 @@ export class TokenController { @Query('after', ParseIntPipe) after?: number, @Query('round', ParseIntPipe) round?: number, @Query('withRelayedScresults', ParseBoolPipe) withRelayedScresults?: boolean, + @Query('withCrossChainTransfers', ParseBoolPipe) withCrossChainTransfers?: boolean, ) { return await this.transactionService.getTransactionCount(new TransactionFilter({ sender, @@ -307,6 +312,7 @@ export class TokenController { after, round, withRelayedScresults, + withCrossChainTransfers, })); } diff --git a/src/endpoints/transactions/transaction-action/transaction.action.service.ts b/src/endpoints/transactions/transaction-action/transaction.action.service.ts index e5c3000f7..07ffbe7de 100644 --- a/src/endpoints/transactions/transaction-action/transaction.action.service.ts +++ b/src/endpoints/transactions/transaction-action/transaction.action.service.ts @@ -12,12 +12,12 @@ import { TransactionType } from "src/endpoints/transactions/entities/transaction import { MetabondingActionRecognizerService } from "./recognizers/mex/mex.metabonding.action.recognizer.service"; import { AddressUtils, BinaryUtils, OriginLogger, StringUtils } from "@multiversx/sdk-nestjs-common"; import { TokenTransferProperties } from "../../tokens/entities/token.transfer.properties"; +import { ApiConfigService } from "../../../common/api-config/api.config.service"; @Injectable() export class TransactionActionService { private recognizers: TransactionActionRecognizerInterface[] = []; private readonly logger = new OriginLogger(TransactionActionService.name); - private crossChainTransferSenderShard = 4294967293; constructor( private readonly mexRecognizer: TransactionActionMexRecognizerService, @@ -27,6 +27,7 @@ export class TransactionActionService { @Inject(forwardRef(() => TokenTransferService)) private readonly tokenTransferService: TokenTransferService, private readonly metabondingRecognizer: MetabondingActionRecognizerService, + private readonly apiConfigService: ApiConfigService, ) { } private async getRecognizers() { @@ -135,7 +136,7 @@ export class TransactionActionService { if (transaction.type === TransactionType.SmartContractResult) { if (metadata.functionName === 'MultiESDTNFTTransfer' && metadata.functionArgs.length > 0 && - metadata.senderShard !== this.crossChainTransferSenderShard + metadata.senderShard !== this.apiConfigService.getCrossChainSenderShardId() ) { // if the first argument has up to 4 hex chars (meaning it will contain up to 65536 transfers) // then we insert the address as the first parameter. otherwise we assume that the address @@ -179,7 +180,7 @@ export class TransactionActionService { sovereign cross chain transfer example: MultiESDTNFTTransfer@02@4147452d626532353731@@01314fb37062980000@42474431362d633437663436@@5d894a4a3a220000 regular chain example: MultiESDTNFTTransfer@0000000000000000050000b4c094947e427d79931a8bad81316b797d238cdb3f@02@4c524f4e452d633133303234@@036f5933a0d19ae387@524f4e452d626232653639@@04493d2ce61b650000@6164644c6971756964697479@01@01 */ - const isSovereignCrossChainTransfer = metadata.senderShard === this.crossChainTransferSenderShard; + const isSovereignCrossChainTransfer = metadata.senderShard === this.apiConfigService.getCrossChainSenderShardId(); if (metadata.sender !== metadata.receiver) { if (!isSovereignCrossChainTransfer) { return undefined; diff --git a/src/test/unit/services/bls.spec.ts b/src/test/unit/services/bls.spec.ts index 0141fe8d1..3fdead1b4 100644 --- a/src/test/unit/services/bls.spec.ts +++ b/src/test/unit/services/bls.spec.ts @@ -100,6 +100,14 @@ describe('BlsService', () => { }); describe('getPublicKeysRaw', () => { + it('should return undefined if getPublicKeys returns undefined', async () => { + jest.spyOn(indexerService, 'getPublicKeys').mockResolvedValue(undefined); + + const result = await blsService['getPublicKeysRaw'](0, 1); + + expect(result).toBeUndefined(); + }); + it('should return public keys if getPublicKeys returns an array', async () => { const publicKeys = ['publicKey1', 'publicKey2']; jest.spyOn(indexerService, 'getPublicKeys').mockResolvedValue(publicKeys); From c8bc1fe12673d63bf69a6cdcd5596889070887e8 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Thu, 30 Jan 2025 14:14:15 +0200 Subject: [PATCH 11/25] always run unit tests on PRs --- .github/workflows/unit.tests.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/unit.tests.yml b/.github/workflows/unit.tests.yml index cdffb6fdd..67768a1b1 100644 --- a/.github/workflows/unit.tests.yml +++ b/.github/workflows/unit.tests.yml @@ -4,10 +4,7 @@ name: Unit tests on: - push: - branches: [main, development] pull_request: - branches: [main, development] jobs: build: From 510cef82d75245766fec35753939a2cabcbf50e3 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu <51945539+bogdan-rosianu@users.noreply.github.com> Date: Fri, 31 Jan 2025 12:42:53 +0200 Subject: [PATCH 12/25] Merge dev feat sov jan30 (#1444) * Add search query parameter to accounts count endpoints (#1441) * add transactions 'isScCall' filter support (#1440) * Enhance transaction and account APIs with 'isScCall' filter support * Enhance TransferController API by adding 'isScCall' query filter for improved transaction detail retrieval * Enhance ElasticIndexerHelper to support 'isScCall' filter for improved query capabilities * fixes after review * fixes after review * Added validatorAuction to GatewayComponentRequest enum in GatewayService, enhancing the request capabilities for transaction processing. (#1431) --------- Co-authored-by: Catalin Faur <52102171+cfaur09@users.noreply.github.com> --- src/common/gateway/gateway.service.ts | 1 + .../indexer/elastic/elastic.indexer.helper.ts | 12 ++++++++++++ src/common/indexer/entities/transaction.ts | 1 + src/endpoints/accounts/account.controller.ts | 19 +++++++++++++++++++ src/endpoints/tokens/token.controller.ts | 14 ++++++++++++++ .../entities/transaction.filter.ts | 1 + .../transactions/entities/transaction.ts | 3 +++ .../transactions/transaction.controller.ts | 8 ++++++++ .../transfers/transfer.controller.ts | 8 ++++++++ src/test/unit/services/accounts.spec.ts | 1 + src/test/unit/services/transactions.spec.ts | 2 ++ 11 files changed, 70 insertions(+) diff --git a/src/common/gateway/gateway.service.ts b/src/common/gateway/gateway.service.ts index 597ced989..45d5c827d 100644 --- a/src/common/gateway/gateway.service.ts +++ b/src/common/gateway/gateway.service.ts @@ -31,6 +31,7 @@ export class GatewayService { GatewayComponentRequest.vmQuery, GatewayComponentRequest.transactionPool, GatewayComponentRequest.guardianData, + GatewayComponentRequest.validatorAuction, ]); private readonly deepHistoryRequestsSet: Set = new Set([ diff --git a/src/common/indexer/elastic/elastic.indexer.helper.ts b/src/common/indexer/elastic/elastic.indexer.helper.ts index 16b1d80ee..19d7e0e97 100644 --- a/src/common/indexer/elastic/elastic.indexer.helper.ts +++ b/src/common/indexer/elastic/elastic.indexer.helper.ts @@ -424,6 +424,12 @@ export class ElasticIndexerHelper { elasticQuery = elasticQuery.withMustMatchCondition('round', filter.round); } + if (filter.isScCall !== undefined) { + elasticQuery = filter.isScCall + ? elasticQuery.withMustCondition(QueryType.Match('isScCall', true)) + : elasticQuery.withMustNotCondition(QueryType.Match('isScCall', true)); + } + return elasticQuery; } @@ -640,6 +646,12 @@ export class ElasticIndexerHelper { ])); } + if (filter.isScCall !== undefined) { + elasticQuery = filter.isScCall + ? elasticQuery.withMustCondition(QueryType.Match('isScCall', true)) + : elasticQuery.withMustNotCondition(QueryType.Match('isScCall', true)); + } + return elasticQuery; } diff --git a/src/common/indexer/entities/transaction.ts b/src/common/indexer/entities/transaction.ts index e93095bd3..f759ec1ea 100644 --- a/src/common/indexer/entities/transaction.ts +++ b/src/common/indexer/entities/transaction.ts @@ -34,4 +34,5 @@ export interface Transaction { relayer: string; relayerSignature: string; isRelayed: boolean; + isScCall: boolean; } diff --git a/src/endpoints/accounts/account.controller.ts b/src/endpoints/accounts/account.controller.ts index 26adf168f..acdc346b6 100644 --- a/src/endpoints/accounts/account.controller.ts +++ b/src/endpoints/accounts/account.controller.ts @@ -147,6 +147,7 @@ export class AccountController { @ApiQuery({ name: 'isSmartContract', description: 'Return total smart contracts count', required: false }) @ApiQuery({ name: 'name', description: 'Filter accounts by assets name', required: false }) @ApiQuery({ name: 'tags', description: 'Filter accounts by assets tags', required: false }) + @ApiQuery({ name: 'search', description: 'Search by account address, assets name', required: false }) @ApiQuery({ name: 'excludeTags', description: 'Exclude specific tags from result', required: false }) @ApiQuery({ name: 'hasAssets', description: 'Returns a list of accounts that have assets', required: false }) async getAccountsCount( @@ -156,6 +157,7 @@ export class AccountController { @Query("tags", ParseArrayPipe) tags?: string[], @Query("excludeTags", ParseArrayPipe) excludeTags?: string[], @Query("hasAssets", ParseBoolPipe) hasAssets?: boolean, + @Query("search") search?: string, ): Promise { return await this.accountService.getAccountsCount( new AccountQueryOptions( @@ -166,6 +168,7 @@ export class AccountController { tags, excludeTags, hasAssets, + search, })); } @@ -178,6 +181,7 @@ export class AccountController { @Query("tags", ParseArrayPipe) tags?: string[], @Query("excludeTags", ParseArrayPipe) excludeTags?: string[], @Query("hasAssets", ParseBoolPipe) hasAssets?: boolean, + @Query("search") search?: string, ): Promise { return await this.accountService.getAccountsCount( new AccountQueryOptions( @@ -188,6 +192,7 @@ export class AccountController { tags, excludeTags, hasAssets, + search, })); } @@ -877,6 +882,7 @@ export class AccountController { @ApiQuery({ name: 'computeScamInfo', required: false, type: Boolean }) @ApiQuery({ name: 'senderOrReceiver', description: 'One address that current address interacted with', required: false }) @ApiQuery({ name: 'isRelayed', description: 'Returns isRelayed transactions details', required: false, type: Boolean }) + @ApiQuery({ name: 'isScCall', description: 'Returns sc call transactions details', required: false, type: Boolean }) @ApiQuery({ name: 'withActionTransferValue', description: 'Returns value in USD and EGLD for transferred tokens within the action attribute', required: false }) @ApiQuery({ name: 'withRelayedScresults', description: 'If set to true, will include smart contract results that resemble relayed transactions', required: false, type: Boolean }) @ApiQuery({ name: 'withCrossChainTransfers', description: 'If set to true, will include cross chain transfer transactions', required: false, type: Boolean }) @@ -906,6 +912,7 @@ export class AccountController { @Query('withBlockInfo', ParseBoolPipe) withBlockInfo?: boolean, @Query('senderOrReceiver', ParseAddressPipe) senderOrReceiver?: string, @Query('isRelayed', ParseBoolPipe) isRelayed?: boolean, + @Query('isScCall', ParseBoolPipe) isScCall?: boolean, @Query('withActionTransferValue', ParseBoolPipe) withActionTransferValue?: boolean, @Query('withRelayedScresults', ParseBoolPipe) withRelayedScresults?: boolean, @Query('withCrossChainTransfers', ParseBoolPipe) withCrossChainTransfers?: boolean, @@ -927,6 +934,7 @@ export class AccountController { order, senderOrReceiver, isRelayed, + isScCall, round, withRelayedScresults, withCrossChainTransfers, @@ -952,6 +960,7 @@ export class AccountController { @ApiQuery({ name: 'round', description: 'Round number', required: false }) @ApiQuery({ name: 'senderOrReceiver', description: 'One address that current address interacted with', required: false }) @ApiQuery({ name: 'isRelayed', description: 'Returns isRelayed transactions details', required: false, type: Boolean }) + @ApiQuery({ name: 'isScCall', description: 'Returns sc call transactions details', required: false, type: Boolean }) @ApiQuery({ name: 'withRelayedScresults', description: 'If set to true, will include smart contract results that resemble relayed transactions', required: false, type: Boolean }) @ApiQuery({ name: 'withCrossChainTransfers', description: 'If set to true, will include cross chain transfer transactions', required: false, type: Boolean }) async getAccountTransactionsCount( @@ -970,6 +979,7 @@ export class AccountController { @Query('round', ParseIntPipe) round?: number, @Query('senderOrReceiver', ParseAddressPipe) senderOrReceiver?: string, @Query('isRelayed', ParseBoolPipe) isRelayed?: boolean, + @Query('isScCall', ParseBoolPipe) isScCall?: boolean, @Query('withRelayedScresults', ParseBoolPipe) withRelayedScresults?: boolean, @Query('withCrossChainTransfers', ParseBoolPipe) withCrossChainTransfers?: boolean, ): Promise { @@ -988,6 +998,7 @@ export class AccountController { after, senderOrReceiver, isRelayed, + isScCall, round, withRelayedScresults, withCrossChainTransfers, @@ -1015,6 +1026,7 @@ export class AccountController { @ApiQuery({ name: 'round', description: 'Round number', required: false }) @ApiQuery({ name: 'fields', description: 'List of fields to filter by', required: false, isArray: true, style: 'form', explode: false }) @ApiQuery({ name: 'relayer', description: 'Address of the relayer', required: false }) + @ApiQuery({ name: 'isScCall', description: 'Returns sc call transactions details', required: false, type: Boolean }) @ApiQuery({ name: 'withScamInfo', description: 'Returns scam information', required: false, type: Boolean }) @ApiQuery({ name: 'withUsername', description: 'Integrates username in assets for all addresses present in the transactions', required: false, type: Boolean }) @ApiQuery({ name: 'withBlockInfo', description: 'Returns sender / receiver block details', required: false, type: Boolean }) @@ -1047,6 +1059,7 @@ export class AccountController { @Query('withUsername', ParseBoolPipe) withUsername?: boolean, @Query('withBlockInfo', ParseBoolPipe) withBlockInfo?: boolean, @Query('senderOrReceiver', ParseAddressPipe) senderOrReceiver?: string, + @Query('isScCall', ParseBoolPipe) isScCall?: boolean, @Query('withLogs', ParseBoolPipe) withLogs?: boolean, @Query('withOperations', ParseBoolPipe) withOperations?: boolean, @Query('withActionTransferValue', ParseBoolPipe) withActionTransferValue?: boolean, @@ -1075,6 +1088,7 @@ export class AccountController { round, withRefunds, withTxsRelayedByAddress, + isScCall, }), new QueryPagination({ from, size }), options, @@ -1097,6 +1111,7 @@ export class AccountController { @ApiQuery({ name: 'before', description: 'Before timestamp', required: false }) @ApiQuery({ name: 'after', description: 'After timestamp', required: false }) @ApiQuery({ name: 'round', description: 'Round number', required: false }) + @ApiQuery({ name: 'isScCall', description: 'Returns sc call transactions details', required: false, type: Boolean }) @ApiQuery({ name: 'senderOrReceiver', description: 'One address that current address interacted with', required: false }) @ApiQuery({ name: 'withRefunds', description: 'Include refund transactions', required: false }) async getAccountTransfersCount( @@ -1114,6 +1129,7 @@ export class AccountController { @Query('after', ParseIntPipe) after?: number, @Query('round', ParseIntPipe) round?: number, @Query('senderOrReceiver', ParseAddressPipe) senderOrReceiver?: string, + @Query('isScCall', ParseBoolPipe) isScCall?: boolean, @Query('withRefunds', ParseBoolPipe) withRefunds?: boolean, ): Promise { return await this.transferService.getTransfersCount(new TransactionFilter({ @@ -1131,6 +1147,7 @@ export class AccountController { after, senderOrReceiver, round, + isScCall, withRefunds, })); } @@ -1153,6 +1170,7 @@ export class AccountController { @Query('round', ParseIntPipe) round?: number, @Query('senderOrReceiver', ParseAddressPipe) senderOrReceiver?: string, @Query('withRefunds', ParseBoolPipe) withRefunds?: boolean, + @Query('isScCall', ParseBoolPipe) isScCall?: boolean, ): Promise { return await this.transferService.getTransfersCount(new TransactionFilter({ address, @@ -1170,6 +1188,7 @@ export class AccountController { senderOrReceiver, round, withRefunds, + isScCall, })); } diff --git a/src/endpoints/tokens/token.controller.ts b/src/endpoints/tokens/token.controller.ts index ac40c72b8..0e2e2da2c 100644 --- a/src/endpoints/tokens/token.controller.ts +++ b/src/endpoints/tokens/token.controller.ts @@ -197,6 +197,7 @@ export class TokenController { @ApiQuery({ name: 'order', description: 'Sort order (asc/desc)', required: false, enum: SortOrder }) @ApiQuery({ name: 'from', description: 'Number of items to skip for the result set', required: false }) @ApiQuery({ name: 'size', description: 'Number of items to retrieve', required: false }) + @ApiQuery({ name: 'isScCall', description: 'Returns sc call transactions details', required: false, type: Boolean }) @ApiQuery({ name: 'withScResults', description: 'Return scResults for transactions', required: false, type: Boolean }) @ApiQuery({ name: 'withOperations', description: 'Return operations for transactions', required: false, type: Boolean }) @ApiQuery({ name: 'withLogs', description: 'Return logs for transactions', required: false, type: Boolean }) @@ -223,6 +224,7 @@ export class TokenController { @Query('round', ParseIntPipe) round?: number, @Query('order', new ParseEnumPipe(SortOrder)) order?: SortOrder, @Query('fields', ParseArrayPipe) fields?: string[], + @Query('isScCall', ParseBoolPipe) isScCall?: boolean, @Query('withScResults', ParseBoolPipe) withScResults?: boolean, @Query('withOperations', ParseBoolPipe) withOperations?: boolean, @Query('withLogs', ParseBoolPipe) withLogs?: boolean, @@ -254,6 +256,7 @@ export class TokenController { after, order, round, + isScCall, withRelayedScresults, withCrossChainTransfers, }); @@ -282,6 +285,7 @@ export class TokenController { @ApiQuery({ name: 'before', description: 'Before timestamp', required: false }) @ApiQuery({ name: 'after', description: 'After timestamp', required: false }) @ApiQuery({ name: 'round', description: 'Filter by round number', required: false }) + @ApiQuery({ name: 'isScCall', description: 'Returns sc call transactions details', required: false, type: Boolean }) @ApiQuery({ name: 'withRelayedScresults', description: 'If set to true, will include smart contract results that resemble relayed transactions', required: false, type: Boolean }) @ApiQuery({ name: 'withCrossChainTransfers', description: 'If set to true, will include cross chain transfer transactions', required: false, type: Boolean }) async getTokenTransactionsCount( @@ -297,6 +301,7 @@ export class TokenController { @Query('after', ParseIntPipe) after?: number, @Query('round', ParseIntPipe) round?: number, @Query('withRelayedScresults', ParseBoolPipe) withRelayedScresults?: boolean, + @Query('isScCall', ParseBoolPipe) isScCall?: boolean, @Query('withCrossChainTransfers', ParseBoolPipe) withCrossChainTransfers?: boolean, ) { return await this.transactionService.getTransactionCount(new TransactionFilter({ @@ -312,6 +317,7 @@ export class TokenController { after, round, withRelayedScresults, + isScCall, withCrossChainTransfers, })); } @@ -366,6 +372,7 @@ export class TokenController { @ApiQuery({ name: 'after', description: 'After timestamp', required: false }) @ApiQuery({ name: 'round', description: 'Filter by round number', required: false }) @ApiQuery({ name: 'fields', description: 'List of fields to filter by', required: false, isArray: true, style: 'form', explode: false }) + @ApiQuery({ name: 'isScCall', description: 'Returns sc call transactions details', required: false, type: Boolean }) @ApiQuery({ name: 'withScamInfo', description: 'Returns scam information', required: false, type: Boolean }) @ApiQuery({ name: 'withUsername', description: 'Integrates username in assets for all addresses present in the transactions', required: false, type: Boolean }) @ApiQuery({ name: 'withBlockInfo', description: 'Returns sender / receiver block details', required: false, type: Boolean }) @@ -387,6 +394,7 @@ export class TokenController { @Query('round', ParseIntPipe) round?: number, @Query('fields', ParseArrayPipe) fields?: string[], @Query('order', new ParseEnumPipe(SortOrder)) order?: SortOrder, + @Query('isScCall', ParseBoolPipe) isScCall?: boolean, @Query('withScamInfo', ParseBoolPipe) withScamInfo?: boolean, @Query('withUsername', ParseBoolPipe) withUsername?: boolean, @Query('withBlockInfo', ParseBoolPipe) withBlockInfo?: boolean, @@ -408,6 +416,7 @@ export class TokenController { after, order, round, + isScCall, }), new QueryPagination({ from, size }), options, @@ -429,6 +438,7 @@ export class TokenController { @ApiQuery({ name: 'before', description: 'Before timestamp', required: false }) @ApiQuery({ name: 'after', description: 'After timestamp', required: false }) @ApiQuery({ name: 'round', description: 'Filter by round number', required: false }) + @ApiQuery({ name: 'isScCall', description: 'Returns sc call transactions details', required: false, type: Boolean }) async getTokenTransfersCount( @Param('identifier', ParseTokenPipe) identifier: string, @Query('sender', ParseAddressArrayPipe) sender?: string[], @@ -442,6 +452,7 @@ export class TokenController { @Query('before', ParseIntPipe) before?: number, @Query('after', ParseIntPipe) after?: number, @Query('round', ParseIntPipe) round?: number, + @Query('isScCall', ParseBoolPipe) isScCall?: boolean, ): Promise { return await this.transferService.getTransfersCount(new TransactionFilter({ senders: sender, @@ -456,6 +467,7 @@ export class TokenController { before, after, round, + isScCall, })); } @@ -474,6 +486,7 @@ export class TokenController { @Query('before', ParseIntPipe) before?: number, @Query('after', ParseIntPipe) after?: number, @Query('round', ParseIntPipe) round?: number, + @Query('isScCall', ParseBoolPipe) isScCall?: boolean, ): Promise { return await this.transferService.getTransfersCount(new TransactionFilter({ senders: sender, @@ -488,6 +501,7 @@ export class TokenController { before, after, round, + isScCall, })); } diff --git a/src/endpoints/transactions/entities/transaction.filter.ts b/src/endpoints/transactions/entities/transaction.filter.ts index c7d9aa0f4..0a2090df5 100644 --- a/src/endpoints/transactions/entities/transaction.filter.ts +++ b/src/endpoints/transactions/entities/transaction.filter.ts @@ -23,6 +23,7 @@ export class TransactionFilter { type?: TransactionType; tokens?: string[]; senderOrReceiver?: string; + isScCall?: boolean; isRelayed?: boolean; relayer?: string; round?: number; diff --git a/src/endpoints/transactions/entities/transaction.ts b/src/endpoints/transactions/entities/transaction.ts index b8e284733..ffd1cb99a 100644 --- a/src/endpoints/transactions/entities/transaction.ts +++ b/src/endpoints/transactions/entities/transaction.ts @@ -110,6 +110,9 @@ export class Transaction { @ApiProperty({ type: String, nullable: true, required: false }) relayerSignature: string | undefined = undefined; + @ApiProperty({ type: Boolean, nullable: true, required: false }) + isScCall: boolean | undefined = undefined; + getDate(): Date | undefined { if (this.timestamp) { return new Date(this.timestamp * 1000); diff --git a/src/endpoints/transactions/transaction.controller.ts b/src/endpoints/transactions/transaction.controller.ts index 274e1722d..2d77daef4 100644 --- a/src/endpoints/transactions/transaction.controller.ts +++ b/src/endpoints/transactions/transaction.controller.ts @@ -49,6 +49,7 @@ export class TransactionController { @ApiQuery({ name: 'withBlockInfo', description: 'Returns sender / receiver block details', required: false, type: Boolean }) @ApiQuery({ name: 'relayer', description: 'Search by a relayer address', required: false }) @ApiQuery({ name: 'isRelayed', description: 'Returns relayed transactions details', required: false, type: Boolean }) + @ApiQuery({ name: 'isScCall', description: 'Returns sc call transactions details', required: false, type: Boolean }) @ApiQuery({ name: 'withActionTransferValue', description: 'Returns value in USD and EGLD for transferred tokens within the action attribute', required: false }) @ApiQuery({ name: 'withRelayedScresults', description: 'If set to true, will include smart contract results that resemble relayed transactions', required: false, type: Boolean }) @ApiQuery({ name: 'withCrossChainTransfers', description: 'If set to true, will include cross chain transfer transactions', required: false, type: Boolean }) @@ -78,6 +79,7 @@ export class TransactionController { @Query('withUsername', ParseBoolPipe) withUsername?: boolean, @Query('withBlockInfo', ParseBoolPipe) withBlockInfo?: boolean, @Query('isRelayed', ParseBoolPipe) isRelayed?: boolean, + @Query('isScCall', ParseBoolPipe) isScCall?: boolean, @Query('withActionTransferValue', ParseBoolPipe) withActionTransferValue?: boolean, @Query('withRelayedScresults', ParseBoolPipe) withRelayedScresults?: boolean, @Query('withCrossChainTransfers', ParseBoolPipe) withCrossChainTransfers?: boolean, @@ -100,6 +102,7 @@ export class TransactionController { order, relayer, isRelayed, + isScCall, round, withRelayedScresults, withCrossChainTransfers, @@ -130,6 +133,7 @@ export class TransactionController { @ApiQuery({ name: 'after', description: 'After timestamp', required: false }) @ApiQuery({ name: 'round', description: 'Round number', required: false }) @ApiQuery({ name: 'isRelayed', description: 'Returns relayed transactions details', required: false, type: Boolean }) + @ApiQuery({ name: 'isScCall', description: 'Returns sc call transactions details', required: false, type: Boolean }) @ApiQuery({ name: 'relayer', description: 'Filter by a relayer address', required: false }) @ApiQuery({ name: 'withRelayedScresults', description: 'If set to true, will include smart contract results that resemble relayed transactions', required: false, type: Boolean }) @ApiQuery({ name: 'withCrossChainTransfers', description: 'If set to true, will include cross chain transfer transactions', required: false, type: Boolean }) @@ -149,6 +153,7 @@ export class TransactionController { @Query('round', ParseIntPipe) round?: number, @Query('relayer', ParseAddressPipe) relayer?: string, @Query('isRelayed', ParseBoolPipe) isRelayed?: boolean, + @Query('isScCall', ParseBoolPipe) isScCall?: boolean, @Query('withRelayedScresults', ParseBoolPipe) withRelayedScresults?: boolean, @Query('withCrossChainTransfers', ParseBoolPipe) withCrossChainTransfers?: boolean, ): Promise { @@ -167,6 +172,7 @@ export class TransactionController { condition, relayer, isRelayed, + isScCall, round, withRelayedScresults, withCrossChainTransfers, @@ -191,6 +197,7 @@ export class TransactionController { @Query('round', ParseIntPipe) round?: number, @Query('relayer', ParseAddressPipe) relayer?: string, @Query('isRelayed', ParseBoolPipe) isRelayed?: boolean, + @Query('isScCall', ParseBoolPipe) isScCall?: boolean, @Query('withRelayedScresults', ParseBoolPipe) withRelayedScresults?: boolean, @Query('withCrossChainTransfers', ParseBoolPipe) withCrossChainTransfers?: boolean, ): Promise { @@ -210,6 +217,7 @@ export class TransactionController { isRelayed, relayer, round, + isScCall, withRelayedScresults, withCrossChainTransfers, })); diff --git a/src/endpoints/transfers/transfer.controller.ts b/src/endpoints/transfers/transfer.controller.ts index 9c8fa4e8c..f127dd2bb 100644 --- a/src/endpoints/transfers/transfer.controller.ts +++ b/src/endpoints/transfers/transfer.controller.ts @@ -40,6 +40,7 @@ export class TransferController { @ApiQuery({ name: 'function', description: 'Filter transfers by function name', required: false }) @ApiQuery({ name: 'relayer', description: 'Filter by relayer address', required: false }) @ApiQuery({ name: 'isRelayed', description: 'Returns relayed transactions details', required: false, type: Boolean }) + @ApiQuery({ name: 'isScCall', description: 'Returns sc call transactions details', required: false, type: Boolean }) @ApiQuery({ name: 'withScamInfo', description: 'Returns scam information', required: false, type: Boolean }) @ApiQuery({ name: 'withUsername', description: 'Integrates username in assets for all addresses present in the transactions', required: false, type: Boolean }) @ApiQuery({ name: 'withBlockInfo', description: 'Returns sender / receiver block details', required: false, type: Boolean }) @@ -66,6 +67,7 @@ export class TransferController { @Query('fields', ParseArrayPipe) fields?: string[], @Query('relayer', ParseAddressPipe) relayer?: string, @Query('isRelayed', ParseBoolPipe) isRelayed?: boolean, + @Query('isScCall', ParseBoolPipe) isScCall?: boolean, @Query('withScamInfo', ParseBoolPipe) withScamInfo?: boolean, @Query('withUsername', ParseBoolPipe) withUsername?: boolean, @Query('withBlockInfo', ParseBoolPipe) withBlockInfo?: boolean, @@ -95,6 +97,7 @@ export class TransferController { isRelayed, round, withRefunds, + isScCall, }), new QueryPagination({ from, size }), options, @@ -119,6 +122,7 @@ export class TransferController { @ApiQuery({ name: 'round', description: 'Round number', required: false }) @ApiQuery({ name: 'relayer', description: 'Filter by the relayer address', required: false }) @ApiQuery({ name: 'isRelayed', description: 'Returns relayed transactions details', required: false, type: Boolean }) + @ApiQuery({ name: 'isScCall', description: 'Returns sc call transactions details', required: false, type: Boolean }) @ApiQuery({ name: 'withRefunds', description: 'Include refund transactions', required: false }) async getAccountTransfersCount( @Query('sender', ParseAddressArrayPipe) sender?: string[], @@ -135,6 +139,7 @@ export class TransferController { @Query('round', ParseIntPipe) round?: number, @Query('relayer', ParseAddressPipe) relayer?: string, @Query('isRelayed', ParseBoolPipe) isRelayed?: boolean, + @Query('isScCall', ParseBoolPipe) isScCall?: boolean, @Query('withRefunds', ParseBoolPipe) withRefunds?: boolean, ): Promise { return await this.transferService.getTransfersCount(new TransactionFilter({ @@ -153,6 +158,7 @@ export class TransferController { isRelayed, round, withRefunds, + isScCall, })); } @@ -173,6 +179,7 @@ export class TransferController { @Query('round', ParseIntPipe) round?: number, @Query('relayer', ParseAddressPipe) relayer?: string, @Query('isRelayed', ParseBoolPipe) isRelayed?: boolean, + @Query('isScCall', ParseBoolPipe) isScCall?: boolean, @Query('withRefunds', ParseBoolPipe) withRefunds?: boolean, ): Promise { return await this.transferService.getTransfersCount(new TransactionFilter({ @@ -191,6 +198,7 @@ export class TransferController { relayer, isRelayed, withRefunds, + isScCall, })); } } diff --git a/src/test/unit/services/accounts.spec.ts b/src/test/unit/services/accounts.spec.ts index 6893f7032..7407d3b8c 100644 --- a/src/test/unit/services/accounts.spec.ts +++ b/src/test/unit/services/accounts.spec.ts @@ -429,6 +429,7 @@ describe('Account Service', () => { version: 2, relayer: '', isRelayed: false, + isScCall: true, relayerSignature: '', }); diff --git a/src/test/unit/services/transactions.spec.ts b/src/test/unit/services/transactions.spec.ts index 5dbb87039..996ae2808 100644 --- a/src/test/unit/services/transactions.spec.ts +++ b/src/test/unit/services/transactions.spec.ts @@ -187,6 +187,7 @@ describe('TransactionService', () => { version: 1, relayer: 'erd1sdrjn0uuulydacwjam3v5afl427ptk797fpcujpfcsakfck8aqjquq9afc', isRelayed: true, + isScCall: true, relayerSignature: 'bc51e9032332740d60c404d4bf553ae225ca77a70ad799a1cdfc6e73609be8ec62e89ac6e2c2621ffbfb89e6fab620c137010662f3ebea9c422c9f1dbec04a03', }, { @@ -227,6 +228,7 @@ describe('TransactionService', () => { version: 1, relayer: 'erd1sdrjn0uuulydacwjam3v5afl427ptk797fpcujpfcsakfck8aqjquq9afc', isRelayed: true, + isScCall: true, relayerSignature: 'bc51e9032332740d60c404d4bf553ae225ca77a70ad799a1cdfc6e73609be8ec62e89ac6e2c2621ffbfb89e6fab620c137010662f3ebea9c422c9f1dbec04a03', }, ]; From 07f0217cae17c0045d2d8c05ffe9995fa4864e00 Mon Sep 17 00:00:00 2001 From: liviuancas-elrond Date: Thu, 20 Feb 2025 12:16:42 +0200 Subject: [PATCH 13/25] updated placeholder config --- config/config.placeholder.yaml | 36 ++++++++--------- entrypoint.sh | 70 +++++++++++++++++++--------------- 2 files changed, 58 insertions(+), 48 deletions(-) diff --git a/config/config.placeholder.yaml b/config/config.placeholder.yaml index 2ca6f4e39..b1b552bfa 100644 --- a/config/config.placeholder.yaml +++ b/config/config.placeholder.yaml @@ -1,14 +1,14 @@ -network: 'DAPP_CONFIG' +network: 'testnet' +dappNetwork: 'DAPP_CONFIG' metaChainShardId: 4294967295 -crossChainSenderShardId: 4294967293 api: - public: true + public: MVX_API_PUBLIC publicPort: 3001 - private: true + private: MVX_API_PRIVATE privatePort: 4001 websocket: true cron: - cacheWarmer: true + cacheWarmer: MVX_CACHEWARMER fastWarm: true queueWorker: true elasticUpdater: false @@ -22,9 +22,9 @@ flags: collectionPropertiesFromGateway: false features: eventsNotifier: - enabled: false + enabled: MVX_EVENTS_NOTIFIER port: 5674 - url: 'amqp://guest:guest@127.0.0.1:5673' + url: 'MVX_EVENTS_NOTIFIER_RABBIT_URL' exchange: 'all_events' queue: 'api-process-logs-and-events' guestCaching: @@ -62,16 +62,16 @@ features: - '' jwtSecret: '' stakingV4: - enabled: false + enabled: MVX_STAKINGV4 cronExpression: '*/5 * * * * *' activationEpoch: 1043 nodeEpochsLeft: enabled: false transactionProcessor: - enabled: false + enabled: MVX_TRANSACTIONPROCESSOR maxLookBehind: 100 transactionCompleted: - enabled: false + enabled: MVX_transactionCompleted maxLookBehind: 100 logLevel: 'Error' transactionBatch: @@ -98,14 +98,14 @@ features: enabled: false maxLookBehindNonces: 100 nodesFetch: - enabled: true - serviceUrl: 'NODESFETCH_URL' + enabled: MVX_NODESFETCH_ENABLE + serviceUrl: 'MVX_NODESFETCH_URL' tokensFetch: - enabled: true - serviceUrl: 'TOKENSFETCH_URL' + enabled: MVX_TOKENSFETCH_ENABLE + serviceUrl: 'MVX_TOKENSFETCH_URL' providersFetch: - enabled: true - serviceUrl: 'PROVIDERSFETCH_URL' + enabled: MVX_PROVIDERSFETCH_ENABLE + serviceUrl: 'MVX_PROVIDERSFETCH_URL' image: width: 600 height: 600 @@ -148,7 +148,7 @@ caching: cacheTtl: 6 processTtl: 600 poolLimit: 50 - cacheDuration: 3 + cacheDuration: MVX_CACHING_cacheDuration keepAliveTimeout: downstream: 61000 upstream: 60000 @@ -169,4 +169,4 @@ inflation: - 719203 nftProcess: parallelism: 1 - maxRetries: 3 + maxRetries: 3 \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh index 6f380f09a..56ac48874 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,30 +1,45 @@ #!/bin/sh # ENV VARIABLES - # MVX_ENV=devnet - # DAPP_CONFIG=devnet - # REDIS_IP=127.0.0.1 - # ELASTICSEARCH_URL=https://devnet-index.multiversx.com - # GATEWAY_URL=https://devnet-gateway.multiversx.com - # RABBITMQ_URL=amqp://127.0.0.1:5672 - # PROVIDERS_URL=https://devnet-delegation-api.multiversx.com/providers - # DELEGATION_URL=https://devnet-delegation-api.multiversx.com - # SOCKET_URL=devnet-socket-api.multiversx.com - # NODESFETCH_URL= https://devnet-api.multiversx.com - # TOKENSFETCH_URL= https://devnet-api.multiversx.com - # PROVIDERSFETCH_URL= https://devnet-api.multiversx.com - # DATAAPI_URL=https://devnet-data-api.multiversx.com - # EXCHANGE_URL=https://devnet-graph.xexchange.com/graphql - # MARKETPLACE_URL=https://devnet-nfts-graph.multiversx.com/graphql - # ASSETSFETCH_URL=https://tools.multiversx.com/assets-cdn - # PLACEHOLDER_DAPP_id=devnet - # PLACEHOLDER_DAPP_name=Devnet - # PLACEHOLDER_DAPP_egldLabel=xEGLD - # PLACEHOLDER_DAPP_walletAddress=https://devnet-wallet.multiversx.com - # PLACEHOLDER_DAPP_apiAddress=https://devnet-api.multiversx.com - # PLACEHOLDER_DAPP_explorerAddress=http://devnet-explorer.multiversx.com - # PLACEHOLDER_DAPP_chainId=D +env_vars_with_defaults="MVX_ENV=devnet \ +DAPP_CONFIG=devnet \ +MVX_API_PUBLIC=true \ +MVX_API_PRIVATE=true \ +MVX_CACHEWARMER=true \ +MVX_TRANSACTIONPROCESSOR=false \ +MVX_transactionCompleted=false \ +MVX_CACHING_cacheDuration=3 \ +MVX_STAKINGV4=false \ +MVX_EVENTS_NOTIFIER=false \ +MVX_EVENTS_NOTIFIER_RABBIT_URL=amqp://guest:guest@127.0.0.1:5673 \ +REDIS_IP=127.0.0.1 \ +ELASTICSEARCH_URL=https://devnet-index.multiversx.com \ +GATEWAY_URL=https://devnet-gateway.multiversx.com \ +RABBITMQ_URL=amqp://127.0.0.1:5672 \ +PROVIDERS_URL=https://devnet-delegation-api.multiversx.com/providers \ +DATAAPI_URL=https://devnet-data-api.multiversx.com \ +EXCHANGE_URL=https://devnet-graph.xexchange.com/graphql \ +MARKETPLACE_URL=https://devnet-nfts-graph.multiversx.com/graphql \ +ASSETSFETCH_URL=https://tools.multiversx.com/assets-cdn \ +DELEGATION_URL=https://devnet-delegation-api.multiversx.com \ +SOCKET_URL=devnet-socket-api.multiversx.com \ +MVX_NODESFETCH_ENABLE=true \ +MVX_NODESFETCH_URL=https://devnet-api.multiversx.com \ +MVX_TOKENSFETCH_ENABLE=true \ +MVX_TOKENSFETCH_URL=https://devnet-api.multiversx.com \ +MVX_PROVIDERSFETCH_ENABLE=true \ +MVX_PROVIDERSFETCH_URL=https://devnet-api.multiversx.com \ +PLACEHOLDER_DAPP_id=devnet \ +PLACEHOLDER_DAPP_name=Devnet \ +PLACEHOLDER_DAPP_egldLabel=xEGLD \ +PLACEHOLDER_DAPP_walletAddress=https://devnet-wallet.multiversx.com \ +PLACEHOLDER_DAPP_apiAddress=https://devnet-api.multiversx.com \ +PLACEHOLDER_DAPP_explorerAddress=http://devnet-explorer.multiversx.com \ +PLACEHOLDER_DAPP_chainId=D" -env_vars_with_defaults="MVX_ENV=devnet DAPP_CONFIG=devnet REDIS_IP=127.0.0.1 ELASTICSEARCH_URL=https://devnet-index.multiversx.com GATEWAY_URL=https://devnet-gateway.multiversx.com RABBITMQ_URL=amqp://127.0.0.1:5672 PROVIDERS_URL=https://devnet-delegation-api.multiversx.com/providers DATAAPI_URL=https://devnet-data-api.multiversx.com EXCHANGE_URL=https://devnet-graph.xexchange.com/graphql MARKETPLACE_URL=https://devnet-nfts-graph.multiversx.com/graphql ASSETSFETCH_URL=https://tools.multiversx.com/assets-cdn DELEGATION_URL=https://devnet-delegation-api.multiversx.com SOCKET_URL=devnet-socket-api.multiversx.com NODESFETCH_URL=https://devnet-api.multiversx.com TOKENSFETCH_URL=https://devnet-api.multiversx.com PROVIDERSFETCH_URL=https://devnet-api.multiversx.com PLACEHOLDER_DAPP_id=devnet PLACEHOLDER_DAPP_name=Devnet PLACEHOLDER_DAPP_egldLabel=xEGLD PLACEHOLDER_DAPP_walletAddress=https://devnet-wallet.multiversx.com PLACEHOLDER_DAPP_apiAddress=https://devnet-api.multiversx.com PLACEHOLDER_DAPP_explorerAddress=http://devnet-explorer.multiversx.com PLACEHOLDER_DAPP_chainId=D" +cp ./config/config.placeholder.yaml /app/dist/config/config.yaml +if [ $? -eq 0 ]; then + echo "Config file copied successfully from config/config.placeholder.yaml /app/dist/config/config.yaml" +fi replace_placeholder() { local var_name=$1 @@ -52,14 +67,9 @@ for entry in $env_vars_with_defaults; do # Use the environment variable value if defined; otherwise, use the default eval "value=\${$var_name:-$default_value}" - cp ./config/config.placeholder.yaml /app/dist/config/config.yaml - if [ $? -eq 0 ]; then - echo "Config file copied successfully from config/config.placeholder.yaml /app/dist/config/config.yaml" - fi - # Execute the function with the variable name and value replace_placeholder "$var_name" "$value" done -exec /usr/local/bin/node dist/src/main.js +exec /usr/local/bin/node dist/src/main.js \ No newline at end of file From c3a78bf5541886a76e28ccba33696326fe5c90a8 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu <51945539+bogdan-rosianu@users.noreply.github.com> Date: Tue, 25 Feb 2025 11:44:07 +0200 Subject: [PATCH 14/25] Merge development into feat/sovereign feb25 (#1457) * Add search query parameter to accounts count endpoints (#1441) * add transactions 'isScCall' filter support (#1440) * Enhance transaction and account APIs with 'isScCall' filter support * Enhance TransferController API by adding 'isScCall' query filter for improved transaction detail retrieval * Enhance ElasticIndexerHelper to support 'isScCall' filter for improved query capabilities * fixes after review * fixes after review * Added validatorAuction to GatewayComponentRequest enum in GatewayService, enhancing the request capabilities for transaction processing. (#1431) * Feat/chain simulator e2e (#1402) * API-72: first integration of chain simulator * API-72: npm init * API-72: refactoring * API-72: fix workflow file + cs start script * API-72: fix workflow file * API-72: update chain simulator tests and configuration * Enhance e2e test workflow: add API startup delay and shutdown step; introduce settings for editor configuration * Replace accounts e2e tests with new blocks e2e tests for improved coverage and functionality * Update blocks e2e test to filter by nonce 0 for accurate count validation * Update blocks e2e test to adjust epoch filter and add validation for high epoch values * Add e2e test for GET /blocks/latest endpoint with property and type validation * Add e2e test for blocks count with high epoch and nonce values * Remove scheduledRootHash from expected properties and type validation in blocks e2e tests * Add e2e tests for GET /blocks and GET /miniblocks endpoints with status code validation * Add e2e tests for GET /miniblocks endpoint with pagination and type filtering * Add e2e tests for GET /rounds * small refactoring * small refactoring * small refactoring_2 * small refactoring_2 * update file formatting * Create results.cs-e2e.ts * Update results.cs-e2e.ts * Update results.cs-e2e.ts * Add issueMultipleESDT + tokens.cs-e2e.ts * Update tokens.cs-e2e.ts * Update tokens.cs-e2e.ts * Update tokens.cs-e2e.ts * Update tokens.cs-e2e.ts * add EOL * add stop-chain-simulator script * refactorin + adding utils checks * move chain simulator operations into utils * add issueMultipleNftsCollections + env Alice Address * update tokens and collections tests + added bob address in config * Update collections.cs-e2e.ts * update docker file + overridable-config * revert chainsimulator image * update chainsimulator image * fixes after review * Update .gitignore * Create stake.cs-e2e.ts (#1407) * Create stake.cs-e2e.ts * Update stake.cs-e2e.ts * Create hello.cs-e2e.ts (#1405) * Create delegation.cs-e2e.ts (#1403) * Create delegation.cs-e2e.ts * Update delegation.cs-e2e.ts * Create delegation-legacy.cs-e2e.ts (#1404) * Create delegation-legacy.cs-e2e.ts * Update delegation-legacy.cs-e2e.ts * Create accounts.cs-e2e.ts (#1409) * Create accounts.cs-e2e.ts * Update tokens.cs-e2e.ts * Update accounts.cs-e2e.ts * Update accounts.cs-e2e.ts * add test sequencer * update * Update tokens.cs-e2e.ts * Update tokens.cs-e2e.ts * setTimeout * remove empty line * fixes after review * Update docker-compose.yml * Update accounts.cs-e2e.ts * update test * add deploy sc method * Update accounts.cs-e2e.ts * API-160: tx pool endpoint tests + new cs image (#1408) * API-160: tx pool endpoint tests + new cs image * push staged file * fix test * remove self sended txs * fixes after review * Create dapp.config.cs-e2e.ts (#1412) * Create dapp.config.cs-e2e.ts * Update dapp.config.cs-e2e.ts * Create shards.cs-e2e.ts (#1406) * Update accounts.cs-e2e.ts (#1410) * Update accounts.cs-e2e.ts * Update accounts.cs-e2e.ts * Update accounts.cs-e2e.ts * Update accounts.cs-e2e.ts * Update accounts.cs-e2e.ts * Update accounts.cs-e2e.ts * fixes after review * Update accounts.cs-e2e.ts * Update accounts.cs-e2e.ts * Update accounts.cs-e2e.ts * fixes after review * Update accounts.cs-e2e.ts * Create events.cs-e2e.ts (#1413) * Create events.cs-e2e.ts * Update events.cs-e2e.ts * fixes after review * Update events.cs-e2e.ts * Create identities.cs-e2e.ts (#1411) * Create identities.cs-e2e.ts * Update identities.cs-e2e.ts * Update identities.cs-e2e.ts * Update identities.cs-e2e.ts * Create applications.cs-e2e.ts * Update applications.cs-e2e.ts * Create transactions.cs-e2e.ts * Update transactions.cs-e2e.ts * Update transactions.cs-e2e.ts * Create websocket-config.cs-e2e.ts (#1415) * added more cs tests (#1418) * add CreateNFTEvent * add metaESDT issue collection / tokens * Create nfts.cs-e2e.ts * Update nfts.cs-e2e.ts * Update nfts.cs-e2e.ts * Update nfts.cs-e2e.ts * Update testSequencer.js * Update accounts.cs-e2e.ts * Update nfts.cs-e2e.ts * temp remove issueMetaESDT * Update accounts.cs-e2e.ts * add prepare data script * Update hello.cs-e2e.ts * Update prepare-test-data.ts * Update nfts.cs-e2e.ts * Update prepare-test-data.ts * Update prepare-test-data.ts * Merge branch 'feat/chain-simulator-e2e' of https://github.com/multiversx/mx-api-service into feat/chain-simulator-e2e * Refactor e2e tests by removing unnecessary waitForEpoch calls - Removed `beforeAll` hooks that called `ChainSimulatorUtils.waitForEpoch(2)` from multiple e2e test files: - This change simplifies the test setup and improves test execution time. * Increase wait time in prepareTestData function from 20 seconds to 23 seconds to ensure proper deployment of the PingPong smart contract. * Add end-to-end tests for tags API endpoints - Implement tests for GET /tags, including validation of response structure, pagination, and search functionality. - Add tests for GET /tags/count to verify the count of tags. - Include tests for GET /tags/:tag to ensure correct tag details are returned. - Enhance overall test coverage for the tags feature in the chain simulator. * Add end-to-end tests for NFT collection API endpoints - Implement tests for GET /collections/:collection/nfts to validate NFT retrieval, pagination, and filtering by various parameters (search term, identifiers, tags, creator, etc.). - Add tests for GET /collections/:collection/nfts/count to verify NFT count based on different criteria. * Reorder NFT collection issuance in prepareTestData function - Moved the issuance of NFT collections to occur after funding the address and before issuing Meta-ESDT collections. - This change improves the logical flow of the test data preparation process. * Update balance assertions in collections e2e tests to use string comparison - Changed balance assertions from numeric comparison (expect(account.balance).toStrictEqual(1)) to string comparison (expect(account.balance).toStrictEqual("1")) in multiple test cases. - This ensures consistency in data type handling for balance values across the tests. * Update collections e2e test to fetch two identifiers for NFT count validation * Increase wait time in prepareTestData function from 23 seconds to 25 seconds * Update collections e2e test to use string comparison for NFT supply validation * Refactor collections e2e test to improve NFT count retrieval * Add comprehensive e2e tests for NFT transactions and counts * Add extensive e2e tests for NFT transfers and counts * revert readme changes * Increase wait time in prepareTestData function from 25 seconds to 30 seconds to allow for additional processing time during test data preparation. * Add comprehensive e2e tests for accounts NFTs retrieval and filtering * Update e2e test for accounts NFTs to use strict equality check for tags validation * Add extensive e2e tests for NFT retrieval and filtering by various parameters * Refactor e2e tests for NFT retrieval: update size parameters, improve response validation, and enhance property checks * fixes + fixes after review * Update e2e tests for NFT retrieval to use NFT names instead of identifiers in API requests * Create nodes.cs-e2e.ts (#1416) * Development merge orchestator (#1445) * Added a check for encoded data in KeysService to handle cases where no data is returned, ensuring a default response of remainingUnBondPeriod as 0. (#1427) * websockets transactions events metrics (#1429) * Enhance ApiMetricsService with new transaction and batch update counters. * Updated WebSocketPublisherController to emit metrics events after processing transactions and batch updates. * Update web.socket controller spec * added function name for pool transactions (#1425) * added function name for pool transactions * fix modules imports * fix unit tests * add function filter * accounts endpoint make es heavy fiealds optional (#1426) * accounts endpoint make es heavy fiealds optional * optimize provider query for simple accounts * early return for null account * use AccountFetchOptions * fixes after review * fixes after review * Enhance AccountController tests to validate optional parameters in account retrieval. Added tests for withTxCount, withScrCount, withTimestamp, and withAssets parameters, ensuring correct behavior and response structure. Updated existing tests to reflect changes in expected account details when optional parameters are used. Improved overall test coverage for account details retrieval. --------- Co-authored-by: bogdan-rosianu Co-authored-by: cfaur09 * better treat invalid transactions (#1428) * Ft/multiple entry/docker file2 (#1434) * added sovereign * added placeholder config * added placeholder config * added placeholder config --------- Co-authored-by: liviuancas-elrond * add support for xoxno data API provider (#1437) * API-98: relayed v3 transactions support (#1395) * API-98: relayed v3 transactions support * added missing filters * fixes after review * fixes after merge * added filter to fetch transfers where an address is relayer * fix unit tests * added checks for multiple fields when getting transaction with isRelayed true * extract v3 version * fix relayed version extractor * include relayedVersion field in single tx fetching * exclude relayed txs if isRelayed=false * fix isRelayed query * Add search query parameter to accounts count endpoints (#1441) * add transactions 'isScCall' filter support (#1440) * Enhance transaction and account APIs with 'isScCall' filter support * Enhance TransferController API by adding 'isScCall' query filter for improved transaction detail retrieval * Enhance ElasticIndexerHelper to support 'isScCall' filter for improved query capabilities * fixes after review * fixes after review * Added validatorAuction to GatewayComponentRequest enum in GatewayService, enhancing the request capabilities for transaction processing. (#1431) * Create nodes.cs-e2e.ts (#1416) * update accounts tests * remove expects * fixes * fixes * fixes_2 --------- Co-authored-by: bogdan-rosianu <51945539+bogdan-rosianu@users.noreply.github.com> Co-authored-by: Rebegea Dragos-Alexandru <42241923+dragos-rebegea@users.noreply.github.com> Co-authored-by: bogdan-rosianu Co-authored-by: Liviu Ancas <83750585+liviuf-ancas@users.noreply.github.com> Co-authored-by: liviuancas-elrond --------- Co-authored-by: cfaur09 Co-authored-by: Catalin Faur <52102171+cfaur09@users.noreply.github.com> Co-authored-by: Rebegea Dragos-Alexandru <42241923+dragos-rebegea@users.noreply.github.com> Co-authored-by: Liviu Ancas <83750585+liviuf-ancas@users.noreply.github.com> Co-authored-by: liviuancas-elrond * update chain simulator github action (#1446) * Add e2e tests for transactions filtering by isScCall parameter * refactor isScCall undefined test * update load tests gh action * remove unused graphql fields (#1448) * remove unused graphql fields * includeHasFarms filter * update specs * fix specs * fixes * refactoring * add context tracker * add selftUrl * mexsettings refactoring * remove double filters * remove unused import * implement curso pagination * fix spec * remove logs * use filteredPairs instead of pairs in settings * pairs are already filtered by state Active * remove hardcoded pairs count and add factory query to fetch the pairs count * update logs * Refactor GraphQL queries into separate files for MEX services * add API documentation and error handling for MEX endpoints * update readme * undo changes * update applications endpoint (#1443) * update applications endpoint * implement cache system * added max size withTxCount request * return single application details * add getApplicationBalance private method to be able to reuse the same functionallity * simplify txCount for single application * Update GitHub Actions workflow to use actions/upload-artifact@v4 * bump version actions/download-artifact@v4 * refactor * update cs tests * fixes after review * updated entrypoint * updated entrypoint * fixes after merge * temp skip failing cs tests --------- Co-authored-by: Catalin Faur <52102171+cfaur09@users.noreply.github.com> Co-authored-by: cfaur09 Co-authored-by: Rebegea Dragos-Alexandru <42241923+dragos-rebegea@users.noreply.github.com> Co-authored-by: Liviu Ancas <83750585+liviuf-ancas@users.noreply.github.com> Co-authored-by: liviuancas-elrond --- .../workflows/chain-simulator-e2e-tests.yml | 65 + .github/workflows/load-tests.yml | 8 +- .gitignore | 5 +- Dockerfile | 22 +- config/config.e2e.mainnet.yaml | 145 +- config/config.placeholder.yaml | 172 -- config/dapp.config.placeholder.json | 17 - entrypoint.py | 173 ++ entrypoint.sh | 75 - package-lock.json | 5 +- package.json | 14 +- src/common/graphql/graphql.service.ts | 3 + .../elastic/elastic.indexer.service.ts | 4 + src/common/indexer/indexer.interface.ts | 2 + src/common/indexer/indexer.service.ts | 5 + .../applications/application.controller.ts | 20 +- .../applications/application.module.ts | 4 + .../applications/application.service.ts | 79 +- .../entities/application.filter.ts | 12 +- .../applications/entities/application.ts | 6 + src/endpoints/mex/entities/mex.pair.ts | 12 +- .../mex/entities/mex.pairs..filter.ts | 1 + src/endpoints/mex/entities/mex.settings.ts | 12 +- src/endpoints/mex/graphql/farms.query.ts | 98 + .../mex/graphql/filtered.pairs.query.ts | 51 + .../mex/graphql/pairs.count.query.ts | 8 + src/endpoints/mex/graphql/settings.query.ts | 60 + .../mex/graphql/staking.proxy.query.ts | 12 + .../token.prices.hour.resolution.query.ts | 13 + src/endpoints/mex/graphql/tokens.query.ts | 9 + src/endpoints/mex/mex.controller.ts | 29 +- src/endpoints/mex/mex.farm.service.ts | 115 +- src/endpoints/mex/mex.pair.service.ts | 169 +- src/endpoints/mex/mex.settings.service.ts | 91 +- src/endpoints/mex/mex.token.charts.service.ts | 14 +- src/endpoints/mex/mex.token.service.ts | 21 +- src/endpoints/tokens/token.service.ts | 21 +- src/test/chain-simulator/accounts.cs-e2e.ts | 1989 +++++++++++++++++ .../chain-simulator/applications.cs-e2e.ts | 76 + src/test/chain-simulator/blocks.cs-e2e.ts | 155 ++ .../chain-simulator/collections.cs-e2e.ts | 1314 +++++++++++ src/test/chain-simulator/config/.env.example | 4 + src/test/chain-simulator/config/env.config.ts | 13 + .../chain-simulator/dapp.config.cs-e2e.ts | 36 + .../delegation-legacy.cs-e2e.ts | 24 + src/test/chain-simulator/delegation.cs-e2e.ts | 14 + .../chain-simulator/docker/docker-compose.yml | 37 + .../docker/overridable-config.toml | 8 + src/test/chain-simulator/events.cs-e2e.ts | 113 + src/test/chain-simulator/hello.cs-e2e.ts | 13 + src/test/chain-simulator/identities.cs-e2e.ts | 41 + src/test/chain-simulator/miniblocks.cs-e2e.ts | 92 + src/test/chain-simulator/network.cs-e2e.ts | 79 + src/test/chain-simulator/nfts.cs-e2e.ts | 461 ++++ src/test/chain-simulator/nodes.cs-e2e.ts | 308 +++ src/test/chain-simulator/pool.cs-e2e.ts | 63 + src/test/chain-simulator/results.cs-e2e.ts | 116 + src/test/chain-simulator/rounds.cs-e2e.ts | 120 + src/test/chain-simulator/shards.cs-e2e.ts | 71 + src/test/chain-simulator/stake.cs-e2e.ts | 47 + src/test/chain-simulator/tags.cs-e2e.ts | 62 + src/test/chain-simulator/tokens.cs-e2e.ts | 423 ++++ .../chain-simulator/transactions.cs-e2e.ts | 358 +++ .../utils/chain.simulator.operations.ts | 551 +++++ .../utils/contracts/ping-pong-egld.wasm | Bin 0 -> 1349 bytes .../utils/prepare-test-data.ts | 37 + src/test/chain-simulator/utils/test.utils.ts | 99 + .../chain-simulator/utils/testSequencer.js | 39 + .../websocket-config.cs-e2e.ts | 12 + src/test/jest-api.json | 2 +- src/test/jest-chain-simulator.json | 21 + .../unit/controllers/mex.controller.spec.ts | 54 +- src/test/unit/services/applications.spec.ts | 110 +- .../unit/services/graphql.service.spec.ts | 1 + src/utils/cache.info.ts | 7 +- tsconfig.json | 12 +- 76 files changed, 7877 insertions(+), 677 deletions(-) create mode 100644 .github/workflows/chain-simulator-e2e-tests.yml delete mode 100644 config/config.placeholder.yaml delete mode 100644 config/dapp.config.placeholder.json create mode 100644 entrypoint.py delete mode 100755 entrypoint.sh create mode 100644 src/endpoints/mex/graphql/farms.query.ts create mode 100644 src/endpoints/mex/graphql/filtered.pairs.query.ts create mode 100644 src/endpoints/mex/graphql/pairs.count.query.ts create mode 100644 src/endpoints/mex/graphql/settings.query.ts create mode 100644 src/endpoints/mex/graphql/staking.proxy.query.ts create mode 100644 src/endpoints/mex/graphql/token.prices.hour.resolution.query.ts create mode 100644 src/endpoints/mex/graphql/tokens.query.ts create mode 100644 src/test/chain-simulator/accounts.cs-e2e.ts create mode 100644 src/test/chain-simulator/applications.cs-e2e.ts create mode 100644 src/test/chain-simulator/blocks.cs-e2e.ts create mode 100644 src/test/chain-simulator/collections.cs-e2e.ts create mode 100644 src/test/chain-simulator/config/.env.example create mode 100644 src/test/chain-simulator/config/env.config.ts create mode 100644 src/test/chain-simulator/dapp.config.cs-e2e.ts create mode 100644 src/test/chain-simulator/delegation-legacy.cs-e2e.ts create mode 100644 src/test/chain-simulator/delegation.cs-e2e.ts create mode 100644 src/test/chain-simulator/docker/docker-compose.yml create mode 100644 src/test/chain-simulator/docker/overridable-config.toml create mode 100644 src/test/chain-simulator/events.cs-e2e.ts create mode 100644 src/test/chain-simulator/hello.cs-e2e.ts create mode 100644 src/test/chain-simulator/identities.cs-e2e.ts create mode 100644 src/test/chain-simulator/miniblocks.cs-e2e.ts create mode 100644 src/test/chain-simulator/network.cs-e2e.ts create mode 100644 src/test/chain-simulator/nfts.cs-e2e.ts create mode 100644 src/test/chain-simulator/nodes.cs-e2e.ts create mode 100644 src/test/chain-simulator/pool.cs-e2e.ts create mode 100644 src/test/chain-simulator/results.cs-e2e.ts create mode 100644 src/test/chain-simulator/rounds.cs-e2e.ts create mode 100644 src/test/chain-simulator/shards.cs-e2e.ts create mode 100644 src/test/chain-simulator/stake.cs-e2e.ts create mode 100644 src/test/chain-simulator/tags.cs-e2e.ts create mode 100644 src/test/chain-simulator/tokens.cs-e2e.ts create mode 100644 src/test/chain-simulator/transactions.cs-e2e.ts create mode 100644 src/test/chain-simulator/utils/chain.simulator.operations.ts create mode 100644 src/test/chain-simulator/utils/contracts/ping-pong-egld.wasm create mode 100644 src/test/chain-simulator/utils/prepare-test-data.ts create mode 100644 src/test/chain-simulator/utils/test.utils.ts create mode 100644 src/test/chain-simulator/utils/testSequencer.js create mode 100644 src/test/chain-simulator/websocket-config.cs-e2e.ts create mode 100644 src/test/jest-chain-simulator.json diff --git a/.github/workflows/chain-simulator-e2e-tests.yml b/.github/workflows/chain-simulator-e2e-tests.yml new file mode 100644 index 000000000..cbacb633e --- /dev/null +++ b/.github/workflows/chain-simulator-e2e-tests.yml @@ -0,0 +1,65 @@ +name: Chain simulator e2e tests workflow + +on: + push: + branches: [main, development] + pull_request: + branches: [main, development, feat/*] + +jobs: + test-chainsimulator-e2e: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [18.x] + + steps: + - uses: actions/checkout@v3 + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + + - name: Build and start chain simulator + run: npm run start-chain-simulator + + - name: Wait for services to be ready + run: | + echo "Waiting for services to be healthy..." + docker ps + docker logs chainsimulator + sleep 20 # Wait for 20 seconds to ensure services are up + + - name: Print docker containers + run: docker ps + + - name: Start API Docker containers + run: | + cd . + docker compose up -d + + - name: Wait for API docker containers to start + run: | + sleep 20 + docker ps + + - run: npm ci + - run: npm run init + + - name: Start API + run: | + npm run start:mainnet:e2e & + sleep 10 # Wait a little more to ensure the API is fully up + + - name: Prepare Test Data + run: npm run prepare:test-data + + - name: Run e2e tests + run: npm run test:cs-e2e + + - name: Stop API after tests + run: | + echo "Stopping the API..." + kill $(lsof -t -i:3001) diff --git a/.github/workflows/load-tests.yml b/.github/workflows/load-tests.yml index 5f14d7355..50568016a 100644 --- a/.github/workflows/load-tests.yml +++ b/.github/workflows/load-tests.yml @@ -58,7 +58,7 @@ jobs: run: k6 run ./k6/script.js - name: Upload result file for base branch - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: base-results path: k6/output/summary.json @@ -119,7 +119,7 @@ jobs: run: k6 run ./k6/script.js - name: Upload result file for head branch - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: head-results path: k6/output/summary.json @@ -135,7 +135,7 @@ jobs: - uses: actions/checkout@v2 - name: Download all artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: path: artifacts @@ -159,7 +159,7 @@ jobs: head: ${{ github.event.pull_request.head.sha }} - name: Upload the report markdown - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: github.event_name == 'pull_request' with: name: report-markdown diff --git a/.gitignore b/.gitignore index d42d00011..0bee3489d 100644 --- a/.gitignore +++ b/.gitignore @@ -41,4 +41,7 @@ lerna-debug.log* /src/plugins -.env \ No newline at end of file +.env + +# CS Environment variables +src/test/chain-simulator/config/.env diff --git a/Dockerfile b/Dockerfile index 72127a190..5a7810721 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18.19-alpine +FROM node:18.19-alpine AS build WORKDIR /app RUN chown -R node:node /app @@ -11,7 +11,23 @@ RUN npm install RUN npm run init RUN npm run build +FROM node:18.19-alpine + +ENV PYTHONUNBUFFERED=1 +RUN apk add --no-cache python3 py3-pip py3-ruamel.yaml + +WORKDIR /app +RUN chown -R node:node /app + + +COPY --from=build --chown=node /app/*.json /app/ +COPY --from=build --chown=node /app/dist /app/dist +COPY --from=build --chown=node /app/node_modules /app/node_modules +COPY --from=build --chown=node /app/config /app/config +COPY entrypoint.py /app/entrypoint.py + +USER node + EXPOSE 3001 -RUN chmod +x entrypoint.sh +CMD ["python", "entrypoint.py"] -CMD ["./entrypoint.sh"] diff --git a/config/config.e2e.mainnet.yaml b/config/config.e2e.mainnet.yaml index ed101f9da..7ea314cf7 100644 --- a/config/config.e2e.mainnet.yaml +++ b/config/config.e2e.mainnet.yaml @@ -3,9 +3,51 @@ metaChainShardId: 4294967295 crossChainSenderShardId: 4294967293 api: public: true + publicPort: 3001 private: true - graphql: true + privatePort: 4001 + websocket: true +cron: + cacheWarmer: true + fastWarm: false + queueWorker: true + elasticUpdater: false +flags: + useRequestCaching: true + useKeepAliveAgent: true + useTracing: false + useRequestLogging: false + useVmQueryTracing: false + processNfts: true + collectionPropertiesFromGateway: false features: + eventsNotifier: + enabled: false + port: 5674 + url: 'amqp://guest:guest@127.0.0.1:5672' + exchange: 'all_events' + queue: 'api-process-logs-and-events' + guestCaching: + enabled: false + hitsThreshold: 100 + ttl: 12 + transactionPool: + enabled: true + transactionPoolWarmer: + enabled: true + cronExpression: '*/5 * * * * *' + ttlInSeconds: 60 + updateCollectionExtraDetails: + enabled: false + updateAccountExtraDetails: + enabled: false + transfersLast24hUrl: 'https://tools.multiversx.com/growth-api/explorer/widgets/most-used/applications' + marketplace: + enabled: false + serviceUrl: 'https://nfts-graph.multiversx.com/graphql' + exchange: + enabled: false + serviceUrl: 'https://graph.xexchange.com/graphql' dataApi: enabled: false serviceUrl: 'https://data-api.multiversx.com' @@ -14,35 +56,93 @@ features: maxExpirySeconds: 86400 acceptedOrigins: - '' + admins: + - '' + jwtSecret: '' + stakingV4: + enabled: false + cronExpression: '*/5 * * * * *' + activationEpoch: 1391 + nodeEpochsLeft: + enabled: false + transactionProcessor: + enabled: false + maxLookBehind: 1000 + transactionCompleted: + enabled: false + maxLookBehind: 1000 + logLevel: 'Error' + transactionBatch: + enabled: false + maxLookBehind: 1000 deepHistory: enabled: false url: '' -cron: - transactionProcessor: false - transactionProcessorMaxLookBehind: 1000 - cacheWarmer: false -flags: - useRequestCaching: true - useKeepAliveAgent: true - useTracing: false - collectionPropertiesFromGateway: false + statusChecker: + enabled: false + thresholds: + tokens: 1000 + nodes: 5000 + providers: 150 + tokenSupplyCount: 100 + tokenAssets: 100 + tokenAccounts: 1000 + tokenTransactions: 1000 + nodeValidators: 3260 + nftScamInfo: + enabled: false + processNfts: + enabled: false + nftQueueName: 'api-process-nfts' + deadLetterQueueName: 'api-process-nfts-dlq' + tps: + enabled: false + maxLookBehindNonces: 100 + nodesFetch: + enabled: false + serviceUrl: 'https://api.multiversx.com' + tokensFetch: + enabled: false + serviceUrl: 'https://api.multiversx.com' + providersFetch: + enabled: false + serviceUrl: 'https://api.multiversx.com' + assetsFetch: + enabled: false + assetesUrl: 'https://tools.multiversx.com/assets-cdn' +image: + width: 600 + height: 600 + type: 'png' +aws: + s3KeyId: '' + s3Secret: '' + s3Bucket: 'media.elrond.com' + s3Region: '' urls: - self: 'https://api.multiversx.com' + self: 'http://localhost:3001' elastic: - - 'https://index.multiversx.com' + - 'http://localhost:9200' gateway: - - 'https://gateway.multiversx.com' + - 'http://localhost:8085' verifier: 'https://play-api.multiversx.com' redis: '127.0.0.1' rabbitmq: 'amqp://127.0.0.1:5672' - providers: 'https://internal-delegation-api.multiversx.com/providers' + providers: 'https://delegation-api.multiversx.com/providers' delegation: 'https://delegation-api.multiversx.com' media: 'https://media.elrond.com' nftThumbnails: 'https://media.elrond.com/nfts/thumbnail' + tmp: '/tmp' + ipfs: 'https://ipfs.io/ipfs' + socket: 'socket-api-fra.multiversx.com' maiarId: 'https://id-api.multiversx.com' +indexer: + type: 'elastic' + maxPagination: 10000 database: enabled: false url: 'mongodb://127.0.0.1:27017/api?authSource=admin' + type: 'mysql' host: 'localhost' port: 3306 username: 'root' @@ -51,7 +151,8 @@ database: caching: cacheTtl: 6 processTtl: 600 - poolLimit: 10 + poolLimit: 50 + cacheDuration: 3 keepAliveTimeout: downstream: 61000 upstream: 60000 @@ -70,14 +171,6 @@ inflation: - 1130177 - 924690 - 719203 -security: - admins: - jwtSecret: -test: - mockKeybases: false - mockNodes: false - mockTokens: false - mockPath: './src/test/mocks/' -transaction-action: - mex: - microServiceUrl: 'https://graph.xexchange.com/graphql' +nftProcess: + parallelism: 1 + maxRetries: 3 diff --git a/config/config.placeholder.yaml b/config/config.placeholder.yaml deleted file mode 100644 index b1b552bfa..000000000 --- a/config/config.placeholder.yaml +++ /dev/null @@ -1,172 +0,0 @@ -network: 'testnet' -dappNetwork: 'DAPP_CONFIG' -metaChainShardId: 4294967295 -api: - public: MVX_API_PUBLIC - publicPort: 3001 - private: MVX_API_PRIVATE - privatePort: 4001 - websocket: true -cron: - cacheWarmer: MVX_CACHEWARMER - fastWarm: true - queueWorker: true - elasticUpdater: false -flags: - useRequestCaching: true - useKeepAliveAgent: true - useTracing: false - useRequestLogging: false - useVmQueryTracing: false - processNfts: true - collectionPropertiesFromGateway: false -features: - eventsNotifier: - enabled: MVX_EVENTS_NOTIFIER - port: 5674 - url: 'MVX_EVENTS_NOTIFIER_RABBIT_URL' - exchange: 'all_events' - queue: 'api-process-logs-and-events' - guestCaching: - enabled: false - hitsThreshold: 100 - ttl: 12 - transactionPool: - enabled: false - transactionPoolWarmer: - enabled: false - cronExpression: '*/5 * * * * *' - ttlInSeconds: 60 - updateCollectionExtraDetails: - enabled: false - updateAccountExtraDetails: - enabled: false - marketplace: - enabled: false - serviceUrl: 'MARKETPLACE_URL' - exchange: - enabled: false - serviceUrl: 'EXCHANGE_URL' - dataApi: - enabled: false - serviceUrl: 'DATAAPI_URL' - assetsFetch: - enabled: true - assetesUrl: 'ASSETSFETCH_URL' - auth: - enabled: false - maxExpirySeconds: 86400 - acceptedOrigins: - - '' - admins: - - '' - jwtSecret: '' - stakingV4: - enabled: MVX_STAKINGV4 - cronExpression: '*/5 * * * * *' - activationEpoch: 1043 - nodeEpochsLeft: - enabled: false - transactionProcessor: - enabled: MVX_TRANSACTIONPROCESSOR - maxLookBehind: 100 - transactionCompleted: - enabled: MVX_transactionCompleted - maxLookBehind: 100 - logLevel: 'Error' - transactionBatch: - enabled: true - maxLookBehind: 100 - statusChecker: - enabled: false - thresholds: - tokens: 500 - nodes: 3000 - providers: 10 - tokenSupplyCount: 20 - tokenAssets: 20 - tokenAccounts: 500 - tokenTransactions: 500 - nodeValidators: 300 - nftScamInfo: - enabled: false - processNfts: - enabled: false - nftQueueName: 'api-process-nfts' - deadLetterQueueName: 'api-process-nfts-dlq' - tps: - enabled: false - maxLookBehindNonces: 100 - nodesFetch: - enabled: MVX_NODESFETCH_ENABLE - serviceUrl: 'MVX_NODESFETCH_URL' - tokensFetch: - enabled: MVX_TOKENSFETCH_ENABLE - serviceUrl: 'MVX_TOKENSFETCH_URL' - providersFetch: - enabled: MVX_PROVIDERSFETCH_ENABLE - serviceUrl: 'MVX_PROVIDERSFETCH_URL' -image: - width: 600 - height: 600 - type: 'png' -aws: - s3KeyId: '' - s3Secret: '' - s3Bucket: 'devnet-media.elrond.com' - s3Region: '' -urls: - self: 'https://devnet-api.multiversx.com' - elastic: - - 'ELASTICSEARCH_URL' - gateway: - - 'GATEWAY_URL' - verifier: 'https://play-api.multiversx.com' - redis: 'REDIS_IP' - rabbitmq: 'RABBITMQ_URL' - providers: 'PROVIDERS_URL' - delegation: 'DELEGATION_URL' - media: 'https://devnet-media.elrond.com' - nftThumbnails: 'https://devnet-media.elrond.com/nfts/thumbnail' - tmp: '/tmp' - ipfs: 'https://ipfs.io/ipfs' - socket: 'SOCKET_URL' - maiarId: 'https://devnet-id-api.multiversx.com' -indexer: - type: 'elastic' - maxPagination: 10000 -database: - enabled: false - url: 'mongodb://127.0.0.1:27017/api?authSource=admin' - type: 'mysql' - host: 'localhost' - port: 3306 - username: 'root' - password: 'root' - database: 'api' -caching: - cacheTtl: 6 - processTtl: 600 - poolLimit: 50 - cacheDuration: MVX_CACHING_cacheDuration -keepAliveTimeout: - downstream: 61000 - upstream: 60000 -contracts: - esdt: 'erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u' - auction: 'erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqplllst77y4l' - staking: 'erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqllls0lczs7' - delegationManager: 'erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqylllslmq6y6' - delegation: 'erd1qqqqqqqqqqqqqpgq97wezxw6l7lgg7k9rxvycrz66vn92ksh2tssxwf7ep' - metabonding: 'erd1qqqqqqqqqqqqqpgqkg7we73j769ew5we4yyx7uyvnn0nefqgd8ssm6vjc2' -inflation: - - 1952123 - - 1746637 - - 1541150 - - 1335663 - - 1130177 - - 924690 - - 719203 -nftProcess: - parallelism: 1 - maxRetries: 3 \ No newline at end of file diff --git a/config/dapp.config.placeholder.json b/config/dapp.config.placeholder.json deleted file mode 100644 index b042458a2..000000000 --- a/config/dapp.config.placeholder.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "id": "PLACEHOLDER_DAPP_id", - "name": "PLACEHOLDER_DAPP_name", - "egldLabel": "PLACEHOLDER_DAPP_egldLabel", - "decimals": "4", - "egldDenomination": "18", - "gasPerDataByte": "1500", - "apiTimeout": "4000", - "walletConnectDeepLink": "https://maiar.page.link/?apn=com.multiversx.maiar.wallet&isi=1519405832&ibi=com.multiversx.maiar.wallet&link=https://maiar.com/", - "walletConnectBridgeAddresses": [ - "https://bridge.walletconnect.org" - ], - "walletAddress": "PLACEHOLDER_DAPP_walletAddress", - "apiAddress": "PLACEHOLDER_DAPP_apiAddress", - "explorerAddress": "PLACEHOLDER_DAPP_explorerAddress", - "chainId": "PLACEHOLDER_DAPP_chainId" -} \ No newline at end of file diff --git a/entrypoint.py b/entrypoint.py new file mode 100644 index 000000000..1a7ad344b --- /dev/null +++ b/entrypoint.py @@ -0,0 +1,173 @@ +import os +import json +from ruamel.yaml import YAML + +yaml = YAML(typ='rt') +yaml.preserve_quotes = True +yaml.default_flow_style = False +yaml.width = 4096 # to avoid long string values being placed on the next line + +# Load the YAML file +def load_yaml(file_path): + with open(file_path, 'r') as file: + return yaml.load(file) + +# Save the updated YAML file +def save_yaml(file_path, data): + with open(file_path, 'w') as file: + yaml.dump(data, file) + +# Load the JSON file +def load_json(file_path): + with open(file_path, 'r') as file: + return json.load(file) + +# Save the updated JSON file +def save_json(file_path, data): + with open(file_path, 'w') as file: + json.dump(data, file, indent=4) + +# Function to convert string to the proper type based on the prefix (bool, num, raw) +def convert_value(value_str): + # Check if the value string contains a colon + if ":" not in value_str: + # If no colon, assume it's a plain string + return value_str + + # Split the string by the ':' delimiter + prefix, value = value_str.split(":", 1) + + match prefix: + # BOOLEAN + case 'bool': + return value.lower() == 'true' # Convert to boolean (True/False) + # NUMBER + case 'num': + try: + return int(value) # Convert to integer + except ValueError: + print(f"Error: Cannot convert '{value_str}' to a number.") + return None + # ARRAY + case 'arr': + # Check if the value looks like a JSON array (starts with '[' and ends with ']') + if value.startswith('[') and value.endswith(']'): + try: + return json.loads(value) # Convert the string to a list + except json.JSONDecodeError: + print(f"Error: Cannot decode '{value_str}' as a JSON array.") + return None + print(f"Error: '{value_str}' is not a valid array format.") + return None # Return None if the array format is incorrect + # RAW + case 'raw': + return value # Return exactly as received (raw string) + # DEFAULT STRING + case _: + return value_str # Default to string if no match + +# Modify the value in the YAML structure based on the variable name +def modify_yaml_variable(data, variable_name, new_value): + keys = variable_name[4:].split('_') # Remove 'CFG_' prefix + sub_data = data + + # Traverse the YAML structure using the keys to reach the variable and modify its value + for key in keys[:-1]: + if key in sub_data: + sub_data = sub_data[key] + else: + print(f"Key '{key}' not found in the YAML structure.") + return + + # Check if the final key exists in the structure + final_key = keys[-1] + if final_key in sub_data: + # Check if it's an array (arr: prefix) + if isinstance(new_value, str) and new_value.startswith('arr:'): + try: + # Parse the value as a JSON array + sub_data[final_key] = json.loads(new_value[4:]) # Strip 'arr:' and parse + except json.JSONDecodeError: + print(f"Error decoding JSON array in value: {new_value}") + else: + sub_data[final_key] = new_value + else: + print(f"Key '{final_key}' not found at the end of the path.") + return + +# Modify the value in the JSON structure based on the variable name +def modify_json_variable(data, variable_name, new_value): + keys = variable_name[5:].split('_') # Remove 'DAPP_' prefix + sub_data = data + + # Traverse the JSON structure using the keys to reach the variable and modify its value + for key in keys[:-1]: + if key in sub_data: + sub_data = sub_data[key] + else: + print(f"Key '{key}' not found in the JSON structure.") + return + + # Check if the value is a JSON array (list) and parse it + final_key = keys[-1] + if final_key in sub_data: + # If the new value is a string representing a JSON array, parse it + if isinstance(new_value, str) and new_value.startswith('[') and new_value.endswith(']'): + try: + # Parse the string as a JSON array + sub_data[final_key] = json.loads(new_value) + except json.JSONDecodeError: + print(f"Error decoding JSON array in value: {new_value}") + else: + sub_data[final_key] = new_value + else: + print(f"Key '{final_key}' not found at the end of the path.") + return + +# Main function +def main(): + # Input and output file paths + default_cfg_file = os.getenv('DEFAULT_CFG_FILE', 'devnet') + + config_yaml_input_file = f'config/config.{default_cfg_file}.yaml' + config_yaml_output_file = '/app/dist/config/config.yaml' + + dapp_config_json_input_file = f'config/dapp.config.{default_cfg_file}.json' + dapp_config_json_output_file = f'config/dapp.config.{default_cfg_file}.json' + + # Load the YAML file + config_yaml = load_yaml(config_yaml_input_file) + + # Load the JSON file + config_json = load_json(dapp_config_json_input_file) + + # Iterate over all environment variables starting with 'CFG_' for YAML + for variable_name, new_value in os.environ.items(): + if variable_name.startswith('CFG_'): + print(f"Updating YAML variable: {variable_name} with value: {new_value}") + # Convert value based on the type (bool, num, raw, or default to string) + converted_value = convert_value(new_value) + if converted_value is not None: + modify_yaml_variable(config_yaml, variable_name, converted_value) + + # Iterate over all environment variables starting with 'DAPP_' for JSON + for variable_name, new_value in os.environ.items(): + if variable_name.startswith('DAPP_'): + print(f"Updating JSON variable: {variable_name} with value: {new_value}") + # Convert value based on the type (bool, num, raw, or default to string) + converted_value = convert_value(new_value) + if converted_value is not None: + modify_json_variable(config_json, variable_name, converted_value) + + # Save the updated YAML file + save_yaml(config_yaml_output_file, config_yaml) + print(f"Updated YAML file saved as {config_yaml_output_file}") + + # Save the updated JSON file + save_json(dapp_config_json_output_file, config_json) + print(f"Updated JSON file saved as {dapp_config_json_output_file}") + + os.execvp('node', ['node', 'dist/src/main.js']) + +if __name__ == "__main__": + main() diff --git a/entrypoint.sh b/entrypoint.sh deleted file mode 100755 index 56ac48874..000000000 --- a/entrypoint.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/sh -# ENV VARIABLES -env_vars_with_defaults="MVX_ENV=devnet \ -DAPP_CONFIG=devnet \ -MVX_API_PUBLIC=true \ -MVX_API_PRIVATE=true \ -MVX_CACHEWARMER=true \ -MVX_TRANSACTIONPROCESSOR=false \ -MVX_transactionCompleted=false \ -MVX_CACHING_cacheDuration=3 \ -MVX_STAKINGV4=false \ -MVX_EVENTS_NOTIFIER=false \ -MVX_EVENTS_NOTIFIER_RABBIT_URL=amqp://guest:guest@127.0.0.1:5673 \ -REDIS_IP=127.0.0.1 \ -ELASTICSEARCH_URL=https://devnet-index.multiversx.com \ -GATEWAY_URL=https://devnet-gateway.multiversx.com \ -RABBITMQ_URL=amqp://127.0.0.1:5672 \ -PROVIDERS_URL=https://devnet-delegation-api.multiversx.com/providers \ -DATAAPI_URL=https://devnet-data-api.multiversx.com \ -EXCHANGE_URL=https://devnet-graph.xexchange.com/graphql \ -MARKETPLACE_URL=https://devnet-nfts-graph.multiversx.com/graphql \ -ASSETSFETCH_URL=https://tools.multiversx.com/assets-cdn \ -DELEGATION_URL=https://devnet-delegation-api.multiversx.com \ -SOCKET_URL=devnet-socket-api.multiversx.com \ -MVX_NODESFETCH_ENABLE=true \ -MVX_NODESFETCH_URL=https://devnet-api.multiversx.com \ -MVX_TOKENSFETCH_ENABLE=true \ -MVX_TOKENSFETCH_URL=https://devnet-api.multiversx.com \ -MVX_PROVIDERSFETCH_ENABLE=true \ -MVX_PROVIDERSFETCH_URL=https://devnet-api.multiversx.com \ -PLACEHOLDER_DAPP_id=devnet \ -PLACEHOLDER_DAPP_name=Devnet \ -PLACEHOLDER_DAPP_egldLabel=xEGLD \ -PLACEHOLDER_DAPP_walletAddress=https://devnet-wallet.multiversx.com \ -PLACEHOLDER_DAPP_apiAddress=https://devnet-api.multiversx.com \ -PLACEHOLDER_DAPP_explorerAddress=http://devnet-explorer.multiversx.com \ -PLACEHOLDER_DAPP_chainId=D" - -cp ./config/config.placeholder.yaml /app/dist/config/config.yaml -if [ $? -eq 0 ]; then - echo "Config file copied successfully from config/config.placeholder.yaml /app/dist/config/config.yaml" -fi - -replace_placeholder() { - local var_name=$1 - local var_value=$2 - - case $var_name in - PLACEHOLDER_DAPP*) - echo "Var ${var_name} defined, replacing ${var_value} in /app/config/dapp.config.placeholder.json" - sed -i "s|${var_name}|${var_value}|g" /app/config/dapp.config.placeholder.json - ;; - *) - echo "Var ${var_name} defined, replacing ${var_value} in /app/dist/config/config.yaml" - sed -i "s|${var_name}|${var_value}|g" /app/dist/config/config.yaml - ;; - esac - -} - -# Loop through each environment variable -for entry in $env_vars_with_defaults; do - # Split the entry into name and value - var_name=$(echo $entry | cut -d= -f1) - default_value=$(echo $entry | cut -d= -f2) - - # Use the environment variable value if defined; otherwise, use the default - eval "value=\${$var_name:-$default_value}" - - # Execute the function with the variable name and value - replace_placeholder "$var_name" "$value" - -done - -exec /usr/local/bin/node dist/src/main.js \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 3a4c41132..b066da289 100644 --- a/package-lock.json +++ b/package-lock.json @@ -82,6 +82,7 @@ "devDependencies": { "@automock/adapters.nestjs": "^2.1.0", "@automock/jest": "^2.1.0", + "@jest/test-sequencer": "^29.7.0", "@nestjs/cli": "10.1.17", "@nestjs/schematics": "10.0.2", "@nestjs/testing": "10.2.4", @@ -90,7 +91,7 @@ "@types/crypto-js": "^4.0.2", "@types/express": "^4.17.13", "@types/fluent-ffmpeg": "^2.1.20", - "@types/jest": "29.5.0", + "@types/jest": "^29.5.0", "@types/js-yaml": "^4.0.5", "@types/json-diff": "^0.7.0", "@types/jsonwebtoken": "^8.5.8", @@ -109,7 +110,7 @@ "prettier": "^2.5.1", "run-script-os": "^1.1.6", "supertest": "^6.2.2", - "ts-jest": "29.0.5", + "ts-jest": "^29.0.5", "ts-loader": "9.4.2", "ts-node": "10.7.0", "tsconfig-paths": "^4.0.0", diff --git a/package.json b/package.json index 7365df6ba..a12b6ca7a 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,9 @@ "start:mainnet": "npm run copy-mainnet-config & nest start", "start:mainnet:watch": "npm run copy-mainnet-config & nest start --watch", "start:mainnet:debug": "npm run copy-mainnet-config & nest start --watch --debug", + "start:mainnet:e2e": "npm run copy-e2e-mainnet-config & nest start", + "start:mainnet:e2e:watch": "npm run copy-e2e-mainnet-config & nest start --watch", + "start:mainnet:e2e:debug": "npm run copy-e2e-mainnet-config & nest start --watch --debug", "lint": "eslint \"{src,apps,libs,test}/**/*.ts\"", "lint:fix": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", "test": "npm run copy-mainnet-config & nest build & jest", @@ -41,6 +44,7 @@ "test:e2e:local": "npm run test:e2e:warm & npm run test:e2e", "test:api": "jest --config ./src/test/jest-api.json --runInBand --detectOpenHandles --forceExit", "test:graph": "jest --config ./src/test/jest-graph-spec.json --runInBand --detectOpenHandles --forceExit", + "test:cs-e2e": "jest --config ./src/test/jest-chain-simulator.json --runInBand --detectOpenHandles --forceExit", "init": "run-script-os", "copy-mainnet-config": "run-script-os", "copy-testnet-config": "run-script-os", @@ -73,7 +77,10 @@ "copy-e2e-mainnet-config:nix": "cp ./config/config.e2e.mainnet.yaml ./config/config.yaml", "copy-e2e-mocked-mainnet-config:nix": "cp ./config/config.e2e-mocked.mainnet.yaml ./config/config.yaml", "copy-e2e-mainnet-config:windows": "copy .\\config\\config.e2e.mainnet.yaml .\\config\\config.yaml", - "copy-e2e-mocked-mainnet-config:windows": "copy .\\config\\config.e2e-mocked.mainnet.yaml .\\config\\config.yaml" + "copy-e2e-mocked-mainnet-config:windows": "copy .\\config\\config.e2e-mocked.mainnet.yaml .\\config\\config.yaml", + "start-chain-simulator": "docker compose -f \"src/test/chain-simulator/docker/docker-compose.yml\" up -d --build", + "stop-chain-simulator": "docker compose -f \"src/test/chain-simulator/docker/docker-compose.yml\" down", + "prepare:test-data": "ts-node src/test/chain-simulator/utils/prepare-test-data.ts" }, "dependencies": { "@aws-sdk/client-s3": "^3.54.0", @@ -149,6 +156,7 @@ "devDependencies": { "@automock/adapters.nestjs": "^2.1.0", "@automock/jest": "^2.1.0", + "@jest/test-sequencer": "^29.7.0", "@nestjs/cli": "10.1.17", "@nestjs/schematics": "10.0.2", "@nestjs/testing": "10.2.4", @@ -157,7 +165,7 @@ "@types/crypto-js": "^4.0.2", "@types/express": "^4.17.13", "@types/fluent-ffmpeg": "^2.1.20", - "@types/jest": "29.5.0", + "@types/jest": "^29.5.0", "@types/js-yaml": "^4.0.5", "@types/json-diff": "^0.7.0", "@types/jsonwebtoken": "^8.5.8", @@ -176,7 +184,7 @@ "prettier": "^2.5.1", "run-script-os": "^1.1.6", "supertest": "^6.2.2", - "ts-jest": "29.0.5", + "ts-jest": "^29.0.5", "ts-loader": "9.4.2", "ts-node": "10.7.0", "tsconfig-paths": "^4.0.0", diff --git a/src/common/graphql/graphql.service.ts b/src/common/graphql/graphql.service.ts index faebff87b..8044f7015 100644 --- a/src/common/graphql/graphql.service.ts +++ b/src/common/graphql/graphql.service.ts @@ -16,6 +16,9 @@ export class GraphQlService { const exchangeServiceUrl = this.apiConfigService.getExchangeServiceUrlMandatory(); const graphqlClient = new GraphQLClient(exchangeServiceUrl, { fetch: this.createFetchWithTimeout(60_000), + headers: { + 'origin': this.apiConfigService.getSelfUrl(), + }, }); try { diff --git a/src/common/indexer/elastic/elastic.indexer.service.ts b/src/common/indexer/elastic/elastic.indexer.service.ts index e596d89d4..661012cb1 100644 --- a/src/common/indexer/elastic/elastic.indexer.service.ts +++ b/src/common/indexer/elastic/elastic.indexer.service.ts @@ -974,6 +974,10 @@ export class ElasticIndexerService implements IndexerInterface { return await this.elasticService.getList('scdeploys', 'address', elasticQuery); } + async getApplication(address: string): Promise { + return await this.elasticService.getItem('scdeploys', 'address', address); + } + async getApplicationCount(filter: ApplicationFilter): Promise { const elasticQuery = this.indexerHelper.buildApplicationFilter(filter); diff --git a/src/common/indexer/indexer.interface.ts b/src/common/indexer/indexer.interface.ts index e6b3fe961..d22317bff 100644 --- a/src/common/indexer/indexer.interface.ts +++ b/src/common/indexer/indexer.interface.ts @@ -188,6 +188,8 @@ export interface IndexerInterface { getApplicationCount(filter: ApplicationFilter): Promise + getApplication(address: string): Promise + getAddressesWithTransfersLast24h(): Promise getEvents(pagination: QueryPagination, filter: EventsFilter): Promise diff --git a/src/common/indexer/indexer.service.ts b/src/common/indexer/indexer.service.ts index f70ca70e1..715670321 100644 --- a/src/common/indexer/indexer.service.ts +++ b/src/common/indexer/indexer.service.ts @@ -446,6 +446,11 @@ export class IndexerService implements IndexerInterface { return await this.indexerInterface.getApplications(filter, pagination); } + @LogPerformanceAsync(MetricsEvents.SetIndexerDuration) + async getApplication(address: string): Promise { + return await this.indexerInterface.getApplication(address); + } + @LogPerformanceAsync(MetricsEvents.SetIndexerDuration) async getApplicationCount(filter: ApplicationFilter): Promise { return await this.indexerInterface.getApplicationCount(filter); diff --git a/src/endpoints/applications/application.controller.ts b/src/endpoints/applications/application.controller.ts index c76a0df14..dd444f1cd 100644 --- a/src/endpoints/applications/application.controller.ts +++ b/src/endpoints/applications/application.controller.ts @@ -1,9 +1,9 @@ -import { Controller, DefaultValuePipe, Get, Query } from "@nestjs/common"; +import { Controller, DefaultValuePipe, Get, Param, Query } from "@nestjs/common"; import { ApiOkResponse, ApiOperation, ApiQuery, ApiTags } from "@nestjs/swagger"; import { ApplicationService } from "./application.service"; import { QueryPagination } from "src/common/entities/query.pagination"; import { ApplicationFilter } from "./entities/application.filter"; -import { ParseIntPipe } from "@multiversx/sdk-nestjs-common"; +import { ParseIntPipe, ParseBoolPipe, ParseAddressPipe } from "@multiversx/sdk-nestjs-common"; import { Application } from "./entities/application"; @Controller() @@ -20,15 +20,18 @@ export class ApplicationController { @ApiQuery({ name: 'size', description: 'Number of items to retrieve', required: false }) @ApiQuery({ name: 'before', description: 'Before timestamp', required: false }) @ApiQuery({ name: 'after', description: 'After timestamp', required: false }) + @ApiQuery({ name: 'withTxCount', description: 'Include transaction count', required: false, type: Boolean }) async getApplications( @Query('from', new DefaultValuePipe(0), ParseIntPipe) from: number, @Query("size", new DefaultValuePipe(25), ParseIntPipe) size: number, @Query('before', ParseIntPipe) before?: number, @Query('after', ParseIntPipe) after?: number, - ): Promise { + @Query('withTxCount', new ParseBoolPipe()) withTxCount?: boolean, + ): Promise { + const applicationFilter = new ApplicationFilter({ before, after, withTxCount }); return await this.applicationService.getApplications( new QueryPagination({ size, from }), - new ApplicationFilter({ before, after }) + applicationFilter ); } @@ -45,4 +48,13 @@ export class ApplicationController { return await this.applicationService.getApplicationsCount(filter); } + + @Get("applications/:address") + @ApiOperation({ summary: 'Application details', description: 'Returns details of a smart contract' }) + @ApiOkResponse({ type: Application }) + async getApplication( + @Param('address', ParseAddressPipe) address: string, + ): Promise { + return await this.applicationService.getApplication(address); + } } diff --git a/src/endpoints/applications/application.module.ts b/src/endpoints/applications/application.module.ts index f9e6dccd2..e8e912c30 100644 --- a/src/endpoints/applications/application.module.ts +++ b/src/endpoints/applications/application.module.ts @@ -2,14 +2,18 @@ import { Module } from "@nestjs/common"; import { ElasticIndexerModule } from "src/common/indexer/elastic/elastic.indexer.module"; import { ApplicationService } from "./application.service"; import { AssetsService } from '../../common/assets/assets.service'; +import { GatewayService } from "src/common/gateway/gateway.service"; +import { TransferModule } from "../transfers/transfer.module"; @Module({ imports: [ ElasticIndexerModule, + TransferModule, ], providers: [ ApplicationService, AssetsService, + GatewayService, ], exports: [ ApplicationService, diff --git a/src/endpoints/applications/application.service.ts b/src/endpoints/applications/application.service.ts index c1d163eeb..49a6ff96a 100644 --- a/src/endpoints/applications/application.service.ts +++ b/src/endpoints/applications/application.service.ts @@ -4,15 +4,41 @@ import { Application } from './entities/application'; import { QueryPagination } from 'src/common/entities/query.pagination'; import { ApplicationFilter } from './entities/application.filter'; import { AssetsService } from '../../common/assets/assets.service'; +import { GatewayService } from 'src/common/gateway/gateway.service'; +import { TransferService } from '../transfers/transfer.service'; +import { TransactionFilter } from '../transactions/entities/transaction.filter'; +import { TransactionType } from '../transactions/entities/transaction.type'; +import { Logger } from '@nestjs/common'; +import { CacheService } from '@multiversx/sdk-nestjs-cache'; +import { CacheInfo } from 'src/utils/cache.info'; @Injectable() export class ApplicationService { + private readonly logger = new Logger(ApplicationService.name); + constructor( private readonly elasticIndexerService: ElasticIndexerService, private readonly assetsService: AssetsService, + private readonly gatewayService: GatewayService, + private readonly transferService: TransferService, + private readonly cacheService: CacheService, ) { } async getApplications(pagination: QueryPagination, filter: ApplicationFilter): Promise { + filter.validate(pagination.size); + + if (!filter.isSet) { + return await this.cacheService.getOrSet( + CacheInfo.Applications(pagination).key, + async () => await this.getApplicationsRaw(pagination, filter), + CacheInfo.Applications(pagination).ttl + ); + } + + return await this.getApplicationsRaw(pagination, filter); + } + + async getApplicationsRaw(pagination: QueryPagination, filter: ApplicationFilter): Promise { const elasticResults = await this.elasticIndexerService.getApplications(filter, pagination); const assets = await this.assetsService.getAllAccountAssets(); @@ -20,17 +46,68 @@ export class ApplicationService { return []; } - return elasticResults.map(item => ({ + const applications = elasticResults.map(item => new Application({ contract: item.address, deployer: item.deployer, owner: item.currentOwner, codeHash: item.initialCodeHash, timestamp: item.timestamp, assets: assets[item.address], + balance: '0', + ...(filter.withTxCount && { txCount: 0 }), })); + + const balancePromises = applications.map(application => + this.getApplicationBalance(application.contract) + .then(balance => { application.balance = balance; }) + ); + await Promise.all(balancePromises); + + if (filter.withTxCount) { + for (const application of applications) { + application.txCount = await this.getApplicationTxCount(application.contract); + } + } + + return applications; } async getApplicationsCount(filter: ApplicationFilter): Promise { return await this.elasticIndexerService.getApplicationCount(filter); } + + async getApplication(address: string): Promise { + const indexResult = await this.elasticIndexerService.getApplication(address); + const assets = await this.assetsService.getAllAccountAssets(); + + const result = new Application({ + contract: indexResult.address, + deployer: indexResult.deployer, + owner: indexResult.currentOwner, + codeHash: indexResult.initialCodeHash, + timestamp: indexResult.timestamp, + assets: assets[address], + balance: '0', + txCount: 0, + }); + + result.txCount = await this.getApplicationTxCount(result.contract); + result.balance = await this.getApplicationBalance(result.contract); + + return result; + } + + private async getApplicationTxCount(address: string): Promise { + return await this.transferService.getTransfersCount(new TransactionFilter({ address, type: TransactionType.Transaction })); + } + + private async getApplicationBalance(address: string): Promise { + try { + const { account: { balance } } = await this.gatewayService.getAddressDetails(address); + return balance; + } catch (error) { + this.logger.error(`Error when getting balance for contract ${address}`, error); + return '0'; + } + } } diff --git a/src/endpoints/applications/entities/application.filter.ts b/src/endpoints/applications/entities/application.filter.ts index 69c16c124..ce7d27475 100644 --- a/src/endpoints/applications/entities/application.filter.ts +++ b/src/endpoints/applications/entities/application.filter.ts @@ -1,3 +1,5 @@ +import { BadRequestException } from "@nestjs/common"; + export class ApplicationFilter { constructor(init?: Partial) { Object.assign(this, init); @@ -5,9 +7,17 @@ export class ApplicationFilter { after?: number; before?: number; + withTxCount?: boolean; + + validate(size: number) { + if (this.withTxCount && size > 25) { + throw new BadRequestException('Size must be less than or equal to 25 when withTxCount is set'); + } + } isSet(): boolean { return this.after !== undefined || - this.before !== undefined; + this.before !== undefined || + this.withTxCount !== undefined; } } diff --git a/src/endpoints/applications/entities/application.ts b/src/endpoints/applications/entities/application.ts index ea5dc2da5..88ef36da9 100644 --- a/src/endpoints/applications/entities/application.ts +++ b/src/endpoints/applications/entities/application.ts @@ -23,4 +23,10 @@ export class Application { @ApiProperty({ type: AccountAssets, nullable: true, description: 'Contract assets' }) assets: AccountAssets | undefined = undefined; + + @ApiProperty({ type: String }) + balance: string = '0'; + + @ApiProperty({ type: Number, required: false }) + txCount?: number; } diff --git a/src/endpoints/mex/entities/mex.pair.ts b/src/endpoints/mex/entities/mex.pair.ts index 0e7cc5d76..a9ecc12d4 100644 --- a/src/endpoints/mex/entities/mex.pair.ts +++ b/src/endpoints/mex/entities/mex.pair.ts @@ -68,12 +68,6 @@ export class MexPair { @ApiProperty({ type: String, example: 'jungledex' }) exchange: MexPairExchange | undefined; - @ApiProperty({ type: Boolean, nullable: true }) - hasFarms: boolean | undefined = undefined; - - @ApiProperty({ type: Boolean, nullable: true }) - hasDualFarms: boolean | undefined = undefined; - @ApiProperty({ type: Number, nullable: true }) tradesCount: number | undefined = undefined; @@ -82,4 +76,10 @@ export class MexPair { @ApiProperty({ type: Number, nullable: true }) deployedAt: number | undefined = undefined; + + @ApiProperty({ type: Boolean, nullable: true }) + hasFarms?: boolean; + + @ApiProperty({ type: Boolean, nullable: true }) + hasDualFarms?: boolean; } diff --git a/src/endpoints/mex/entities/mex.pairs..filter.ts b/src/endpoints/mex/entities/mex.pairs..filter.ts index 3021a4a3a..604682ccd 100644 --- a/src/endpoints/mex/entities/mex.pairs..filter.ts +++ b/src/endpoints/mex/entities/mex.pairs..filter.ts @@ -5,4 +5,5 @@ export class MexPairsFilter { Object.assign(this, init); } exchange?: MexPairExchange; + includeFarms?: boolean; } diff --git a/src/endpoints/mex/entities/mex.settings.ts b/src/endpoints/mex/entities/mex.settings.ts index 28dd58bcf..f7e730772 100644 --- a/src/endpoints/mex/entities/mex.settings.ts +++ b/src/endpoints/mex/entities/mex.settings.ts @@ -23,7 +23,7 @@ export class MexSettings { ...response.proxy.map((x: any) => x.address), ]; settings.pairContracts = [ - ...response.pairs.filter((x: any) => x.state === 'Active').map((x: any) => x.address), + ...response.pairs.map((x: any) => x.address), ...response.proxy.map((x: any) => x.address), ]; settings.wrapContracts = response.wrappingInfo.map((x: any) => x.address); @@ -39,11 +39,11 @@ export class MexSettings { settings.lockedAssetIdentifier = lockedAssetIdentifiers.find((identifier: string) => identifier.startsWith('LKMEX')); settings.lockedAssetIdentifierV2 = lockedAssetIdentifiers.find((identifier: string) => identifier.startsWith('XMEX')); - const mexEgldPairs = response.pairs.filter((x: any) => x.firstToken.name === 'WrappedEGLD' && x.secondToken.name === 'MEX'); - if (mexEgldPairs.length > 0) { - settings.wegldId = mexEgldPairs[0].firstToken.identifier; - settings.mexId = mexEgldPairs[0].secondToken.identifier; - } + const wrappedToken = response.wrappingInfo[0].wrappedToken.identifier; + const mexToken = response.simpleLockEnergy.baseAssetToken.identifier; + + settings.wegldId = wrappedToken; + settings.mexId = mexToken; return settings; } diff --git a/src/endpoints/mex/graphql/farms.query.ts b/src/endpoints/mex/graphql/farms.query.ts new file mode 100644 index 000000000..95b3f3c99 --- /dev/null +++ b/src/endpoints/mex/graphql/farms.query.ts @@ -0,0 +1,98 @@ +import { gql } from "graphql-request"; + +export const farmsQuery = gql` + query { + farms { + ... on FarmModelV1_2 { + version + address + farmToken { + collection + name + ticker + __typename + } + farmingToken { + name + identifier + decimals + __typename + } + farmedToken { + name + identifier + decimals + __typename + } + farmTokenPriceUSD + farmingTokenPriceUSD + farmedTokenPriceUSD + } + ... on FarmModelV1_3 { + version + address + farmToken { + collection + name + ticker + __typename + } + farmingToken { + name + identifier + decimals + __typename + } + farmedToken { + name + identifier + decimals + __typename + } + farmTokenPriceUSD + farmingTokenPriceUSD + farmedTokenPriceUSD + } + ... on FarmModelV2 { + version + address + farmToken { + collection + name + ticker + __typename + } + farmingToken { + name + identifier + decimals + __typename + } + farmedToken { + name + identifier + decimals + __typename + } + farmTokenPriceUSD + farmingTokenPriceUSD + farmedTokenPriceUSD + } + } + stakingFarms { + address + farmingToken { + name + identifier + decimals + __typename + } + farmToken { + name + collection + decimals + __typename + } + } + } + `; diff --git a/src/endpoints/mex/graphql/filtered.pairs.query.ts b/src/endpoints/mex/graphql/filtered.pairs.query.ts new file mode 100644 index 000000000..189688771 --- /dev/null +++ b/src/endpoints/mex/graphql/filtered.pairs.query.ts @@ -0,0 +1,51 @@ +import { gql } from "graphql-request"; + +export const filteredPairsQuery = (includeFarms: boolean = false) => { + const farmFields = includeFarms ? ` + hasFarms + hasDualFarms` : ''; + + return gql` + query filteredPairs($pagination: ConnectionArgs!, $filters: PairsFilter!) { + filteredPairs(pagination: $pagination, filters: $filters) { + edges { + cursor + node { + address + liquidityPoolToken { + identifier + name + __typename + } + liquidityPoolTokenPriceUSD + firstToken { + name + identifier + previous24hPrice + __typename + } + secondToken { + name + identifier + previous24hPrice + __typename + } + firstTokenPriceUSD + secondTokenPriceUSD + state + type + lockedValueUSD + volumeUSD24h + tradesCount + tradesCount24h + deployedAt + ${farmFields} + } + } + pageInfo { + hasNextPage + } + } + } + `; +}; diff --git a/src/endpoints/mex/graphql/pairs.count.query.ts b/src/endpoints/mex/graphql/pairs.count.query.ts new file mode 100644 index 000000000..50eb5efdd --- /dev/null +++ b/src/endpoints/mex/graphql/pairs.count.query.ts @@ -0,0 +1,8 @@ +import { gql } from "graphql-request"; + +export const pairCountQuery = gql` +query PairCount { + factory { + pairCount + } + }`; diff --git a/src/endpoints/mex/graphql/settings.query.ts b/src/endpoints/mex/graphql/settings.query.ts new file mode 100644 index 000000000..66401c089 --- /dev/null +++ b/src/endpoints/mex/graphql/settings.query.ts @@ -0,0 +1,60 @@ +import { gql } from "graphql-request"; + +export const settingsQuery = (pairLimitCount: number) => gql` +query { + filteredPairs(pagination: {first: ${pairLimitCount}}, filters: {state: ["Active"]}) { + edges { + node { + address + } + } + } + proxy { + address + lockedAssetTokens { + collection + } + } + farms { + ... on FarmModelV1_2 { + state + address + } + ... on FarmModelV1_3 { + state + address + } + ... on FarmModelV2 { + state + address + } + } + wrappingInfo { + address + wrappedToken { + identifier + } + } + distribution { + address + } + lockedAssetFactory { + address + } + stakingFarms { + state + address + } + stakingProxies { + address + } + factory { + address + } + simpleLockEnergy { + baseAssetToken { + identifier + } + } +} +`; diff --git a/src/endpoints/mex/graphql/staking.proxy.query.ts b/src/endpoints/mex/graphql/staking.proxy.query.ts new file mode 100644 index 000000000..d1afc2111 --- /dev/null +++ b/src/endpoints/mex/graphql/staking.proxy.query.ts @@ -0,0 +1,12 @@ +import { gql } from "graphql-request"; + +export const stakingProxyQuery = gql` +query StakingProxy { + stakingProxies { + address + dualYieldToken { + name + collection + } + } +}`; diff --git a/src/endpoints/mex/graphql/token.prices.hour.resolution.query.ts b/src/endpoints/mex/graphql/token.prices.hour.resolution.query.ts new file mode 100644 index 000000000..cf87057b3 --- /dev/null +++ b/src/endpoints/mex/graphql/token.prices.hour.resolution.query.ts @@ -0,0 +1,13 @@ +import { gql } from "graphql-request"; + +export const tokenPricesHourResolutionQuery = (tokenIdentifier: string) => gql` + query tokenPricesHourResolution { + values24h( + series: "${tokenIdentifier}", + metric: "priceUSD" + ) { + timestamp + value + } + } + `; diff --git a/src/endpoints/mex/graphql/tokens.query.ts b/src/endpoints/mex/graphql/tokens.query.ts new file mode 100644 index 000000000..4d69a9420 --- /dev/null +++ b/src/endpoints/mex/graphql/tokens.query.ts @@ -0,0 +1,9 @@ +import { gql } from "graphql-request"; + +export const tokensQuery = gql` + query tokens { + tokens { + identifier + type + } + }`; diff --git a/src/endpoints/mex/mex.controller.ts b/src/endpoints/mex/mex.controller.ts index 1d07276cd..988ef755d 100644 --- a/src/endpoints/mex/mex.controller.ts +++ b/src/endpoints/mex/mex.controller.ts @@ -11,7 +11,7 @@ import { MexTokenService } from "./mex.token.service"; import { MexFarmService } from './mex.farm.service'; import { MexFarm } from './entities/mex.farm'; import { QueryPagination } from 'src/common/entities/query.pagination'; -import { ParseIntPipe, ParseTokenPipe, ParseEnumPipe } from '@multiversx/sdk-nestjs-common'; +import { ParseIntPipe, ParseTokenPipe, ParseEnumPipe, ParseBoolPipe } from '@multiversx/sdk-nestjs-common'; import { MexPairExchange } from './entities/mex.pair.exchange'; import { MexPairsFilter } from './entities/mex.pairs..filter'; import { MexTokenChartsService } from './mex.token.charts.service'; @@ -31,10 +31,8 @@ export class MexController { @Get("/mex/settings") @ApiExcludeEndpoint() - @ApiResponse({ - status: 200, - description: 'The settings of the xExchange', - }) + @ApiResponse({ status: 200, description: 'The settings of the xExchange' }) + @ApiNotFoundResponse({ description: 'MEX settings not found' }) async getMexSettings(): Promise { const settings = await this.mexSettingsService.getSettings(); if (!settings) { @@ -56,12 +54,14 @@ export class MexController { @ApiQuery({ name: 'from', description: 'Number of items to skip for the result set', required: false }) @ApiQuery({ name: 'size', description: 'Number of items to retrieve', required: false }) @ApiQuery({ name: 'exchange', description: 'Filter by exchange', required: false, enum: MexPairExchange }) + @ApiQuery({ name: 'includeFarms', description: 'Include farms information in response', required: false, type: Boolean }) async getMexPairs( @Query('from', new DefaultValuePipe(0), ParseIntPipe) from: number, @Query("size", new DefaultValuePipe(25), ParseIntPipe) size: number, @Query('exchange', new ParseEnumPipe(MexPairExchange)) exchange?: MexPairExchange, + @Query('includeFarms', new DefaultValuePipe(false), ParseBoolPipe) includeFarms?: boolean, ): Promise { - const filter = new MexPairsFilter({ exchange }); + const filter = new MexPairsFilter({ exchange, includeFarms }); return await this.mexPairsService.getMexPairs(from, size, filter); } @@ -83,10 +83,12 @@ export class MexController { @Get("/mex/pairs/count") @ApiOperation({ summary: 'Maiar Exchange pairs count', description: 'Returns active liquidity pools count available on Maiar Exchange' }) @ApiQuery({ name: 'exchange', description: 'Filter by exchange', required: false, enum: MexPairExchange }) + @ApiQuery({ name: 'includeFarms', description: 'Include farms information in response', required: false, type: Boolean }) async getMexPairsCount( @Query('exchange', new ParseEnumPipe(MexPairExchange)) exchange?: MexPairExchange, + @Query('includeFarms', new DefaultValuePipe(false), ParseBoolPipe) includeFarms?: boolean, ): Promise { - const filter = new MexPairsFilter({ exchange }); + const filter = new MexPairsFilter({ exchange, includeFarms }); return await this.mexPairsService.getMexPairsCount(filter); } @@ -146,19 +148,25 @@ export class MexController { @Get("/mex/pairs/:baseId/:quoteId") @ApiOperation({ summary: 'xExchange pairs details', description: 'Returns liquidity pool details by providing a combination of two tokens' }) @ApiOkResponse({ type: MexPair }) + @ApiNotFoundResponse({ description: 'Pair not found' }) + @ApiQuery({ name: 'includeFarms', description: 'Include farms information in response', required: false, type: Boolean }) async getMexPair( @Param('baseId') baseId: string, @Param('quoteId') quoteId: string, + @Query('includeFarms', new DefaultValuePipe(false), ParseBoolPipe) includeFarms?: boolean, ): Promise { - const pair = await this.mexPairsService.getMexPair(baseId, quoteId); + const pair = await this.mexPairsService.getMexPair(baseId, quoteId, includeFarms); if (!pair) { - throw new NotFoundException(); + throw new NotFoundException('Pair not found'); } return pair; } @Get('mex/tokens/prices/hourly/:identifier') + @ApiOperation({ summary: 'xExchange token prices hourly', description: 'Returns token prices hourly' }) + @ApiOkResponse({ type: [MexTokenChart] }) + @ApiNotFoundResponse({ description: 'Price not available for given token identifier' }) async getTokenPricesHourResolution( @Param('identifier', ParseTokenPipe) identifier: string): Promise { const charts = await this.mexTokenChartsService.getTokenPricesHourResolution(identifier); @@ -170,6 +178,9 @@ export class MexController { } @Get('mex/tokens/prices/daily/:identifier') + @ApiOperation({ summary: 'xExchange token prices daily', description: 'Returns token prices daily' }) + @ApiOkResponse({ type: [MexTokenChart] }) + @ApiNotFoundResponse({ description: 'Price not available for given token identifier' }) async getTokenPricesDayResolution( @Param('identifier', ParseTokenPipe) identifier: string, @Query('after') after: string): Promise { diff --git a/src/endpoints/mex/mex.farm.service.ts b/src/endpoints/mex/mex.farm.service.ts index 0bce98f5e..4cebd7b1f 100644 --- a/src/endpoints/mex/mex.farm.service.ts +++ b/src/endpoints/mex/mex.farm.service.ts @@ -1,7 +1,6 @@ import { Constants } from "@multiversx/sdk-nestjs-common"; import { CacheService } from "@multiversx/sdk-nestjs-cache"; import { forwardRef, Inject, Injectable } from "@nestjs/common"; -import { gql } from "graphql-request"; import { QueryPagination } from "src/common/entities/query.pagination"; import { CacheInfo } from "src/utils/cache.info"; import { GraphQlService } from "src/common/graphql/graphql.service"; @@ -9,6 +8,8 @@ import { MexFarm } from "./entities/mex.farm"; import { MexTokenService } from "./mex.token.service"; import { MexStakingProxy } from "./entities/mex.staking.proxy"; import { ApiConfigService } from "src/common/api-config/api.config.service"; +import { farmsQuery } from "./graphql/farms.query"; +import { stakingProxyQuery } from "./graphql/staking.proxy.query"; @Injectable() export class MexFarmService { @@ -53,104 +54,7 @@ export class MexFarmService { } private async getAllMexFarmsRaw(): Promise { - const query = gql` - query { - farms { - ... on FarmModelV1_2 { - version - address - farmToken { - collection - name - ticker - __typename - } - farmingToken { - name - identifier - decimals - __typename - } - farmedToken { - name - identifier - decimals - __typename - } - farmTokenPriceUSD - farmingTokenPriceUSD - farmedTokenPriceUSD - } - ... on FarmModelV1_3 { - version - address - farmToken { - collection - name - ticker - __typename - } - farmingToken { - name - identifier - decimals - __typename - } - farmedToken { - name - identifier - decimals - __typename - } - farmTokenPriceUSD - farmingTokenPriceUSD - farmedTokenPriceUSD - } - ... on FarmModelV2 { - version - address - farmToken { - collection - name - ticker - __typename - } - farmingToken { - name - identifier - decimals - __typename - } - farmedToken { - name - identifier - decimals - __typename - } - farmTokenPriceUSD - farmingTokenPriceUSD - farmedTokenPriceUSD - } - } - stakingFarms { - address - farmingToken { - name - identifier - decimals - __typename - } - farmToken { - name - collection - decimals - __typename - } - } - } - `; - - const response: any = await this.graphQlService.getExchangeServiceData(query, {}); + const response: any = await this.graphQlService.getExchangeServiceData(farmsQuery, {}); if (!response) { return []; } @@ -178,18 +82,7 @@ export class MexFarmService { } private async getAllStakingProxiesRaw(): Promise { - const query = gql` - query StakingProxy { - stakingProxies { - address - dualYieldToken { - name - collection - } - } - }`; - - const response: any = await this.graphQlService.getExchangeServiceData(query, {}); + const response: any = await this.graphQlService.getExchangeServiceData(stakingProxyQuery, {}); if (!response) { return []; } diff --git a/src/endpoints/mex/mex.pair.service.ts b/src/endpoints/mex/mex.pair.service.ts index 353503ebb..a3ad3824c 100644 --- a/src/endpoints/mex/mex.pair.service.ts +++ b/src/endpoints/mex/mex.pair.service.ts @@ -1,7 +1,6 @@ import { Constants } from '@multiversx/sdk-nestjs-common'; import { CacheService } from '@multiversx/sdk-nestjs-cache'; import { BadRequestException, Injectable } from '@nestjs/common'; -import { gql } from 'graphql-request'; import { CacheInfo } from 'src/utils/cache.info'; import { GraphQlService } from 'src/common/graphql/graphql.service'; import { MexPair } from './entities/mex.pair'; @@ -13,6 +12,7 @@ import { ApiConfigService } from 'src/common/api-config/api.config.service'; import { MexPairExchange } from './entities/mex.pair.exchange'; import { MexPairsFilter } from './entities/mex.pairs..filter'; import { MexPairStatus } from './entities/mex.pair.status'; +import { filteredPairsQuery } from './graphql/filtered.pairs.query'; @Injectable() export class MexPairService { @@ -26,134 +26,87 @@ export class MexPairService { ) { } async refreshMexPairs(): Promise { - const pairs = await this.getAllMexPairsRaw(); + const pairs = await this.getAllMexPairsRaw(false); await this.cachingService.setRemote(CacheInfo.MexPairs.key, pairs, CacheInfo.MexPairs.ttl); await this.cachingService.setLocal(CacheInfo.MexPairs.key, pairs, Constants.oneSecond() * 30); } async getMexPairs(from: number, size: number, filter?: MexPairsFilter): Promise { - let allMexPairs = await this.getAllMexPairs(); + let allMexPairs = await this.getAllMexPairs(filter?.includeFarms ?? false); allMexPairs = this.applyFilters(allMexPairs, filter); return allMexPairs.slice(from, from + size); } - - async getMexPair(baseId: string, quoteId: string): Promise { - const allMexPairs = await this.getAllMexPairs(); + async getMexPair(baseId: string, quoteId: string, includeFarms: boolean = false): Promise { + const allMexPairs = await this.getAllMexPairs(includeFarms); return allMexPairs.find(pair => pair.baseId === baseId && pair.quoteId === quoteId); } - async getAllMexPairs(): Promise { + async getAllMexPairs(includeFarms: boolean = false): Promise { if (!this.apiConfigService.isExchangeEnabled()) { return []; } + const cacheKey = includeFarms ? CacheInfo.MexPairsWithFarms.key : CacheInfo.MexPairs.key; + const ttl = includeFarms ? CacheInfo.MexPairsWithFarms.ttl : CacheInfo.MexPairs.ttl; + return await this.cachingService.getOrSet( - CacheInfo.MexPairs.key, - async () => await this.getAllMexPairsRaw(), - CacheInfo.MexPairs.ttl, + cacheKey, + async () => await this.getAllMexPairsRaw(includeFarms), + ttl, Constants.oneSecond() * 30, ); } async getMexPairsCount(filter?: MexPairsFilter): Promise { - const mexPairs = await this.getAllMexPairs(); + const mexPairs = await this.getAllMexPairs(filter?.includeFarms ?? false); const filteredPairs = this.applyFilters(mexPairs, filter); return filteredPairs.length; } - async getAllMexPairsRaw(): Promise { + async getAllMexPairsRaw(includeFarms: boolean = false): Promise { try { const settings = await this.mexSettingService.getSettings(); if (!settings) { throw new BadRequestException('Could not fetch MEX settings'); } - const pairsLimit = gql` - query PairCount { - factory { - pairCount - } - }`; + const allPairs: MexPair[] = []; + let cursor: string | null = null; + let hasNextPage = true; - const pairsLimitResult: any = await this.graphQlService.getExchangeServiceData(pairsLimit); - const totalPairs = pairsLimitResult?.factory?.pairCount; + while (hasNextPage) { + const variables = { + pagination: { first: 25, after: cursor }, + filters: { state: [MexPairStatus.active] }, + }; - const variables = { - pagination: { first: totalPairs }, - filters: { state: MexPairStatus.active }, - }; + const query = filteredPairsQuery(includeFarms); + const result: any = await this.graphQlService.getExchangeServiceData(query, variables); - const query = gql` - query filteredPairs($pagination: ConnectionArgs!, $filters: PairsFilter!) { - filteredPairs(pagination: $pagination, filters: $filters) { - edges { - cursor - node { - address - liquidityPoolToken { - identifier - name - __typename - } - liquidityPoolTokenPriceUSD - firstToken { - name - identifier - decimals - previous24hPrice - __typename - } - secondToken { - name - identifier - decimals - previous24hPrice - __typename - } - firstTokenPrice - firstTokenPriceUSD - secondTokenPrice - secondTokenPriceUSD - info { - reserves0 - reserves1 - totalSupply - __typename - } - state - type - lockedValueUSD - volumeUSD24h - hasFarms - hasDualFarms - tradesCount - tradesCount24h - deployedAt - __typename - } - } - } + if (!result) { + break; } - `; - const result: any = await this.graphQlService.getExchangeServiceData(query, variables); - if (!result) { - return []; + const pairs = result.filteredPairs.edges.map((edge: any) => this.getPairInfo(edge.node, includeFarms)); + allPairs.push(...pairs.filter((pair: MexPair | undefined) => pair !== undefined)); + + hasNextPage = result.filteredPairs.pageInfo.hasNextPage; + cursor = result.filteredPairs.edges.length > 0 ? result.filteredPairs.edges[result.filteredPairs.edges.length - 1].cursor : null; } - return result.filteredPairs.edges - .map((edge: any) => this.getPairInfo(edge.node)); + return allPairs; } catch (error) { - this.logger.error('An error occurred while getting all mex pairs'); + this.logger.error('An error occurred while getting all mex pairs from the exchange'); this.logger.error(error); return []; } } - private getPairInfo(pair: any): MexPair | undefined { + + private getPairInfo(pair: any, includeFarms: boolean = false): MexPair | undefined { const firstTokenSymbol = pair.firstToken.identifier.split('-')[0]; const secondTokenSymbol = pair.secondToken.identifier.split('-')[0]; const state = this.getPairState(pair.state); @@ -178,13 +131,29 @@ export class MexPairService { exchange = MexPairExchange.unknown; } + const baseInfo = { + address: pair.address, + id: pair.liquidityPoolToken.identifier, + symbol: pair.liquidityPoolToken.identifier.split('-')[0], + name: pair.liquidityPoolToken.name, + price: Number(pair.liquidityPoolTokenPriceUSD), + totalValue: Number(pair.lockedValueUSD), + volume24h: Number(pair.volumeUSD24h), + tradesCount: Number(pair.tradesCount), + tradesCount24h: Number(pair.tradesCount24h), + deployedAt: Number(pair.deployedAt), + state, + type, + exchange, + ...(includeFarms && { + hasFarms: pair.hasFarms ?? false, + hasDualFarms: pair.hasDualFarms ?? false, + }), + }; + if ((firstTokenSymbol === 'WEGLD' && secondTokenSymbol === 'USDC') || secondTokenSymbol === 'WEGLD') { return { - address: pair.address, - id: pair.liquidityPoolToken.identifier, - symbol: pair.liquidityPoolToken.identifier.split('-')[0], - name: pair.liquidityPoolToken.name, - price: Number(pair.liquidityPoolTokenPriceUSD), + ...baseInfo, basePrevious24hPrice: Number(pair.firstToken.previous24hPrice), quotePrevious24hPrice: Number(pair.secondToken.previous24hPrice), baseId: pair.firstToken.identifier, @@ -195,25 +164,11 @@ export class MexPairService { quotePrice: Number(pair.secondTokenPriceUSD), quoteSymbol: secondTokenSymbol, quoteName: pair.secondToken.name, - totalValue: Number(pair.lockedValueUSD), - volume24h: Number(pair.volumeUSD24h), - hasFarms: pair.hasFarms, - hasDualFarms: pair.hasDualFarms, - tradesCount: Number(pair.tradesCount), - tradesCount24h: Number(pair.tradesCount24h), - deployedAt: Number(pair.deployedAt), - state, - type, - exchange, }; } return { - address: pair.address, - id: pair.liquidityPoolToken.identifier, - symbol: pair.liquidityPoolToken.identifier.split('-')[0], - name: pair.liquidityPoolToken.name, - price: Number(pair.liquidityPoolTokenPriceUSD), + ...baseInfo, basePrevious24hPrice: Number(pair.secondToken.previous24hPrice), quotePrevious24hPrice: Number(pair.firstToken.previous24hPrice), baseId: pair.secondToken.identifier, @@ -224,16 +179,6 @@ export class MexPairService { quotePrice: Number(pair.firstTokenPriceUSD), quoteSymbol: firstTokenSymbol, quoteName: pair.firstToken.name, - totalValue: Number(pair.lockedValueUSD), - volume24h: Number(pair.volumeUSD24h), - hasFarms: pair.hasFarms, - hasDualFarms: pair.hasDualFarms, - tradesCount: Number(pair.tradesCount), - tradesCount24h: Number(pair.tradesCount24h), - deployedAt: Number(pair.deployedAt), - state, - type, - exchange, }; } diff --git a/src/endpoints/mex/mex.settings.service.ts b/src/endpoints/mex/mex.settings.service.ts index 2770ef3f8..243c8a6f9 100644 --- a/src/endpoints/mex/mex.settings.service.ts +++ b/src/endpoints/mex/mex.settings.service.ts @@ -1,13 +1,14 @@ import { Constants } from "@multiversx/sdk-nestjs-common"; import { CacheService } from "@multiversx/sdk-nestjs-cache"; import { Injectable } from "@nestjs/common"; -import { gql } from "graphql-request"; import { CacheInfo } from "src/utils/cache.info"; import { GraphQlService } from "src/common/graphql/graphql.service"; import { TransactionMetadata } from "../transactions/transaction-action/entities/transaction.metadata"; import { TransactionMetadataTransfer } from "../transactions/transaction-action/entities/transaction.metadata.transfer"; import { MexSettings } from "./entities/mex.settings"; import { ApiConfigService } from "src/common/api-config/api.config.service"; +import { settingsQuery } from "./graphql/settings.query"; +import { pairCountQuery } from "./graphql/pairs.count.query"; @Injectable() export class MexSettingsService { @@ -87,83 +88,33 @@ export class MexSettingsService { } public async getSettingsRaw(): Promise { - const variables = { - offset: 0, - limit: 500, - }; - - const query = gql` - query ($offset: Int, $limit: Int) { - pairs(offset: $offset, limit: $limit) { - state - address - firstToken { - name - identifier - decimals - __typename - } - secondToken { - name - identifier - decimals - __typename - } - } - proxy { - address - lockedAssetTokens { - collection - __typename - } - } - farms { - ... on FarmModelV1_2 { - state - address - } - ... on FarmModelV1_3 { - state - address - } - ... on FarmModelV2 { - state - address - } - } - wrappingInfo { - address - shard - } - distribution { - address - } - lockedAssetFactory { - address - } - stakingFarms { - state - address - } - stakingProxies { - address - } - factory { - address - } - } - `; - - const response = await this.graphQlService.getExchangeServiceData(query, variables); + const pairLimitCount = await this.getPairLimitCount(); + const response = await this.graphQlService.getExchangeServiceData(settingsQuery(pairLimitCount)); if (!response) { return null; } - const settings = MexSettings.fromQueryResponse(response); + const transformedResponse = { + ...response, + pairs: response.filteredPairs.edges.map((edge: { node: { address: string } }) => ({ + address: edge.node.address, + })), + }; + + const settings = MexSettings.fromQueryResponse(transformedResponse); return settings; } getWegldId(): string | undefined { return this.wegldId; } + + private async getPairLimitCount(): Promise { + const response = await this.graphQlService.getExchangeServiceData(pairCountQuery); + if (!response) { + return 500; + } + + return response.factory.pairCount; + } } diff --git a/src/endpoints/mex/mex.token.charts.service.ts b/src/endpoints/mex/mex.token.charts.service.ts index 8d2e62b94..0b3dde374 100644 --- a/src/endpoints/mex/mex.token.charts.service.ts +++ b/src/endpoints/mex/mex.token.charts.service.ts @@ -6,6 +6,7 @@ import { MexTokenChart } from "./entities/mex.token.chart"; import { MexTokenService } from "./mex.token.service"; import { CacheService } from "@multiversx/sdk-nestjs-cache"; import { CacheInfo } from "src/utils/cache.info"; +import { tokenPricesHourResolutionQuery } from "./graphql/token.prices.hour.resolution.query"; @Injectable() export class MexTokenChartsService { @@ -31,19 +32,8 @@ export class MexTokenChartsService { return undefined; } - const query = gql` - query tokenPricesHourResolution { - values24h( - series: "${tokenIdentifier}", - metric: "priceUSD" - ) { - timestamp - value - } - } - `; - try { + const query = tokenPricesHourResolutionQuery(tokenIdentifier); const data = await this.graphQlService.getExchangeServiceData(query); return this.convertToMexTokenChart(data?.values24h) || []; } catch (error) { diff --git a/src/endpoints/mex/mex.token.service.ts b/src/endpoints/mex/mex.token.service.ts index c98b180c9..7907bf258 100644 --- a/src/endpoints/mex/mex.token.service.ts +++ b/src/endpoints/mex/mex.token.service.ts @@ -2,7 +2,6 @@ import { BadRequestException, forwardRef, Inject, Injectable } from "@nestjs/com import { CacheInfo } from "src/utils/cache.info"; import { MexToken } from "./entities/mex.token"; import { MexPairService } from "./mex.pair.service"; -import { MexPairState } from "./entities/mex.pair.state"; import { MexPair } from "./entities/mex.pair"; import { ApiConfigService } from "src/common/api-config/api.config.service"; import { MexFarmService } from "./mex.farm.service"; @@ -13,7 +12,7 @@ import { OriginLogger } from "@multiversx/sdk-nestjs-common"; import { QueryPagination } from "src/common/entities/query.pagination"; import { MexTokenType } from "./entities/mex.token.type"; import { GraphQlService } from "src/common/graphql/graphql.service"; -import { gql } from "graphql-request"; +import { tokensQuery } from "./graphql/tokens.query"; @Injectable() export class MexTokenService { @@ -172,10 +171,9 @@ export class MexTokenService { private async getAllMexTokensRaw(): Promise { const pairs = await this.mexPairService.getAllMexPairs(); - const filteredPairs = pairs.filter(x => x.state === MexPairState.active); const mexTokens: MexToken[] = []; - for (const pair of filteredPairs) { + for (const pair of pairs) { if (pair.baseSymbol === 'WEGLD' && pair.quoteSymbol === "USDC") { const wegldToken = new MexToken(); wegldToken.id = pair.baseId; @@ -184,7 +182,7 @@ export class MexTokenService { wegldToken.price = pair.basePrice; wegldToken.previous24hPrice = pair.basePrevious24hPrice; wegldToken.previous24hVolume = pair.volume24h; - wegldToken.tradesCount = this.computeTradesCountForMexToken(wegldToken, filteredPairs); + wegldToken.tradesCount = this.computeTradesCountForMexToken(wegldToken, pairs); mexTokens.push(wegldToken); } @@ -193,7 +191,7 @@ export class MexTokenService { continue; } - mexToken.tradesCount = this.computeTradesCountForMexToken(mexToken, filteredPairs); + mexToken.tradesCount = this.computeTradesCountForMexToken(mexToken, pairs); mexTokens.push(mexToken); } @@ -261,16 +259,7 @@ export class MexTokenService { throw new BadRequestException('Could not fetch MEX tokens'); } - const query = gql` - query tokens { - tokens { - identifier - type - } - } - `; - - const result: any = await this.graphQlService.getExchangeServiceData(query); + const result: any = await this.graphQlService.getExchangeServiceData(tokensQuery); if (!result || !result.tokens) { return []; } diff --git a/src/endpoints/tokens/token.service.ts b/src/endpoints/tokens/token.service.ts index bd3f02768..33597dbd9 100644 --- a/src/endpoints/tokens/token.service.ts +++ b/src/endpoints/tokens/token.service.ts @@ -122,7 +122,7 @@ export class TokenService { } async getTokens(queryPagination: QueryPagination, filter: TokenFilter): Promise { - const {from, size} = queryPagination; + const { from, size } = queryPagination; let tokens = await this.getFilteredTokens(filter); @@ -132,9 +132,9 @@ export class TokenService { this.applyTickerFromAssets(token); } - return tokens - .map(item => ApiUtils.mergeObjects(new TokenDetailed(), item)) - .filter(t => t.identifier !== this.egldIdentifierInMultiTransfer); + return tokens + .map(item => ApiUtils.mergeObjects(new TokenDetailed(), item)) + .filter(t => t.identifier !== this.egldIdentifierInMultiTransfer); } applyTickerFromAssets(token: Token) { @@ -371,11 +371,11 @@ export class TokenService { if (TokenUtils.isNft(identifier)) { const nftData = await this.gatewayService.getAddressNft(address, identifier); - tokenWithBalance = new TokenDetailedWithBalance({...token, ...nftData}); + tokenWithBalance = new TokenDetailedWithBalance({ ...token, ...nftData }); } else { const esdtData = await this.gatewayService.getAddressEsdt(address, identifier); - tokenWithBalance = new TokenDetailedWithBalance({...token, ...esdtData}); + tokenWithBalance = new TokenDetailedWithBalance({ ...token, ...esdtData }); } // eslint-disable-next-line require-await @@ -984,9 +984,9 @@ export class TokenService { private async getTotalTransactions(token: TokenDetailed): Promise<{ count: number, lastUpdatedAt: number } | undefined> { try { - const count = await this.transactionService.getTransactionCount(new TransactionFilter({tokens: [token.identifier, ...token.assets?.extraTokens ?? []]})); + const count = await this.transactionService.getTransactionCount(new TransactionFilter({ tokens: [token.identifier, ...token.assets?.extraTokens ?? []] })); - return {count, lastUpdatedAt: new Date().getTimeInSeconds()}; + return { count, lastUpdatedAt: new Date().getTimeInSeconds() }; } catch (error) { this.logger.error(`An unhandled error occurred when getting transaction count for token '${token.identifier}'`); this.logger.error(error); @@ -1032,11 +1032,10 @@ export class TokenService { private async applyMexLiquidity(tokens: TokenDetailed[]): Promise { try { - const pairs = await this.mexPairService.getAllMexPairs(); - const filteredPairs = pairs.filter(x => x.state === MexPairState.active); + const allPairs = await this.mexPairService.getAllMexPairs(); for (const token of tokens) { - const pairs = filteredPairs.filter(x => x.baseId === token.identifier || x.quoteId === token.identifier); + const pairs = allPairs.filter(x => x.baseId === token.identifier || x.quoteId === token.identifier); if (pairs.length > 0) { token.totalLiquidity = pairs.sum(x => x.totalValue / 2); token.totalVolume24h = pairs.sum(x => x.volume24h ?? 0); diff --git a/src/test/chain-simulator/accounts.cs-e2e.ts b/src/test/chain-simulator/accounts.cs-e2e.ts new file mode 100644 index 000000000..431516f4b --- /dev/null +++ b/src/test/chain-simulator/accounts.cs-e2e.ts @@ -0,0 +1,1989 @@ +import axios from "axios"; +import { config } from "./config/env.config"; +import { NftType } from "src/endpoints/nfts/entities/nft.type"; +import { NftSubType } from "src/endpoints/nfts/entities/nft.sub.type"; + +describe('Accounts e2e tests with chain simulator', () => { + describe('GET /accounts with query parameters', () => { + it('should return paginated results with from and size parameters', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts?from=0&size=5`); + expect(response.status).toBe(200); + expect(response.data.length).toBe(5); + }); + + it('should filter accounts by owner address', async () => { + const address = 'erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u'; + const response = await axios.get(`${config.apiServiceUrl}/accounts?ownerAddress=${address}`); + expect(response.status).toBe(200); + + for (const account of response.data) { + expect(account.ownerAddress).toBe(address); + } + }); + + it('should filter smart contract accounts', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts?isSmartContract=true`); + expect(response.status).toBe(200); + + for (const account of response.data) { + expect(account.shard).toBe(4294967295); + } + }); + + it('should search accounts by address', async () => { + const searchTerm = config.aliceAddress.substring(0, 10); + const response = await axios.get(`${config.apiServiceUrl}/accounts?search=${searchTerm}`); + expect(response.status).toBe(200); + + for (const account of response.data) { + expect(account.address.toLowerCase()).toContain(searchTerm.toLowerCase()); + } + }); + + it('should return accounts with transaction count when requested', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts?withTxCount=true&withDeployInfo=true`); + expect(response.status).toBe(200); + for (const account of response.data) { + expect(account).toHaveProperty('txCount'); + } + }); + + it('should validate account structure', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts`); + expect(response.status).toBe(200); + + response.data.forEach((account: any) => { + expect(account).toHaveProperty('address'); + expect(account).toHaveProperty('balance'); + expect(account).toHaveProperty('nonce'); + expect(account).toHaveProperty('timestamp'); + expect(account).toHaveProperty('shard'); + }); + }); + }); + + describe('GET /accounts/count', () => { + it('should return the total number of accounts', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/count`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThan(0); + }); + + it('should filter accounts by owner address', async () => { + const ownerAddress = 'erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u'; + const response = await axios.get(`${config.apiServiceUrl}/accounts/count?ownerAddress=${ownerAddress}`); + expect(response.status).toBe(200); + expect(response.data).toBe(1); + }); + + it('should filter smart contract accounts', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/count?isSmartContract=true`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + }); + + describe('GET /accounts/c alternative', () => { + it('should return the total number of accounts', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/c`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThan(0); + }); + + it('should filter accounts by owner address', async () => { + const ownerAddress = 'erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u'; + const response = await axios.get(`${config.apiServiceUrl}/accounts/c?ownerAddress=${ownerAddress}`); + expect(response.status).toBe(200); + expect(response.data).toBe(1); + }); + + it('should filter smart contract accounts', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/c?isSmartContract=true`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + }); + + describe('GET /accounts/:address', () => { + it('should return account details for a given address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}`); + expect(response.status).toBe(200); + }); + + it('should return account details for a given address with guardian info', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}?withGuardianInfo=true`); + expect(response.status).toBe(200); + expect(response.data.isGuarded).toBe(false); + }); + + it('should return correct account details with all fields', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}`); + expect(response.status).toBe(200); + + expect(response.data.balance).toBeDefined(); + expect(response.data.shard).toBeDefined(); + expect(response.data.nonce).toBeDefined(); + + expect(typeof response.data.balance).toBe('string'); + expect(typeof response.data.shard).toBe('number'); + expect(typeof response.data.nonce).toBe('number'); + + const responseWithDetails = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}?withScrCount=true&withTxCount=true`); + expect(responseWithDetails.status).toBe(200); + expect(responseWithDetails.data.txCount).toBeDefined(); + expect(responseWithDetails.data.scrCount).toBeDefined(); + }); + + it('should return 400 for non-existent / invalid address', async () => { + const invalidAddress = 'erd1invalid000000000000000000000000000000000000000000000000000'; + try { + await axios.get(`${config.apiServiceUrl}/accounts/${invalidAddress}`); + } catch (error: any) { + expect(error.response.status).toBe(400); + } + }); + + it('should return address field in response when fields query parameter is provided', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}?fields=address`); + expect(response.status).toBe(200); + expect(response.data.address).toBeDefined(); + }); + }); + + describe('GET /accounts/:address/tokens', () => { + it('should return tokens for a given address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/tokens`); + expect(response.status).toBe(200); + expect(Array.isArray(response.data)).toBe(true); + }); + + it('should return paginated results with from and size parameters', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/tokens?from=0&size=2`); + expect(response.status).toBe(200); + expect(response.data.length).toBeLessThanOrEqual(2); + }); + + it('should return tokens with correct structure', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/tokens`); + expect(response.status).toBe(200); + + for (const token of response.data) { + expect(token).toHaveProperty('type'); + expect(token).toHaveProperty('identifier'); + expect(token).toHaveProperty('name'); + expect(token).toHaveProperty('ticker'); + expect(token).toHaveProperty('decimals'); + expect(token).toHaveProperty('balance'); + expect(typeof token.balance).toBe('string'); + } + }); + + it('should filter tokens by type', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/tokens?type=FungibleESDT`); + expect(response.status).toBe(200); + + for (const token of response.data) { + expect(token.type).toBe('FungibleESDT'); + } + }); + + it('should search tokens by name', async () => { + const searchTerm = 'Token'; + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/tokens?name=${searchTerm}`); + expect(response.status).toBe(200); + + for (const token of response.data) { + expect(token.name.toLowerCase()).toContain(searchTerm.toLowerCase()); + } + }); + + it('should filter tokens by identifier', async () => { + const accountToken = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/tokens`); + const identifier = accountToken.data[0].identifier; + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/tokens?identifier=${identifier}`); + expect(response.status).toBe(200); + + for (const token of response.data) { + expect(token.identifier).toBe(identifier); + } + }); + + it('should return empty array for non-existent address', async () => { + const invalidAddress = 'erd1invalid000000000000000000000000000000000000000000000000000'; + try { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${invalidAddress}/tokens`); + expect(response.status).toBe(200); + expect(response.data).toEqual([]); + } catch (error: any) { + expect(error.response.status).toBe(400); + } + }); + }); + + describe('GET /accounts/:address/tokens/count', () => { + it('should return the total number of tokens for a given address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/tokens/count`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThan(0); + }); + + it('should filter tokens by type', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/tokens/count?type=FungibleESDT`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(0); + expect(typeof response.data).toBe('number'); + }); + + it('should return 0 for an address with 0 tokens', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.bobAddress}/tokens/count`); + expect(response.status).toBe(200); + expect(response.data).toBe(0); + expect(typeof response.data).toBe('number'); + }); + + it('should filter tokens by name', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/tokens/count?name=Token`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(0); + }); + + it('should filter tokens by identifier', async () => { + const tokens = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/tokens`); + const identifier = tokens.data[0].identifier; + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/tokens/count?identifier=${identifier}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(1); + }); + + it('should filter tokens by identifiers', async () => { + const tokens = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/tokens`); + const identifiers = tokens.data.map((token: any) => token.identifier); + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/tokens/count?identifiers=${identifiers.join(',')}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(identifiers.length); + }); + }); + + describe('GET /accounts/:address/tokens/:token', () => { + it('should return token details for a given address and token', async () => { + const tokens = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/tokens`); + const identifier = tokens.data[0].identifier; + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/tokens/${identifier}`); + + expect(response.status).toBe(200); + expect(response.data.identifier).toStrictEqual(identifier); + }); + }); + + describe('GET /accounts/:address/roles/collections', () => { + it('should return collections with roles for a given address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/collections`); + expect(response.status).toBe(200); + }); + + it('should return paginated results with from and size parameters', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/collections?from=0&size=2`); + expect(response.status).toBe(200); + expect(response.data.length).toBeLessThanOrEqual(2); + }); + + it('should return results by owner parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/collections?owner=${config.aliceAddress}`); + expect(response.status).toBe(200); + + for (const collection of response.data) { + expect(collection.owner).toBe(config.aliceAddress); + } + }); + + it('should return results by canCreate parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/collections?canCreate=false`); + expect(response.status).toBe(200); + + for (const collection of response.data) { + expect(collection.canCreate).toBe(false); + } + }); + + it('should return results by canBurn parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/collections?canBurn=false`); + expect(response.status).toBe(200); + + for (const collection of response.data) { + expect(collection.canBurn).toBe(false); + } + }); + + it('should return results by canAddQuantity parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/collections?canAddQuantity=false`); + expect(response.status).toBe(200); + }); + + it('should return results by canUpdateAttributes parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/collections?canUpdateAttributes=false`); + expect(response.status).toBe(200); + + for (const collection of response.data) { + expect(collection.canUpdateAttributes).toBe(false); + } + }); + + it('should return results by canAddUri parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/collections?canAddUri=false`); + expect(response.status).toBe(200); + + for (const collection of response.data) { + expect(collection.canAddUri).toBe(false); + } + }); + + it('should return results by canTransferRole parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/collections?canTransferRole=false`); + expect(response.status).toBe(200); + }); + + it('should return collection with all expected fields', async () => { + const expectedProperties = [ + 'collection', + 'type', + 'subType', + 'name', + 'ticker', + 'owner', + 'timestamp', + 'canFreeze', + 'canWipe', + 'canPause', + 'canTransferNftCreateRole', + 'canChangeOwner', + 'canUpgrade', + 'canAddSpecialRoles', + 'canTransfer', + 'canCreate', + 'canBurn', + 'canUpdateAttributes', + 'canAddUri', + ]; + + const expectedRoleProperties = [ + 'canCreate', + 'canBurn', + 'canAddQuantity', + 'canUpdateAttributes', + 'canAddUri', + ]; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/collections`); + expect(response.status).toBe(200); + + const collection = response.data[0]; + + for (const property of expectedProperties) { + expect(collection).toHaveProperty(property); + } + + expect(collection).toHaveProperty('role'); + for (const property of expectedRoleProperties) { + expect(collection.role).toHaveProperty(property); + } + }); + }); + + describe('GET /accounts/:address/roles/collections/count', () => { + it('should return the total number of collections with roles for a given address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/collections/count`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThan(0); + }); + + it('should return results by type parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/collections/count?type=NonFungibleESDT`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + + it('should return results by owner parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/collections/count?owner=${config.aliceAddress}`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + + it('should return results by canAddQuantity parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/collections/count?canAddQuantity=false`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + + it('should return results by excludeMetaESDT parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/collections/count?excludeMetaESDT=true`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + }); + + describe('GET /accounts/:address/roles/collections/:collection', () => { + it('should return collection details with roles for a given address and collection', async () => { + const collections = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/collections`); + const collection = collections.data[0].collection; + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/collections/${collection}`); + + expect(response.status).toBe(200); + expect(response.data.collection).toBe(collection); + + const expectedProperties = [ + 'collection', + 'type', + 'subType', + 'name', + 'ticker', + 'owner', + 'timestamp', + 'canFreeze', + 'canWipe', + 'canPause', + 'canTransferNftCreateRole', + 'canChangeOwner', + 'canUpgrade', + 'canAddSpecialRoles', + 'canTransfer', + 'canCreate', + 'canBurn', + 'canUpdateAttributes', + 'canAddUri', + ]; + + for (const property of expectedProperties) { + expect(response.data).toHaveProperty(property); + } + }); + + it('should return 404 for non-existent collection', async () => { + try { + await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/collections/NFT2-b1cf6d`); + } catch (error: any) { + expect(error.response.status).toBe(404); + } + }); + }); + + describe('GET /accounts/:address/roles/tokens', () => { + it('should return tokens with roles for a given address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/tokens`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThan(0); + + const expectedProperties = [ + 'type', + 'subType', + 'identifier', + 'name', + 'ticker', + 'owner', + 'decimals', + 'isPaused', + 'transactions', + 'transactionsLastUpdatedAt', + 'transfers', + 'transfersLastUpdatedAt', + 'accounts', + 'accountsLastUpdatedAt', + 'canUpgrade', + 'canMint', + 'canChangeOwner', + 'canAddSpecialRoles', + 'canPause', + 'canFreeze', + 'canWipe', + 'timestamp', + 'mexPairType', + 'ownersHistory', + 'role', + 'canLocalMint', + 'canLocalBurn', + 'canTransfer', + ]; + + for (const property of expectedProperties) { + expect(response.data[0]).toHaveProperty(property); + } + }); + + it('should return paginated results with from and size parameters', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/tokens?from=0&size=2`); + expect(response.status).toBe(200); + expect(response.data.length).toBeLessThanOrEqual(2); + }); + + it('should return results by owner parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/tokens?owner=${config.aliceAddress}`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + }); + + it('should return results by canMint parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/tokens?canMint=false`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + }); + + it('should return results by canBurn parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/tokens?canBurn=false`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + }); + + it('should return results based on search parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/tokens?search=Token1`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + }); + }); + + describe('GET /accounts/:address/roles/tokens/count', () => { + it('should return the total number of tokens with roles for a given address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/tokens/count`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThan(1); + }); + + it('should return results by owner parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/tokens/count?owner=${config.aliceAddress}`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + + it('should return results by canMint parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/tokens/count?canMint=false`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + + it('should return results by canBurn parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/tokens/count?canBurn=false`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + + it('should return results by search parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/tokens/count?search=Token1`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + }); + + describe('GET /accounts/:address/roles/tokens/:identifier', () => { + it('should return token details with roles for a given address and identifier', async () => { + const tokens = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/tokens`); + const identifier = tokens.data[0].identifier; + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/roles/tokens/${identifier}`); + + expect(response.status).toBe(200); + + const expectedProperties = [ + 'type', + 'subType', + 'identifier', + 'name', + 'ticker', + 'owner', + 'decimals', + 'isPaused', + 'transactions', + 'transactionsLastUpdatedAt', + 'transfers', + 'transfersLastUpdatedAt', + 'accounts', + 'accountsLastUpdatedAt', + 'canUpgrade', + 'canMint', + 'canChangeOwner', + 'canAddSpecialRoles', + 'canPause', + 'canFreeze', + 'canWipe', + 'timestamp', + 'mexPairType', + 'ownersHistory', + 'role', + 'canLocalMint', + 'canLocalBurn', + 'canTransfer', + ]; + + for (const property of expectedProperties) { + expect(response.data).toHaveProperty(property); + } + }); + }); + + //TODO: Add tests for the collections endpoint when CS is updated + describe.skip('GET /accounts/:address/collections', () => { + it('should return NFT collections for a specific address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/collections`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + }); + }); + + describe('GET /accounts/:address/stake', () => { + it('should return stake details for a specific address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/stake`); + expect(response.status).toBe(200); + expect(response.data).toHaveProperty('totalStaked'); + }); + }); + + describe('GET /accounts/:address/delegation-legacy', () => { + it('should return delegation details for a specific address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/delegation-legacy`); + expect(response.status).toBe(200); + + const expectedProperties = [ + 'userWithdrawOnlyStake', + 'userWaitingStake', + 'userActiveStake', + 'userUnstakedStake', + 'userDeferredPaymentStake', + 'claimableRewards', + ]; + + for (const property of expectedProperties) { + expect(response.data).toHaveProperty(property); + } + }); + }); + + describe('GET /accounts/:address/deploys', () => { + it('should return deploys details for a given address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/deploys`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + + const properties = [ + 'address', + 'deployTxHash', + 'timestamp', + ]; + + for (const property of properties) { + expect(response.data[0]).toHaveProperty(property); + } + }); + + it('should return paginated results with from and size parameters', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/deploys?from=0&size=1`); + expect(response.status).toBe(200); + expect(response.data.length).toBeLessThanOrEqual(1); + }); + }); + + describe('GET /accounts/:address/deploys/count', () => { + it('should return the total number of deploys for a given address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/deploys/count`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + }); + + describe('GET /accounts/:address/deploys/c alternative', () => { + it('should return the total number of deploys for a given address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/deploys/c`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + }); + + describe('GET /accounts/:address/contracts', () => { + it('should return contracts details for a given address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/contracts`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + }); + + it('should return paginated results with from and size parameters', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/contracts?from=0&size=1`); + expect(response.status).toBe(200); + expect(response.data.length).toBeLessThanOrEqual(1); + }); + }); + + describe('GET /accounts/:address/contracts/count', () => { + it('should return the total number of contracts for a given address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/contracts/count`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + }); + + describe('GET /accounts/:address/contracts/c alternative', () => { + it('should return the total number of contracts for a given address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/contracts/c`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + }); + + describe('GET /accounts/:address/results', () => { + it('should return smart contract results for a given address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/results`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + }); + + it('should return paginated results with from and size parameters', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/results?from=0&size=1`); + expect(response.status).toBe(200); + expect(response.data.length).toBeLessThanOrEqual(1); + }); + + it('should return results with properties', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/results`); + const properties = [ + 'hash', + 'timestamp', + 'nonce', + 'gasLimit', + 'gasPrice', + 'value', + 'sender', + 'receiver', + 'data', + 'prevTxHash', + 'originalTxHash', + 'callType', + 'miniBlockHash', + 'status', + ]; + + for (const property of properties) { + expect(response.data[0]).toHaveProperty(property); + } + }); + }); + + describe('GET /accounts/:address/results/count', () => { + it('should return the total number of smart contract results for a given address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/results/count`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + }); + + describe('GET /accounts/:address/results/:scHash', () => { + it('should return smart contract result for a given address and scHash', async () => { + const results = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/results`); + const scHash = results.data[0].hash; + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/results/${scHash}`); + const properties = [ + 'hash', + 'timestamp', + 'nonce', + 'gasLimit', + 'gasPrice', + 'value', + 'sender', + 'receiver', + 'data', + 'prevTxHash', + 'originalTxHash', + 'callType', + 'miniBlockHash', + 'status', + ]; + + for (const property of properties) { + expect(response.data).toHaveProperty(property); + } + expect(response.status).toBe(200); + }); + }); + + describe('GET /accounts/:address/history', () => { + it('should return account history for a given address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/history`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + + const properties = [ + 'address', + 'balance', + 'timestamp', + 'isSender', + ]; + + for (const property of properties) { + expect(response.data[0]).toHaveProperty(property); + } + }); + + it('should return paginated results with from and size parameters', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/history?from=0&size=1`); + expect(response.status).toBe(200); + expect(response.data.length).toBeLessThanOrEqual(1); + }); + }); + + describe('GET /accounts/:address/history/count', () => { + it('should return the total number of account history for a given address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/history/count`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + }); + + describe('GET /accounts/:address/history/:tokenIdentifier/count', () => { + it('should return the total number of account history for a given address and token identifier', async () => { + const tokens = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/tokens`); + const tokenIdentifier = tokens.data[0].identifier; + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/history/${tokenIdentifier}/count`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + }); + + describe('GET /accounts/:address/esdthistory', () => { + it('should return account esdt history for a given address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/esdthistory`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + }); + + it('should return paginated results with from and size parameters', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/esdthistory?from=0&size=1`); + expect(response.status).toBe(200); + expect(response.data.length).toBeLessThanOrEqual(1); + }); + + it('should return results with properties', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/esdthistory`); + const properties = [ + 'address', + 'balance', + 'timestamp', + 'token', + ]; + + for (const property of properties) { + expect(response.data[0]).toHaveProperty(property); + } + }); + + it('should return results with token parameter', async () => { + const tokens = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/tokens`); + const tokenIdentifier = tokens.data[0].identifier; + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/esdthistory?token=${tokenIdentifier}`); + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(1); + }); + }); + + describe('GET /accounts/:address/esdthistory/count', () => { + it('should return the total number of account esdt history for a given address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/esdthistory/count`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + + it('should return the total number of account esdt history for a given address and token identifier', async () => { + const tokens = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/tokens`); + const tokenIdentifier = tokens.data[0].identifier; + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/esdthistory/count?token=${tokenIdentifier}`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toStrictEqual(1); + }); + }); + + describe('GET /accounts/:address/history/:tokenIdentifier', () => { + it('should return account history for a given address and token identifier', async () => { + const tokens = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/tokens`); + const tokenIdentifier = tokens.data[0].identifier; + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/history/${tokenIdentifier}`); + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(1); + }); + }); + + describe('GET /accounts/:address/transactions', () => { + const properties = [ + 'txHash', + 'gasLimit', + 'gasPrice', + 'gasUsed', + 'miniBlockHash', + 'nonce', + 'receiver', + 'receiverShard', + 'round', + 'sender', + 'senderShard', + 'signature', + 'status', + 'value', + 'fee', + 'timestamp', + 'data', + 'function', + 'action', + ]; + it('should return transactions for a given address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + }); + + it('should return paginated results with from and size parameters', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?from=0&size=2`); + expect(response.status).toBe(200); + expect(response.data.length).toBeLessThanOrEqual(2); + }); + + it('should return transactions with properties', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions`); + + for (const property of properties) { + expect(response.data[0]).toHaveProperty(property); + } + }); + + it('should return transactions with sender parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?sender=${config.aliceAddress}`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + }); + + it('should return transactions with receiver parameter', async () => { + const receiverAddress = 'erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u'; + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?receiver=${receiverAddress}`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + }); + + it('should return transactions with senderShard parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?senderShard=1`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + }); + + it('should return transactions with receiverShard parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?receiverShard=4294967295`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + }); + + it('should return transactions with miniBlockHash parameter', async () => { + const miniBlockHashes = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?size=1`); + const miniBlockHash = miniBlockHashes.data[0].miniBlockHash; + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?miniBlockHash=${miniBlockHash}`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + }); + + it('should return transactions with hashes parameter', async () => { + const hashes = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?size=2`); + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?hashes=${hashes.data[0].txHash},${hashes.data[1].txHash}`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(2); + }); + + it('should return transactions with status parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?status=success`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + }); + + it('should return transactions with function parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?function=issue`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + }); + + it('should return transactions with round parameter', async () => { + const rounds = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?size=1`); + const round = rounds.data[0].round; + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?round=${round}`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + }); + + it('should return transactions with logs when withLogs parameter is used', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?size=50&withLogs=true`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + }); + + it('should return transactions with scResults when withScResults parameter is used', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?size=50&withScResults=true`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + + const hasScResults = response.data.some((transaction: any) => transaction.results && transaction.results.length > 0); + expect(hasScResults).toBe(true); + }); + + it('should return transactions with operations when withOperations parameter is used', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?size=50&withOperations=true`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + + const hasOperations = response.data.some((transaction: any) => transaction.operations && transaction.operations.length > 0); + expect(hasOperations).toBe(true); + }); + + it('should return transactions with block info when withBlockInfo parameter is used', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?size=50&withBlockInfo=true`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + + const hasBlockInfo = response.data.some((transaction: any) => + transaction.senderBlockHash && + transaction.senderBlockNonce && + transaction.receiverBlockHash && + transaction.receiverBlockNonce + ); + expect(hasBlockInfo).toBe(true); + }); + + it('should return 400 Bad Request when size > 50 with withScResults parameter', async () => { + try { + await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?size=51&withScResults=true`); + fail('Should have thrown error'); + } catch (error: any) { + expect(error.response.status).toBe(400); + } + }); + + it('should return 400 Bad Request when size > 50 with withOperations parameter', async () => { + try { + await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?size=51&withOperations=true`); + fail('Should have thrown error'); + } catch (error: any) { + expect(error.response.status).toBe(400); + } + }); + + it('should return 400 Bad Request when size > 50 with withLogs parameter', async () => { + try { + await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?size=51&withLogs=true`); + fail('Should have thrown error'); + } catch (error: any) { + expect(error.response.status).toBe(400); + } + }); + + it('should return 400 Bad Request when size > 50 with withBlockInfo parameter', async () => { + try { + await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?size=51&withBlockInfo=true`); + fail('Should have thrown error'); + } catch (error: any) { + expect(error.response.status).toBe(400); + } + }); + + it('should return transactions with senderOrReceiver parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?senderOrReceiver=${config.aliceAddress}`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + }); + }); + + describe('GET /accounts/:address/transactions/count', () => { + it('should return the total number of transactions for a given address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions/count`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + + it('should return the total number of transactions for a given address with sender parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions/count?sender=${config.aliceAddress}`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + + it('should return the total number of transactions for a given address with receiver parameter', async () => { + const receiverAddress = 'erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u'; + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions/count?receiver=${receiverAddress}`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + + it('should return the total number of transactions for a given address with senderShard parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions/count?senderShard=1`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + + it('should return the total number of transactions for a given address with receiverShard parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions/count?receiverShard=4294967295`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + + it('should return the total number of transactions for a given address with miniBlockHash parameter', async () => { + const miniBlockHashes = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?size=1`); + const miniBlockHash = miniBlockHashes.data[0].miniBlockHash; + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions/count?miniBlockHash=${miniBlockHash}`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toStrictEqual(1); + }); + + it('should return the total number of transactions for a given address with hashes parameter', async () => { + const hashes = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?size=2`); + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions/count?hashes=${hashes.data[0].txHash},${hashes.data[1].txHash}`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toStrictEqual(2); + }); + + it('should return the total number of transactions for a given address with status parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions/count?status=success`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + + it('should return the total number of transactions for a given address with function parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions/count?function=issue`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + + it('should return the total number of transactions for a given address with round parameter', async () => { + const rounds = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions?size=1`); + const round = rounds.data[0].round; + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions/count?round=${round}`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toStrictEqual(1); + }); + + it('should return the total number of transactions for a given address with senderOrReceiver parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transactions/count?senderOrReceiver=${config.aliceAddress}`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + }); + + describe('GET /accounts/:address/transfers', () => { + it('should return transfers for a given address', async () => { + const countResponse = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers/count`); + const expectedCount = countResponse.data; + + expect(expectedCount).toBeGreaterThan(0); + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?size=500`); + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(expectedCount); + }); + + it('should have transfers count / list greater than 0', async () => { + const countResponse = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers/count`); + expect(countResponse.status).toBe(200); + expect(countResponse.data).toBeGreaterThan(0); + + const transfersResponse = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers`); + expect(transfersResponse.status).toBe(200); + expect(transfersResponse.data.length).toBeGreaterThan(0); + }); + + it('should support pagination', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?size=2`); + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(2); + }); + + it('should return transfers with sender parameter', async () => { + const countResponse = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers/count?sender=${config.aliceAddress}`); + const expectedCount = countResponse.data; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?sender=${config.aliceAddress}&size=500`); + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(expectedCount); + + for (const transfer of response.data) { + expect(transfer.sender).toBe(config.aliceAddress); + } + }); + + it('should return transfers with receiver parameter', async () => { + const receiverAddress = 'erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u'; + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?receiver=${receiverAddress}`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + + for (const transfer of response.data) { + expect(transfer.receiver).toBe(receiverAddress); + } + }); + + it('should return transfers with token parameter', async () => { + const accountTokens = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/tokens`); + const token = accountTokens.data[0].identifier; + + const countResponse = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers/count?token=${token}`); + const expectedCount = countResponse.data; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?token=${token}`); + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(expectedCount); + + for (const transfer of response.data) { + expect(transfer.action.arguments.transfers[0].token).toBe(token); + expect(transfer.function).toBe('ESDTTransfer'); + } + }); + + it('should return transfers with senderShard parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?senderShard=1`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + + for (const transfer of response.data) { + expect(transfer.senderShard).toBe(1); + } + }); + + it('should return transfers with receiverShard parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?receiverShard=4294967295`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + + for (const transfer of response.data) { + expect(transfer.receiverShard).toBe(4294967295); + } + }); + + it('should return transfers with miniBlockHash parameter', async () => { + const miniBlockHashes = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?size=1`); + const miniBlockHash = miniBlockHashes.data[0].miniBlockHash; + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?miniBlockHash=${miniBlockHash}`); + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(1); + + for (const transfer of response.data) { + expect(transfer.miniBlockHash).toBe(miniBlockHash); + } + }); + + it('should return transfers with hashes parameter', async () => { + const hashes = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?size=2`); + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?hashes=${hashes.data[0].txHash},${hashes.data[1].txHash}`); + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(2); + expect(response.data).toContainEqual(hashes.data[0]); + expect(response.data).toContainEqual(hashes.data[1]); + }); + + it('should return transfers with status parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?status=success`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + + for (const transfer of response.data) { + expect(transfer.status).toBe('success'); + } + }); + + it('should return transfers with round parameter', async () => { + const rounds = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?size=1`); + const round = rounds.data[0].round; + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?round=${round}`); + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(1); + + for (const transfer of response.data) { + expect(transfer.round).toBe(round); + } + }); + + it('should return transfers with senderOrReceiver parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?senderOrReceiver=${config.aliceAddress}`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + + for (const transfer of response.data) { + expect(transfer.sender === config.aliceAddress || transfer.receiver === config.aliceAddress).toBe(true); + } + }); + + it('should return transfers with withLogs parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?withLogs=true`); + expect(response.status).toBe(200); + + const hasLogs = response.data.some((transfer: any) => transfer.logs); + expect(hasLogs).toBe(true); + + const hasValidLogs = response.data.some((transfer: any) => { + if (!transfer.logs) { + return false; + } + + const hasRequiredLogProps = ['events', 'address'].every(prop => + Object.prototype.hasOwnProperty.call(transfer.logs, prop) + ); + if (!hasRequiredLogProps) { + return false; + } + + if (!Array.isArray(transfer.logs.events)) { + return false; + } + + return transfer.logs.events.some((event: any) => + ['address', 'identifier', 'topics', 'data'].every(prop => + Object.prototype.hasOwnProperty.call(event, prop) + ) + ); + }); + + expect(hasValidLogs).toBe(true); + }); + + it('should return transfers with withOperations parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?withOperations=true`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + const hasOperations = response.data.some((transfer: any) => transfer.operations && transfer.operations.length > 0); + expect(hasOperations).toBe(true); + + const transferWithOperations = response.data.find((transfer: any) => transfer.operations && transfer.operations.length > 0); + expect(transferWithOperations.operations).toBeDefined(); + expect(Array.isArray(transferWithOperations.operations)).toBe(true); + expect(transferWithOperations.operations.length).toBeGreaterThan(0); + + const operation = transferWithOperations.operations[0]; + const expectedProperties = ['id', 'action', 'type', 'sender', 'receiver', 'value']; + const foundProperties = expectedProperties.filter(prop => prop in operation); + expect(foundProperties.length).toBeGreaterThan(0); + expect(foundProperties.length).toBeLessThanOrEqual(expectedProperties.length); + }); + + it('should return transfers with expected properties', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?size=1`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + + const expectedProperties = [ + 'txHash', + 'gasLimit', + 'gasPrice', + 'gasUsed', + 'miniBlockHash', + 'nonce', + 'receiver', + 'receiverShard', + 'round', + 'sender', + 'senderShard', + 'signature', + 'status', + 'value', + 'fee', + 'timestamp', + 'function', + 'action', + 'type', + 'data', + ]; + + const transfer = response.data[0]; + for (const property of expectedProperties) { + expect(transfer).toHaveProperty(property); + } + + expect(transfer.action).toHaveProperty('category'); + expect(transfer.action).toHaveProperty('name'); + expect(transfer.action).toHaveProperty('description'); + }); + }); + + describe('GET /accounts/:address/transfers/count', () => { + it('should return the total number of transfers for a given address', async () => { + const accountTransfers = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?size=500`); + const expectedCount = accountTransfers.data.length; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers/count`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toStrictEqual(expectedCount); + }); + + it('should return the total number of transfers for a given address with sender parameter', async () => { + const accountSenderTransfers = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?sender=${config.aliceAddress}&size=500`); + const expectedCount = accountSenderTransfers.data.length; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers/count?sender=${config.aliceAddress}`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toStrictEqual(expectedCount); + }); + + it('should return the total number of transfers for a given address with receiver parameter', async () => { + const accountReceiverTransfers = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?receiver=${config.aliceAddress}&size=500`); + const expectedCount = accountReceiverTransfers.data.length; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers/count?receiver=${config.aliceAddress}`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toStrictEqual(expectedCount); + }); + + it('should return the total number of transfers for a given address with token parameter', async () => { + const accountTokens = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/tokens`); + const token = accountTokens.data[0].identifier; + + const accountTokenTransfers = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?token=${token}`); + const expectedCount = accountTokenTransfers.data.length; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers/count?token=${token}`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toStrictEqual(expectedCount); + }); + + it('should return the total number of transfers for a given address with senderShard parameter', async () => { + const accountSenderShardTransfers = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?senderShard=1&size=500`); + const expectedCount = accountSenderShardTransfers.data.length; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers/count?senderShard=1`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toStrictEqual(expectedCount); + }); + + it('should return the total number of transfers for a given address with receiverShard parameter', async () => { + const accountReceiverShardTransfers = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?receiverShard=4294967295`); + const expectedCount = accountReceiverShardTransfers.data.length; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers/count?receiverShard=4294967295`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toStrictEqual(expectedCount); + }); + + it('should return the total number of transfers for a given address with miniBlockHash parameter', async () => { + const miniBlockHashes = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?size=1`); + const miniBlockHash = miniBlockHashes.data[0].miniBlockHash; + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers/count?miniBlockHash=${miniBlockHash}`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toStrictEqual(1); + }); + + it('should return the total number of transfers for a given address with hashes parameter', async () => { + const hashes = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?size=2`); + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers/count?hashes=${hashes.data[0].txHash},${hashes.data[1].txHash}`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toStrictEqual(2); + }); + + it('should return the total number of transfers for a given address with status parameter', async () => { + const accountSuccessTransfers = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?status=success&size=500`); + const expectedCount = accountSuccessTransfers.data.length; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers/count?status=success`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toStrictEqual(expectedCount); + }); + + it('should return the total number of transfers for a given address with round parameter', async () => { + const rounds = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?size=1`); + const round = rounds.data[0].round; + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers/count?round=${round}`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toStrictEqual(1); + }); + + it('should return the total number of transfers for a given address with senderOrReceiver parameter', async () => { + const accountSenderOrReceiverTransfers = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?senderOrReceiver=${config.aliceAddress}&size=500`); + const expectedCount = accountSenderOrReceiverTransfers.data.length; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers/count?senderOrReceiver=${config.aliceAddress}`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toStrictEqual(expectedCount); + }); + + it('should return the total number for a given status', async () => { + const accountSuccessTransfers = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers?status=success&size=500`); + const expectedCount = accountSuccessTransfers.data.length; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/transfers/count?status=success`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toStrictEqual(expectedCount); + }); + }); + + describe('GET /accounts/:address/nfts', () => { + it('should return accounts nfts', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts`); + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(25); + }); + + it('should return accounts nfts paginated', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?from=0&size=10`); + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(10); + }); + + it('should return different results for different from values', async () => { + const firstResponse = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?from=0&size=1`); + const secondResponse = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?from=1&size=1`); + + expect(firstResponse.status).toBe(200); + expect(secondResponse.status).toBe(200); + expect(firstResponse.data.length).toBe(1); + expect(secondResponse.data.length).toBe(1); + expect(firstResponse.data[0].identifier).not.toBe(secondResponse.data[0].identifier); + }); + + it('should return accounts nfts for a size > 25', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?size=26`); + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(26); + }); + + it('should return accounts nfts filtered by search parameter', async () => { + const accountNfts = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?size=1`); + const nft = accountNfts.data[0]; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?search=${nft.identifier}`); + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(1); + expect(response.data[0].identifier).toStrictEqual(nft.identifier); + }); + + it('should return accounts nfts filtered by identifiers parameter', async () => { + const accountNfts = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?size=2`); + const nfts = accountNfts.data; + const firstNft = nfts[0].identifier; + const secondNft = nfts[1].identifier; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?identifiers=${firstNft},${secondNft}`); + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(2); + expect(response.data[0].identifier).toStrictEqual(firstNft); + expect(response.data[1].identifier).toStrictEqual(secondNft); + }); + + it('should return accounts nfts filtered by type parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?type=${NftType.NonFungibleESDT}`); + expect(response.status).toBe(200); + + for (const nft of response.data) { + expect(nft.type).toStrictEqual(NftType.NonFungibleESDT); + } + }); + + it('should return accounts sfts filtered by type parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?type=${NftType.SemiFungibleESDT}`); + expect(response.status).toBe(200); + + for (const nft of response.data) { + expect(nft.type).toStrictEqual(NftType.SemiFungibleESDT); + } + }); + + it('should return accounts MetaESDTs filtered by type parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?type=${NftType.MetaESDT}`); + expect(response.status).toBe(200); + + for (const nft of response.data) { + expect(nft.type).toStrictEqual(NftType.MetaESDT); + } + }); + + it('should return accounts nftsV2 filtered by subType parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?subType=${NftSubType.NonFungibleESDTv2}`); + expect(response.status).toBe(200); + + for (const nft of response.data) { + expect(nft.subType).toStrictEqual(NftSubType.NonFungibleESDTv2); + } + }); + + it('should return accounts sft filtered by subType parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?subType=${NftSubType.SemiFungibleESDT}`); + expect(response.status).toBe(200); + + for (const nft of response.data) { + expect(nft.subType).toStrictEqual(NftSubType.SemiFungibleESDT); + } + }); + + it('should return accounts MetaESDTs filtered by subType parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?subType=${NftSubType.MetaESDT}`); + expect(response.status).toBe(200); + + for (const nft of response.data) { + expect(nft.subType).toStrictEqual(NftSubType.MetaESDT); + } + }); + + it('should return accounts nfts filtered by collection parameter', async () => { + const accountCollections = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/collections`); + const collection = accountCollections.data[0].collection; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?collection=${collection}`); + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + }); + + it('should return accounts nfts filtered by collections parameter', async () => { + const accountCollections = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/collections?size=2`); + const collections = accountCollections.data.map((c: any) => c.collection).join(','); + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?collections=${collections}`); + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(10); + }); + + it('should return accounts nfts filtered by name parameter', async () => { + const accountNfts = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?size=1`); + const nftName = accountNfts.data[0].name; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?name=${nftName}`); + expect(response.status).toBe(200); + + for (const nft of response.data) { + expect(nft.name).toStrictEqual(nftName); + } + }); + + it('should return accounts nfts filtered by tags parameter', async () => { + const accountNfts = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?size=1`); + const nftTags = accountNfts.data[0].tags; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?tags=${nftTags}`); + expect(response.status).toBe(200); + + for (const nft of response.data) { + expect(nft.tags).toEqual(nftTags); + } + }); + + it('should return accounts nfts filtered by creator parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?creator=${config.aliceAddress}`); + expect(response.status).toBe(200); + + for (const nft of response.data) { + expect(nft.creator).toStrictEqual(config.aliceAddress); + } + }); + + it('should return accounts nfts filtered by hasUris parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?hasUris=true`); + expect(response.status).toBe(200); + + for (const nft of response.data) { + expect(nft.uris).toBeDefined(); + expect(nft.uris.length).toBeGreaterThan(0); + expect(nft.uris).toEqual([ + "aHR0cHM6Ly9leGFtcGxlLmNvbS9uZnQucG5n", + "aHR0cHM6Ly9leGFtcGxlLmNvbS9uZnQuanNvbg==", + ]); + } + }); + + it('should return acoount SFT filtered by withSupply parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?withSupply=true&type=${NftType.SemiFungibleESDT}`); + expect(response.status).toBe(200); + + for (const nft of response.data) { + expect(nft.type).toStrictEqual(NftType.SemiFungibleESDT); + expect(nft.supply).toBeDefined(); + } + }); + + it('should return acoount NFT filtered by withSupply parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?withSupply=true&type=${NftType.NonFungibleESDT}`); + expect(response.status).toBe(200); + + for (const nft of response.data) { + expect(nft.type).toStrictEqual(NftType.NonFungibleESDT); + expect(nft.supply).not.toBeDefined(); + } + }); + + it('should return acoount MetaESDT filtered by withSupply parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?withSupply=true&type=${NftType.MetaESDT}`); + expect(response.status).toBe(200); + + for (const nft of response.data) { + expect(nft.type).toStrictEqual(NftType.MetaESDT); + expect(nft.supply).toBeDefined(); + } + }); + + it('should return accounts nfts without MetaESDTs', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?excludeMetaESDT=true`); + expect(response.status).toBe(200); + + for (const nft of response.data) { + expect(nft.type).not.toStrictEqual(NftType.MetaESDT); + } + + expect(response.data.every((nft: any) => + [NftType.NonFungibleESDT, NftType.SemiFungibleESDT].includes(nft.type) + )).toBe(true); + }); + }); + + describe('GET /accounts/:address/nfts/count', () => { + it('should return the total number of nfts for a given address', async () => { + const accountNfts = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?size=100`); + const expectedCount = accountNfts.data.length; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/count`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(expectedCount); + }); + + it('should return the total number of nfts for a given address filtered by search parameter', async () => { + const accountNfts = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?size=1&type=${NftType.NonFungibleESDT}`); + const nft = accountNfts.data[0]; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/count?search=${nft.name}`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + + it('should return the total number of nfts for a given address filtered by identifiers parameter', async () => { + const accountNfts = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?size=2`); + const nfts = accountNfts.data; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/count?identifiers=${nfts[0].identifier},${nfts[1].identifier}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(2); + }); + + it('should return the total number of nfts for a given address filtered by type parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/count?type=${NftType.NonFungibleESDT}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(10); + }); + + it('should return the total number of sfts for a given address filtered by type parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/count?type=${NftType.SemiFungibleESDT}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(10); + }); + + it('should return the total number of metaesdt for a given address filtered by type parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/count?type=${NftType.MetaESDT}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(10); + }); + + it('should return the total number of nfts for a given address filtered by subType parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/count?subType=${NftSubType.NonFungibleESDTv2}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(10); + }); + + it('should return the total number of sfts for a given address filtered by subType parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/count?subType=${NftSubType.SemiFungibleESDT}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(10); + }); + + it('should return the total number of metaesdt for a given address filtered by subType parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/count?subType=${NftSubType.MetaESDT}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(10); + }); + + it('should return the total number of nfts for a given address filtered by collection parameter', async () => { + const accountCollections = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/collections`); + const collection = accountCollections.data[0].collection; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/count?collection=${collection}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(5); + }); + + it('should return the total number of nfts for a given address filtered by collections parameter', async () => { + const accountCollections = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/collections?size=2`); + const collections = accountCollections.data.map((c: any) => c.collection).join(','); + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/count?collections=${collections}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(10); + }); + + it('should return the total number of nfts for a given address filtered by name parameter', async () => { + const accountNfts = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?size=1`); + const nftName = accountNfts.data[0].name; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/count?name=${nftName}`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + }); + + describe('GET /accounts/:address/nfts/c alternative', () => { + it('should return the total number of nfts for a given address', async () => { + const accountNfts = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?size=100`); + const expectedCount = accountNfts.data.length; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/c`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(expectedCount); + }); + + it('should return the total number of nfts for a given address filtered by search parameter', async () => { + const accountNfts = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?size=2&type=${NftType.NonFungibleESDT}`); + const nft = accountNfts.data[0]; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/c?search=${nft.name}`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + + it('should return the total number of nfts for a given address filtered by identifiers parameter', async () => { + const accountNfts = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?size=2`); + const nfts = accountNfts.data; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/c?identifiers=${nfts[0].identifier},${nfts[1].identifier}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(2); + }); + + it('should return the total number of nfts for a given address filtered by type parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/c?type=${NftType.NonFungibleESDT}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(10); + }); + + it('should return the total number of sfts for a given address filtered by type parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/c?type=${NftType.SemiFungibleESDT}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(10); + }); + + it('should return the total number of metaesdt for a given address filtered by type parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/c?type=${NftType.MetaESDT}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(10); + }); + + it('should return the total number of nfts for a given address filtered by subType parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/c?subType=${NftSubType.NonFungibleESDTv2}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(10); + }); + + it('should return the total number of sfts for a given address filtered by subType parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/c?subType=${NftSubType.SemiFungibleESDT}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(10); + }); + + it('should return the total number of metaesdt for a given address filtered by subType parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/c?subType=${NftSubType.MetaESDT}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(10); + }); + + it('should return the total number of nfts for a given address filtered by collection parameter', async () => { + const accountCollections = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/collections`); + const collection = accountCollections.data[0].collection; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/c?collection=${collection}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(5); + }); + + it('should return the total number of nfts for a given address filtered by collections parameter', async () => { + const accountCollections = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/collections?size=2`); + const collections = accountCollections.data.map((c: any) => c.collection).join(','); + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/c?collections=${collections}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(10); + }); + + it('should return the total number of nfts for a given address filtered by name parameter', async () => { + const accountNfts = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?size=1`); + const nftName = accountNfts.data[0].name; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/c?name=${nftName}`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(1); + }); + }); + + describe('GET /accounts/:address/nfts/:nft', () => { + it('should return the nft details for a given address and nft', async () => { + const accountNfts = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?size=1`); + const nft = accountNfts.data[0]; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/${nft.identifier}`); + expect(response.status).toBe(200); + expect(response.data).toBeDefined(); + expect(response.data.identifier).toStrictEqual(nft.identifier); + }); + + it('should return the MetaESDT details with the proper fields', async () => { + const accountNfts = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?size=1&type=${NftType.MetaESDT}`); + const nft = accountNfts.data[0]; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/${nft.identifier}`); + expect(response.status).toBe(200); + + const expectedFields = [ + 'identifier', + 'collection', + 'type', + 'subType', + 'name', + 'creator', + 'tags', + ]; + + for (const field of expectedFields) { + expect(response.data).toHaveProperty(field); + } + }); + + it('should return the NonFungibleESDT details with the proper fields', async () => { + const accountNfts = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?size=1&type=${NftType.NonFungibleESDT}`); + const nft = accountNfts.data[0]; + + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts/${nft.identifier}?fields=identifier,name,type,subType,creator,collection,tags,uris,supply`); + expect(response.status).toBe(200); + + const expectedFields = [ + 'identifier', + 'collection', + 'type', + 'subType', + 'name', + 'creator', + 'uris', + 'tags', + ]; + + for (const field of expectedFields) { + expect(response.data).toHaveProperty(field); + } + }); + }); +}); diff --git a/src/test/chain-simulator/applications.cs-e2e.ts b/src/test/chain-simulator/applications.cs-e2e.ts new file mode 100644 index 000000000..e496ecdc6 --- /dev/null +++ b/src/test/chain-simulator/applications.cs-e2e.ts @@ -0,0 +1,76 @@ +import axios from "axios"; +import { config } from "./config/env.config"; + +describe('Applications e2e tests with chain simulator', () => { + describe('GET /applications', () => { + it('should return status code 200 and a list of applications', async () => { + const response = await axios.get(`${config.apiServiceUrl}/applications`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + }); + + it('should support pagination', async () => { + const response = await axios.get(`${config.apiServiceUrl}/applications?from=0&size=1`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + expect(response.data.length).toStrictEqual(1); + }); + + it('should return applications with expected properties', async () => { + const response = await axios.get(`${config.apiServiceUrl}/applications`); + const application = response.data[0]; + + const requiredProps = [ + 'contract', + 'deployer', + 'owner', + 'codeHash', + 'timestamp', + ]; + + for (const prop of requiredProps) { + expect(application).toHaveProperty(prop); + } + }); + + it('should return applications with txCount field if withTxCount query param is true', async () => { + const response = await axios.get(`${config.apiServiceUrl}/applications?withTxCount=true`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + expect(response.data[0]).toHaveProperty('txCount'); + }); + }); + + describe('GET /applications/:address', () => { + it('should return status code 200 and an application', async () => { + const application = await axios.get(`${config.apiServiceUrl}/applications`); + const response = await axios.get(`${config.apiServiceUrl}/applications/${application.data[0].contract}`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Object); + }); + + it('should return application details with txCount and balance fields', async () => { + const application = await axios.get(`${config.apiServiceUrl}/applications`); + const response = await axios.get(`${config.apiServiceUrl}/applications/${application.data[0].contract}`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Object); + expect(response.data).toHaveProperty('txCount'); + expect(response.data).toHaveProperty('balance'); + }); + }); + + describe('GET /applications/count', () => { + it('should return the number of applications', async () => { + const response = await axios.get(`${config.apiServiceUrl}/applications/count`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + }); + + it('should return the number of applications with the given timestamp ( before )', async () => { + const applicationsCount = await axios.get(`${config.apiServiceUrl}/applications`); + const response = await axios.get(`${config.apiServiceUrl}/applications/count?before=${applicationsCount.data[0].timestamp}`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + }); + }); +}); diff --git a/src/test/chain-simulator/blocks.cs-e2e.ts b/src/test/chain-simulator/blocks.cs-e2e.ts new file mode 100644 index 000000000..203608079 --- /dev/null +++ b/src/test/chain-simulator/blocks.cs-e2e.ts @@ -0,0 +1,155 @@ +import axios from 'axios'; +import { config } from './config/env.config'; + +describe('Blocks e2e tests with chain simulator', () => { + describe('GET /blocks', () => { + it('should return status code 200', async () => { + const response = await axios.get(`${config.apiServiceUrl}/blocks`); + expect(response.status).toBe(200); + }); + + it('should handle invalid block requests gracefully', async () => { + try { + await axios.get(`${config.apiServiceUrl}/blocks/invalid`); + } catch (error: any) { + expect(error.response.status).toBe(400); + } + }); + }); + + describe('GET /blocks/count', () => { + it('should return blocks count', async () => { + const response = await axios.get(`${config.apiServiceUrl}/blocks/count`); + const count = response.data; + + expect(count).toBeGreaterThan(0); + }); + + it('should return blocks count filter by shard', async () => { + const response = await axios.get( + `${config.apiServiceUrl}/blocks/count?shard=1`, + ); + const count = response.data; + + expect(count).toBeGreaterThan(0); + }); + + it('should return blocks count filter by epoch', async () => { + const response = await axios.get( + `${config.apiServiceUrl}/blocks/count?epoch=1`, + ); + const count = response.data; + + expect(count).toBeGreaterThan(1); + }); + + it('should return blocks count 0 if epoch value is to high', async () => { + const response = await axios.get( + `${config.apiServiceUrl}/blocks/count?epoch=10000`, + ); + const count = response.data; + + expect(count).toStrictEqual(0); + }); + + it('should return blocks count filter by nonce', async () => { + const response = await axios.get( + `${config.apiServiceUrl}/blocks/count?nonce=0`, + ); + const count = response.data; + + expect(count).toBeGreaterThan(0); + }); + + it('should return blocks count 0 if nonce value is to high', async () => { + const response = await axios.get( + `${config.apiServiceUrl}/blocks/count?nonce=10000`, + ); + const count = response.data; + + expect(count).toStrictEqual(0); + }); + }); + + describe('GET /blocks filter tests', () => { + it('should support pagination', async () => { + const response = await axios.get(`${config.apiServiceUrl}/blocks?size=10`); + const blocks = response.data; + + expect(blocks).toBeInstanceOf(Array); + expect(blocks.length).toBeLessThanOrEqual(10); + }); + + it('should filter blocks by shard', async () => { + const response = await axios.get(`${config.apiServiceUrl}/blocks?shard=1`); + const blocks = response.data; + + for (const block of blocks) { + expect(block.shard).toBe(1); + } + }); + + it('should filter blocks by epoch', async () => { + const response = await axios.get(`${config.apiServiceUrl}/blocks?epoch=2`); + const blocks = response.data; + + for (const block of blocks) { + expect(block.epoch).toBe(2); + } + }); + }); + + describe('GET /blocks/latest', () => { + it('should return the latest block data', async () => { + const response = await axios.get(`${config.apiServiceUrl}/blocks/latest`); + const block = response.data; + + const expectedProperties = [ + 'hash', + 'epoch', + 'nonce', + 'prevHash', + 'pubKeyBitmap', + 'round', + 'shard', + 'size', + 'sizeTxs', + 'stateRootHash', + 'timestamp', + 'txCount', + 'gasConsumed', + 'gasRefunded', + 'gasPenalized', + 'maxGasLimit', + ]; + + for (const property of expectedProperties) { + expect(block).toHaveProperty(property); + expect(block[property]).not.toBeNull(); + } + + const typeValidation = { + hash: 'string', + epoch: 'number', + nonce: 'number', + prevHash: 'string', + pubKeyBitmap: 'string', + round: 'number', + shard: 'number', + size: 'number', + sizeTxs: 'number', + stateRootHash: 'string', + timestamp: 'number', + txCount: 'number', + gasConsumed: 'number', + gasRefunded: 'number', + gasPenalized: 'number', + maxGasLimit: 'number', + }; + + Object.entries(typeValidation).forEach(([key, type]) => { + expect(typeof block[key]).toBe(type); + }); + }); + }); +}); diff --git a/src/test/chain-simulator/collections.cs-e2e.ts b/src/test/chain-simulator/collections.cs-e2e.ts new file mode 100644 index 000000000..4f05aa317 --- /dev/null +++ b/src/test/chain-simulator/collections.cs-e2e.ts @@ -0,0 +1,1314 @@ +import axios from 'axios'; +import { config } from './config/env.config'; +import { NftType } from 'src/common/indexer/entities/nft.type'; + +describe('Collections e2e tests with chain simulator', () => { + describe('GET /collections', () => { + it('should return status code 200', async () => { + const response = await axios.get(`${config.apiServiceUrl}/collections`); + expect(response.status).toBe(200); + }); + + it('should support pagination', async () => { + const response = await axios.get(`${config.apiServiceUrl}/collections?size=2`); + expect(response.status).toBe(200); + expect(response.data.length).toBe(2); + }); + + it('should filter by search term', async () => { + const response = await axios.get(`${config.apiServiceUrl}/collections?search=NFTCollection1`); + expect(response.status).toBe(200); + expect(response.data.some((collection: any) => collection.name.includes('NFTCollection1'))).toBe(true); + }); + + it('should filter by identifiers', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=2`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + const response = await axios.get(`${config.apiServiceUrl}/collections?identifiers=${[collection[0], collection[1]]}`); + + expect(response.status).toBe(200); + expect(response.data.length).toBe(2); + }); + + it('should filter by type', async () => { + const response = await axios.get(`${config.apiServiceUrl}/collections?type=NonFungibleESDT`); + expect(response.status).toBe(200); + expect(response.data.every((collection: any) => collection.type === 'NonFungibleESDT')).toBe(true); + }); + + it('should exclude MetaESDT collections when specified', async () => { + const response = await axios.get(`${config.apiServiceUrl}/collections?excludeMetaESDT=true`); + expect(response.status).toBe(200); + expect(response.data.every((collection: any) => collection.type !== 'MetaESDT')).toBe(true); + }); + + it('should sort collections', async () => { + const response = await axios.get(`${config.apiServiceUrl}/collections?sort=timestamp&order=desc`); + expect(response.status).toBe(200); + + const timestamps = response.data.map((collection: any) => collection.timestamp); + const sortedTimestamps = [...timestamps].sort((a, b) => b - a); + expect(timestamps).toEqual(sortedTimestamps); + }); + }); + + describe('GET /collections/count', () => { + it('should return status code 200', async () => { + const response = await axios.get(`${config.apiServiceUrl}/collections/count`); + + expect(response.status).toBe(200); + }); + + it('should return total count of collections', async () => { + const response = await axios.get(`${config.apiServiceUrl}/collections/count`); + + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(0); + expect(typeof response.data).toBe('number'); + }); + + it('should return filtered collection count by search term', async () => { + const searchTerm = 'NFTCollection1'; + const response = await axios.get(`${config.apiServiceUrl}/collections/count?search=${searchTerm}`); + + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(0); + expect(typeof response.data).toBe('number'); + }); + + it('should return filtered collection count by type', async () => { + const type = NftType.NonFungibleESDT; + const response = await axios.get(`${config.apiServiceUrl}/collections/count?type=${type}`); + + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(0); + expect(typeof response.data).toBe('number'); + }); + }); + + describe('GET /collections/c (alternative endpoint)', () => { + it('should return status code 200', async () => { + const response = await axios.get(`${config.apiServiceUrl}/collections/c`); + + expect(response.status).toBe(200); + }); + + it('should return total count of collections', async () => { + const response = await axios.get(`${config.apiServiceUrl}/collections/c`); + + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(0); + expect(typeof response.data).toBe('number'); + }); + + it('should return filtered collection count by search term', async () => { + const searchTerm = 'NFTCollection1'; + const response = await axios.get(`${config.apiServiceUrl}/collections/c?search=${searchTerm}`); + + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(0); + expect(typeof response.data).toBe('number'); + }); + + it('should return filtered collection count by type', async () => { + const type = NftType.NonFungibleESDT; + const response = await axios.get(`${config.apiServiceUrl}/collections/c?type=${type}`); + + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(0); + expect(typeof response.data).toBe('number'); + }); + }); + + describe('GET /collections/:collection', () => { + it('should return status code 200', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}`); + + expect(response.status).toBe(200); + expect(response.data.collection).toBe(collection[0]); + }); + }); + + describe('GET /collections/:collections/nfts', () => { + it('should return all nfts for a collection', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + }); + + it('should support pagination', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts?from=0&size=1`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(1); + }); + + it('should return different NFTs with same pagination size', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const firstSet = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts?from=0&size=1`); + const secondSet = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts?from=1&size=1`); + + expect(firstSet.status).toBe(200); + expect(secondSet.status).toBe(200); + + expect(firstSet.data.length).toStrictEqual(1); + expect(secondSet.data.length).toStrictEqual(1); + + expect(firstSet.data[0].identifier).not.toEqual(secondSet.data[0].identifier); + }); + + it('should return nfts with search term', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const collectionNft = await axios.get(`${config.apiServiceUrl}/collections/${collection}/nfts`); + const collectionNftName = collectionNft.data.map((nft: any) => nft.name); + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts?search=${collectionNftName[0]}`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(1); + }); + + it('should return nfts by identifiers', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=2&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const collectionNft = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts`); + const collectionNftIdentifiers = collectionNft.data.map((nft: any) => nft.identifier); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts?identifiers=${[collectionNftIdentifiers[0], collectionNftIdentifiers[1]]}`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(2); + }); + + it('should return nfts with name', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const collectionNft = await axios.get(`${config.apiServiceUrl}/collections/${collection}/nfts`); + const collectionNftName = collectionNft.data.map((nft: any) => nft.name); + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts?search=${collectionNftName[0]}`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(1); + }); + + it('should return nfts with tags', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts?tags=test`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + }); + + it('should return nfts with creator', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts?creator=${config.aliceAddress}`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + }); + + it('should return nfts with isWhitelistedStorage false', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts?isWhitelistedStorage=false`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + }); + + it('should return nfts that have uris', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts?hasUris=true`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + + expect(response.data.every((nft: any) => + nft.uris && + Array.isArray(nft.uris) && + nft.uris.includes('aHR0cHM6Ly9leGFtcGxlLmNvbS9uZnQucG5n') && + nft.uris.includes('aHR0cHM6Ly9leGFtcGxlLmNvbS9uZnQuanNvbg==') + )).toBe(true); + }); + + it('should return nfts with nonceBefore', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts?nonceBefore=1`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(1); + expect(response.data[0].nonce).toBe(1); + }); + + it('should return nfts with nonceBefore', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts?nonceBefore=2`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(2); + expect(response.data[0].nonce).toBe(2); + expect(response.data[1].nonce).toBe(1); + }); + + it('should return nfts with nonceAfter', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts?nonceAfter=2`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(4); + expect(response.data[0].nonce).toBe(5); + expect(response.data[1].nonce).toBe(4); + expect(response.data[2].nonce).toBe(3); + expect(response.data[3].nonce).toBe(2); + }); + + it('should return nfts with withOwner', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts?withOwner=true`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + expect(response.data.supply).toBeUndefined(); + + expect(response.data.every((nft: any) => nft.owner === config.aliceAddress)).toBe(true); + expect(response.data.every((nft: any) => nft.type === NftType.NonFungibleESDT)).toBe(true); + }); + + it('should return nfts with withSupply', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=SemiFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts?withSupply=true`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + expect(response.data.owner).toBeUndefined(); + + expect(response.data.every((nft: any) => nft.supply === "10")).toBe(true); + expect(response.data.every((nft: any) => nft.type === NftType.SemiFungibleESDT)).toBe(true); + }); + }); + + describe('GET /collections/:collection/nfts/count', () => { + it('should return nfts count for a collection', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts/count`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(5); + }); + + it('should return nfts count for a collection with search term', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const collectionNft = await axios.get(`${config.apiServiceUrl}/collections/${collection}/nfts`); + const collectionNftName = collectionNft.data.map((nft: any) => nft.name); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts/count?search=${collectionNftName[0]}`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(1); + }); + + it('should return nfts count for a collection with name', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const collectionNft = await axios.get(`${config.apiServiceUrl}/collections/${collection}/nfts`); + const collectionNftName = collectionNft.data.map((nft: any) => nft.name); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts/count?name=${collectionNftName[0]}`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(1); + }); + + it('should return nfts count for a collection with tags', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts/count?tags=test`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(5); + }); + + it('should return nfts count for a collection with identifiers', async () => { + const collectionsIdentifiers = await axios + .get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const collectionNft = await axios + .get(`${config.apiServiceUrl}/collections/${collection}/nfts`); + + const collectionNftIdentifiers = collectionNft.data.map((nft: any) => nft.identifier); + + const response = await axios + .get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts/count?identifiers=${[collectionNftIdentifiers[0], collectionNftIdentifiers[1]]}`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(2); + }); + + it('should return nfts count for a collection with creator', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts/count?creator=${config.aliceAddress}`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(5); + }); + + it('should return nfts count for a collection with isWhitelistedStorage', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts/count?isWhitelistedStorage=false`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(5); + }); + + it('should return nfts count for a collection with hasUris', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts/count?hasUris=true`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(5); + }); + + it('should return nfts count for a collection with nonceBefore', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const firstSet = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts/count?nonceBefore=1`); + const secondSet = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts/count?nonceBefore=2`); + + expect(firstSet.status).toBe(200); + expect(secondSet.status).toBe(200); + expect(firstSet.data).toStrictEqual(1); + expect(secondSet.data).toStrictEqual(2); + }); + + it('should return nfts count for a collection with nonceAfter', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/nfts/count?nonceAfter=2`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(4); + }); + }); + + describe('GET /collections/:collection/accounts', () => { + it('should return accounts for a collection', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/accounts`); + + for (const account of response.data) { + expect(account.address).toBe(config.aliceAddress); + expect(account.balance).toStrictEqual("1"); + } + }); + + it('should return accounts for a collection with from and size', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/accounts?from=0&size=1`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(1); + + for (const account of response.data) { + expect(account.address).toBe(config.aliceAddress); + expect(account.balance).toStrictEqual("1"); + } + }); + + it('should return accounts for a collection with identifier', async () => { + const collectionsIdentifiers = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collection = collectionsIdentifiers.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collection[0]}/accounts?identifier=${collection[0]}`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + + for (const account of response.data) { + expect(account.address).toBe(config.aliceAddress); + expect(account.balance).toStrictEqual("1"); + } + }); + }); + + describe('GET /collections/:collection/transactions', () => { + it('should return transactions for a collection of type NFT', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + }); + + it('should return transactions for a collection of type SFT', async () => { + const collectionSFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=SemiFungibleESDT`); + const collectionSFTDetails = collectionSFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionSFTDetails[0]}/transactions`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + }); + + it('should return transactions for a collection of type MetaESDT', async () => { + const collectionMetaESDT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=MetaESDT`); + const collectionMetaESDTDetails = collectionMetaESDT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionMetaESDTDetails[0]}/transactions`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + }); + + it('should return transactions for a collection of type NFT and contains properties', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions`); + + expect(response.status).toBe(200); + + const expectedProps = [ + 'txHash', + 'gasLimit', + 'gasPrice', + 'gasUsed', + 'miniBlockHash', + 'nonce', + 'receiver', + 'receiverShard', + 'round', + 'sender', + 'senderShard', + 'signature', + 'status', + 'value', + 'fee', + 'timestamp', + 'data', + 'function', + 'action', + ]; + + for (const transaction of response.data) { + for (const prop of expectedProps) { + expect(transaction).toHaveProperty(prop); + } + } + }); + + it('should return transactions for a collection of type NFT with a specific sender', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions?sender=${config.aliceAddress}`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + + for (const transaction of response.data) { + expect(transaction.sender).toStrictEqual(config.aliceAddress); + } + }); + + it('should return transactions for a collection of type NFT with a specific receiver', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions?receiver=${config.aliceAddress}`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + + for (const transaction of response.data) { + expect(transaction.receiver).toStrictEqual(config.aliceAddress); + } + }); + + it('should return transactions for a collection of type NFT with a specific senderShard', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions?senderShard=1`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + + for (const transaction of response.data) { + expect(transaction.senderShard).toStrictEqual(1); + } + }); + + it('should return transactions for a collection of type NFT with a specific receiverShard', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions?receiverShard=1`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + + for (const transaction of response.data) { + expect(transaction.receiverShard).toStrictEqual(1); + } + }); + + it('should return transactions for a collection of type NFT with a specific miniBlockHash', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + const txCollectionMiniBlockHash = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions`); + const miniBlockHash = txCollectionMiniBlockHash.data.map((transaction: any) => transaction.miniBlockHash); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions?miniBlockHash=${miniBlockHash[0]}`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(1); + + for (const transaction of response.data) { + expect(transaction.miniBlockHash).toStrictEqual(miniBlockHash[0]); + } + }); + + it('should return transactions for a collection of type NFT with specific hashes', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const txCollectionHashes = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions`); + const hashes = txCollectionHashes.data.map((transaction: any) => transaction.txHash); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions?hashes=${hashes[0]},${hashes[1]}`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(2); + + const returnedHashes = response.data.map((transaction: any) => transaction.txHash); + expect(returnedHashes).toContain(hashes[0]); + expect(returnedHashes).toContain(hashes[1]); + }); + + it('should return transactions for a collection of type NFT with a specific status', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions?status=success`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + + for (const transaction of response.data) { + expect(transaction.status).toStrictEqual('success'); + } + }); + + it('should return transactions for a collection of type NFT with a specific function', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions?function=ESDTNFTCreate`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + + for (const transaction of response.data) { + expect(transaction.function).toStrictEqual('ESDTNFTCreate'); + } + }); + + it('should return transactions for a collection of type NFT with a specific before', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const txCollectionBefore = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions`); + const before = txCollectionBefore.data.map((transaction: any) => transaction.timestamp); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions?before=${before[1]}`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(4); + + const returnedTimestamps = response.data.map((transaction: any) => transaction.timestamp); + expect(returnedTimestamps).toContain(before[1]); + }); + + it('should return transactions for a collection of type NFT with a specific after', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const txCollectionAfter = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions`); + const after = txCollectionAfter.data.map((transaction: any) => transaction.timestamp); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions?after=${after[1]}`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(2); + + const returnedTimestamps = response.data.map((transaction: any) => transaction.timestamp); + expect(returnedTimestamps).toContain(after[1]); + }); + + it('should return transactions for a collection of type NFT with a specific round', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const txCollectionRound = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions`); + const round = txCollectionRound.data.map((transaction: any) => transaction.round); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions?round=${round[1]}`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(1); + + for (const transaction of response.data) { + expect(transaction.round).toStrictEqual(round[1]); + } + }); + + it('should return transactions for a collection of type NFT paginated', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions?from=0&size=1`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(1); + }); + + it('should return different transactions when using different pagination parameters', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const firstPage = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions?from=0&size=1`); + const secondPage = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions?from=1&size=2`); + + expect(firstPage.status).toBe(200); + expect(secondPage.status).toBe(200); + + expect(firstPage.data.length).toStrictEqual(1); + expect(secondPage.data.length).toStrictEqual(2); + + const firstPageHash = firstPage.data[0].txHash; + const secondPageHashes = secondPage.data.map((tx: any) => tx.txHash); + + expect(secondPageHashes).not.toContain(firstPageHash); + }); + + it('should return transactions for a collection of type NFT with operations when withOperations is true', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions?withOperations=true`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + + for (const transaction of response.data) { + expect(transaction.operations).toBeDefined(); + } + }); + + it('should throw 400 bad request when withOperations=true and size=51', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + try { + await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions?withOperations=true&size=51`); + fail('Should have thrown 400 error'); + } catch (error: any) { + expect(error.response.status).toBe(400); + } + }); + + it('should return transactions for a collection of type NFT with operations when withLogs is true', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions?withLogs=true`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + + for (const transaction of response.data) { + expect(transaction.logs).toBeDefined(); + } + }); + + it('should throw 400 bad request when withLogs=true and size=51', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + try { + await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions?withLogs=true&size=51`); + fail('Should have thrown 400 error'); + } catch (error: any) { + expect(error.response.status).toBe(400); + } + }); + }); + + describe('GET /collections/:collection/transactions/count', () => { + it('should return the count of transactions for a collection of type NFT', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions/count`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(5); + }); + + it('should return the count of transactions for a collection of type NFT with a specific sender', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions/count?sender=${config.aliceAddress}`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(5); + }); + + it('should return the count of transactions for a collection of type NFT with a specific receiver', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions/count?receiver=${config.aliceAddress}`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(5); + }); + + it('should return the count of transactions for a collection of type NFT with a specific senderShard', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions/count?senderShard=1`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(5); + }); + + it('should return the count of transactions for a collection of type NFT with a specific receiverShard', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions/count?receiverShard=1`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(5); + }); + + it('should return the count of transactions for a collection of type NFT with a specific miniBlockHash', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + const txCollectionMiniBlockHash = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions`); + const miniBlockHash = txCollectionMiniBlockHash.data.map((transaction: any) => transaction.miniBlockHash); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions/count?miniBlockHash=${miniBlockHash[0]}`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(1); + }); + + it('should return the count of transactions for a collection of type NFT with a specific hashes', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const txCollectionHashes = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions`); + const hashes = txCollectionHashes.data.map((transaction: any) => transaction.txHash); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions/count?hashes=${hashes[0]},${hashes[1]}`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(2); + }); + + it('should return the count of transactions for a collection of type NFT with a specific status', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions/count?status=success`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(5); + }); + + it('should return the count of transaction for a collection of type NFT with a specific round', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const txCollectionRound = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions`); + const round = txCollectionRound.data.map((transaction: any) => transaction.round); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transactions/count?round=${round[1]}`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(1); + }); + }); + + describe('GET /collections/:collection/transfers', () => { + it('should return transfers for a collection of type NFT', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + }); + + it('should return transfers for a collection of type SFT', async () => { + const collectionSFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=SemiFungibleESDT`); + const collectionSFTDetails = collectionSFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionSFTDetails[0]}/transfers`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + }); + + it('should return transfers for a collection of type MetaESDT', async () => { + const collectionMetaESDT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=MetaESDT`); + const collectionMetaESDTDetails = collectionMetaESDT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionMetaESDTDetails[0]}/transfers`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + }); + + it('should return transfers for a collection of type NFT and contains properties', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers`); + + expect(response.status).toBe(200); + + const expectedProps = [ + 'txHash', + 'gasLimit', + 'gasPrice', + 'gasUsed', + 'miniBlockHash', + 'nonce', + 'receiver', + 'receiverShard', + 'round', + 'sender', + 'senderShard', + 'signature', + 'status', + 'value', + 'fee', + 'timestamp', + 'data', + 'function', + 'action', + ]; + + for (const transfer of response.data) { + for (const prop of expectedProps) { + expect(transfer).toHaveProperty(prop); + } + } + }); + + it('should return transfers for a collection of type NFT with a specific sender', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers?sender=${config.aliceAddress}`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + + for (const transfer of response.data) { + expect(transfer.sender).toStrictEqual(config.aliceAddress); + } + }); + + it('should return transfers for a collection of type NFT with a specific receiver', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers?receiver=${config.aliceAddress}`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + + for (const transfer of response.data) { + expect(transfer.receiver).toStrictEqual(config.aliceAddress); + } + }); + + it('should return transfers for a collection of type NFT with a specific senderShard', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers?senderShard=1`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + + for (const transfer of response.data) { + expect(transfer.senderShard).toStrictEqual(1); + } + }); + + it('should return transfers for a collection of type NFT with a specific receiverShard', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers?receiverShard=1`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + + for (const transfer of response.data) { + expect(transfer.receiverShard).toStrictEqual(1); + } + }); + + it('should return transfers for a collection of type NFT with a specific miniBlockHash', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + const txCollectionMiniBlockHash = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers`); + const miniBlockHash = txCollectionMiniBlockHash.data.map((transaction: any) => transaction.miniBlockHash); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers?miniBlockHash=${miniBlockHash[0]}`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(1); + + for (const transfer of response.data) { + expect(transfer.miniBlockHash).toStrictEqual(miniBlockHash[0]); + } + }); + + it('should return transfers for a collection of type NFT with specific hashes', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const txCollectionHashes = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers`); + const hashes = txCollectionHashes.data.map((transaction: any) => transaction.txHash); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers?hashes=${hashes[0]},${hashes[1]}`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(2); + + const returnedHashes = response.data.map((transfer: any) => transfer.txHash); + expect(returnedHashes).toContain(hashes[0]); + expect(returnedHashes).toContain(hashes[1]); + }); + + it('should return transfers for a collection of type NFT with a specific status', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers?status=success`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + + for (const transfer of response.data) { + expect(transfer.status).toStrictEqual('success'); + } + }); + + it('should return transfers for a collection of type NFT with a specific function', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers?function=ESDTNFTCreate`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + + for (const transfer of response.data) { + expect(transfer.function).toStrictEqual('ESDTNFTCreate'); + } + }); + + it('should return transfers for a collection of type NFT with a specific before', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const txCollectionBefore = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers`); + const before = txCollectionBefore.data.map((transaction: any) => transaction.timestamp); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers?before=${before[1]}`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(4); + + const returnedTimestamps = response.data.map((transfer: any) => transfer.timestamp); + expect(returnedTimestamps).toContain(before[1]); + }); + + it('should return transfers for a collection of type NFT with a specific after', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const txCollectionAfter = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers`); + const after = txCollectionAfter.data.map((transaction: any) => transaction.timestamp); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers?after=${after[1]}`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(2); + + const returnedTimestamps = response.data.map((transfer: any) => transfer.timestamp); + expect(returnedTimestamps).toContain(after[1]); + }); + + it('should return transfers for a collection of type NFT with a specific round', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const txCollectionRound = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers`); + const round = txCollectionRound.data.map((transaction: any) => transaction.round); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers?round=${round[1]}`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(1); + + for (const transfer of response.data) { + expect(transfer.round).toStrictEqual(round[1]); + } + }); + + it('should return transfers for a collection of type NFT paginated', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers?from=0&size=1`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(1); + }); + + it('should return different transfers when using different pagination parameters', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const firstPage = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers?from=0&size=1`); + const secondPage = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers?from=1&size=2`); + + expect(firstPage.status).toBe(200); + expect(secondPage.status).toBe(200); + + expect(firstPage.data.length).toStrictEqual(1); + expect(secondPage.data.length).toStrictEqual(2); + + const firstPageHash = firstPage.data[0].txHash; + const secondPageHashes = secondPage.data.map((tx: any) => tx.txHash); + + expect(secondPageHashes).not.toContain(firstPageHash); + }); + + it('should return transfers for a collection of type NFT with operations when withOperations is true', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers?withOperations=true`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + + for (const transfer of response.data) { + expect(transfer.operations).toBeDefined(); + } + }); + + it('should throw 400 bad request when withOperations=true and size=51', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + try { + await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers?withOperations=true&size=51`); + fail('Should have thrown 400 error'); + } catch (error: any) { + expect(error.response.status).toBe(400); + } + }); + + it('should return transfers for a collection of type NFT with operations when withLogs is true', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers?withLogs=true`); + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(5); + + for (const transfer of response.data) { + expect(transfer.logs).toBeDefined(); + } + }); + + it('should throw 400 bad request when withLogs=true and size=51', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + try { + await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers?withLogs=true&size=51`); + fail('Should have thrown 400 error'); + } catch (error: any) { + expect(error.response.status).toBe(400); + } + }); + }); + + describe('GET /collections/:collection/transfers/count', () => { + it('should return the count of transfers for a collection of type NFT', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers/count`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(5); + }); + + it('should return the count of transfers for a collection of type NFT with a specific sender', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers/count?sender=${config.aliceAddress}`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(5); + }); + + it('should return the count of transfers for a collection of type NFT with a specific receiver', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers/count?receiver=${config.aliceAddress}`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(5); + }); + + it('should return the count of transfers for a collection of type NFT with a specific senderShard', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers/count?senderShard=1`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(5); + }); + + it('should return the count of transfers for a collection of type NFT with a specific receiverShard', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers/count?receiverShard=1`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(5); + }); + + it('should return the count of transfers for a collection of type NFT with a specific miniBlockHash', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + const txCollectionMiniBlockHash = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers`); + const miniBlockHash = txCollectionMiniBlockHash.data.map((transaction: any) => transaction.miniBlockHash); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers/count?miniBlockHash=${miniBlockHash[0]}`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(1); + }); + + it('should return the count of transfers for a collection of type NFT with a specific hashes', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const txCollectionHashes = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers`); + const hashes = txCollectionHashes.data.map((transaction: any) => transaction.txHash); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers/count?hashes=${hashes[0]},${hashes[1]}`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(2); + }); + + it('should return the count of transfers for a collection of type NFT with a specific status', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers/count?status=success`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(5); + }); + + it('should return the count of transfers for a collection of type NFT with a specific round', async () => { + const collectionNFT = await axios.get(`${config.apiServiceUrl}/collections?size=1&type=NonFungibleESDT`); + const collectionNFTDetails = collectionNFT.data.map((collection: any) => collection.collection); + + const txCollectionRound = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers`); + const round = txCollectionRound.data.map((transaction: any) => transaction.round); + + const response = await axios.get(`${config.apiServiceUrl}/collections/${collectionNFTDetails[0]}/transfers/count?round=${round[1]}`); + + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(1); + }); + }); +}); + diff --git a/src/test/chain-simulator/config/.env.example b/src/test/chain-simulator/config/.env.example new file mode 100644 index 000000000..dcb650fc6 --- /dev/null +++ b/src/test/chain-simulator/config/.env.example @@ -0,0 +1,4 @@ +CHAIN_SIMULATOR_URL=http://localhost:8085 +API_SERVICE_URL=http://localhost:3001 +ALICE_ADDRESS=erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th +BOB_ADDRESS=erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx diff --git a/src/test/chain-simulator/config/env.config.ts b/src/test/chain-simulator/config/env.config.ts new file mode 100644 index 000000000..d52a5f1ef --- /dev/null +++ b/src/test/chain-simulator/config/env.config.ts @@ -0,0 +1,13 @@ +import * as dotenv from 'dotenv'; +import * as path from 'path'; + +dotenv.config({ + path: path.resolve(__dirname, '.env'), +}); + +export const config = { + chainSimulatorUrl: process.env.CHAIN_SIMULATOR_URL || 'http://localhost:8085', + apiServiceUrl: process.env.API_SERVICE_URL || 'http://localhost:3001', + aliceAddress: process.env.ALICE_ADDRESS || 'erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th', + bobAddress: process.env.BOB_ADDRESS || 'erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx', +}; diff --git a/src/test/chain-simulator/dapp.config.cs-e2e.ts b/src/test/chain-simulator/dapp.config.cs-e2e.ts new file mode 100644 index 000000000..45a711faa --- /dev/null +++ b/src/test/chain-simulator/dapp.config.cs-e2e.ts @@ -0,0 +1,36 @@ +import axios from "axios"; +import { config } from "./config/env.config"; + +describe('Dapp config e2e tests with chain simulator', () => { + describe('GET /dapp/config', () => { + it('should return status code 200 and dapp config', async () => { + const response = await axios.get(`${config.apiServiceUrl}/dapp/config`); + expect(response.status).toBe(200); + }); + + it('should return dapp config with all required properties', async () => { + const response = await axios.get(`${config.apiServiceUrl}/dapp/config`); + const dappConfig = response.data; + + const requiredProps = [ + 'id', + 'name', + 'egldLabel', + 'decimals', + 'egldDenomination', + 'gasPerDataByte', + 'apiTimeout', + 'walletConnectDeepLink', + 'walletConnectBridgeAddresses', + 'walletAddress', + 'apiAddress', + 'explorerAddress', + 'chainId', + ]; + + for (const prop of requiredProps) { + expect(dappConfig).toHaveProperty(prop); + } + }); + }); +}); diff --git a/src/test/chain-simulator/delegation-legacy.cs-e2e.ts b/src/test/chain-simulator/delegation-legacy.cs-e2e.ts new file mode 100644 index 000000000..d25705a67 --- /dev/null +++ b/src/test/chain-simulator/delegation-legacy.cs-e2e.ts @@ -0,0 +1,24 @@ +import axios from 'axios'; +import { config } from "./config/env.config"; + +// TODO: Uncomment this test once the legacy delegation legacy contract is deployed +describe.skip('Delegation legacy e2e tests with chain simulator', () => { + describe('GET /delegations-legacy', () => { + it('should return status code 200 and a delegation legacy object details', async () => { + const response = await axios.get(`${config.apiServiceUrl}/delegation-legacy`); + const properties = Object.keys(response.data); + + expect(response.status).toBe(200); + const expectedProperties = [ + 'totalWithdrawOnlyStake', + 'totalWaitingStake', + 'totalActiveStake', + 'totalUnstakedStake', + 'totalDeferredPaymentStake', + 'numUsers', + ]; + + expect(properties).toEqual(expectedProperties); + }); + }); +}); diff --git a/src/test/chain-simulator/delegation.cs-e2e.ts b/src/test/chain-simulator/delegation.cs-e2e.ts new file mode 100644 index 000000000..36dc38edf --- /dev/null +++ b/src/test/chain-simulator/delegation.cs-e2e.ts @@ -0,0 +1,14 @@ +import axios from 'axios'; +import { config } from "./config/env.config"; + +describe('Delegation e2e tests with chain simulator', () => { + describe('GET /delegations', () => { + it('should return status code 200 and a delegation object details', async () => { + const response = await axios.get(`${config.apiServiceUrl}/delegation`); + const properties = Object.keys(response.data); + + expect(response.status).toBe(200); + expect(properties).toEqual(['stake', 'topUp', 'locked', 'minDelegation']); + }); + }); +}); diff --git a/src/test/chain-simulator/docker/docker-compose.yml b/src/test/chain-simulator/docker/docker-compose.yml new file mode 100644 index 000000000..69e37abe4 --- /dev/null +++ b/src/test/chain-simulator/docker/docker-compose.yml @@ -0,0 +1,37 @@ +services: + elasticsearch: + ports: + - "9200:9200" + container_name: es-container + image: docker.elastic.co/elasticsearch/elasticsearch:7.16.1 + environment: + - "discovery.type=single-node" + - "xpack.security.enabled=false" + - "ES_JAVA_OPTS=-Xms512m -Xmx512m" + ulimits: + memlock: + soft: -1 + hard: -1 + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:9200" ] + interval: 10s + timeout: 5s + retries: 5 + + chainsimulator: + container_name: chainsimulator + image: multiversx/chainsimulator:v1.8.4-barnard-test2 + command: ["--node-override-config", "./overridable-config.toml"] + volumes: + - ./overridable-config.toml:/multiversx/overridable-config.toml + depends_on: + - elasticsearch + environment: + ELASTIC_SEARCH_URL: 'http://localhost:9200' + ports: + - "8085:8085" + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:8085/simulator/observers" ] + interval: 10s + timeout: 5s + retries: 5 diff --git a/src/test/chain-simulator/docker/overridable-config.toml b/src/test/chain-simulator/docker/overridable-config.toml new file mode 100644 index 000000000..50141f850 --- /dev/null +++ b/src/test/chain-simulator/docker/overridable-config.toml @@ -0,0 +1,8 @@ +OverridableConfigTomlValues = [ + { File = "external.toml", Path = "ElasticSearchConnector.Enabled", Value = true }, + { File = "external.toml", Path = "ElasticSearchConnector.URL", Value = "http://elasticsearch:9200" }, + { File = "enableEpochs.toml", Path = "EnableEpochs.StakeLimitsEnableEpoch", Value = 1000000 }, + { File = "systemSmartContractsConfig.toml", Path = "ESDTSystemSCConfig.BaseIssuingCost", Value = "50000000000000000" }, # (0.05 EGLD) + { File = "config.toml", Path = "Debug.Process.Enabled", Value = false }, + { File = "config.toml", Path = "WebServerAntiflood.WebServerAntifloodEnabled", Value = false} +] diff --git a/src/test/chain-simulator/events.cs-e2e.ts b/src/test/chain-simulator/events.cs-e2e.ts new file mode 100644 index 000000000..6a1c86791 --- /dev/null +++ b/src/test/chain-simulator/events.cs-e2e.ts @@ -0,0 +1,113 @@ +import { config } from "./config/env.config"; +import axios from "axios"; + +describe('Events e2e tests with chain simulator', () => { + describe('GET /events', () => { + it('should return status code 200 and a list of events', async () => { + const response = await axios.get(`${config.apiServiceUrl}/events`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + }); + + it('should support pagination', async () => { + const response = await axios.get(`${config.apiServiceUrl}/events?from=0&size=2`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + expect(response.data.length).toStrictEqual(2); + }); + + it('should return different results for different from/size parameters', async () => { + const firstSet = await axios.get(`${config.apiServiceUrl}/events?from=0&size=2`); + const secondSet = await axios.get(`${config.apiServiceUrl}/events?from=1&size=2`); + + expect(firstSet.status).toBe(200); + expect(secondSet.status).toBe(200); + + expect(firstSet.data).not.toEqual(secondSet.data); + expect(firstSet.data[1]).toEqual(secondSet.data[0]); + }); + + it('should return events with expected properties', async () => { + const response = await axios.get(`${config.apiServiceUrl}/events`); + const event = response.data[0]; + expect(response.status).toBe(200); + + const requiredProps = [ + 'txHash', + 'logAddress', + 'identifier', + 'address', + 'topics', + 'shardID', + 'txOrder', + 'order', + 'timestamp', + ]; + + for (const prop of requiredProps) { + expect(event).toHaveProperty(prop); + } + + expect(event.topics).toBeInstanceOf(Array); + }); + + it('should support filtering by address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/events?address=${config.aliceAddress}`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + expect(response.data.length).toBeGreaterThan(1); + expect(response.data[0].address).toBe(config.aliceAddress); + }); + + it('should support filtering by identifier', async () => { + const response = await axios.get(`${config.apiServiceUrl}/events?identifier=completedTxEvent`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + expect(response.data.length).toBeGreaterThan(1); + expect(response.data[0].identifier).toBe('completedTxEvent'); + }); + + // TODO: fix this + it.skip('should support filtering by txHash', async () => { + const events = await axios.get(`${config.apiServiceUrl}/events`); + const txHash = events.data[0].txHash; + const response = await axios.get(`${config.apiServiceUrl}/events?txHash=${txHash}`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + expect(response.data.length).toBeGreaterThan(1); + }); + + it('should support filtering by shard', async () => { + const response = await axios.get(`${config.apiServiceUrl}/events?shard=0`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + expect(response.data.length).toBeGreaterThan(1); + }); + }); + + describe('GET /events/count', () => { + it('should return status code 200 and the number of events', async () => { + const response = await axios.get(`${config.apiServiceUrl}/events/count`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + }); + + it('should return the number of events with the given address', async () => { + const response = await axios.get(`${config.apiServiceUrl}/events/count?address=${config.aliceAddress}`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThan(1); + }); + + it('should return the number of events with the given identifier', async () => { + const response = await axios.get(`${config.apiServiceUrl}/events/count?identifier=completedTxEvent`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThan(1); + }); + + it('should return the number of events with the given shard', async () => { + const response = await axios.get(`${config.apiServiceUrl}/events/count?shard=0`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThan(1); + }); + }); +}); diff --git a/src/test/chain-simulator/hello.cs-e2e.ts b/src/test/chain-simulator/hello.cs-e2e.ts new file mode 100644 index 000000000..7124e5689 --- /dev/null +++ b/src/test/chain-simulator/hello.cs-e2e.ts @@ -0,0 +1,13 @@ +import axios from "axios"; +import { config } from "./config/env.config"; + +describe('Hello endpoint e2e tests with chain simulator', () => { + describe('GET /hello', () => { + it('should return status code 200 and a hello message', async () => { + const response = await axios.get(`${config.apiServiceUrl}/hello`); + + expect(response.status).toBe(200); + expect(response.data).toBe('hello'); + }); + }); +}); diff --git a/src/test/chain-simulator/identities.cs-e2e.ts b/src/test/chain-simulator/identities.cs-e2e.ts new file mode 100644 index 000000000..5363947db --- /dev/null +++ b/src/test/chain-simulator/identities.cs-e2e.ts @@ -0,0 +1,41 @@ +import axios from "axios"; +import { config } from "./config/env.config"; + +describe('Identities e2e tests with chain simulator', () => { + describe('GET /identities', () => { + it('should return status code 200 and a list of identities', async () => { + const response = await axios.get(`${config.apiServiceUrl}/identities`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + }); + + it('should support pagination', async () => { + const response = await axios.get(`${config.apiServiceUrl}/identities?size=1`); + expect(response.status).toBe(200); + expect(response.data.length).toBe(1); + }); + + it('should return identities with expected properties', async () => { + const response = await axios.get(`${config.apiServiceUrl}/identities`); + expect(response.status).toBe(200); + + const expectedProps = [ + 'locked', + 'distribution', + 'name', + 'score', + 'validators', + 'stake', + 'topUp', + 'stakePercent', + 'rank', + ]; + + for (const identity of response.data) { + for (const expectedProp of expectedProps) { + expect(identity).toHaveProperty(expectedProp); + } + } + }); + }); +}); diff --git a/src/test/chain-simulator/miniblocks.cs-e2e.ts b/src/test/chain-simulator/miniblocks.cs-e2e.ts new file mode 100644 index 000000000..99162b3ba --- /dev/null +++ b/src/test/chain-simulator/miniblocks.cs-e2e.ts @@ -0,0 +1,92 @@ +import axios from 'axios'; +import { config } from './config/env.config'; + +describe('Miniblocks e2e tests with chain simulator', () => { + describe('GET /miniblocks', () => { + it('should return status code 200', async () => { + const response = await axios.get(`${config.apiServiceUrl}/miniblocks`); + expect(response.status).toBe(200); + }); + + it('should handle invalid miniblock requests gracefully', async () => { + try { + await axios.get(`${config.apiServiceUrl}/miniblocks/invalid`); + } catch (error: any) { + expect(error.response.status).toBe(400); + } + }); + + it('should return a list of miniblocks', async () => { + const response = await axios.get(`${config.apiServiceUrl}/miniblocks`); + const miniblocks = response.data; + + expect(Array.isArray(miniblocks)).toBe(true); + expect(miniblocks.length).toBeGreaterThan(5); + }); + + it('should return miniblocks with the correct structure', async () => { + const response = await axios.get(`${config.apiServiceUrl}/miniblocks`); + const miniblocks = response.data; + + //TBD - senderBlockHash is not in the response + const expectedProperties = [ + 'miniBlockHash', + 'receiverShard', + 'senderShard', + 'timestamp', + 'type', + ]; + + for (const miniblock of miniblocks) { + for (const property of expectedProperties) { + expect(miniblock).toHaveProperty(property); + } + } + }); + }); + + describe('GET /miniblocks filters', () => { + it('should support pagination', async () => { + const response = await axios.get(`${config.apiServiceUrl}/miniblocks?size=5`); + const miniblocks = response.data; + + expect(miniblocks.length).toBe(5); + }); + + it('should support filtering by types', async () => { + const response = await axios.get( + `${config.apiServiceUrl}/miniblocks?type=SmartContractResultBlock`, + ); + const miniblocks = response.data; + + for (const miniblock of miniblocks) { + expect(miniblock.type).toStrictEqual('SmartContractResultBlock'); + } + }); + + it('should support filtering by types', async () => { + const response = await axios.get( + `${config.apiServiceUrl}/miniblocks?type=InvalidBlock`, + ); + const miniblocks = response.data; + + for (const miniblock of miniblocks) { + expect(miniblock.type).toStrictEqual('InvalidBlock'); + } + }); + + const typesToTest = ['SmartContractResultBlock', 'InvalidBlock', 'TxBlock']; + for (const type of typesToTest) { + it(`should return miniblocks filtered by type: ${type}`, async () => { + const response = await axios.get( + `${config.apiServiceUrl}/miniblocks?type=${type}`, + ); + const miniblocks = response.data; + + for (const miniblock of miniblocks) { + expect(miniblock.type).toStrictEqual(type); + } + }); + } + }); +}); diff --git a/src/test/chain-simulator/network.cs-e2e.ts b/src/test/chain-simulator/network.cs-e2e.ts new file mode 100644 index 000000000..8056d05cf --- /dev/null +++ b/src/test/chain-simulator/network.cs-e2e.ts @@ -0,0 +1,79 @@ +import axios from 'axios'; +import { config } from './config/env.config'; + +describe('Network e2e tests with chain simulator', () => { + describe('GET /constants', () => { + it('should return status code 200 constants details', async () => { + const response = await axios.get(`${config.apiServiceUrl}/constants`); + const results = response.data; + + expect(response.status).toBe(200); + expect(results).toEqual( + expect.objectContaining({ + chainId: expect.any(String), + gasPerDataByte: expect.any(Number), + minGasLimit: expect.any(Number), + minGasPrice: expect.any(Number), + minTransactionVersion: expect.any(Number), + }) + ); + }); + + it.skip('shoult return status code 200 and economics details', async () => { + const response = await axios.get(`${config.apiServiceUrl}/economics`); + const results = response.data; + + expect(response.status).toBe(200); + expect(results).toEqual( + expect.objectContaining({ + totalSupply: expect.any(Number), + circulatingSupply: expect.any(Number), + staked: expect.any(Number), + price: expect.any(Number), + marketCap: expect.any(Number), + apr: expect.any(Number), + topUpApr: expect.any(Number), + baseApr: expect.any(Number), + tokenMarketCap: expect.any(Number), + }) + ); + }); + + it('should return status code 200 and stats details', async () => { + const response = await axios.get(`${config.apiServiceUrl}/stats`); + const results = response.data; + + expect(response.status).toBe(200); + expect(results).toEqual( + expect.objectContaining({ + accounts: expect.any(Number), + blocks: expect.any(Number), + epoch: expect.any(Number), + refreshRate: expect.any(Number), + roundsPassed: expect.any(Number), + roundsPerEpoch: expect.any(Number), + shards: expect.any(Number), + transactions: expect.any(Number), + scResults: expect.any(Number), + }) + ); + }); + + it.skip('should return status code 200 and about details', async () => { + const response = await axios.get(`${config.apiServiceUrl}/about`); + const results = response.data; + + expect(response.status).toBe(200); + expect(results).toEqual( + expect.objectContaining({ + appVersion: expect.any(String), + features: expect.any(Object), + network: expect.any(String), + pluginsVersion: expect.any(String), + version: expect.any(String), + scamEngineVersion: expect.any(String), + }) + ); + }); + }); +}); diff --git a/src/test/chain-simulator/nfts.cs-e2e.ts b/src/test/chain-simulator/nfts.cs-e2e.ts new file mode 100644 index 000000000..6df95685f --- /dev/null +++ b/src/test/chain-simulator/nfts.cs-e2e.ts @@ -0,0 +1,461 @@ +import axios from "axios"; +import { config } from "./config/env.config"; +import { NftType } from 'src/common/indexer/entities/nft.type'; +import { NftSubType } from "src/endpoints/nfts/entities/nft.sub.type"; + +describe('NFTs e2e tests with chain simulator', () => { + describe('GET /nfts', () => { + it('should return status code 200', async () => { + const response = await axios.get(`${config.apiServiceUrl}/nfts`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + }); + + it('should return all nfts paginated', async () => { + const response = await axios.get(`${config.apiServiceUrl}/nfts?size=5`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + expect(response.data.length).toStrictEqual(5); + }); + + it('should return different paginated results for different from values', async () => { + const firstSet = await axios.get(`${config.apiServiceUrl}/nfts?from=0&size=5`); + const secondSet = await axios.get(`${config.apiServiceUrl}/nfts?from=5&size=5`); + expect(firstSet.status).toBe(200); + expect(secondSet.status).toBe(200); + expect(firstSet.data.length).toStrictEqual(5); + expect(secondSet.data.length).toStrictEqual(5); + expect(firstSet.data).not.toStrictEqual(secondSet.data); + }); + + it('should return nfts filtered by identifiers', async () => { + const nfts = await axios.get(`${config.apiServiceUrl}/nfts?size=2`); + const identifiers = nfts.data.map((nft: any) => nft.identifier); + + const response = await axios.get(`${config.apiServiceUrl}/nfts?identifiers=${identifiers[0]},${identifiers[1]}`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + expect(response.data.length).toStrictEqual(2); + expect(response.data.every((nft: any) => identifiers.includes(nft.identifier))).toBe(true); + }); + + + it('should return nfts filtered by different type combinations', async () => { + // Test NonFungibleESDT filter + const nonFungibleResponse = await axios.get(`${config.apiServiceUrl}/nfts?type=${NftType.NonFungibleESDT}`); + expect(nonFungibleResponse.status).toBe(200); + expect(nonFungibleResponse.data).toBeInstanceOf(Array); + expect(nonFungibleResponse.data.every((nft: any) => nft.type === NftType.NonFungibleESDT)).toBe(true); + + // Test SemiFungibleESDT filter + const semiFungibleResponse = await axios.get(`${config.apiServiceUrl}/nfts?type=${NftType.SemiFungibleESDT}`); + expect(semiFungibleResponse.status).toBe(200); + expect(semiFungibleResponse.data).toBeInstanceOf(Array); + expect(semiFungibleResponse.data.every((nft: any) => nft.type === NftType.SemiFungibleESDT)).toBe(true); + + // Test combined NonFungible and SemiFungible filter + const combinedResponse = await axios.get(`${config.apiServiceUrl}/nfts?type=${NftType.NonFungibleESDT},${NftType.SemiFungibleESDT}`); + expect(combinedResponse.status).toBe(200); + expect(combinedResponse.data).toBeInstanceOf(Array); + expect(combinedResponse.data.every((nft: any) => + [NftType.NonFungibleESDT, NftType.SemiFungibleESDT].includes(nft.type) + )).toBe(true); + }); + + it('should return nfts filtered by different subType combinations', async () => { + // Test NonFungibleESDTv2 filter + const nonFungibleV2Response = await axios.get(`${config.apiServiceUrl}/nfts?subType=${NftSubType.NonFungibleESDTv2}`); + expect(nonFungibleV2Response.status).toBe(200); + expect(nonFungibleV2Response.data).toBeInstanceOf(Array); + expect(nonFungibleV2Response.data.every((nft: any) => nft.subType === NftSubType.NonFungibleESDTv2)).toBe(true); + + // Test SemiFungibleESDT filter + const semiFungibleResponse = await axios.get(`${config.apiServiceUrl}/nfts?subType=${NftSubType.SemiFungibleESDT}`); + expect(semiFungibleResponse.status).toBe(200); + expect(semiFungibleResponse.data).toBeInstanceOf(Array); + expect(semiFungibleResponse.data.every((nft: any) => nft.subType === NftSubType.SemiFungibleESDT)).toBe(true); + + // Test combined NonFungibleESDTv2 and SemiFungibleESDT filter + const combinedResponse = await axios.get(`${config.apiServiceUrl}/nfts?subType=${NftSubType.NonFungibleESDTv2},${NftSubType.SemiFungibleESDT}`); + expect(combinedResponse.status).toBe(200); + expect(combinedResponse.data).toBeInstanceOf(Array); + expect(combinedResponse.data.every((nft: any) => + [NftSubType.NonFungibleESDTv2, NftSubType.SemiFungibleESDT].includes(nft.subType) + )).toBe(true); + }); + + it('should return nfts filtered by collection', async () => { + const collections = await axios.get(`${config.apiServiceUrl}/collections?size=1`); + const collection = collections.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/nfts?collection=${collection[0]}`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + expect(response.data.every((nft: any) => nft.collection === collection[0])).toBe(true); + }); + + it('should return nfts filtered by collections', async () => { + const collections = await axios.get(`${config.apiServiceUrl}/collections?size=2`); + const collection = collections.data.map((collection: any) => collection.collection); + + const response = await axios.get(`${config.apiServiceUrl}/nfts?collections=${collection[0]},${collection[1]}`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + expect(response.data.every((nft: any) => collection.includes(nft.collection))).toBe(true); + }); + + it('should return nfts filtered by name', async () => { + const nfts = await axios.get(`${config.apiServiceUrl}/nfts?size=2`); + const name = nfts.data.map((nft: any) => nft.name); + + const response = await axios.get(`${config.apiServiceUrl}/nfts?name=${name[0]}`); + expect(response.data).toBeInstanceOf(Array); + expect(response.data.every((nft: any) => nft.name === name[0])).toBe(true); + }); + + it('should return nfts filtered by tags', async () => { + const response = await axios.get(`${config.apiServiceUrl}/nfts?tags=test,example`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + expect(response.data.every((nft: any) => + nft.tags.includes('test') && nft.tags.includes('example') + )).toBe(true); + }); + + it('should return nfts filtered by isWhitelistedStorage', async () => { + const response = await axios.get(`${config.apiServiceUrl}/nfts?isWhitelistedStorage=false`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + expect(response.data.every((nft: any) => nft.isWhitelistedStorage === false)).toBe(true); + }); + + it('should return nfts filtered by hasUris', async () => { + const response = await axios.get(`${config.apiServiceUrl}/nfts?hasUris=true`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + expect(response.data.every((nft: any) => nft.uris.length > 0)).toBe(true); + }); + + it('should return nfts with owner field defined only for NonFungibleESDT type', async () => { + const response = await axios.get(`${config.apiServiceUrl}/nfts?withOwner=true&type=${NftType.NonFungibleESDT}`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + expect(response.data.every((nft: any) => nft.type === 'NonFungibleESDT')).toBe(true); + expect(response.data.every((nft: any) => nft.owner !== undefined)).toBe(true); + }); + + it('should return nfts with owner field undefined', async () => { + const response = await axios.get(`${config.apiServiceUrl}/nfts?withOwner=false`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + expect(response.data.every((nft: any) => nft.owner === undefined)).toBe(true); + }); + + it('should return nfts with supply field defined only for SemiFungibleESDT type', async () => { + const response = await axios.get(`${config.apiServiceUrl}/nfts?withSupply=true&type=${NftType.SemiFungibleESDT}`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + expect(response.data.every((nft: any) => nft.type === 'SemiFungibleESDT')).toBe(true); + expect(response.data.every((nft: any) => nft.supply !== undefined)).toBe(true); + }); + + it('should return nfts with supply field undefined', async () => { + const response = await axios.get(`${config.apiServiceUrl}/nfts?withSupply=false`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + expect(response.data.every((nft: any) => nft.supply === undefined)).toBe(true); + }); + }); + + describe('GET /nfts/count', () => { + let nfts: any; + + beforeAll(async () => { + nfts = await axios.get(`${config.apiServiceUrl}/nfts?size=10000`); + }); + + it('should return the total number of nfts', async () => { + const response = await axios.get(`${config.apiServiceUrl}/nfts/count`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(nfts.data.length); + }); + + it('should return the total number of nfts filtered by type', async () => { + const nftsByTypeNFT = nfts.data.filter((nft: any) => nft.type === NftType.NonFungibleESDT); + const responseNFT = await axios.get(`${config.apiServiceUrl}/nfts/count?type=${NftType.NonFungibleESDT}`); + expect(responseNFT.status).toBe(200); + expect(responseNFT.data).toStrictEqual(nftsByTypeNFT.length); + + const nftsByTypeSFT = nfts.data.filter((nft: any) => nft.type === NftType.SemiFungibleESDT); + const responseSFT = await axios.get(`${config.apiServiceUrl}/nfts/count?type=${NftType.SemiFungibleESDT}`); + expect(responseSFT.status).toBe(200); + expect(responseSFT.data).toStrictEqual(nftsByTypeSFT.length); + }); + + it('should return the total number of nfts filtered by subType', async () => { + const nftsBySubTypeNFT = nfts.data.filter((nft: any) => nft.subType === NftSubType.NonFungibleESDTv2); + const responseNFT = await axios.get(`${config.apiServiceUrl}/nfts/count?subType=${NftSubType.NonFungibleESDTv2}`); + expect(responseNFT.status).toBe(200); + expect(responseNFT.data).toStrictEqual(nftsBySubTypeNFT.length); + + const nftsBySubTypeSFT = nfts.data.filter((nft: any) => nft.subType === NftSubType.SemiFungibleESDT); + const responseSFT = await axios.get(`${config.apiServiceUrl}/nfts/count?subType=${NftSubType.SemiFungibleESDT}`); + expect(responseSFT.status).toBe(200); + expect(responseSFT.data).toStrictEqual(nftsBySubTypeSFT.length); + }); + + it('should return the total number of nfts filtered by identifiers', async () => { + const identifiers = nfts.data.map((nft: any) => nft.identifier); + const response = await axios.get(`${config.apiServiceUrl}/nfts/count?identifiers=${identifiers[0]},${identifiers[1]}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(2); + }); + + it('should return the total number of nfts filtered by collection', async () => { + const collections = await axios.get(`${config.apiServiceUrl}/collections?size=1`); + const collection = collections.data.map((collection: any) => collection.collection); + + const nftsByCollection = nfts.data.filter((nft: any) => nft.collection === collection[0]); + const response = await axios.get(`${config.apiServiceUrl}/nfts/count?collection=${collection[0]}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(nftsByCollection.length); + }); + + it('should return the total number of nfts filtered by collections', async () => { + const collections = await axios.get(`${config.apiServiceUrl}/collections?size=2`); + const collection = collections.data.map((collection: any) => collection.collection); + + const nftsByCollections = nfts.data.filter((nft: any) => + collection.includes(nft.collection) + ); + const response = await axios.get(`${config.apiServiceUrl}/nfts/count?collections=${collection[0]},${collection[1]}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(nftsByCollections.length); + }); + + it('should return the total number of nfts filtered by isWhitelistedStorage', async () => { + const nftsWhitelisted = nfts.data.filter((nft: any) => nft.isWhitelistedStorage === false); + const response = await axios.get(`${config.apiServiceUrl}/nfts/count?isWhitelistedStorage=false`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(nftsWhitelisted.length); + }); + + it('should return the total number of nfts filtered by hasUris', async () => { + const nftsWithUris = nfts.data.filter((nft: any) => nft.uris.length > 0); + const response = await axios.get(`${config.apiServiceUrl}/nfts/count?hasUris=true`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(nftsWithUris.length); + }); + }); + + describe('GET /nfts/c alternative', () => { + let nfts: any; + + beforeAll(async () => { + nfts = await axios.get(`${config.apiServiceUrl}/nfts?size=10000`); + }); + + it('should have nfts count / list greater than 0', async () => { + const countResponse = await axios.get(`${config.apiServiceUrl}/nfts/c`); + expect(countResponse.status).toBe(200); + expect(countResponse.data).toBeGreaterThan(0); + + const nftsResponse = await axios.get(`${config.apiServiceUrl}/nfts/c`); + expect(nftsResponse.status).toBe(200); + expect(nftsResponse.data).toBeGreaterThan(0); + }); + + it('should return the total number of nfts', async () => { + const response = await axios.get(`${config.apiServiceUrl}/nfts/c`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(nfts.data.length); + }); + + it('should return the total number of nfts filtered by type', async () => { + const nftsByTypeNFT = nfts.data.filter((nft: any) => nft.type === NftType.NonFungibleESDT); + const responseNFT = await axios.get(`${config.apiServiceUrl}/nfts/c?type=${NftType.NonFungibleESDT}`); + expect(responseNFT.status).toBe(200); + expect(responseNFT.data).toStrictEqual(nftsByTypeNFT.length); + + const nftsByTypeSFT = nfts.data.filter((nft: any) => nft.type === NftType.SemiFungibleESDT); + const responseSFT = await axios.get(`${config.apiServiceUrl}/nfts/c?type=${NftType.SemiFungibleESDT}`); + expect(responseSFT.status).toBe(200); + expect(responseSFT.data).toStrictEqual(nftsByTypeSFT.length); + }); + + it('should return the total number of nfts filtered by subType', async () => { + const nftsBySubTypeNFT = nfts.data.filter((nft: any) => nft.subType === NftSubType.NonFungibleESDTv2); + const responseNFT = await axios.get(`${config.apiServiceUrl}/nfts/c?subType=${NftSubType.NonFungibleESDTv2}`); + expect(responseNFT.status).toBe(200); + expect(responseNFT.data).toStrictEqual(nftsBySubTypeNFT.length); + + const nftsBySubTypeSFT = nfts.data.filter((nft: any) => nft.subType === NftSubType.SemiFungibleESDT); + const responseSFT = await axios.get(`${config.apiServiceUrl}/nfts/c?subType=${NftSubType.SemiFungibleESDT}`); + expect(responseSFT.status).toBe(200); + expect(responseSFT.data).toStrictEqual(nftsBySubTypeSFT.length); + }); + + it('should return the total number of nfts filtered by identifiers', async () => { + const identifiers = nfts.data.map((nft: any) => nft.identifier); + const response = await axios.get(`${config.apiServiceUrl}/nfts/c?identifiers=${identifiers[0]},${identifiers[1]}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(2); + }); + + it('should return the total number of nfts filtered by collection', async () => { + const collections = await axios.get(`${config.apiServiceUrl}/collections?size=1`); + const collection = collections.data.map((collection: any) => collection.collection); + + const nftsByCollection = nfts.data.filter((nft: any) => nft.collection === collection[0]); + const response = await axios.get(`${config.apiServiceUrl}/nfts/c?collection=${collection[0]}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(nftsByCollection.length); + }); + + it('should return the total number of nfts filtered by collections', async () => { + const collections = await axios.get(`${config.apiServiceUrl}/collections?size=2`); + const collection = collections.data.map((collection: any) => collection.collection); + + const nftsByCollections = nfts.data.filter((nft: any) => + collection.includes(nft.collection) + ); + const response = await axios.get(`${config.apiServiceUrl}/nfts/c?collections=${collection[0]},${collection[1]}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(nftsByCollections.length); + }); + + it('should return the total number of nfts filtered by isWhitelistedStorage', async () => { + const nftsWhitelisted = nfts.data.filter((nft: any) => nft.isWhitelistedStorage === false); + const response = await axios.get(`${config.apiServiceUrl}/nfts/c?isWhitelistedStorage=false`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(nftsWhitelisted.length); + }); + + it('should return the total number of nfts filtered by hasUris', async () => { + const nftsWithUris = nfts.data.filter((nft: any) => nft.uris.length > 0); + const response = await axios.get(`${config.apiServiceUrl}/nfts/c?hasUris=true`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(nftsWithUris.length); + }); + }); + + describe('GET /nfts/:identifier', () => { + it('should return the nft details with owner field', async () => { + const nfts = await axios.get(`${config.apiServiceUrl}/nfts?size=1&type=${NftType.NonFungibleESDT}`); + const identifier = nfts.data[0].identifier; + + const response = await axios.get(`${config.apiServiceUrl}/nfts/${identifier}`); + expect(response.status).toBe(200); + + const expectedNft = { + ...nfts.data[0], + owner: response.data.owner, + }; + expect(response.data).toStrictEqual(expectedNft); + }); + + it('should return the nft details with supply field', async () => { + const nfts = await axios.get(`${config.apiServiceUrl}/nfts?size=1&type=${NftType.SemiFungibleESDT}`); + const identifier = nfts.data[0].identifier; + + const response = await axios.get(`${config.apiServiceUrl}/nfts/${identifier}`); + expect(response.status).toBe(200); + + const expectedNft = { + ...nfts.data[0], + supply: response.data.supply, + }; + expect(response.data).toStrictEqual(expectedNft); + }); + }); + + describe('GET /nfts/:identifier/supply', () => { + it('should return the sft supply', async () => { + const nfts = await axios.get(`${config.apiServiceUrl}/nfts?size=1&type=${NftType.SemiFungibleESDT}`); + const identifier = nfts.data[0].identifier; + + const response = await axios.get(`${config.apiServiceUrl}/nfts/${identifier}/supply`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual({ supply: "10" }); + }); + + it('should return the nft supply', async () => { + const nfts = await axios.get(`${config.apiServiceUrl}/nfts?size=1&type=${NftType.NonFungibleESDT}`); + const identifier = nfts.data[0].identifier; + + const response = await axios.get(`${config.apiServiceUrl}/nfts/${identifier}/supply`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual({ supply: "1" }); + }); + }); + + describe('GET /nfts/:identifier/accounts', () => { + it('should return the nft accounts', async () => { + const nfts = await axios.get(`${config.apiServiceUrl}/nfts?size=1&type=${NftType.SemiFungibleESDT}`); + const identifier = nfts.data[0].identifier; + + const response = await axios.get(`${config.apiServiceUrl}/nfts/${identifier}/accounts`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual([{ + address: "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th", + balance: "10", + }]); + }); + + it('should return the nft accounts with pagination', async () => { + const nfts = await axios.get(`${config.apiServiceUrl}/nfts?size=1&type=${NftType.SemiFungibleESDT}`); + const identifier = nfts.data[0].identifier; + + const response = await axios.get(`${config.apiServiceUrl}/nfts/${identifier}/accounts?from=0&size=1`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual([{ + address: "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th", + balance: "10", + }]); + }); + + it('should return the nft accounts based on identifier', async () => { + const nfts = await axios.get(`${config.apiServiceUrl}/nfts?size=1&type=${NftType.SemiFungibleESDT}`); + const identifier = nfts.data[0].identifier; + + const response = await axios.get(`${config.apiServiceUrl}/nfts/${identifier}/accounts`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual([{ + address: "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th", + balance: "10", + }]); + }); + + // TODO: analyze why the unit test fails (maybe the new regex for sovereign tokens) + it.skip('should return 400 Bad Request for invalid identifier', async () => { + const invalidIdentifier = 'invalid-identifier'; + + const response = await axios.get(`${config.apiServiceUrl}/nfts/${invalidIdentifier}/accounts`) + .catch(err => err.response); + + expect(response.status).toBe(400); + }); + }); + + describe('GET /nfts/:identifier/accounts/count', () => { + it('should return the nft accounts count', async () => { + const nfts = await axios.get(`${config.apiServiceUrl}/nfts?size=1&type=${NftType.SemiFungibleESDT}`); + const identifier = nfts.data[0].identifier; + + const response = await axios.get(`${config.apiServiceUrl}/nfts/${identifier}/accounts/count`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(1); + }); + + // TODO: analyze why the unit test fails (maybe the new regex for sovereign tokens) + it.skip('should return 400 Bad Request for invalid identifier', async () => { + const invalidIdentifier = 'invalid-identifier'; + + const response = await axios.get(`${config.apiServiceUrl}/nfts/${invalidIdentifier}/accounts/count`) + .catch(err => err.response); + + expect(response.status).toBe(400); + }); + }); +}); + diff --git a/src/test/chain-simulator/nodes.cs-e2e.ts b/src/test/chain-simulator/nodes.cs-e2e.ts new file mode 100644 index 000000000..3ce74262f --- /dev/null +++ b/src/test/chain-simulator/nodes.cs-e2e.ts @@ -0,0 +1,308 @@ +import axios from "axios"; +import { config } from "./config/env.config"; +import { ChainSimulatorUtils } from "./utils/test.utils"; +import { NodeType } from "src/endpoints/nodes/entities/node.type"; +import { NodeStatus } from "src/endpoints/nodes/entities/node.status"; + +describe('Nodes e2e tests with chain simulator', () => { + beforeAll(async () => { + await ChainSimulatorUtils.waitForEpoch(2); + await new Promise((resolve) => setTimeout(resolve, 5000)); + }); + + describe('GET /nodes', () => { + it('should return status code 200 and a list of nodes', async () => { + const response = await axios.get(`${config.apiServiceUrl}/nodes`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + }); + + it('should return different paginated results for different from values', async () => { + const firstSet = await axios.get(`${config.apiServiceUrl}/nodes?from=0&size=2`); + const secondSet = await axios.get(`${config.apiServiceUrl}/nodes?from=1&size=2`); + + expect(firstSet.status).toBe(200); + expect(secondSet.status).toBe(200); + expect(firstSet.data).toBeInstanceOf(Array); + expect(secondSet.data).toBeInstanceOf(Array); + expect(firstSet.data).not.toEqual(secondSet.data); + + expect(firstSet.data.length).toBe(2); + expect(secondSet.data.length).toBe(2); + }); + + it('should return nodes filtered by keys', async () => { + const keys = await axios.get(`${config.apiServiceUrl}/nodes`); + const firstKey = keys.data[0].bls; + const secondKey = keys.data[1].bls; + + const response = await axios.get(`${config.apiServiceUrl}/nodes?keys=${firstKey},${secondKey}`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + expect(response.data.length).toBe(2); + + expect(response.data[0].bls).toBe(firstKey); + expect(response.data[1].bls).toBe(secondKey); + }); + + it('should return nodes filtered by search', async () => { + const keys = await axios.get(`${config.apiServiceUrl}/nodes`); + const firstKey = keys.data[0].bls; + + const response = await axios.get(`${config.apiServiceUrl}/nodes?search=${firstKey}`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + + expect(response.data.length).toStrictEqual(1); + expect(response.data[0].bls).toStrictEqual(firstKey); + }); + + it('should return nodes filtered by online', async () => { + const response = await axios.get(`${config.apiServiceUrl}/nodes?online=true`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + + for (const node of response.data) { + expect(node.online).toStrictEqual(true); + } + }); + + it('should return nodes filtered by type', async () => { + const response = await axios.get(`${config.apiServiceUrl}/nodes?type=validator`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + + for (const node of response.data) { + expect(node.type).toStrictEqual(NodeType.validator); + } + }); + + it('should return nodes filtered by status', async () => { + const response = await axios.get(`${config.apiServiceUrl}/nodes?status=eligible`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + + for (const node of response.data) { + expect(node.status).toStrictEqual(NodeStatus.eligible); + } + }); + + it('should return nodes filtered by shard', async () => { + const shards = [0, 1, 4294967295]; + + for (const shard of shards) { + const response = await axios.get(`${config.apiServiceUrl}/nodes?shard=${shard}`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + + for (const node of response.data) { + expect(node.shard).toStrictEqual(shard); + } + } + }); + + it('should return nodes filtered / sorted by tempRating in ascending order', async () => { + const response = await axios.get(`${config.apiServiceUrl}/nodes?sort=tempRating&order=asc`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + + for (let i = 0; i < response.data.length - 1; i++) { + expect(response.data[i].tempRating).toBeLessThanOrEqual(response.data[i + 1].tempRating); + } + }); + }); + + describe('GET /nodes/count', () => { + it('should return status code 200 and a number of nodes', async () => { + const nodesResponse = await axios.get(`${config.apiServiceUrl}/nodes`); + const expectedCount = nodesResponse.data.length; + + const countResponse = await axios.get(`${config.apiServiceUrl}/nodes/count`); + expect(countResponse.status).toBe(200); + expect(countResponse.data).toStrictEqual(expectedCount); + }); + + it('should return nodes count filtered by search', async () => { + const nodesResponse = await axios.get(`${config.apiServiceUrl}/nodes?search=node`); + const expectedCount = nodesResponse.data.length; + + const response = await axios.get(`${config.apiServiceUrl}/nodes/count?search=node`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(expectedCount); + }); + + it('should return nodes count filtered by online', async () => { + const nodesResponse = await axios.get(`${config.apiServiceUrl}/nodes?online=true`); + const expectedCount = nodesResponse.data.length; + + const response = await axios.get(`${config.apiServiceUrl}/nodes/count?online=true`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(expectedCount); + }); + + it('should return nodes count filtered by type', async () => { + const nodesResponse = await axios.get(`${config.apiServiceUrl}/nodes?type=validator`); + const expectedCount = nodesResponse.data.length; + + const response = await axios.get(`${config.apiServiceUrl}/nodes/count?type=validator`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(expectedCount); + }); + + it('should return nodes count filtered by status', async () => { + const nodesResponse = await axios.get(`${config.apiServiceUrl}/nodes?status=eligible`); + const expectedCount = nodesResponse.data.length; + + const response = await axios.get(`${config.apiServiceUrl}/nodes/count?status=eligible`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(expectedCount); + }); + + it('should return nodes count filtered by shard', async () => { + const shards = [0, 1, 4294967295]; + + for (const shard of shards) { + const nodesResponse = await axios.get(`${config.apiServiceUrl}/nodes?shard=${shard}`); + const expectedCount = nodesResponse.data.length; + + const response = await axios.get(`${config.apiServiceUrl}/nodes/count?shard=${shard}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(expectedCount); + } + }); + + it('should return nodes count filtered by owner', async () => { + const nodesResponse = await axios.get(`${config.apiServiceUrl}/nodes`); + const owner = nodesResponse.data[0].owner; + + const response = await axios.get(`${config.apiServiceUrl}/nodes/count?owner=${owner}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(1); + }); + }); + + describe('GET /nodes/count alternative', () => { + it('should return status code 200 and a number of nodes', async () => { + const nodesResponse = await axios.get(`${config.apiServiceUrl}/nodes`); + const expectedCount = nodesResponse.data.length; + + const countResponse = await axios.get(`${config.apiServiceUrl}/nodes/c`); + expect(countResponse.status).toBe(200); + expect(countResponse.data).toStrictEqual(expectedCount); + }); + + it('should return nodes count filtered by search', async () => { + const nodesResponse = await axios.get(`${config.apiServiceUrl}/nodes?search=node`); + const expectedCount = nodesResponse.data.length; + + const response = await axios.get(`${config.apiServiceUrl}/nodes/c?search=node`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(expectedCount); + }); + + it('should return nodes count filtered by online', async () => { + const nodesResponse = await axios.get(`${config.apiServiceUrl}/nodes?online=true`); + const expectedCount = nodesResponse.data.length; + + const response = await axios.get(`${config.apiServiceUrl}/nodes/c?online=true`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(expectedCount); + }); + + it('should return nodes count filtered by type', async () => { + const nodesResponse = await axios.get(`${config.apiServiceUrl}/nodes?type=validator`); + const expectedCount = nodesResponse.data.length; + + const response = await axios.get(`${config.apiServiceUrl}/nodes/c?type=validator`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(expectedCount); + }); + + it('should return nodes count filtered by status', async () => { + const nodesResponse = await axios.get(`${config.apiServiceUrl}/nodes?status=eligible`); + const expectedCount = nodesResponse.data.length; + + const response = await axios.get(`${config.apiServiceUrl}/nodes/c?status=eligible`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(expectedCount); + }); + + it('should return nodes count filtered by shard', async () => { + const shards = [0, 1, 4294967295]; + + for (const shard of shards) { + const nodesResponse = await axios.get(`${config.apiServiceUrl}/nodes?shard=${shard}`); + const expectedCount = nodesResponse.data.length; + + const response = await axios.get(`${config.apiServiceUrl}/nodes/c?shard=${shard}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(expectedCount); + } + }); + + it('should return nodes count filtered by owner', async () => { + const nodesResponse = await axios.get(`${config.apiServiceUrl}/nodes`); + const owner = nodesResponse.data[0].owner; + + const response = await axios.get(`${config.apiServiceUrl}/nodes/c?owner=${owner}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(1); + }); + }); + + describe('GET /nodes/:bls', () => { + it('should return status code 200 and a node', async () => { + const nodesResponse = await axios.get(`${config.apiServiceUrl}/nodes`); + const bls = nodesResponse.data[0].bls; + + const response = await axios.get(`${config.apiServiceUrl}/nodes/${bls}`); + expect(response.status).toBe(200); + + const expectedProps = [ + 'bls', + 'rating', + 'tempRating', + 'ratingModifier', + 'shard', + 'type', + 'status', + 'online', + 'nonce', + 'instances', + 'owner', + 'stake', + 'topUp', + 'locked', + 'leaderFailure', + 'leaderSuccess', + 'validatorFailure', + 'validatorIgnoredSignatures', + 'validatorSuccess', + 'position', + ]; + + for (const prop of expectedProps) { + expect(response.data).toHaveProperty(prop); + expect(response.data[prop]).toBeDefined(); + } + }); + + it('should return status code 404 if the node is not found', async () => { + const bls = '05ca60d1e19f52dbf9e68e03c74272c174ee007663da989fe91c5b0446dcb04de7837b7560d5a66faeb0281dbf672c085da0acad0f4c2d8c3297a1d4d51417b3ff703884b4792bc303eed92789c257bf38dd4a14ec58a0175f6659a06a295304'; + try { + await axios.get(`${config.apiServiceUrl}/nodes/${bls}`); + } catch (error: any) { + expect(error.response.status).toBe(404); + } + }); + + it('should return status code 400 if the bls key is not valid', async () => { + const invalidBls = 'invalid-bls-key'; + try { + await axios.get(`${config.apiServiceUrl}/nodes/${invalidBls}`); + } catch (error: any) { + expect(error.response.status).toBe(400); + } + }); + }); +}); diff --git a/src/test/chain-simulator/pool.cs-e2e.ts b/src/test/chain-simulator/pool.cs-e2e.ts new file mode 100644 index 000000000..e6329f68b --- /dev/null +++ b/src/test/chain-simulator/pool.cs-e2e.ts @@ -0,0 +1,63 @@ +import axios from 'axios'; +import { config } from './config/env.config'; + +describe('Pool e2e tests with chain simulator', () => { + describe('GET /pool', () => { + it('should return status code 200', async () => { + const response = await axios.get(`${config.apiServiceUrl}/pool`); + const txsPool = response.data; + + expect(response.status).toBe(200); + expect(txsPool).toBeInstanceOf(Array); + }); + + it('should return the transaction pool', async () => { + const response = await axios.get( + `${config.apiServiceUrl}/pool`, + ); + const pool = response.data; + const expectedProperties = [ + 'txHash', + 'nonce', + 'receiver', + 'gasPrice', + 'gasLimit', + ]; + + for (const tx of pool) { + for (const property of expectedProperties) { + expect(tx).toHaveProperty(property); + } + } + }); + }); + + describe('GET /pool/:txhash', () => { + it('should return status code 200 and the transaction', async () => { + const poolResponse = await axios.get( + `${config.apiServiceUrl}/pool?size=1`, + ); + const response = await axios.get( + `${config.apiServiceUrl}/pool/${poolResponse.data[0].txHash}`, + ); + const tx = response.data; + + expect(response.status).toBe(200); + expect(tx).toHaveProperty( + 'txHash', + poolResponse.data[0].txHash, + ); + }); + + it('should return status code 404 for non-existent tx hash', async () => { + const nonExistentTxHash = '0000000000000000000000000000000000000000000000000000000000000000'; + try { + await axios.get( + `${config.apiServiceUrl}/pool/${nonExistentTxHash}`, + ); + } catch (error: any) { + expect(error.response.status).toBe(404); + } + }); + }); +}); diff --git a/src/test/chain-simulator/results.cs-e2e.ts b/src/test/chain-simulator/results.cs-e2e.ts new file mode 100644 index 000000000..6a0168d99 --- /dev/null +++ b/src/test/chain-simulator/results.cs-e2e.ts @@ -0,0 +1,116 @@ +import axios from 'axios'; +import { config } from './config/env.config'; + +describe('Smart Contract Results e2e tests with chain simulator', () => { + describe('GET /results', () => { + it('should return status code 200 and a list of smart contract results', async () => { + const response = await axios.get(`${config.apiServiceUrl}/results`); + const results = response.data; + expect(response.status).toBe(200); + expect(results).toBeInstanceOf(Array); + }); + + it('should return filtered smart contract results by sender', async () => { + const sender = + 'erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqplllst77y4l'; + const response = await axios.get( + `${config.apiServiceUrl}/results?sender=${sender}`, + ); + const results = response.data; + expect(response.status).toBe(200); + for (const result of results) { + expect(result.sender).toBe(sender); + } + }); + + it('should return filtered smart contract results by receiver', async () => { + const receiver = + 'erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqplllst77y4l'; + const response = await axios.get( + `${config.apiServiceUrl}/results?receiver=${receiver}`, + ); + const results = response.data; + expect(response.status).toBe(200); + for (const result of results) { + expect(result.receiver).toBe(receiver); + } + }); + + // Skipped due to the lack of smart contract results with function 'transfer' + it.skip('should return filtered smart contract results by function', async () => { + const functionName = 'transfer'; + const response = await axios.get( + `${config.apiServiceUrl}/results?function=${functionName}`, + ); + const results = response.data; + expect(response.status).toBe(200); + for (const result of results) { + expect(result.function).toBe(functionName); + } + }); + }); + + describe('GET /results/count', () => { + it('should return status code 200 and the total count of smart contract results', async () => { + const response = await axios.get(`${config.apiServiceUrl}/results/count`); + const count = response.data; + expect(response.status).toBe(200); + expect(count).toBeGreaterThanOrEqual(1); + expect(typeof count).toBe('number'); + }); + + it('should return filtered smart contract results count by sender', async () => { + const sender = + 'erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqplllst77y4l'; + const response = await axios.get( + `${config.apiServiceUrl}/results/count?sender=${sender}`, + ); + const count = response.data; + expect(response.status).toBe(200); + expect(typeof count).toBe('number'); + }); + + it('should return filtered smart contract results count by receiver', async () => { + const receiver = + 'erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqplllst77y4l'; + const response = await axios.get( + `${config.apiServiceUrl}/results/count?receiver=${receiver}`, + ); + const count = response.data; + expect(response.status).toBe(200); + expect(typeof count).toBe('number'); + }); + + it('should return filtered smart contract results count by function', async () => { + const functionName = 'transfer'; + const response = await axios.get( + `${config.apiServiceUrl}/results/count?function=${functionName}`, + ); + const count = response.data; + expect(response.status).toBe(200); + expect(typeof count).toBe('number'); + }); + }); + + describe('GET /results/:scHash', () => { + it('should return status code 200 and smart contract result details (test )', async () => { + const results = await axios.get(`${config.apiServiceUrl}/results`); + const hash = results.data[0].hash; + + const response = await axios.get(`${config.apiServiceUrl}/results/${hash}`); + const result = response.data; + + expect(response.status).toBe(200); + expect(result).toHaveProperty('hash', hash); + }); + + it('should return status code 400 for invalid smart contract hash', async () => { + const scHash = 'nonExistentHash'; + try { + await axios.get(`${config.apiServiceUrl}/results/${scHash}`); + } catch (error: any) { + expect(error.response.status).toBe(400); + } + }); + }); +}); diff --git a/src/test/chain-simulator/rounds.cs-e2e.ts b/src/test/chain-simulator/rounds.cs-e2e.ts new file mode 100644 index 000000000..62147b079 --- /dev/null +++ b/src/test/chain-simulator/rounds.cs-e2e.ts @@ -0,0 +1,120 @@ +import axios from 'axios'; +import { config } from './config/env.config'; + +describe('Rounds e2e tests with chain simulator', () => { + describe('GET /rounds', () => { + it('sgould return status code 200', async () => { + const response = await axios.get(`${config.apiServiceUrl}/rounds`); + expect(response.status).toBe(200); + }); + + it('should return status code 200 and a list of rounds', async () => { + const response = await axios.get(`${config.apiServiceUrl}/rounds`); + const rounds = response.data; + expect(response.status).toBe(200); + expect(rounds).toBeInstanceOf(Array); + }); + + it('should support pagination and return 10 rounds', async () => { + const response = await axios.get(`${config.apiServiceUrl}/rounds?size=10`); + const rounds = response.data; + + expect(response.status).toBe(200); + expect(rounds.length).toBe(10); + expect(Array.isArray(rounds)).toBe(true); + }); + + it('should return filtered rounds by shard', async () => { + const shard = 0; + const response = await axios.get( + `${config.apiServiceUrl}/rounds?shard=${shard}`, + ); + + expect(response.status).toBe(200); + for (const round of response.data) { + expect(round.shard).toStrictEqual(shard); + } + }); + + it('should return filtered rounds by epoch', async () => { + const epoch = 2; + const response = await axios.get( + `${config.apiServiceUrl}/rounds?epoch=${epoch}`, + ); + expect(response.status).toBe(200); + + for (const round of response.data) { + expect(round.epoch).toBe(epoch); + } + }); + }); + + describe('GET /rounds/count', () => { + it('should return status code 200 and the total count of rounds', async () => { + const response = await axios.get(`${config.apiServiceUrl}/rounds/count`); + const rounds = response.data; + + expect(response.status).toBe(200); + expect(typeof rounds).toBe('number'); + expect(rounds).toBeGreaterThan(10); + }); + + it('should return filtered round count by shard', async () => { + const shard = 0; + const response = await axios.get( + `${config.apiServiceUrl}/rounds/count?shard=${shard}`, + ); + const rounds = response.data; + + expect(response.status).toBe(200); + expect(typeof rounds).toBe('number'); + }); + + it('should return filtered round count by epoch', async () => { + const epoch = 2; + const response = await axios.get( + `${config.apiServiceUrl}/rounds/count?epoch=${epoch}`, + ); + const rounds = response.data; + + expect(response.status).toBe(200); + expect(typeof rounds).toBe('number'); + }); + + it('should return filtered round count 0 by epoch if epoch value is high', async () => { + const epoch = 10000; + const response = await axios.get( + `${config.apiServiceUrl}/rounds/count?epoch=${epoch}`, + ); + const rounds = response.data; + + expect(response.status).toBe(200); + expect(typeof rounds).toBe('number'); + expect(rounds).toStrictEqual(0); + }); + }); + + describe('GET /rounds/:shard/:round', () => { + it('should return status code 200 and round details', async () => { + const shard = 0; + const round = 1; + const response = await axios.get( + `${config.apiServiceUrl}/rounds/${shard}/${round}`, + ); + const roundDetails = response.data; + expect(response.status).toBe(200); + expect(roundDetails).toHaveProperty('shard', shard); + expect(roundDetails).toHaveProperty('round', round); + }); + + it('should return status code 404 for non-existent round ', async () => { + const shard = 0; + const round = 999999; + try { + await axios.get(`${config.apiServiceUrl}/rounds/${shard}/${round}`); + } catch (error: any) { + expect(error.response.status).toBe(404); + } + }); + }); +}); diff --git a/src/test/chain-simulator/shards.cs-e2e.ts b/src/test/chain-simulator/shards.cs-e2e.ts new file mode 100644 index 000000000..e576cb392 --- /dev/null +++ b/src/test/chain-simulator/shards.cs-e2e.ts @@ -0,0 +1,71 @@ +import axios from 'axios'; +import { config } from "./config/env.config"; + +describe('Shards e2e tests with chain simulator', () => { + describe('GET /shards', () => { + it('should return status code 200 and a list of shards', async () => { + const response = await axios.get(`${config.apiServiceUrl}/shards`); + + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + }); + }); + + describe('GET /shards with pagination', () => { + it('should return status code 200 and paginated shards with default values', async () => { + const response = await axios.get(`${config.apiServiceUrl}/shards`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + expect(response.data.length).toBe(4); + }); + + it('should return paginated shards with custom size', async () => { + const size = 2; + const response = await axios.get(`${config.apiServiceUrl}/shards?size=${size}`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + expect(response.data.length).toBe(size); + }); + + it('should return paginated shards with custom from', async () => { + const from = 1; + const response = await axios.get(`${config.apiServiceUrl}/shards?from=${from}`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + expect(response.data.length).toBe(3); + }); + + it('should return paginated shards with both from and size', async () => { + const from = 1; + const size = 2; + const response = await axios.get(`${config.apiServiceUrl}/shards?from=${from}&size=${size}`); + expect(response.status).toBe(200); + expect(response.data).toBeInstanceOf(Array); + expect(response.data.length).toBe(size); + }); + + it('should validate shard structure and data', async () => { + const response = await axios.get(`${config.apiServiceUrl}/shards`); + const shards = response.data; + + for (const shard of shards) { + expect(shard).toHaveProperty('shard'); + expect(shard).toHaveProperty('validators'); + expect(shard).toHaveProperty('activeValidators'); + expect(typeof shard.shard).toBe('number'); + expect(typeof shard.validators).toBe('number'); + expect(typeof shard.activeValidators).toBe('number'); + } + }); + + it('should contain metachain shard (4294967295)', async () => { + const response = await axios.get(`${config.apiServiceUrl}/shards`); + const shards = response.data; + const metachainShard = shards.find((shard: { shard: number }) => shard.shard === 4294967295); + + expect(metachainShard).toBeDefined(); + expect(metachainShard?.validators).toBeGreaterThanOrEqual(1); + expect(metachainShard?.activeValidators).toBeGreaterThanOrEqual(1); + }); + }); +}); diff --git a/src/test/chain-simulator/stake.cs-e2e.ts b/src/test/chain-simulator/stake.cs-e2e.ts new file mode 100644 index 000000000..56cbfab8b --- /dev/null +++ b/src/test/chain-simulator/stake.cs-e2e.ts @@ -0,0 +1,47 @@ +import axios from "axios"; +import { config } from "./config/env.config"; + +describe('Stake e2e tests with chain simulator', () => { + describe('GET /stake', () => { + let stakeResponse: any; + + beforeEach(async () => { + stakeResponse = await axios.get(`${config.apiServiceUrl}/stake`); + }); + + it('should return status code 200 and a stake object', () => { + expect(stakeResponse.status).toBe(200); + expect(stakeResponse.data).toBeInstanceOf(Object); + }); + + it('should return the correct total number of validators', () => { + expect(stakeResponse.data.totalValidators).toBeGreaterThanOrEqual(0); + }); + + it('should return the correct number of active validators', () => { + expect(stakeResponse.data.activeValidators).toBeGreaterThanOrEqual(0); + }); + + it('should return the correct number of total observers', () => { + expect(stakeResponse.data.totalObservers).toBeGreaterThanOrEqual(0); + }); + + it('should return the correct queue size', () => { + expect(stakeResponse.data.queueSize).toBeGreaterThanOrEqual(0); + }); + + it('should return all expected properties in the response', () => { + const expectedProperties = [ + 'totalValidators', + 'activeValidators', + 'totalObservers', + 'queueSize', + 'totalStaked', + ]; + + for (const property of expectedProperties) { + expect(stakeResponse.data).toHaveProperty(property); + } + }); + }); +}); diff --git a/src/test/chain-simulator/tags.cs-e2e.ts b/src/test/chain-simulator/tags.cs-e2e.ts new file mode 100644 index 000000000..8274f91e0 --- /dev/null +++ b/src/test/chain-simulator/tags.cs-e2e.ts @@ -0,0 +1,62 @@ +import axios from 'axios'; +import { config } from "./config/env.config"; + +describe('Tags e2e tests with chain simulator', () => { + describe('GET /tags', () => { + it('should return the tags', async () => { + const response = await axios.get(`${config.apiServiceUrl}/tags`); + const expectedProperties = ['tag', 'count']; + + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(2); + + for (const tag of response.data) { + expect(Object.keys(tag)).toStrictEqual(expectedProperties); + } + }); + + it('should return the tags with pagination', async () => { + const response = await axios.get(`${config.apiServiceUrl}/tags?size=1&from=1`); + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(1); + }); + + it('should support different pagination sizes', async () => { + const firstSet = await axios.get(`${config.apiServiceUrl}/tags?from=0&size=1`); + const secondSet = await axios.get(`${config.apiServiceUrl}/tags?from=1&size=1`); + + expect(firstSet.status).toBe(200); + expect(secondSet.status).toBe(200); + + expect(firstSet.data.length).toStrictEqual(1); + expect(secondSet.data.length).toStrictEqual(1); + }); + + it('should return the tags with search', async () => { + const response = await axios.get(`${config.apiServiceUrl}/tags?search=test`); + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(1); + + expect(response.data[0].tag).toStrictEqual('test'); + }); + }); + + describe('GET /tags/count', () => { + it('should return the tags count', async () => { + const response = await axios.get(`${config.apiServiceUrl}/tags/count`); + expect(response.status).toBe(200); + expect(typeof response.data).toBe('number'); + expect(response.data).toStrictEqual(2); + }); + }); + + describe('GET /tags/:tag', () => { + it('should return the tag details', async () => { + const response = await axios.get(`${config.apiServiceUrl}/tags/test`); + expect(response.status).toBe(200); + expect(response.data.tag).toBe('test'); + expect(response.data.count).toBeGreaterThanOrEqual(0); + expect(typeof response.data.count).toBe('number'); + }); + }); +}); diff --git a/src/test/chain-simulator/tokens.cs-e2e.ts b/src/test/chain-simulator/tokens.cs-e2e.ts new file mode 100644 index 000000000..abe7c026c --- /dev/null +++ b/src/test/chain-simulator/tokens.cs-e2e.ts @@ -0,0 +1,423 @@ +import axios from 'axios'; +import { config } from './config/env.config'; + +const BOB_ADDRESS = + 'erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx'; + +describe('Tokens e2e tests with chain simulator', () => { + describe('GET /tokens', () => { + it('should return status code 200 and a list of tokens', async () => { + const response = await axios.get(`${config.apiServiceUrl}/tokens`); + const tokens = response.data; + + expect(response.status).toBe(200); + expect(tokens).toBeInstanceOf(Array); + }); + + it('should return filtered tokens by name', async () => { + const tokenName = 'Token1'; + const response = await axios.get( + `${config.apiServiceUrl}/tokens?name=${tokenName}`, + ); + const tokens = response.data; + + expect(response.status).toBe(200); + for (const token of tokens) { + expect(token.name).toBe(tokenName); + } + }); + + it('should return filtered tokens by identifier', async () => { + const fetchTokens = await axios.get(`${config.apiServiceUrl}/tokens`); + const tokenIdentifier = fetchTokens.data[0].identifier; + const response = await axios.get( + `${config.apiServiceUrl}/tokens?identifier=${tokenIdentifier}`, + ); + const tokens = response.data; + + expect(response.status).toBe(200); + for (const token of tokens) { + expect(token.identifier).toBe(tokenIdentifier); + } + }); + + it('should support pagination and return 2 tokens', async () => { + const response = await axios.get(`${config.apiServiceUrl}/tokens?size=2`); + const tokens = response.data; + + expect(response.status).toBe(200); + expect(tokens.length).toBe(2); + expect(Array.isArray(tokens)).toBe(true); + }); + + it('should return filtered tokens by type', async () => { + const tokenType = 'FungibleESDT'; + const response = await axios.get( + `${config.apiServiceUrl}/tokens?type=${tokenType}`, + ); + const tokens = response.data; + + expect(response.status).toBe(200); + for (const token of tokens) { + expect(token.type).toBe(tokenType); + } + }); + + it('should return filtered tokens by multiple identifiers', async () => { + const fetchTokens = await axios.get(`${config.apiServiceUrl}/tokens`); + const identifiers = fetchTokens.data.map( + (token: any) => token.identifier, + ); + const response = await axios.get( + `${config.apiServiceUrl}/tokens?identifiers=${identifiers.join(',')}`, + ); + const tokens = response.data; + + expect(response.status).toBe(200); + for (const token of tokens) { + expect(identifiers).toContain(token.identifier); + } + }); + + it('should return filtered tokens by search term', async () => { + const searchTerm = 'Token1'; + const response = await axios.get( + `${config.apiServiceUrl}/tokens?search=${searchTerm}`, + ); + const tokens = response.data; + + expect(response.status).toBe(200); + for (const token of tokens) { + expect(token.name).toContain(searchTerm); + } + }); + }); + + describe('GET /tokens/count', () => { + it('should return status code 200 and the total count of tokens', async () => { + const response = await axios.get(`${config.apiServiceUrl}/tokens/count`); + const count = response.data; + + expect(response.status).toBe(200); + expect(count).toBeGreaterThanOrEqual(0); + expect(typeof count).toBe('number'); + }); + + it('should return filtered token count by name', async () => { + const tokenName = 'Token1'; + const response = await axios.get( + `${config.apiServiceUrl}/tokens/count?name=${tokenName}`, + ); + const count = response.data; + + expect(response.status).toBe(200); + expect(typeof count).toBe('number'); + }); + + it('should return filtered token count by search term', async () => { + const searchTerm = 'Token'; + const response = await axios.get( + `${config.apiServiceUrl}/tokens/count?search=${searchTerm}`, + ); + const count = response.data; + + expect(response.status).toBe(200); + expect(typeof count).toBe('number'); + }); + }); + + describe('GET /tokens/:identifier', () => { + it('should return status code 200 and token details', async () => { + const tokensResponse = await axios.get( + `${config.apiServiceUrl}/tokens?size=1`, + ); + const response = await axios.get( + `${config.apiServiceUrl}/tokens/${tokensResponse.data[0].identifier}`, + ); + const token = response.data; + + expect(response.status).toBe(200); + expect(token).toHaveProperty( + 'identifier', + tokensResponse.data[0].identifier, + ); + }); + + it('should return status code 400 for non-existent token', async () => { + const nonExistentTokenIdentifier = 'NON_EXISTENT_TOKEN'; + try { + await axios.get( + `${config.apiServiceUrl}/tokens/${nonExistentTokenIdentifier}`, + ); + } catch (error: any) { + expect(error.response.status).toBe(400); + } + }); + + it('should return token details with denominated supply (number)', async () => { + const tokensResponse = await axios.get( + `${config.apiServiceUrl}/tokens?size=1`, + ); + const response = await axios.get( + `${config.apiServiceUrl}/tokens/${tokensResponse.data[0].identifier}?denominated=true`, + ); + const token = response.data; + + expect(response.status).toBe(200); + expect(token).toHaveProperty( + 'identifier', + tokensResponse.data[0].identifier, + ); + expect(token).toHaveProperty('supply'); + expect(typeof token.supply).toStrictEqual('number'); + }); + + it('should return token details with supply (string)', async () => { + const tokensResponse = await axios.get( + `${config.apiServiceUrl}/tokens?size=1`, + ); + const response = await axios.get( + `${config.apiServiceUrl}/tokens/${tokensResponse.data[0].identifier}?denominated=false`, + ); + const token = response.data; + + expect(response.status).toBe(200); + expect(token).toHaveProperty( + 'identifier', + tokensResponse.data[0].identifier, + ); + expect(token).toHaveProperty('supply'); + expect(typeof token.supply).toStrictEqual('string'); + }); + }); + + describe('GET /tokens/:identifier/roles', () => { + it('should return status code 200 and token roles', async () => { + const tokensResponse = await axios.get( + `${config.apiServiceUrl}/tokens?size=1`, + ); + const response = await axios.get( + `${config.apiServiceUrl}/tokens/${tokensResponse.data[0].identifier}/roles`, + ); + const roles = response.data; + + expect(response.status).toBe(200); + expect(roles).toBeInstanceOf(Array); + for (const role of roles) { + expect(role).toHaveProperty('canLocalMint'); + expect(role).toHaveProperty('canLocalBurn'); + expect(role).toHaveProperty('roles'); + expect(role.roles).toBeInstanceOf(Array); + } + }); + + it('should return status code 400 for invalid token identifier', async () => { + const nonExistentTokenIdentifier = 'NON_EXISTENT_TOKEN'; + try { + await axios.get( + `${config.apiServiceUrl}/tokens/${nonExistentTokenIdentifier}/roles`, + ); + } catch (error: any) { + expect(error.response.status).toBe(400); + } + }); + + it('should return status code 404 for non-existent token roles', async () => { + const nonExistentTokenIdentifier = 'TKNTEST1-f61adc'; + try { + await axios.get( + `${config.apiServiceUrl}/tokens/${nonExistentTokenIdentifier}/roles`, + ); + } catch (error: any) { + expect(error.response.status).toBe(404); + } + }); + }); + + describe('GET /tokens/:identifier/roles/:address', () => { + it('should return status code 200 and token roles for the address', async () => { + const tokensResponse = await axios.get( + `${config.apiServiceUrl}/tokens?size=1`, + ); + const response = await axios.get( + `${config.apiServiceUrl}/tokens/${tokensResponse.data[0].identifier}/roles/${config.aliceAddress}`, + ); + const roles = response.data; + expect(response.status).toBe(200); + expect(roles).toHaveProperty('canLocalMint'); + expect(roles).toHaveProperty('canLocalBurn'); + }); + + it('should return status code 400 for non-existent token roles for the address', async () => { + const nonExistentTokenIdentifier = 'NON_EXISTENT_TOKEN'; + try { + await axios.get( + `${config.apiServiceUrl}/tokens/${nonExistentTokenIdentifier}/roles/${config.aliceAddress}`, + ); + } catch (error: any) { + expect(error.response.status).toBe(400); + } + }); + + it('should return status code 404 for non-existent address roles for the token', async () => { + const tokensResponse = await axios.get( + `${config.apiServiceUrl}/tokens?size=1`, + ); + + try { + await axios.get( + `${config.apiServiceUrl}/tokens/${tokensResponse.data[0].identifier}/roles/${BOB_ADDRESS}`, + ); + } catch (error: any) { + expect(error.response.status).toBe(404); + } + }); + }); + + describe('GET /tokens/:identifier/transfers', () => { + it('should return status code 200 and a list of transfers', async () => { + const tokensResponse = await axios.get( + `${config.apiServiceUrl}/tokens?size=1`, + ); + const response = await axios.get( + `${config.apiServiceUrl}/tokens/${tokensResponse.data[0].identifier}/transfers`, + ); + const transfers = response.data; + expect(response.status).toBe(200); + expect(transfers).toBeInstanceOf(Array); + }); + + it('should return filtered transfers by receiver', async () => { + const tokensResponse = await axios.get( + `${config.apiServiceUrl}/tokens?size=1`, + ); + const response = await axios.get( + `${config.apiServiceUrl}/tokens/${tokensResponse.data[0].identifier}/transfers?receiver=${config.aliceAddress}`, + ); + const transfers = response.data; + expect(response.status).toBe(200); + for (const transfer of transfers) { + expect(transfer.receiver).toBe(config.aliceAddress); + } + }); + + it('should return filtered transfers by receiver', async () => { + const sender = + 'erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u'; + const tokensResponse = await axios.get( + `${config.apiServiceUrl}/tokens?size=1`, + ); + const response = await axios.get( + `${config.apiServiceUrl}/tokens/${tokensResponse.data[0].identifier}/transfers?receiver=${sender}`, + ); + const transfers = response.data; + expect(response.status).toBe(200); + for (const transfer of transfers) { + expect(transfer.receiver).toBe(BOB_ADDRESS); + } + }); + + it('should return filtered transfers by status', async () => { + const tokensResponse = await axios.get( + `${config.apiServiceUrl}/tokens?size=1`, + ); + const status = 'success'; + const response = await axios.get( + `${config.apiServiceUrl}/tokens/${tokensResponse.data[0].identifier}/transfers?status=${status}`, + ); + const transfers = response.data; + expect(response.status).toBe(200); + for (const transfer of transfers) { + expect(transfer.status).toBe(status); + } + }); + + it('should support pagination and return 1 transfer', async () => { + const tokensResponse = await axios.get( + `${config.apiServiceUrl}/tokens?size=1`, + ); + const response = await axios.get( + `${config.apiServiceUrl}/tokens/${tokensResponse.data[0].identifier}/transfers?size=1`, + ); + const transfers = response.data; + expect(response.status).toBe(200); + expect(transfers.length).toBe(1); + expect(Array.isArray(transfers)).toBe(true); + }); + + it('should return status code 400 for non-existent token transfers', async () => { + const nonExistentTokenIdentifier = 'NON_EXISTENT_TOKEN'; + try { + await axios.get( + `${config.apiServiceUrl}/tokens/${nonExistentTokenIdentifier}/transfers`, + ); + } catch (error: any) { + expect(error.response.status).toBe(400); + } + }); + }); + + describe('GET /tokens/:identifier/transfers/count', () => { + it('should return status code 200 and the total count of transfers', async () => { + const tokensResponse = await axios.get( + `${config.apiServiceUrl}/tokens?size=1`, + ); + const response = await axios.get( + `${config.apiServiceUrl}/tokens/${tokensResponse.data[0].identifier}/transfers/count`, + ); + const count = response.data; + expect(response.status).toBe(200); + expect(typeof count).toBe('number'); + }); + + it('should return filtered transfer count by sender', async () => { + const sender = + 'erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u'; + const tokensResponse = await axios.get( + `${config.apiServiceUrl}/tokens?size=1`, + ); + const response = await axios.get( + `${config.apiServiceUrl}/tokens/${tokensResponse.data[0].identifier}/transfers/count?sender=${sender}`, + ); + const count = response.data; + expect(response.status).toBe(200); + expect(typeof count).toBe('number'); + }); + + it('should return filtered transfer count by receiver', async () => { + const tokensResponse = await axios.get( + `${config.apiServiceUrl}/tokens?size=1`, + ); + const response = await axios.get( + `${config.apiServiceUrl}/tokens/${tokensResponse.data[0].identifier}/transfers/count?receiver=${config.aliceAddress}`, + ); + const count = response.data; + expect(response.status).toBe(200); + expect(typeof count).toBe('number'); + }); + + it('should return filtered transfer count by status', async () => { + const tokensResponse = await axios.get( + `${config.apiServiceUrl}/tokens?size=1`, + ); + const status = 'success'; + const response = await axios.get( + `${config.apiServiceUrl}/tokens/${tokensResponse.data[0].identifier}/transfers/count?status=${status}`, + ); + const count = response.data; + expect(response.status).toBe(200); + expect(typeof count).toBe('number'); + }); + + it('should return status code 400 for non-existent token transfers count', async () => { + const nonExistentTokenIdentifier = 'NON_EXISTENT_TOKEN'; + try { + await axios.get( + `${config.apiServiceUrl}/tokens/${nonExistentTokenIdentifier}/transfers/count`, + ); + } catch (error: any) { + expect(error.response.status).toBe(400); + } + }); + }); +}); diff --git a/src/test/chain-simulator/transactions.cs-e2e.ts b/src/test/chain-simulator/transactions.cs-e2e.ts new file mode 100644 index 000000000..620880805 --- /dev/null +++ b/src/test/chain-simulator/transactions.cs-e2e.ts @@ -0,0 +1,358 @@ +import axios from "axios"; +import { config } from "./config/env.config"; + +describe('Transactions e2e tests with chain simulator', () => { + describe('GET /transactions', () => { + it('should return status code 200 and a list of transactions', async () => { + const response = await axios.get(`${config.apiServiceUrl}/transactions`); + expect(response.status).toBe(200); + }); + + it('should support pagination', async () => { + const response = await axios.get(`${config.apiServiceUrl}/transactions?from=0&size=1`); + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(1); + }); + + it('should return transactions with sender filter applied', async () => { + const response = await axios.get(`${config.apiServiceUrl}/transactions?sender=${config.aliceAddress}`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThan(1); + + for (const transaction of response.data) { + expect(transaction.sender).toBe(config.aliceAddress); + } + }); + + it('should return transactions with receiver filter applied', async () => { + const receiver = 'erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu'; + const response = await axios.get(`${config.apiServiceUrl}/transactions?receiver=${receiver}`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThan(1); + + for (const transaction of response.data) { + expect(transaction.receiver).toBe(receiver); + } + }); + + it('should correctly filter transactions by senderShard', async () => { + const allTransactions = await axios.get(`${config.apiServiceUrl}/transactions`); + expect(allTransactions.status).toBe(200); + expect(allTransactions.data.length).toBeGreaterThan(0); + + const availableShards = [...new Set(allTransactions.data.map((tx: { senderShard: number }) => tx.senderShard))]; + expect(availableShards.length).toBeGreaterThan(0); + + const testShard = availableShards[0]; + const response = await axios.get(`${config.apiServiceUrl}/transactions?senderShard=${testShard}`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThan(0); + + for (const transaction of response.data) { + expect(transaction.senderShard).toBe(testShard); + } + }); + + it('should return transactions with receiverShard filter applied', async () => { + const receiverShard = 0; + const response = await axios.get(`${config.apiServiceUrl}/transactions?receiverShard=${receiverShard}`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + + for (const transaction of response.data) { + expect(transaction.receiverShard).toBe(receiverShard); + } + }); + + it.skip('should return transactions with miniBlockHash filter applied', async () => { + const transaction = await axios.get(`${config.apiServiceUrl}/transactions?size=1`); + const miniBlockHash = transaction.data[0].miniBlockHash; + const response = await axios.get(`${config.apiServiceUrl}/transactions?miniBlockHash=${miniBlockHash}`); + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(1); + + for (const transaction of response.data) { + expect(transaction.miniBlockHash).toBe(miniBlockHash); + } + }); + + it('should return transactions with hashes filter applied', async () => { + const transaction = await axios.get(`${config.apiServiceUrl}/transactions?size=2`); + const hashes = [transaction.data[0].txHash, transaction.data[1].txHash]; + const response = await axios.get(`${config.apiServiceUrl}/transactions?hashes=${hashes}`); + expect(response.status).toBe(200); + expect(response.data.length).toStrictEqual(2); + + for (const transaction of response.data) { + expect(hashes).toContain(transaction.txHash); + } + }); + + it('should return transactions with status filter applied', async () => { + const response = await axios.get(`${config.apiServiceUrl}/transactions?status=success`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + + for (const transaction of response.data) { + expect(transaction.status).toBe('success'); + } + }); + + it('should return transactions with function filter applied', async () => { + const response = await axios.get(`${config.apiServiceUrl}/transactions?function=scDeploy`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + + for (const transaction of response.data) { + expect(transaction.function).toBe('scDeploy'); + } + }); + + it('should return transactions with round filter applied', async () => { + const transaction = await axios.get(`${config.apiServiceUrl}/transactions?size=1`); + const round = transaction.data[0].round; + const response = await axios.get(`${config.apiServiceUrl}/transactions?round=${round}`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThanOrEqual(1); + + for (const transaction of response.data) { + expect(transaction.round).toBe(round); + } + }); + + it('should return transactions with withLogs filter applied and logs present', async () => { + const response = await axios.get(`${config.apiServiceUrl}/transactions?withLogs=true&size=50`); + expect(response.status).toBe(200); + }); + + it('should return transactions with withOperations filter applied and operations present', async () => { + const response = await axios.get(`${config.apiServiceUrl}/transactions?withOperations=true`); + expect(response.status).toBe(200); + const hasOperations = response.data.some((transaction: any) => transaction.operations && transaction.operations.length > 0); + expect(hasOperations).toBe(true); + }); + + it('should return transactions with withBlockInfo filter applied and block info present', async () => { + const response = await axios.get(`${config.apiServiceUrl}/transactions?withBlockInfo=true`); + expect(response.status).toBe(200); + const hasBlockInfo = response.data.some((transaction: any) => + transaction.senderBlockHash && + transaction.senderBlockNonce && + transaction.receiverBlockHash && + transaction.receiverBlockNonce + ); + expect(hasBlockInfo).toBe(true); + }); + + it('should return 400 Bad Request when size > 50 with withScResults parameter', async () => { + try { + await axios.get(`${config.apiServiceUrl}/transactions?size=51&withScResults=true`); + fail('Should have thrown error'); + } catch (error: any) { + expect(error.response.status).toBe(400); + } + }); + + it('should return 400 Bad Request when size > 50 with withOperations parameter', async () => { + try { + await axios.get(`${config.apiServiceUrl}/transactions?size=51&withOperations=true`); + fail('Should have thrown error'); + } catch (error: any) { + expect(error.response.status).toBe(400); + } + }); + + it('should return 400 Bad Request when size > 50 with withLogs parameter', async () => { + try { + await axios.get(`${config.apiServiceUrl}/transactions?size=51&withLogs=true`); + fail('Should have thrown error'); + } catch (error: any) { + expect(error.response.status).toBe(400); + } + }); + + it('should return 400 Bad Request when size > 50 with withBlockInfo parameter', async () => { + try { + await axios.get(`${config.apiServiceUrl}/transactions?size=51&withBlockInfo=true`); + fail('Should have thrown error'); + } catch (error: any) { + expect(error.response.status).toBe(400); + } + }); + + it('should validate all transactions contain required fields', async () => { + const response = await axios.get(`${config.apiServiceUrl}/transactions?size=10`); + expect(response.status).toBe(200); + + const expectedFields = [ + 'txHash', + 'gasLimit', + 'gasPrice', + 'gasUsed', + 'miniBlockHash', + 'nonce', + 'receiver', + 'receiverShard', + 'round', + 'sender', + 'senderShard', + 'status', + 'value', + 'timestamp', + 'function', + ]; + + for (const transaction of response.data) { + for (const field of expectedFields) { + expect(transaction).toHaveProperty(field); + } + } + }); + + it('should return transactions filtered by isScCall parameter', async () => { + const response = await axios.get(`${config.apiServiceUrl}/transactions?isScCall=true`); + expect(response.status).toBe(200); + + for (const transaction of response.data) { + expect(transaction.isScCall).toBe(true); + } + }); + + it('should handle isScCall field appropriately when isScCall parameter is not provided', async () => { + const response = await axios.get(`${config.apiServiceUrl}/transactions`); + expect(response.status).toBe(200); + expect(response.data.length).toBeGreaterThan(0); + + const hasScCalls = response.data.some((tx: { isScCall?: boolean }) => tx.isScCall === true); + const hasNonScCalls = response.data.some((tx: { isScCall?: boolean }) => tx.isScCall === false); + + expect(hasScCalls || hasNonScCalls).toBe(true); + }); + + it('should return transactions without isScCall field when isScCall parameter is false', async () => { + const response = await axios.get(`${config.apiServiceUrl}/transactions?isScCall=false`); + expect(response.status).toBe(200); + + for (const transaction of response.data) { + expect(transaction.isScCall).toBeUndefined(); + } + }); + }); + + describe('GET /transactions/count', () => { + it('should return the total number of transactions', async () => { + const response = await axios.get(`${config.apiServiceUrl}/transactions/count`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThan(0); + expect(typeof response.data).toBe('number'); + }); + + it('should return the total number of transactions with sender filter applied', async () => { + const response = await axios.get(`${config.apiServiceUrl}/transactions/count?sender=${config.aliceAddress}`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThan(0); + expect(typeof response.data).toBe('number'); + }); + + it('should return the total number of transactions with receiver filter applied', async () => { + const receiver = 'erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu'; + const response = await axios.get(`${config.apiServiceUrl}/transactions/count?receiver=${receiver}`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThan(0); + expect(typeof response.data).toBe('number'); + }); + + it('should return the total number of transactions with senderShard filter applied', async () => { + const senderShard = 0; + const response = await axios.get(`${config.apiServiceUrl}/transactions/count?senderShard=${senderShard}`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(0); + expect(typeof response.data).toBe('number'); + }); + + it('should return the total number of transactions with receiverShard filter applied', async () => { + const receiverShard = 0; + const response = await axios.get(`${config.apiServiceUrl}/transactions/count?receiverShard=${receiverShard}`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThan(0); + expect(typeof response.data).toBe('number'); + }); + + it.skip('should return the total number of transactions with miniBlockHash filter applied', async () => { + const transaction = await axios.get(`${config.apiServiceUrl}/transactions?size=1`); + const miniBlockHash = transaction.data[0].miniBlockHash; + const response = await axios.get(`${config.apiServiceUrl}/transactions/count?miniBlockHash=${miniBlockHash}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(1); + expect(typeof response.data).toBe('number'); + }); + + it('should return the total number of transactions with hashes filter applied', async () => { + const transaction = await axios.get(`${config.apiServiceUrl}/transactions?size=2`); + const hashes = [transaction.data[0].txHash, transaction.data[1].txHash]; + const response = await axios.get(`${config.apiServiceUrl}/transactions/count?hashes=${hashes}`); + expect(response.status).toBe(200); + expect(response.data).toStrictEqual(2); + }); + + it('should return the total number of transactions with status filter applied', async () => { + const response = await axios.get(`${config.apiServiceUrl}/transactions/count?status=success`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(1); + expect(typeof response.data).toBe('number'); + }); + + it('should return the total number of transactions with function filter applied', async () => { + const response = await axios.get(`${config.apiServiceUrl}/transactions/count?function=scDeploy`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(1); + expect(typeof response.data).toBe('number'); + }); + + it('should return the total number of transactions with before filter applied', async () => { + const transaction = await axios.get(`${config.apiServiceUrl}/transactions?size=1`); + const before = transaction.data[0].timestamp; + const response = await axios.get(`${config.apiServiceUrl}/transactions/count?before=${before}`); + expect(response.status).toBe(200); + expect(response.data).toBeGreaterThanOrEqual(1); + expect(typeof response.data).toBe('number'); + }); + + it('should return the total number of transactions with round filter applied', async () => { + const transaction = await axios.get(`${config.apiServiceUrl}/transactions?size=1`); + const round = transaction.data[0].round; + const response = await axios.get(`${config.apiServiceUrl}/transactions/count?round=${round}`); + expect(response.status).toBe(200); + }); + }); + + describe('GET /transactions/:txHash', () => { + it('should return a transaction by hash', async () => { + const transaction = await axios.get(`${config.apiServiceUrl}/transactions?size=1`); + const txHash = transaction.data[0].txHash; + const response = await axios.get(`${config.apiServiceUrl}/transactions/${txHash}`); + + const expectedFields = [ + 'txHash', + 'gasLimit', + 'gasPrice', + 'gasUsed', + 'miniBlockHash', + 'nonce', + 'receiver', + 'receiverShard', + 'round', + 'sender', + 'senderShard', + 'status', + 'value', + 'timestamp', + 'function', + ]; + + for (const field of expectedFields) { + expect(response.data).toHaveProperty(field); + } + }); + }); +}); diff --git a/src/test/chain-simulator/utils/chain.simulator.operations.ts b/src/test/chain-simulator/utils/chain.simulator.operations.ts new file mode 100644 index 000000000..1b39153fa --- /dev/null +++ b/src/test/chain-simulator/utils/chain.simulator.operations.ts @@ -0,0 +1,551 @@ +import axios from 'axios'; +import { AddressUtils } from "@multiversx/sdk-nestjs-common"; + +const VM_TYPE = '0500'; +const CODE_METADATA = '0100'; +const SC_DEPLOY_ADDRESS = + 'erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu'; +const ESDT_ADDRESS = + 'erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u'; + +export async function fundAddress(chainSimulatorUrl: string, address: string) { + const payload = [ + { + address: address, + balance: '100000000000000000000000', + }, + ]; + await axios.post(`${chainSimulatorUrl}/simulator/set-state`, payload); +} + +export async function getNonce( + chainSimulatorUrl: string, + address: string, +): Promise { + try { + const currentNonceResponse = await axios.get( + `${chainSimulatorUrl}/address/${address}/nonce`, + ); + return currentNonceResponse.data.data.nonce; + } catch (e) { + console.error(e); + return 0; + } +} + +export async function deploySc(args: DeployScArgs): Promise { + try { + const contractCodeHex = Buffer.from(args.contractCodeRaw).toString('hex'); + const contractArgs = [VM_TYPE, CODE_METADATA, ...args.hexArguments]; + const contractPayload = contractCodeHex + '@' + contractArgs.join('@'); + + const txHash = await sendTransaction( + new SendTransactionArgs({ + chainSimulatorUrl: args.chainSimulatorUrl, + sender: args.deployer, + receiver: SC_DEPLOY_ADDRESS, + dataField: contractPayload, + }), + ); + + const txResponse = await axios.get( + `${args.chainSimulatorUrl}/transaction/${txHash}?withResults=true`, + ); + const scDeployLog = txResponse?.data?.data?.transaction?.logs?.events?.find( + (event: { identifier: string }) => event.identifier === 'SCDeploy', + ); + console.log( + `Deployed SC. tx hash: ${txHash}. address: ${scDeployLog?.address}`, + ); + return scDeployLog?.address; + } catch (e) { + console.error(e); + return 'n/a'; + } +} + +export async function issueEsdt(args: IssueEsdtArgs) { + const txHash = await sendTransaction( + new SendTransactionArgs({ + chainSimulatorUrl: args.chainSimulatorUrl, + sender: args.issuer, + receiver: ESDT_ADDRESS, + dataField: `issue@${Buffer.from(args.tokenName).toString( + 'hex', + )}@${Buffer.from(args.tokenTicker).toString( + 'hex', + )}@1e9b0e04e39e5845000000@12`, + value: '50000000000000000', + }), + ); + + const txResponse = await axios.get( + `${args.chainSimulatorUrl}/transaction/${txHash}?withResults=true`, + ); + const esdtIssueLog = txResponse?.data?.data?.transaction?.logs?.events?.find( + (event: { identifier: string }) => event.identifier === 'issue', + ); + const tokenIdentifier = Buffer.from( + esdtIssueLog.topics[0], + 'base64', + ).toString(); + console.log( + `Issued token with ticker ${args.tokenTicker}. tx hash: ${txHash}. identifier: ${tokenIdentifier}`, + ); + return tokenIdentifier; +} + +export async function transferEsdt(args: TransferEsdtArgs) { + const transferValue = args.plainAmountOfTokens * 10 ** 18; + return await sendTransaction( + new SendTransactionArgs({ + chainSimulatorUrl: args.chainSimulatorUrl, + sender: args.sender, + receiver: args.receiver, + dataField: `ESDTTransfer@${Buffer.from(args.tokenIdentifier).toString( + 'hex', + )}@${transferValue.toString(16)}`, + value: '0', + }), + ); +} + +export async function sendTransaction( + args: SendTransactionArgs, +): Promise { + try { + const nonce = await getNonce(args.chainSimulatorUrl, args.sender); + + const tx = { + sender: args.sender, + receiver: args.receiver, + nonce: nonce + (args.nonceOffset ?? 0), + value: args.value, + gasPrice: 1000000000, + gasLimit: args.gasLimit ?? (50_000 + 1_500 * args.dataField.length), + data: Buffer.from(args.dataField).toString('base64'), + signature: 'a'.repeat(128), + chainID: 'chain', + version: 1, + }; + + const txHashResponse = await axios.post( + `${args.chainSimulatorUrl}/transaction/send`, + tx, + ); + const txHash = txHashResponse.data.data.txHash; + if (args.nonceOffset) { + // when a nonce offset is present, it means that the transaction won't be executed in real time, so we should early exit + console.log(`Broadcasted tx hash ${txHash} of sender ${args.sender} with nonce ${tx.nonce}`); + console.log(JSON.stringify(tx)); + await axios.post( + `${args.chainSimulatorUrl}/simulator/generate-blocks/1`, + ); + return txHash; + } + + await axios.post( + `${args.chainSimulatorUrl}/simulator/generate-blocks-until-transaction-processed/${txHash}`, + ); + return txHash; + } catch (e) { + console.error(e); + return 'n/a'; + } +} + +export async function issueMultipleEsdts( + chainSimulatorUrl: string, + issuer: string, + numTokens: number, +) { + const tokenIdentifiers = []; + for (let i = 1; i <= numTokens; i++) { + const tokenName = `Token${i}`; + const tokenTicker = `TKN${i}`; + const tokenIdentifier = await issueEsdt( + new IssueEsdtArgs({ + chainSimulatorUrl, + issuer, + tokenName, + tokenTicker, + }), + ); + tokenIdentifiers.push(tokenIdentifier); + } + return tokenIdentifiers; +} + +export class SendTransactionArgs { + chainSimulatorUrl: string = ''; + sender: string = ''; + receiver: string = ''; + dataField: string = ''; + value?: string = '0'; + gasLimit?: number = 100_000_000; + nonceOffset?: number = 0; // useful for scenarios where a higher nonce is desired + + constructor(options: Partial = {}) { + Object.assign(this, options); + } +} + +export class IssueEsdtArgs { + chainSimulatorUrl: string = ''; + issuer: string = ''; + tokenName: string = ''; + tokenTicker: string = ''; + + constructor(options: Partial = {}) { + Object.assign(this, options); + } +} + +export class TransferEsdtArgs { + chainSimulatorUrl: string = ''; + sender: string = ''; + receiver: string = ''; + tokenIdentifier: string = ''; + plainAmountOfTokens: number = 1; + + constructor(options: Partial = {}) { + Object.assign(this, options); + } +} + +export class DeployScArgs { + chainSimulatorUrl: string = ''; + deployer: string = ''; + contractCodeRaw: Buffer = Buffer.from(''); + hexArguments: string[] = []; + + constructor(options: Partial = {}) { + Object.assign(this, options); + } +} + +export async function issueCollection(args: IssueNftArgs, type: 'NonFungible' | 'SemiFungible'): Promise { + const properties = [ + 'canFreeze', + 'canWipe', + 'canPause', + 'canTransferNFTCreateRole', + 'canChangeOwner', + 'canUpgrade', + 'canAddSpecialRoles', + ]; + + const dataFields = [ + `issue${type}`, + Buffer.from(args.tokenName).toString('hex'), + Buffer.from(args.tokenTicker).toString('hex'), + ]; + + // Add all properties and their values in hex + for (const prop of properties) { + dataFields.push(Buffer.from(prop).toString('hex')); + dataFields.push(Buffer.from('true').toString('hex')); + } + + const txHash = await sendTransaction( + new SendTransactionArgs({ + chainSimulatorUrl: args.chainSimulatorUrl, + sender: args.issuer, + receiver: ESDT_ADDRESS, + dataField: dataFields.join('@'), + value: '50000000000000000', + gasLimit: 60000000, + }) + ); + + const txResponse = await axios.get( + `${args.chainSimulatorUrl}/transaction/${txHash}?withResults=true` + ); + + const issueLog = txResponse?.data?.data?.transaction?.logs?.events?.find( + (event: { identifier: string }) => event.identifier === `issue${type}` + ); + + const tokenIdentifier = Buffer.from( + issueLog.topics[0], + 'base64' + ).toString(); + + console.log( + `Issued ${type} collection with ticker ${args.tokenTicker}. tx hash: ${txHash}. identifier: ${tokenIdentifier}` + ); + + return tokenIdentifier; +} + +export async function issueNftCollection(args: IssueNftArgs): Promise { + return await issueCollection(args, 'NonFungible'); +} + +export async function issueSftCollection(args: IssueNftArgs): Promise { + return await issueCollection(args, 'SemiFungible'); +} + +export async function issueMultipleNftsCollections( + chainSimulatorUrl: string, + issuer: string, + numCollections: number, + numNfts: number, + collectionType: 'nft' | 'sft' | 'both' = 'nft' // Default to NFT for backward compatibility +) { + const nftCollectionIdentifiers = []; + for (let i = 1; i <= numCollections; i++) { + if (collectionType === 'nft' || collectionType === 'both') { + const nftTokenName = `NFTCollection${i}`; + const nftTokenTicker = `NFT${i}`; + const nftTokenIdentifier = await issueNftCollection( + new IssueNftArgs({ + chainSimulatorUrl, + issuer, + tokenName: nftTokenName, + tokenTicker: nftTokenTicker, + }), + ); + nftCollectionIdentifiers.push({ identifier: nftTokenIdentifier, type: 'nft' }); + } + + if (collectionType === 'sft' || collectionType === 'both') { + const sftTokenName = `SFTCollection${i}`; + const sftTokenTicker = `SFT${i}`; + const sftTokenIdentifier = await issueSftCollection( + new IssueNftArgs({ + chainSimulatorUrl, + issuer, + tokenName: sftTokenName, + tokenTicker: sftTokenTicker, + }), + ); + nftCollectionIdentifiers.push({ identifier: sftTokenIdentifier, type: 'sft' }); + } + } + + // Wait a bit before setting roles + await new Promise(resolve => setTimeout(resolve, 5000)); + + // Set roles for each collection + for (const { identifier: tokenIdentifier, type } of nftCollectionIdentifiers) { + const roles = []; + if (type === 'sft') { + roles.push( + Buffer.from('ESDTRoleNFTCreate').toString('hex'), + Buffer.from('ESDTRoleNFTBurn').toString('hex'), + Buffer.from('ESDTRoleNFTAddQuantity').toString('hex'), + Buffer.from('ESDTTransferRole').toString('hex') + ); + } else { + roles.push( + Buffer.from('ESDTRoleNFTCreate').toString('hex'), + Buffer.from('ESDTRoleNFTBurn').toString('hex'), + Buffer.from('ESDTRoleNFTUpdateAttributes').toString('hex'), + Buffer.from('ESDTRoleNFTAddURI').toString('hex'), + Buffer.from('ESDTTransferRole').toString('hex') + ); + } + + const dataFields = [ + 'setSpecialRole', + Buffer.from(tokenIdentifier).toString('hex'), + AddressUtils.bech32Decode(issuer), + ...roles, + ]; + + const txHash = await sendTransaction( + new SendTransactionArgs({ + chainSimulatorUrl, + sender: issuer, + receiver: ESDT_ADDRESS, + dataField: dataFields.join('@'), + value: '0', + gasLimit: 60000000, + }) + ); + + console.log( + `Set special roles for collection ${tokenIdentifier}. tx hash: ${txHash}` + ); + + // Wait a bit after setting roles before creating NFT + await new Promise(resolve => setTimeout(resolve, 5000)); + + // Create multiple NFT's / SFT's for each collection + for (let j = 1; j <= numNfts; j++) { + const nftCreateDataFields = [ + 'ESDTNFTCreate', + Buffer.from(tokenIdentifier).toString('hex'), + type === 'sft' ? '0a' : '01', + Buffer.from(`Test${type === 'sft' ? 'SFT' : 'NFT'}${j}`).toString('hex'), + '0064', + Buffer.from('TestHash').toString('hex'), + Buffer.from(`tags:test,example;description:Test ${type === 'sft' ? 'SFT' : 'NFT'} ${j}`).toString('hex'), + Buffer.from('https://example.com/nft.png').toString('hex'), + Buffer.from('https://example.com/nft.json').toString('hex'), + ]; + + const createTxHash = await sendTransaction( + new SendTransactionArgs({ + chainSimulatorUrl, + sender: issuer, + receiver: issuer, + dataField: nftCreateDataFields.join('@'), + value: '0', + gasLimit: 100000000, + }) + ); + + // Check transaction status + const txResponse = await axios.get( + `${chainSimulatorUrl}/transaction/${createTxHash}?withResults=true` + ); + + if (txResponse?.data?.data?.status === 'fail') { + console.error(`Failed to create NFT ${j} for collection ${tokenIdentifier}. tx hash: ${createTxHash}`); + console.error('Error:', txResponse?.data?.data?.logs?.events[0]?.topics[1]); + } else { + console.log( + `Created ${type === 'sft' ? 'SFT' : 'NFT'}${j} for collection ${tokenIdentifier}. tx hash: ${createTxHash}` + ); + } + } + } + + return nftCollectionIdentifiers.map(x => x.identifier); +} + +export class IssueNftArgs { + chainSimulatorUrl: string = ''; + issuer: string = ''; + tokenName: string = ''; + tokenTicker: string = ''; + + constructor(options: Partial = {}) { + Object.assign(this, options); + } +} + +export async function issueMultipleMetaESDTCollections( + chainSimulatorUrl: string, + issuer: string, + numberOfCollections: number, + tokensPerCollection: number +): Promise { + const metaEsdtCollectionIdentifiers: { identifier: string }[] = []; + + for (let i = 0; i < numberOfCollections; i++) { + const tokenName = `MetaESDTCollection${i}`; + const tokenTicker = `META${i}`; + + const txHash = await sendTransaction( + new SendTransactionArgs({ + chainSimulatorUrl: chainSimulatorUrl, + sender: issuer, + receiver: ESDT_ADDRESS, + value: '50000000000000000', + gasLimit: 60000000, + dataField: [ + 'registerMetaESDT', + Buffer.from(tokenName).toString('hex'), + Buffer.from(tokenTicker).toString('hex'), + '12', // number of decimals + Buffer.from('canFreeze').toString('hex'), + Buffer.from('true').toString('hex'), + Buffer.from('canWipe').toString('hex'), + Buffer.from('true').toString('hex'), + Buffer.from('canPause').toString('hex'), + Buffer.from('true').toString('hex'), + Buffer.from('canTransferNFTCreateRole').toString('hex'), + Buffer.from('true').toString('hex'), + Buffer.from('canChangeOwner').toString('hex'), + Buffer.from('true').toString('hex'), + Buffer.from('canUpgrade').toString('hex'), + Buffer.from('true').toString('hex'), + Buffer.from('canAddSpecialRoles').toString('hex'), + Buffer.from('true').toString('hex'), + ].join('@'), + }), + ); + + const txResponse = await axios.get( + `${chainSimulatorUrl}/transaction/${txHash}?withResults=true`, + ); + + const esdtIssueLog = txResponse?.data?.data?.transaction?.logs?.events?.find( + (event: { identifier: string }) => event.identifier === 'registerMetaESDT', + ); + + if (esdtIssueLog) { + const tokenIdentifier = Buffer.from( + esdtIssueLog.topics[0], + 'base64', + ).toString(); + + metaEsdtCollectionIdentifiers.push({ identifier: tokenIdentifier }); + + console.log( + `Issued MetaESDT collection ${tokenName}. tx hash: ${txHash}. identifier: ${tokenIdentifier}`, + ); + + // Set special roles for the MetaESDT collection + const setRolesTxHash = await sendTransaction( + new SendTransactionArgs({ + chainSimulatorUrl: chainSimulatorUrl, + sender: issuer, + receiver: ESDT_ADDRESS, + value: '0', + gasLimit: 60000000, + dataField: [ + 'setSpecialRole', + Buffer.from(tokenIdentifier).toString('hex'), + AddressUtils.bech32Decode(issuer), + Buffer.from('ESDTRoleNFTCreate').toString('hex'), + Buffer.from('ESDTRoleNFTBurn').toString('hex'), + Buffer.from('ESDTRoleNFTAddQuantity').toString('hex'), + ].join('@'), + }), + ); + + console.log( + `Set special roles for collection ${tokenIdentifier}. tx hash: ${setRolesTxHash}` + ); + + // Wait a bit after setting roles + await new Promise(resolve => setTimeout(resolve, 5000)); + + // Create MetaESDT tokens for this collection + for (let j = 1; j <= tokensPerCollection; j++) { + const createTxHash = await sendTransaction( + new SendTransactionArgs({ + chainSimulatorUrl, + sender: issuer, + receiver: issuer, + dataField: [ + 'ESDTNFTCreate', + Buffer.from(tokenIdentifier).toString('hex'), + '0a', // Initial quantity (10) + Buffer.from(`TestMetaESDT${j}`).toString('hex'), + '0064', // Royalties (100 = 1%) + Buffer.from('TestHash').toString('hex'), + Buffer.from(`tags:test,example;description:Test MetaESDT ${j}`).toString('hex'), + Buffer.from('https://example.com/nft.png').toString('hex'), + Buffer.from('https://example.com/nft.json').toString('hex'), + ].join('@'), + value: '0', + gasLimit: 100000000, + }) + ); + + console.log( + `Created MetaESDT${j} for collection ${tokenIdentifier}. tx hash: ${createTxHash}` + ); + } + } + } + + return metaEsdtCollectionIdentifiers.map(x => x.identifier); +} + + diff --git a/src/test/chain-simulator/utils/contracts/ping-pong-egld.wasm b/src/test/chain-simulator/utils/contracts/ping-pong-egld.wasm new file mode 100644 index 0000000000000000000000000000000000000000..fcf8eecd259400aa10d3f33b808d2e3baac68cca GIT binary patch literal 1349 zcmZuxO>f&q5S`tnELtmBE7_4Fxk*-v0_2iw5cK4AYWD+$5x{PHlxb=85u2n!F75gx z`_OZH=%Kw8D0<2v$Nq?3`WN~~+Rl)4;sPZ=?(UnJH}ht92|*e%0AP=+C%{%Ge6_+a z08QY86xdNnzM71CQhX3#*mZLwi}2)%Z^V1;xgAZpUYb@vGn}SH&se zX6aZaq`?;Mn}y!}qfd^HlORe_WU0CRzEjk{uY>c<7A;&a3@^iFLD4MR{7tfOsAX0( za;xw#!Z^cS?E7OZcP|*9!JwKgXGt)z@US)-O#&B;aGwN| zqtV<3%h73&TET1YyjGpDmD(JDVj5%@7v_f>pWde&3_BaZa}H?P0wpvYc)Lw$e!uoj zR{_XY5z94bro5i!w+KcWAOz$A`aA}s&IWu4nrmk6JN#V#E#4U4B{=mj@)cPwlH@tB zBON#O*Tz#7tCSzZ|L48ca!xQ-!(to_|E_a98H<| z2cN3uJAGDXl1zqu3}7;~AyL-@)m6;~Q|&%i9}NUb+|dH@o>G{bI*0p(C(As^`TxS% zkY+(pM}0p|9WMu%DIkjRba a+95n$d}}8<%|f~l%kuYUnWfk{6A literal 0 HcmV?d00001 diff --git a/src/test/chain-simulator/utils/prepare-test-data.ts b/src/test/chain-simulator/utils/prepare-test-data.ts new file mode 100644 index 000000000..e02a454b9 --- /dev/null +++ b/src/test/chain-simulator/utils/prepare-test-data.ts @@ -0,0 +1,37 @@ +import { config } from '../config/env.config'; +import { fundAddress, issueMultipleEsdts, issueMultipleMetaESDTCollections, issueMultipleNftsCollections } from './chain.simulator.operations'; +import { ChainSimulatorUtils } from './test.utils'; + +async function prepareTestData() { + try { + console.log('Starting test data preparation...'); + + console.log('Waiting for epoch 2...'); + await ChainSimulatorUtils.waitForEpoch(2); + console.log('✓ Chain simulator reached epoch 2'); + + await fundAddress(config.chainSimulatorUrl, config.aliceAddress); + console.log('✓ Funded address'); + + await issueMultipleEsdts(config.chainSimulatorUrl, config.aliceAddress, 5); + console.log('✓ Issued ESDTs'); + + await issueMultipleNftsCollections(config.chainSimulatorUrl, config.aliceAddress, 2, 5, 'both'); + console.log('✓ Issued NFT collections'); + + await issueMultipleMetaESDTCollections(config.chainSimulatorUrl, config.aliceAddress, 2, 5); + console.log('✓ Issued Meta-ESDT collections'); + + await ChainSimulatorUtils.deployPingPongSc(config.aliceAddress); + console.log('✓ Deployed PingPong smart contract'); + + await new Promise((resolve) => setTimeout(resolve, 30000)); + + console.log('Test data preparation completed successfully!'); + } catch (error) { + console.error('Error preparing test data:', error); + process.exit(1); + } +} + +void prepareTestData(); diff --git a/src/test/chain-simulator/utils/test.utils.ts b/src/test/chain-simulator/utils/test.utils.ts new file mode 100644 index 000000000..41e20f9fa --- /dev/null +++ b/src/test/chain-simulator/utils/test.utils.ts @@ -0,0 +1,99 @@ +import axios from 'axios'; +import { config } from '../config/env.config'; +import { DeployScArgs } from './chain.simulator.operations'; +import { fundAddress } from './chain.simulator.operations'; +import { deploySc } from './chain.simulator.operations'; +import fs from 'fs'; +export class ChainSimulatorUtils { + static async waitForEpoch(targetEpoch: number = 2, maxRetries: number = 50) { + try { + // First check if simulator is running + await this.checkSimulatorHealth(maxRetries); + + let retries = 0; + while (retries < maxRetries) { + try { + const networkStatus = await axios.get(`${config.chainSimulatorUrl}/network/status/4294967295`); + const currentEpoch = networkStatus.data.erd_epoch_number; + + if (currentEpoch >= targetEpoch) { + return true; + } + + await axios.post( + `${config.chainSimulatorUrl}/simulator/generate-blocks-until-epoch-reached/${targetEpoch}`, + {}, + ); + + // Verify we reached the target epoch + const stats = await axios.get(`${config.apiServiceUrl}/stats`); + const newEpoch = stats.data.epoch; + + if (newEpoch >= targetEpoch) { + return true; + } + + retries++; + await new Promise(resolve => setTimeout(resolve, 1000)); + } catch (error) { + retries++; + if (retries >= maxRetries) { + throw new Error(`Failed to reach epoch ${targetEpoch} after ${maxRetries} retries`); + } + await new Promise(resolve => setTimeout(resolve, 1000)); + } + } + + throw new Error(`Failed to reach epoch ${targetEpoch} after ${maxRetries} retries`); + } catch (error) { + console.error('Error in waitForEpoch:', error); + throw error; + } + } + + private static async checkSimulatorHealth(maxRetries: number = 50): Promise { + let retries = 0; + + while (retries < maxRetries) { + try { + const response = await axios.get(`${config.chainSimulatorUrl}/simulator/observers`); + if (response.status === 200) { + return true; + } + } catch (error) { + retries++; + if (retries >= maxRetries) { + throw new Error('Chain simulator not started or not responding!'); + } + // Wait for 1 second before retrying + await new Promise(resolve => setTimeout(resolve, 1000)); + } + } + + return false; + } + + public static async deployPingPongSc(deployer: string): Promise { + try { + const contractCodeRaw = fs.readFileSync('./src/test/chain-simulator/utils/contracts/ping-pong-egld.wasm'); + const contractArgs = [ + '0de0b6b3a7640000', + ]; + + await fundAddress(config.chainSimulatorUrl, deployer); + + const scAddress = await deploySc(new DeployScArgs({ + chainSimulatorUrl: config.chainSimulatorUrl, + deployer: deployer, + contractCodeRaw: contractCodeRaw, + hexArguments: contractArgs, + })); + + console.log(`Deployed ping pong SC. Address: ${scAddress} with deployer: ${deployer}`); + return scAddress; + } catch (error) { + console.error('Error deploying ping pong SC:', error); + throw error; + } + } +} diff --git a/src/test/chain-simulator/utils/testSequencer.js b/src/test/chain-simulator/utils/testSequencer.js new file mode 100644 index 000000000..f1a70a4a8 --- /dev/null +++ b/src/test/chain-simulator/utils/testSequencer.js @@ -0,0 +1,39 @@ +const Sequencer = require('@jest/test-sequencer').default; + +class CustomSequencer extends Sequencer { + sort(tests) { + const orderPath = [ + 'tokens.cs-e2e.ts', + 'collections.cs-e2e.ts', + 'nfts.cs-e2e.ts', + 'network.cs-e2e.ts', + 'hello.cs-e2e.ts', + 'blocks.cs-e2e.ts', + 'delegation.cs-e2e.ts', + 'delegation-legacy.cs-e2e.ts', + 'accounts.cs-e2e.ts', + 'stake.cs-e2e.ts', + 'round.cs-e2e.ts', + 'results.cs-e2e.ts', + 'miniblocks.cs-e2e.ts', + ]; + + return tests.sort((testA, testB) => { + const indexA = orderPath.findIndex(path => testA.path.includes(path)); + const indexB = orderPath.findIndex(path => testB.path.includes(path)); + + if (indexA !== -1 && indexB !== -1) { + return indexA - indexB; + } + if (indexA !== -1) { + return -1; + } + if (indexB !== -1) { + return 1; + } + return 0; + }); + } +} + +module.exports = CustomSequencer; diff --git a/src/test/chain-simulator/websocket-config.cs-e2e.ts b/src/test/chain-simulator/websocket-config.cs-e2e.ts new file mode 100644 index 000000000..b09149625 --- /dev/null +++ b/src/test/chain-simulator/websocket-config.cs-e2e.ts @@ -0,0 +1,12 @@ +import axios from "axios"; +import { config } from "./config/env.config"; + +describe('Websocket config e2e tests with chain simulator', () => { + describe('GET /websocket/config', () => { + it('should return status code 200 and websocket config', async () => { + const response = await axios.get(`${config.apiServiceUrl}/websocket/config`); + expect(response.status).toBe(200); + expect(response.data.url).toStrictEqual('socket-api-fra.multiversx.com'); + }); + }); +}); diff --git a/src/test/jest-api.json b/src/test/jest-api.json index 913123878..4b0a4b665 100644 --- a/src/test/jest-api.json +++ b/src/test/jest-api.json @@ -17,4 +17,4 @@ "../.." ], "testTimeout": 180000 -} \ No newline at end of file +} diff --git a/src/test/jest-chain-simulator.json b/src/test/jest-chain-simulator.json new file mode 100644 index 000000000..b3beb1ab2 --- /dev/null +++ b/src/test/jest-chain-simulator.json @@ -0,0 +1,21 @@ +{ + "moduleFileExtensions": [ + "js", + "json", + "ts" + ], + "rootDir": "../../", + "testEnvironment": "node", + "testSequencer": "/src/test/chain-simulator/utils/testSequencer.js", + "testRegex": ".cs-e2e.ts$", + "transform": { + "^.+\\.(t|j)s$": "ts-jest" + }, + "modulePaths": [ + "" + ], + "collectCoverageFrom": [ + "./src/**/*.(t|j)s" + ], + "testTimeout": 180000 +} \ No newline at end of file diff --git a/src/test/unit/controllers/mex.controller.spec.ts b/src/test/unit/controllers/mex.controller.spec.ts index 4ea1c1029..ab913746d 100644 --- a/src/test/unit/controllers/mex.controller.spec.ts +++ b/src/test/unit/controllers/mex.controller.spec.ts @@ -11,6 +11,7 @@ import request = require('supertest'); import { PublicAppModule } from "src/public.app.module"; import { QueryPagination } from "src/common/entities/query.pagination"; import { MexPairExchange } from "src/endpoints/mex/entities/mex.pair.exchange"; +import { MexPairsFilter } from 'src/endpoints/mex/entities/mex.pairs..filter'; describe('MexController', () => { let app: INestApplication; @@ -68,7 +69,7 @@ describe('MexController', () => { .expect(200); expect(mexPairServiceMocks.getMexPairs).toHaveBeenCalledWith( - 0, 25, { "exchange": undefined } + 0, 25, new MexPairsFilter({ exchange: undefined, includeFarms: false }) ); }); @@ -81,7 +82,7 @@ describe('MexController', () => { .expect(200); expect(mexPairServiceMocks.getMexPairs).toHaveBeenCalledWith( - 0, 5, { "exchange": undefined } + 0, 5, new MexPairsFilter({ exchange: undefined, includeFarms: false }) ); }); @@ -94,7 +95,7 @@ describe('MexController', () => { .expect(200); expect(mexPairServiceMocks.getMexPairs).toHaveBeenCalledWith( - 0, 5, { "exchange": MexPairExchange.xexchange } + 0, 5, new MexPairsFilter({ exchange: MexPairExchange.xexchange, includeFarms: false }) ); }); @@ -107,7 +108,7 @@ describe('MexController', () => { .expect(200); expect(mexPairServiceMocks.getMexPairs).toHaveBeenCalledWith( - 0, 5, { "exchange": MexPairExchange.unknown } + 0, 5, new MexPairsFilter({ exchange: MexPairExchange.unknown, includeFarms: false }) ); }); @@ -121,7 +122,7 @@ describe('MexController', () => { }); expect(mexPairServiceMocks.getMexPairsCount).toHaveBeenCalledWith( - { "exchange": undefined } + new MexPairsFilter({ exchange: undefined, includeFarms: false }) ); }); @@ -135,7 +136,7 @@ describe('MexController', () => { }); expect(mexPairServiceMocks.getMexPairsCount).toHaveBeenCalledWith( - { "exchange": MexPairExchange.xexchange } + new MexPairsFilter({ exchange: MexPairExchange.xexchange, includeFarms: false }) ); }); @@ -149,7 +150,7 @@ describe('MexController', () => { }); expect(mexPairServiceMocks.getMexPairsCount).toHaveBeenCalledWith( - { "exchange": MexPairExchange.unknown } + new MexPairsFilter({ exchange: MexPairExchange.unknown, includeFarms: false }) ); }); @@ -162,7 +163,44 @@ describe('MexController', () => { .get(`${path}/pairs/${baseId}/${quoteId}`) .expect(200); - expect(mexPairServiceMocks.getMexPair).toHaveBeenCalledWith(baseId, quoteId); + expect(mexPairServiceMocks.getMexPair).toHaveBeenCalledWith(baseId, quoteId, false); + }); + + it('should return mex pairs with farms information', async () => { + mexPairServiceMocks.getMexPairs.mockReturnValue([]); + await request(app.getHttpServer()) + .get(`${path}/pairs?includeFarms=true`) + .expect(200); + + expect(mexPairServiceMocks.getMexPairs).toHaveBeenCalledWith( + 0, 25, new MexPairsFilter({ exchange: undefined, includeFarms: true }) + ); + }); + + it('should return mex pair with farms information', async () => { + mexPairServiceMocks.getMexPair.mockReturnValue({}); + const baseId = 'MEX-455c57'; + const quoteId = 'WEGLD-bd4d79'; + + await request(app.getHttpServer()) + .get(`${path}/pairs/${baseId}/${quoteId}?includeFarms=true`) + .expect(200); + + expect(mexPairServiceMocks.getMexPair).toHaveBeenCalledWith(baseId, quoteId, true); + }); + + it('should return total mex pairs count with farms information', async () => { + mexPairServiceMocks.getMexPairsCount.mockReturnValue(10); + await request(app.getHttpServer()) + .get(`${path}/pairs/count?includeFarms=true`) + .expect(200) + .expect(response => { + expect(+response.text).toStrictEqual(10); + }); + + expect(mexPairServiceMocks.getMexPairsCount).toHaveBeenCalledWith( + new MexPairsFilter({ exchange: undefined, includeFarms: true }) + ); }); }); diff --git a/src/test/unit/services/applications.spec.ts b/src/test/unit/services/applications.spec.ts index 65de79ac4..6cc7bb6af 100644 --- a/src/test/unit/services/applications.spec.ts +++ b/src/test/unit/services/applications.spec.ts @@ -6,12 +6,19 @@ import { ApplicationFilter } from 'src/endpoints/applications/entities/applicati import { AssetsService } from '../../../common/assets/assets.service'; import { AccountAssetsSocial } from '../../../common/assets/entities/account.assets.social'; import { AccountAssets } from '../../../common/assets/entities/account.assets'; +import { Application } from 'src/endpoints/applications/entities/application'; +import { GatewayService } from 'src/common/gateway/gateway.service'; +import { TransferService } from 'src/endpoints/transfers/transfer.service'; +import { CacheService } from '@multiversx/sdk-nestjs-cache'; +import { BadRequestException } from '@nestjs/common'; describe('ApplicationService', () => { let service: ApplicationService; let indexerService: ElasticIndexerService; let assetsService: AssetsService; - + let gatewayService: GatewayService; + let transferService: TransferService; + let cacheService: CacheService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [ @@ -29,12 +36,33 @@ describe('ApplicationService', () => { getAllAccountAssets: jest.fn(), }, }, + { + provide: GatewayService, + useValue: { + getAddressDetails: jest.fn(), + }, + }, + { + provide: TransferService, + useValue: { + getTransfersCount: jest.fn(), + }, + }, + { + provide: CacheService, + useValue: { + getOrSet: jest.fn(), + }, + }, ], }).compile(); service = module.get(ApplicationService); indexerService = module.get(ElasticIndexerService); assetsService = module.get(AssetsService); + gatewayService = module.get(GatewayService); + transferService = module.get(TransferService); + cacheService = module.get(CacheService); }); it('should be defined', () => { @@ -80,22 +108,37 @@ describe('ApplicationService', () => { jest.spyOn(indexerService, 'getApplications').mockResolvedValue(indexResult); jest.spyOn(assetsService, 'getAllAccountAssets').mockResolvedValue(assets); + jest.spyOn(gatewayService, 'getAddressDetails').mockResolvedValue({ + account: { + address: '', + nonce: 0, + balance: '0', + username: '', + code: '', + codeHash: '', + rootHash: '', + codeMetadata: '', + developerReward: '', + ownerAddress: '', + }, + }); const queryPagination = new QueryPagination(); const filter = new ApplicationFilter(); - const result = await service.getApplications(queryPagination, filter); + const result = await service.getApplicationsRaw(queryPagination, filter); expect(indexerService.getApplications).toHaveBeenCalledWith(filter, queryPagination); expect(indexerService.getApplications).toHaveBeenCalledTimes(1); expect(assetsService.getAllAccountAssets).toHaveBeenCalled(); - const expectedApplications = indexResult.map(item => ({ + const expectedApplications = indexResult.map(item => new Application({ contract: item.address, deployer: item.deployer, owner: item.currentOwner, codeHash: item.initialCodeHash, timestamp: item.timestamp, assets: assets[item.address], + balance: '0', })); expect(result).toEqual(expectedApplications); @@ -115,6 +158,67 @@ describe('ApplicationService', () => { expect(result).toEqual([]); }); + + it('should return an array of applications with tx count', async () => { + const indexResult = [ + { + address: 'erd1qqqqqqqqqqqqqpgq8372f63glekg7zl22tmx7wzp4drql25r6avs70dmp0', + deployer: 'erd1j770k2n46wzfn5g63gjthhqemu9r23n9tp7seu95vpz5gk5s6avsk5aams', + currentOwner: 'erd1j770k2n46wzfn5g63gjthhqemu9r23n9tp7seu95vpz5gk5s6avsk5aams', + initialCodeHash: 'kDh8hR9vyceELMUuy6JdAg0X90+ZaLeyVQS6tPbY82s=', + timestamp: 1724955216, + }, + ]; + + jest.spyOn(indexerService, 'getApplications').mockResolvedValue(indexResult); + jest.spyOn(assetsService, 'getAllAccountAssets').mockResolvedValue({}); + jest.spyOn(gatewayService, 'getAddressDetails').mockResolvedValue({ + account: { + address: '', + nonce: 0, + balance: '0', + username: '', + code: '', + codeHash: '', + rootHash: '', + codeMetadata: '', + developerReward: '', + ownerAddress: '', + }, + }); + jest.spyOn(transferService, 'getTransfersCount').mockResolvedValue(42); + + const queryPagination = new QueryPagination(); + const filter = new ApplicationFilter({ withTxCount: true }); + const result = await service.getApplicationsRaw(queryPagination, filter); + + const expectedApplications = indexResult.map(item => new Application({ + contract: item.address, + deployer: item.deployer, + owner: item.currentOwner, + codeHash: item.initialCodeHash, + timestamp: item.timestamp, + balance: '0', + txCount: 42, + })); + + expect(result).toEqual(expectedApplications); + expect(transferService.getTransfersCount).toHaveBeenCalled(); + }); + + it('should return an empty array of applications from cache', async () => { + const queryPagination = new QueryPagination(); + const filter = new ApplicationFilter(); + jest.spyOn(cacheService, 'getOrSet').mockResolvedValue([]); + const result = await service.getApplications(queryPagination, filter); + expect(result).toEqual([]); + }); + + it('should throw an error when size is greater than 25 and withTxCount is set', async () => { + const queryPagination = new QueryPagination({ size: 50 }); + const filter = new ApplicationFilter({ withTxCount: true }); + await expect(service.getApplications(queryPagination, filter)).rejects.toThrow(BadRequestException); + }); }); describe('getApplicationsCount', () => { diff --git a/src/test/unit/services/graphql.service.spec.ts b/src/test/unit/services/graphql.service.spec.ts index 4f184aa02..25a61e43c 100644 --- a/src/test/unit/services/graphql.service.spec.ts +++ b/src/test/unit/services/graphql.service.spec.ts @@ -14,6 +14,7 @@ describe('GraphQlService', () => { mockApiConfigService = { getExchangeServiceUrlMandatory: jest.fn().mockReturnValue('https://graph.xexchange.com/graphql'), getMarketplaceServiceUrl: jest.fn().mockReturnValue('https://nfts-graph.multiversx.com/graphql'), + getSelfUrl: jest.fn().mockReturnValue('https://api.multiversx.com'), }; mockGraphQLClient = { diff --git a/src/utils/cache.info.ts b/src/utils/cache.info.ts index d95dcec43..7af510671 100644 --- a/src/utils/cache.info.ts +++ b/src/utils/cache.info.ts @@ -338,6 +338,11 @@ export class CacheInfo { ttl: Constants.oneMinute() * 10, }; + static MexPairsWithFarms: CacheInfo = { + key: 'mexPairsWithFarms', + ttl: Constants.oneMinute() * 10, + }; + static MexTokens: CacheInfo = { key: "mexTokens", ttl: Constants.oneMinute() * 10, @@ -692,7 +697,7 @@ export class CacheInfo { static Applications(queryPagination: QueryPagination): CacheInfo { return { key: `applications:${queryPagination.from}:${queryPagination.size}`, - ttl: Constants.oneHour(), + ttl: Constants.oneMinute(), }; } diff --git a/tsconfig.json b/tsconfig.json index 783e96093..8d7f8f65a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -36,6 +36,14 @@ "node_modules/@types", ], "skipLibCheck": true, - "resolveJsonModule": true - } + "resolveJsonModule": true, + "types": [ + "jest", + "node" + ] + }, + "include": [ + "src/**/*", + "test/**/*" + ] } \ No newline at end of file From 2cd40748c58fa0fdc179adf43d1f25f92598783f Mon Sep 17 00:00:00 2001 From: bogdan-rosianu <51945539+bogdan-rosianu@users.noreply.github.com> Date: Tue, 18 Mar 2025 14:53:29 +0200 Subject: [PATCH 15/25] Added custom hrp support (#1465) * added custom hrp support * use sdk-js library config for custom hrp * add logs + extend about endpoint * fix unit test --- config/config.devnet-old.yaml | 2 ++ config/config.devnet.yaml | 2 ++ config/config.e2e-mocked.mainnet.yaml | 2 ++ config/config.e2e.mainnet.yaml | 2 ++ config/config.mainnet.yaml | 2 ++ config/config.testnet.yaml | 2 ++ src/common/api-config/api.config.service.ts | 4 ++++ src/endpoints/network/entities/about.ts | 3 +++ src/endpoints/network/entities/feature.configs.ts | 6 ++++++ src/endpoints/network/network.service.ts | 3 +++ .../transactions.batch/transactions.batch.service.ts | 9 ++++++++- src/main.ts | 4 ++++ src/test/unit/controllers/network.controller.spec.ts | 3 +++ 13 files changed, 43 insertions(+), 1 deletion(-) diff --git a/config/config.devnet-old.yaml b/config/config.devnet-old.yaml index b57e84e0e..e6d6722b5 100644 --- a/config/config.devnet-old.yaml +++ b/config/config.devnet-old.yaml @@ -123,6 +123,8 @@ inflation: - 1130177 - 924690 - 719203 +chainSettings: + hrp: 'erd' nftProcess: parallelism: 1 maxRetries: 3 diff --git a/config/config.devnet.yaml b/config/config.devnet.yaml index f5fd9befc..840351797 100644 --- a/config/config.devnet.yaml +++ b/config/config.devnet.yaml @@ -167,6 +167,8 @@ inflation: - 1130177 - 924690 - 719203 +chainSettings: + hrp: 'erd' nftProcess: parallelism: 1 maxRetries: 3 diff --git a/config/config.e2e-mocked.mainnet.yaml b/config/config.e2e-mocked.mainnet.yaml index e848cd20b..046e11588 100644 --- a/config/config.e2e-mocked.mainnet.yaml +++ b/config/config.e2e-mocked.mainnet.yaml @@ -67,6 +67,8 @@ inflation: - 1130177 - 924690 - 719203 +chainSettings: + hrp: 'erd' security: admins: jwtSecret: diff --git a/config/config.e2e.mainnet.yaml b/config/config.e2e.mainnet.yaml index 7ea314cf7..93d574fde 100644 --- a/config/config.e2e.mainnet.yaml +++ b/config/config.e2e.mainnet.yaml @@ -171,6 +171,8 @@ inflation: - 1130177 - 924690 - 719203 +chainSettings: + hrp: 'erd' nftProcess: parallelism: 1 maxRetries: 3 diff --git a/config/config.mainnet.yaml b/config/config.mainnet.yaml index ecea5b5d9..36ba639f5 100644 --- a/config/config.mainnet.yaml +++ b/config/config.mainnet.yaml @@ -171,6 +171,8 @@ inflation: - 1130177 - 924690 - 719203 +chainSettings: + hrp: 'erd' nftProcess: parallelism: 1 maxRetries: 3 diff --git a/config/config.testnet.yaml b/config/config.testnet.yaml index 16c13888b..27704b75d 100644 --- a/config/config.testnet.yaml +++ b/config/config.testnet.yaml @@ -170,6 +170,8 @@ inflation: - 1130177 - 924690 - 719203 +chainSettings: + hrp: 'erd' nftProcess: parallelism: 1 maxRetries: 3 diff --git a/src/common/api-config/api.config.service.ts b/src/common/api-config/api.config.service.ts index 71a972595..1b74001a6 100644 --- a/src/common/api-config/api.config.service.ts +++ b/src/common/api-config/api.config.service.ts @@ -871,6 +871,10 @@ export class ApiConfigService { return deepHistoryUrl; } + getChainHrp(): string { + return this.configService.get('chainSettings.hrp') ?? 'erd'; + } + isAssetsCdnFeatureEnabled(): boolean { return this.configService.get('features.assetsFetch.enabled') ?? false; } diff --git a/src/endpoints/network/entities/about.ts b/src/endpoints/network/entities/about.ts index e61665f13..56c7c94cf 100644 --- a/src/endpoints/network/entities/about.ts +++ b/src/endpoints/network/entities/about.ts @@ -21,6 +21,9 @@ export class About { @ApiProperty({ type: String }) version: string = ''; + @ApiProperty({ type: String }) + hrp: string = 'erd'; + @ApiProperty({ type: String }) indexerVersion: string | undefined = undefined; diff --git a/src/endpoints/network/entities/feature.configs.ts b/src/endpoints/network/entities/feature.configs.ts index cbd9692c9..075907fbd 100644 --- a/src/endpoints/network/entities/feature.configs.ts +++ b/src/endpoints/network/entities/feature.configs.ts @@ -16,4 +16,10 @@ export class FeatureConfigs { @ApiProperty({ description: 'DataApi flag activation value' }) dataApi: boolean = false; + + @ApiProperty({ description: 'External tokens fetch flag value' }) + tokensFetch: boolean = false; + + @ApiProperty({ description: 'External assets fetch flag value' }) + assetsFetch: boolean = false; } diff --git a/src/endpoints/network/network.service.ts b/src/endpoints/network/network.service.ts index ae0aeab7e..f8a5a2670 100644 --- a/src/endpoints/network/network.service.ts +++ b/src/endpoints/network/network.service.ts @@ -314,6 +314,8 @@ export class NetworkService { marketplace: this.apiConfigService.isMarketplaceFeatureEnabled(), exchange: this.apiConfigService.isExchangeEnabled(), dataApi: this.apiConfigService.isDataApiFeatureEnabled(), + tokensFetch: this.apiConfigService.isTokensFetchFeatureEnabled(), + assetsFetch: this.apiConfigService.isAssetsCdnFeatureEnabled(), }); let indexerVersion: string | undefined; @@ -337,6 +339,7 @@ export class NetworkService { network: this.apiConfigService.getNetwork(), cluster: this.apiConfigService.getCluster(), version: apiVersion, + hrp: this.apiConfigService.getChainHrp(), indexerVersion: indexerVersion, gatewayVersion: gatewayVersion, features: features, diff --git a/src/endpoints/transactions.batch/transactions.batch.service.ts b/src/endpoints/transactions.batch/transactions.batch.service.ts index 78bea9c89..b17121f9e 100644 --- a/src/endpoints/transactions.batch/transactions.batch.service.ts +++ b/src/endpoints/transactions.batch/transactions.batch.service.ts @@ -1,4 +1,11 @@ -import { Address, Transaction as ErdJsTransaction, TransactionHash, TransactionOptions, TransactionPayload, TransactionVersion } from "@multiversx/sdk-core/out"; +import { + Address, + Transaction as ErdJsTransaction, + TransactionHash, + TransactionOptions, + TransactionPayload, + TransactionVersion, +} from "@multiversx/sdk-core/out"; import { Signature } from "@multiversx/sdk-core/out/signature"; import { BinaryUtils } from "@multiversx/sdk-nestjs-common"; import { CacheService } from "@multiversx/sdk-nestjs-cache"; diff --git a/src/main.ts b/src/main.ts index 0ffab0cd9..85252e17c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -35,6 +35,7 @@ import { JwtOrNativeAuthGuard } from '@multiversx/sdk-nestjs-auth'; import { WebSocketPublisherModule } from './common/websockets/web-socket-publisher-module'; import { IndexerService } from './common/indexer/indexer.service'; import { NotWritableError } from './common/indexer/entities/not.writable.error'; +import { LibraryConfig } from "@multiversx/sdk-core/out"; async function bootstrap() { const logger = new Logger('Bootstrapper'); @@ -45,6 +46,8 @@ async function bootstrap() { const apiConfigApp = await NestFactory.create(ApiConfigModule); const apiConfigService = apiConfigApp.get(ApiConfigService); + LibraryConfig.DefaultAddressHrp = apiConfigService.getChainHrp() ?? 'erd'; + if (apiConfigService.getUseTracingFlag() === true) { require('dd-trace').init(); } @@ -175,6 +178,7 @@ async function bootstrap() { logger.log(`Guest caching enabled: ${apiConfigService.isGuestCacheFeatureActive()}`); logger.log(`Transaction pool enabled: ${apiConfigService.isTransactionPoolEnabled()}`); logger.log(`Transaction pool cache warmer enabled: ${apiConfigService.isTransactionPoolCacheWarmerEnabled()}`); + logger.log(`Address HRP (human readable part): ${apiConfigService.getChainHrp()}`); } async function configurePublicApp(publicApp: NestExpressApplication, apiConfigService: ApiConfigService) { diff --git a/src/test/unit/controllers/network.controller.spec.ts b/src/test/unit/controllers/network.controller.spec.ts index a032ebff6..af96f8d30 100644 --- a/src/test/unit/controllers/network.controller.spec.ts +++ b/src/test/unit/controllers/network.controller.spec.ts @@ -98,6 +98,7 @@ describe("NetworkController", () => { network: "mainnet", cluster: "mainnet-aws-fra", version: "v1.3.0-hotfix2-next", + hrp: 'erd', indexerVersion: "v1.4.19", gatewayVersion: "v1.1.44-0-g5282fa5", scamEngineVersion: "1.0.0", @@ -106,6 +107,8 @@ describe("NetworkController", () => { marketplace: true, exchange: true, dataApi: true, + tokensFetch: true, + assetsFetch: true, }, }; networkServiceMocks.getAbout.mockResolvedValue(mockAbout); From d0ec85fb00bfd149535a9f9ebb55886ec12c9b4e Mon Sep 17 00:00:00 2001 From: bogdan-rosianu <51945539+bogdan-rosianu@users.noreply.github.com> Date: Thu, 17 Apr 2025 11:36:18 +0300 Subject: [PATCH 16/25] Update proccess nft sovereign (#1487) * update sovereign collection id * added log * added more logs * added more logs * remove temp logs + update token id --------- Co-authored-by: axenteoctavian --- src/common/rabbitmq/rabbitmq.nft.handler.service.ts | 7 +++++-- src/endpoints/process-nfts/process.nfts.service.ts | 9 +++++++-- src/utils/token.helpers.ts | 6 +++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/common/rabbitmq/rabbitmq.nft.handler.service.ts b/src/common/rabbitmq/rabbitmq.nft.handler.service.ts index a5f8ba8e9..8195bb09b 100644 --- a/src/common/rabbitmq/rabbitmq.nft.handler.service.ts +++ b/src/common/rabbitmq/rabbitmq.nft.handler.service.ts @@ -6,7 +6,7 @@ import { NftWorkerService } from 'src/queue.worker/nft.worker/nft.worker.service import { CacheInfo } from '../../utils/cache.info'; import { NotifierEvent } from './entities/notifier.event'; import { CacheService } from "@multiversx/sdk-nestjs-cache"; -import { BinaryUtils, OriginLogger } from '@multiversx/sdk-nestjs-common'; +import { BinaryUtils, OriginLogger, TokenUtils } from '@multiversx/sdk-nestjs-common'; import { IndexerService } from '../indexer/indexer.service'; @Injectable() @@ -74,7 +74,10 @@ export class RabbitMqNftHandlerService { public async handleNftCreateEvent(event: NotifierEvent): Promise { const identifier = this.getNftIdentifier(event.topics); - const collectionIdentifier = identifier.split('-').slice(0, 2).join('-'); + let collectionIdentifier = identifier.split('-').slice(0, 2).join('-'); + if (TokenUtils.isSovereignIdentifier(identifier)) { + collectionIdentifier = identifier.split('-').slice(0, 3).join('-'); + } const collectionType = await this.getCollectionType(collectionIdentifier); if (collectionType === NftType.MetaESDT) { return false; diff --git a/src/endpoints/process-nfts/process.nfts.service.ts b/src/endpoints/process-nfts/process.nfts.service.ts index 2a9f75c8a..ae9f7e888 100644 --- a/src/endpoints/process-nfts/process.nfts.service.ts +++ b/src/endpoints/process-nfts/process.nfts.service.ts @@ -1,4 +1,4 @@ -import { AddressUtils } from "@multiversx/sdk-nestjs-common"; +import { AddressUtils, TokenUtils } from '@multiversx/sdk-nestjs-common'; import { CacheService } from "@multiversx/sdk-nestjs-cache"; import { Injectable } from "@nestjs/common"; import { ApiConfigService } from "src/common/api-config/api.config.service"; @@ -57,7 +57,12 @@ export class ProcessNftsService { throw new Error('Thumbnails have already been generated'); } - const collection = collectionOrIdentifier.split('-').slice(0, 2).join('-'); + const isSovereignIdentifier = TokenUtils.isSovereignIdentifier(collectionOrIdentifier); + let collection = collectionOrIdentifier.split('-').slice(0, 2).join('-'); + if (isSovereignIdentifier) { + // sov-NFT-00aabbb-0a + collection = collectionOrIdentifier.split('-').slice(0, 3).join('-'); + } const isCollectionOwner = await this.isCollectionOwner(address, collection); if (!isCollectionOwner) { diff --git a/src/utils/token.helpers.ts b/src/utils/token.helpers.ts index 9918a2b02..39c2c8086 100644 --- a/src/utils/token.helpers.ts +++ b/src/utils/token.helpers.ts @@ -5,6 +5,7 @@ import { CollectionRoles } from "src/endpoints/tokens/entities/collection.roles" import { TokenRoles } from "src/endpoints/tokens/entities/token.roles"; import { ApiUtils } from '@multiversx/sdk-nestjs-http'; import '@multiversx/sdk-nestjs-common/lib/utils/extensions/string.extensions'; +import { TokenUtils } from "@multiversx/sdk-nestjs-common"; export class TokenHelpers { static canBool(string: string) { @@ -32,7 +33,10 @@ export class TokenHelpers { } static getThumbnailUrlIdentifier(nftIdentifier: string, fileUrl: string) { - const collectionIdentifier = nftIdentifier.split('-').slice(0, 2).join('-'); + let collectionIdentifier = nftIdentifier.split('-').slice(0, 2).join('-'); + if (TokenUtils.isSovereignIdentifier(nftIdentifier)) { + collectionIdentifier = nftIdentifier.split('-').slice(0, 3).join('-'); + } const urlHash = TokenHelpers.getUrlHash(fileUrl); return `${collectionIdentifier}-${urlHash}`; From d6a0e01e977271188bfec1b667c2bc630c6a93d2 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu <51945539+bogdan-rosianu@users.noreply.github.com> Date: Tue, 29 Apr 2025 13:40:47 +0300 Subject: [PATCH 17/25] Merge development sov apr24 (#1491) --- .eslintrc.js | 1 + config/config.devnet.yaml | 12 + config/config.e2e.mainnet.yaml | 12 +- config/config.mainnet.yaml | 12 + config/config.testnet.yaml | 12 + entrypoint.py | 39 +- package-lock.json | 4329 ++++++++--------- package.json | 25 +- src/common/api-config/api.config.service.ts | 38 +- .../circuit.breaker.proxy.module.ts | 15 + .../circuit.breaker.proxy.service.ts | 109 + .../indexer/elastic/elastic.indexer.module.ts | 4 +- .../elastic/elastic.indexer.service.ts | 33 +- src/common/indexer/indexer.interface.ts | 2 + src/common/indexer/indexer.service.ts | 5 + .../locked-asset/locked-asset.service.ts | 2 +- .../rabbitmq/rabbitmq.nft.handler.service.ts | 2 +- .../web-socket-publisher-controller.ts | 2 +- .../web-socket-publisher-service.ts | 2 +- .../cache.warmer/cache.warmer.service.ts | 6 +- .../batch.transaction.processor.service.ts | 2 +- .../nft.create.transaction.extractor.ts | 2 +- ...update.attributes.transaction.extractor.ts | 2 +- .../sft.change.transaction.extractor.ts | 2 +- .../transaction.extractor.interface.ts | 2 +- .../extractor/transfer.ownership.extractor.ts | 2 +- .../transaction.completed.service.ts | 3 +- .../transaction.processor.service.ts | 3 +- src/endpoints/accounts/account.controller.ts | 10 +- src/endpoints/blocks/block.service.ts | 20 +- src/endpoints/blocks/entities/block.proof.ts | 37 + src/endpoints/blocks/entities/block.ts | 7 + .../caching/local.cache.controller.ts | 4 +- .../collections/collection.service.ts | 4 +- .../dapp-config/dapp.config.controller.ts | 4 +- .../dapp-config/dapp.config.service.ts | 18 +- .../dapp-config/entities/dapp-config.ts | 3 + src/endpoints/endpoints.controllers.module.ts | 2 + src/endpoints/endpoints.services.module.ts | 4 +- src/endpoints/esdt/esdt.address.service.ts | 54 +- src/endpoints/esdt/esdt.service.ts | 2 +- .../entities/identity.sort.criteria.ts | 3 +- .../identities/identities.controller.ts | 6 +- .../identities/identities.service.ts | 35 +- src/endpoints/media/media.controller.ts | 66 + src/endpoints/media/media.module.ts | 13 + src/endpoints/media/media.service.ts | 67 + src/endpoints/mex/mex.controller.ts | 10 +- src/endpoints/mex/mex.farm.service.ts | 2 +- src/endpoints/mex/mex.pair.service.ts | 2 +- src/endpoints/mex/mex.settings.service.ts | 6 +- src/endpoints/mex/mex.token.charts.service.ts | 11 +- src/endpoints/mex/mex.token.service.ts | 8 +- src/endpoints/mex/mex.warmer.service.ts | 6 +- src/endpoints/network/entities/constants.ts | 3 + src/endpoints/network/network.service.ts | 2 + src/endpoints/nfts/entities/nft.account.ts | 3 + .../nfts/entities/nft.query.options.ts | 8 + src/endpoints/nfts/entities/nft.ts | 3 + src/endpoints/nfts/nft.service.ts | 56 +- src/endpoints/nodes/node.service.ts | 6 +- src/endpoints/pool/pool.service.ts | 25 +- src/endpoints/providers/provider.module.ts | 2 +- src/endpoints/rounds/round.module.ts | 2 + src/endpoints/rounds/round.service.ts | 20 +- src/endpoints/tokens/token.service.ts | 9 +- .../constants/gas.bucket.constants.ts | 11 + .../transactions/entities/gas.bucket.ts | 29 + .../transactions/entities/ppu.metadata.ts | 25 + .../entities/transaction.create.ts | 6 + .../transactions/entities/transaction.ts | 3 + .../entities/transaction.with.ppu.ts | 8 + ...saction.action.stake.recognizer.service.ts | 2 +- .../transactions/transaction.controller.ts | 17 + .../transactions/transaction.module.ts | 6 + .../transactions/transaction.service.ts | 176 + src/endpoints/usernames/username.service.ts | 3 + .../job-services/media/nft.media.service.ts | 11 +- .../metadata/nft.metadata.service.ts | 2 +- .../nft.worker/queue/nft.queue.controller.ts | 2 +- src/test/chain-simulator/accounts.cs-e2e.ts | 32 + .../chain-simulator/transactions.cs-e2e.ts | 2 + .../utils/chain.simulator.operations.ts | 74 + .../utils/test-ppu-calculation.ts | 482 ++ .../controllers/identities.controller.spec.ts | 49 + .../unit/controllers/media.controller.spec.ts | 55 + .../controllers/network.controller.spec.ts | 1 + .../controllers/scresults.controller.spec.ts | 4 + .../services.mock/account.services.mock.ts | 3 + .../web.socket.publiser.controller.spec.ts | 2 +- src/test/unit/services/api.config.spec.ts | 4 +- src/test/unit/services/blocks.spec.ts | 20 +- src/test/unit/services/media.spec.ts | 135 + .../unit/services/mex.token.charts.spec.ts | 4 +- src/test/unit/services/rounds.spec.ts | 104 +- src/test/unit/services/tokens.spec.ts | 123 + src/test/unit/services/transactions.spec.ts | 22 + src/test/unit/services/username.spec.ts | 26 + .../unit/utils/circuit.breaker.proxy.spec.ts | 316 ++ src/test/unit/utils/transaction.utils.spec.ts | 2 +- src/utils/cache.info.ts | 17 +- src/utils/token.helpers.ts | 15 +- 102 files changed, 4555 insertions(+), 2461 deletions(-) create mode 100644 src/common/indexer/elastic/circuit-breaker/circuit.breaker.proxy.module.ts create mode 100644 src/common/indexer/elastic/circuit-breaker/circuit.breaker.proxy.service.ts create mode 100644 src/endpoints/blocks/entities/block.proof.ts create mode 100644 src/endpoints/media/media.controller.ts create mode 100644 src/endpoints/media/media.module.ts create mode 100644 src/endpoints/media/media.service.ts create mode 100644 src/endpoints/transactions/constants/gas.bucket.constants.ts create mode 100644 src/endpoints/transactions/entities/gas.bucket.ts create mode 100644 src/endpoints/transactions/entities/ppu.metadata.ts create mode 100644 src/endpoints/transactions/entities/transaction.with.ppu.ts create mode 100644 src/test/chain-simulator/utils/test-ppu-calculation.ts create mode 100644 src/test/unit/controllers/media.controller.spec.ts create mode 100644 src/test/unit/services/media.spec.ts create mode 100644 src/test/unit/utils/circuit.breaker.proxy.spec.ts diff --git a/.eslintrc.js b/.eslintrc.js index bbc47fd2b..f5700ffbd 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -28,6 +28,7 @@ module.exports = { "semi": ["error"], "comma-dangle": ["error", "always-multiline"], "eol-last": ["error"], + "@typescript-eslint/await-thenable": "error", }, ignorePatterns: ['.eslintrc.js'], }; \ No newline at end of file diff --git a/config/config.devnet.yaml b/config/config.devnet.yaml index 840351797..634b46f0c 100644 --- a/config/config.devnet.yaml +++ b/config/config.devnet.yaml @@ -53,6 +53,10 @@ features: assetsFetch: enabled: true assetesUrl: 'https://tools.multiversx.com/assets-cdn' + mediaRedirect: + enabled: false + storageUrls: + - 'https://s3.amazonaws.com/devnet-media.elrond.com' auth: enabled: false maxExpirySeconds: 86400 @@ -65,6 +69,9 @@ features: enabled: false cronExpression: '*/5 * * * * *' activationEpoch: 1043 + chainAndromeda: + enabled: false + activationEpoch: 4 nodeEpochsLeft: enabled: false transactionProcessor: @@ -77,6 +84,11 @@ features: transactionBatch: enabled: true maxLookBehind: 100 + elasticCircuitBreaker: + enabled: false + durationThresholdMs: 5000 + failureCountThreshold: 5 + resetTimeoutMs: 30000 statusChecker: enabled: false thresholds: diff --git a/config/config.e2e.mainnet.yaml b/config/config.e2e.mainnet.yaml index 93d574fde..37f7f4e3c 100644 --- a/config/config.e2e.mainnet.yaml +++ b/config/config.e2e.mainnet.yaml @@ -63,6 +63,9 @@ features: enabled: false cronExpression: '*/5 * * * * *' activationEpoch: 1391 + chainAndromeda: + enabled: false + activationEpoch: 4 nodeEpochsLeft: enabled: false transactionProcessor: @@ -78,6 +81,11 @@ features: deepHistory: enabled: false url: '' + elasticCircuitBreaker: + enabled: false + durationThresholdMs: 5000 + failureCountThreshold: 5 + resetTimeoutMs: 30000 statusChecker: enabled: false thresholds: @@ -171,8 +179,8 @@ inflation: - 1130177 - 924690 - 719203 -chainSettings: - hrp: 'erd' nftProcess: parallelism: 1 maxRetries: 3 +chainSettings: + hrp: 'erd' diff --git a/config/config.mainnet.yaml b/config/config.mainnet.yaml index 36ba639f5..790e8726d 100644 --- a/config/config.mainnet.yaml +++ b/config/config.mainnet.yaml @@ -63,6 +63,9 @@ features: enabled: false cronExpression: '*/5 * * * * *' activationEpoch: 1391 + chainAndromeda: + enabled: false + activationEpoch: 4 nodeEpochsLeft: enabled: false transactionProcessor: @@ -78,6 +81,11 @@ features: deepHistory: enabled: false url: '' + elasticCircuitBreaker: + enabled: false + durationThresholdMs: 5000 + failureCountThreshold: 5 + resetTimeoutMs: 30000 statusChecker: enabled: false thresholds: @@ -110,6 +118,10 @@ features: assetsFetch: enabled: true assetesUrl: 'https://tools.multiversx.com/assets-cdn' + mediaRedirect: + enabled: false + storageUrls: + - 'https://s3.amazonaws.com/media.elrond.com' image: width: 600 height: 600 diff --git a/config/config.testnet.yaml b/config/config.testnet.yaml index 27704b75d..3d377e491 100644 --- a/config/config.testnet.yaml +++ b/config/config.testnet.yaml @@ -62,6 +62,9 @@ features: enabled: false cronExpression: '*/5 * * * * *' activationEpoch: 1043 + chainAndromeda: + enabled: false + activationEpoch: 4 nodeEpochsLeft: enabled: false transactionProcessor: @@ -77,6 +80,11 @@ features: deepHistory: enabled: false url: '' + elasticCircuitBreaker: + enabled: false + durationThresholdMs: 5000 + failureCountThreshold: 5 + resetTimeoutMs: 30000 statusChecker: enabled: false thresholds: @@ -109,6 +117,10 @@ features: assetsFetch: enabled: true assetesUrl: 'https://tools.multiversx.com/assets-cdn' + mediaRedirect: + enabled: false + storageUrls: + - 'https://s3.amazonaws.com/testnet-media.elrond.com' image: width: 600 height: 600 diff --git a/entrypoint.py b/entrypoint.py index 1a7ad344b..87a189890 100644 --- a/entrypoint.py +++ b/entrypoint.py @@ -96,33 +96,26 @@ def modify_yaml_variable(data, variable_name, new_value): return # Modify the value in the JSON structure based on the variable name -def modify_json_variable(data, variable_name, new_value): - keys = variable_name[5:].split('_') # Remove 'DAPP_' prefix +def modify_yaml_variable(data, variable_name, new_value): + keys = variable_name[4:].split('_') # Remove 'CFG_' prefix sub_data = data - - # Traverse the JSON structure using the keys to reach the variable and modify its value + + # Traverse and create missing keys for key in keys[:-1]: - if key in sub_data: - sub_data = sub_data[key] - else: - print(f"Key '{key}' not found in the JSON structure.") - return - - # Check if the value is a JSON array (list) and parse it + if key not in sub_data or not isinstance(sub_data[key], dict): + sub_data[key] = {} # Create intermediate dict if not present + sub_data = sub_data[key] + final_key = keys[-1] - if final_key in sub_data: - # If the new value is a string representing a JSON array, parse it - if isinstance(new_value, str) and new_value.startswith('[') and new_value.endswith(']'): - try: - # Parse the string as a JSON array - sub_data[final_key] = json.loads(new_value) - except json.JSONDecodeError: - print(f"Error decoding JSON array in value: {new_value}") - else: - sub_data[final_key] = new_value + # Handle array separately + if isinstance(new_value, str) and new_value.startswith('arr:'): + try: + sub_data[final_key] = json.loads(new_value[4:]) + except json.JSONDecodeError: + print(f"Error decoding JSON array in value: {new_value}") + return else: - print(f"Key '{final_key}' not found at the end of the path.") - return + sub_data[final_key] = new_value # Main function def main(): diff --git a/package-lock.json b/package-lock.json index b066da289..fe33e043f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,21 +10,19 @@ "license": "UNLICENSED", "dependencies": { "@aws-sdk/client-s3": "^3.54.0", - "@elrondnetwork/erdjs-dex": "^0.2.12-alpha", - "@elrondnetwork/native-auth": "^0.1.19", - "@elrondnetwork/transaction-processor": "^0.1.26", "@golevelup/nestjs-rabbitmq": "^4.0.0", "@multiversx/sdk-core": "^13.2.2", "@multiversx/sdk-data-api-client": "^0.7.0", - "@multiversx/sdk-nestjs-auth": "4.1.0-beta.0", - "@multiversx/sdk-nestjs-cache": "4.1.0-beta.0", - "@multiversx/sdk-nestjs-common": "4.1.0-beta.0", - "@multiversx/sdk-nestjs-elastic": "4.1.0-beta.0", - "@multiversx/sdk-nestjs-http": "4.1.0-beta.0", - "@multiversx/sdk-nestjs-monitoring": "4.1.0-beta.0", - "@multiversx/sdk-nestjs-rabbitmq": "4.1.0-beta.0", - "@multiversx/sdk-nestjs-redis": "4.1.0-beta.0", - "@multiversx/sdk-wallet": "^4.0.0", + "@multiversx/sdk-exchange": "^0.2.21", + "@multiversx/sdk-nestjs-auth": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-cache": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-common": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-elastic": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-http": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-monitoring": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-rabbitmq": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-redis": "5.0.2-beta.0", + "@multiversx/sdk-transaction-processor": "^0.1.35", "@nestjs/apollo": "12.0.11", "@nestjs/common": "10.2.0", "@nestjs/config": "3.0.1", @@ -132,9 +130,9 @@ } }, "node_modules/@adobe/css-tools": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz", - "integrity": "sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==", + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.2.tgz", + "integrity": "sha512-baYZExFpsdkBNuvGKTKWCwKH57HRZLVtycZS05WTQNVOiXVSeAki3nU35zlRbToeMW8aHlJfyS+1C4BOv27q0A==", "dev": true }, "node_modules/@ampproject/remapping": { @@ -176,6 +174,15 @@ } } }, + "node_modules/@angular-devkit/core/node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/@angular-devkit/schematics": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.2.0.tgz", @@ -259,6 +266,15 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/@angular-devkit/schematics/node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/@apollo/cache-control-types": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@apollo/cache-control-types/-/cache-control-types-1.0.3.tgz", @@ -293,15 +309,15 @@ } }, "node_modules/@apollo/server": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@apollo/server/-/server-4.11.0.tgz", - "integrity": "sha512-SWDvbbs0wl2zYhKG6aGLxwTJ72xpqp0awb2lotNpfezd9VcAvzaUizzKQqocephin2uMoaA8MguoyBmgtPzNWw==", + "version": "4.11.3", + "resolved": "https://registry.npmjs.org/@apollo/server/-/server-4.11.3.tgz", + "integrity": "sha512-mW8idE2q0/BN14mimfJU5DAnoPHZRrAWgwsVLBEdACds+mxapIYxIbI6AH4AsOpxfrpvHts3PCYDbopy1XPW1g==", "peer": true, "dependencies": { "@apollo/cache-control-types": "^1.0.3", "@apollo/server-gateway-interface": "^1.1.1", "@apollo/usage-reporting-protobuf": "^4.1.1", - "@apollo/utils.createhash": "^2.0.0", + "@apollo/utils.createhash": "^2.0.2", "@apollo/utils.fetcher": "^2.0.0", "@apollo/utils.isnodelike": "^2.0.0", "@apollo/utils.keyvaluecache": "^2.1.0", @@ -314,7 +330,7 @@ "@types/node-fetch": "^2.6.1", "async-retry": "^1.2.1", "cors": "^2.8.5", - "express": "^4.17.1", + "express": "^4.21.1", "loglevel": "^1.6.8", "lru-cache": "^7.10.1", "negotiator": "^0.6.3", @@ -369,9 +385,9 @@ } }, "node_modules/@apollo/utils.createhash": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@apollo/utils.createhash/-/utils.createhash-2.0.1.tgz", - "integrity": "sha512-fQO4/ZOP8LcXWvMNhKiee+2KuKyqIcfHrICA+M4lj/h/Lh1H10ICcUtk6N/chnEo5HXu0yejg64wshdaiFitJg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@apollo/utils.createhash/-/utils.createhash-2.0.2.tgz", + "integrity": "sha512-UkS3xqnVFLZ3JFpEmU/2cM2iKJotQXMoSTgxXsfQgXLC5gR1WaepoXagmYnPSA7Q/2cmnyTYK5OgAgoC4RULPg==", "peer": true, "dependencies": { "@apollo/utils.isnodelike": "^2.0.1", @@ -783,660 +799,600 @@ } }, "node_modules/@aws-sdk/client-s3": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.679.0.tgz", - "integrity": "sha512-P93tUbJXiDtSPgBfFpnjaijLV38hyPlE3g0XybsPTmSYNV6A9Jt1TUIF6vX+o6LdFuq3FerCiagUjhfDANWkAw==", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.775.0.tgz", + "integrity": "sha512-Z/BeVmYc3nj4FNE46MtvBYeCVvBZwlujMEvr5UOChP14899QWkBfOvf74RwQY9qy5/DvhVFkHlA8en1L6+0NrA==", "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.679.0", - "@aws-sdk/client-sts": "3.679.0", - "@aws-sdk/core": "3.679.0", - "@aws-sdk/credential-provider-node": "3.679.0", - "@aws-sdk/middleware-bucket-endpoint": "3.679.0", - "@aws-sdk/middleware-expect-continue": "3.679.0", - "@aws-sdk/middleware-flexible-checksums": "3.679.0", - "@aws-sdk/middleware-host-header": "3.679.0", - "@aws-sdk/middleware-location-constraint": "3.679.0", - "@aws-sdk/middleware-logger": "3.679.0", - "@aws-sdk/middleware-recursion-detection": "3.679.0", - "@aws-sdk/middleware-sdk-s3": "3.679.0", - "@aws-sdk/middleware-ssec": "3.679.0", - "@aws-sdk/middleware-user-agent": "3.679.0", - "@aws-sdk/region-config-resolver": "3.679.0", - "@aws-sdk/signature-v4-multi-region": "3.679.0", - "@aws-sdk/types": "3.679.0", - "@aws-sdk/util-endpoints": "3.679.0", - "@aws-sdk/util-user-agent-browser": "3.679.0", - "@aws-sdk/util-user-agent-node": "3.679.0", - "@aws-sdk/xml-builder": "3.679.0", - "@smithy/config-resolver": "^3.0.9", - "@smithy/core": "^2.4.8", - "@smithy/eventstream-serde-browser": "^3.0.10", - "@smithy/eventstream-serde-config-resolver": "^3.0.7", - "@smithy/eventstream-serde-node": "^3.0.9", - "@smithy/fetch-http-handler": "^3.2.9", - "@smithy/hash-blob-browser": "^3.1.6", - "@smithy/hash-node": "^3.0.7", - "@smithy/hash-stream-node": "^3.1.6", - "@smithy/invalid-dependency": "^3.0.7", - "@smithy/md5-js": "^3.0.7", - "@smithy/middleware-content-length": "^3.0.9", - "@smithy/middleware-endpoint": "^3.1.4", - "@smithy/middleware-retry": "^3.0.23", - "@smithy/middleware-serde": "^3.0.7", - "@smithy/middleware-stack": "^3.0.7", - "@smithy/node-config-provider": "^3.1.8", - "@smithy/node-http-handler": "^3.2.4", - "@smithy/protocol-http": "^4.1.4", - "@smithy/smithy-client": "^3.4.0", - "@smithy/types": "^3.5.0", - "@smithy/url-parser": "^3.0.7", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.23", - "@smithy/util-defaults-mode-node": "^3.0.23", - "@smithy/util-endpoints": "^2.1.3", - "@smithy/util-middleware": "^3.0.7", - "@smithy/util-retry": "^3.0.7", - "@smithy/util-stream": "^3.1.9", - "@smithy/util-utf8": "^3.0.0", - "@smithy/util-waiter": "^3.1.6", + "@aws-sdk/core": "3.775.0", + "@aws-sdk/credential-provider-node": "3.775.0", + "@aws-sdk/middleware-bucket-endpoint": "3.775.0", + "@aws-sdk/middleware-expect-continue": "3.775.0", + "@aws-sdk/middleware-flexible-checksums": "3.775.0", + "@aws-sdk/middleware-host-header": "3.775.0", + "@aws-sdk/middleware-location-constraint": "3.775.0", + "@aws-sdk/middleware-logger": "3.775.0", + "@aws-sdk/middleware-recursion-detection": "3.775.0", + "@aws-sdk/middleware-sdk-s3": "3.775.0", + "@aws-sdk/middleware-ssec": "3.775.0", + "@aws-sdk/middleware-user-agent": "3.775.0", + "@aws-sdk/region-config-resolver": "3.775.0", + "@aws-sdk/signature-v4-multi-region": "3.775.0", + "@aws-sdk/types": "3.775.0", + "@aws-sdk/util-endpoints": "3.775.0", + "@aws-sdk/util-user-agent-browser": "3.775.0", + "@aws-sdk/util-user-agent-node": "3.775.0", + "@aws-sdk/xml-builder": "3.775.0", + "@smithy/config-resolver": "^4.1.0", + "@smithy/core": "^3.2.0", + "@smithy/eventstream-serde-browser": "^4.0.2", + "@smithy/eventstream-serde-config-resolver": "^4.1.0", + "@smithy/eventstream-serde-node": "^4.0.2", + "@smithy/fetch-http-handler": "^5.0.2", + "@smithy/hash-blob-browser": "^4.0.2", + "@smithy/hash-node": "^4.0.2", + "@smithy/hash-stream-node": "^4.0.2", + "@smithy/invalid-dependency": "^4.0.2", + "@smithy/md5-js": "^4.0.2", + "@smithy/middleware-content-length": "^4.0.2", + "@smithy/middleware-endpoint": "^4.1.0", + "@smithy/middleware-retry": "^4.1.0", + "@smithy/middleware-serde": "^4.0.3", + "@smithy/middleware-stack": "^4.0.2", + "@smithy/node-config-provider": "^4.0.2", + "@smithy/node-http-handler": "^4.0.4", + "@smithy/protocol-http": "^5.1.0", + "@smithy/smithy-client": "^4.2.0", + "@smithy/types": "^4.2.0", + "@smithy/url-parser": "^4.0.2", + "@smithy/util-base64": "^4.0.0", + "@smithy/util-body-length-browser": "^4.0.0", + "@smithy/util-body-length-node": "^4.0.0", + "@smithy/util-defaults-mode-browser": "^4.0.8", + "@smithy/util-defaults-mode-node": "^4.0.8", + "@smithy/util-endpoints": "^3.0.2", + "@smithy/util-middleware": "^4.0.2", + "@smithy/util-retry": "^4.0.2", + "@smithy/util-stream": "^4.2.0", + "@smithy/util-utf8": "^4.0.0", + "@smithy/util-waiter": "^4.0.3", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.679.0.tgz", - "integrity": "sha512-/0cAvYnpOZTo/Y961F1kx2fhDDLUYZ0SQQ5/75gh3xVImLj7Zw+vp74ieqFbqWLYGMaq8z1Arr9A8zG95mbLdg==", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.775.0.tgz", + "integrity": "sha512-vqG1S2ap77WP4D5qt4bEPE0duQ4myN+cDr1NeP8QpSTajetbkDGVo7h1VViYMcUoFUVWBj6Qf1X1VfOq+uaxbA==", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.679.0", - "@aws-sdk/middleware-host-header": "3.679.0", - "@aws-sdk/middleware-logger": "3.679.0", - "@aws-sdk/middleware-recursion-detection": "3.679.0", - "@aws-sdk/middleware-user-agent": "3.679.0", - "@aws-sdk/region-config-resolver": "3.679.0", - "@aws-sdk/types": "3.679.0", - "@aws-sdk/util-endpoints": "3.679.0", - "@aws-sdk/util-user-agent-browser": "3.679.0", - "@aws-sdk/util-user-agent-node": "3.679.0", - "@smithy/config-resolver": "^3.0.9", - "@smithy/core": "^2.4.8", - "@smithy/fetch-http-handler": "^3.2.9", - "@smithy/hash-node": "^3.0.7", - "@smithy/invalid-dependency": "^3.0.7", - "@smithy/middleware-content-length": "^3.0.9", - "@smithy/middleware-endpoint": "^3.1.4", - "@smithy/middleware-retry": "^3.0.23", - "@smithy/middleware-serde": "^3.0.7", - "@smithy/middleware-stack": "^3.0.7", - "@smithy/node-config-provider": "^3.1.8", - "@smithy/node-http-handler": "^3.2.4", - "@smithy/protocol-http": "^4.1.4", - "@smithy/smithy-client": "^3.4.0", - "@smithy/types": "^3.5.0", - "@smithy/url-parser": "^3.0.7", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.23", - "@smithy/util-defaults-mode-node": "^3.0.23", - "@smithy/util-endpoints": "^2.1.3", - "@smithy/util-middleware": "^3.0.7", - "@smithy/util-retry": "^3.0.7", - "@smithy/util-utf8": "^3.0.0", + "@aws-sdk/core": "3.775.0", + "@aws-sdk/middleware-host-header": "3.775.0", + "@aws-sdk/middleware-logger": "3.775.0", + "@aws-sdk/middleware-recursion-detection": "3.775.0", + "@aws-sdk/middleware-user-agent": "3.775.0", + "@aws-sdk/region-config-resolver": "3.775.0", + "@aws-sdk/types": "3.775.0", + "@aws-sdk/util-endpoints": "3.775.0", + "@aws-sdk/util-user-agent-browser": "3.775.0", + "@aws-sdk/util-user-agent-node": "3.775.0", + "@smithy/config-resolver": "^4.1.0", + "@smithy/core": "^3.2.0", + "@smithy/fetch-http-handler": "^5.0.2", + "@smithy/hash-node": "^4.0.2", + "@smithy/invalid-dependency": "^4.0.2", + "@smithy/middleware-content-length": "^4.0.2", + "@smithy/middleware-endpoint": "^4.1.0", + "@smithy/middleware-retry": "^4.1.0", + "@smithy/middleware-serde": "^4.0.3", + "@smithy/middleware-stack": "^4.0.2", + "@smithy/node-config-provider": "^4.0.2", + "@smithy/node-http-handler": "^4.0.4", + "@smithy/protocol-http": "^5.1.0", + "@smithy/smithy-client": "^4.2.0", + "@smithy/types": "^4.2.0", + "@smithy/url-parser": "^4.0.2", + "@smithy/util-base64": "^4.0.0", + "@smithy/util-body-length-browser": "^4.0.0", + "@smithy/util-body-length-node": "^4.0.0", + "@smithy/util-defaults-mode-browser": "^4.0.8", + "@smithy/util-defaults-mode-node": "^4.0.8", + "@smithy/util-endpoints": "^3.0.2", + "@smithy/util-middleware": "^4.0.2", + "@smithy/util-retry": "^4.0.2", + "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-sso-oidc": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.679.0.tgz", - "integrity": "sha512-/dBYWcCwbA/id4sFCIVZvf0UsvzHCC68SryxeNQk/PDkY9N4n5yRcMUkZDaEyQCjowc3kY4JOXp2AdUP037nhA==", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.679.0", - "@aws-sdk/credential-provider-node": "3.679.0", - "@aws-sdk/middleware-host-header": "3.679.0", - "@aws-sdk/middleware-logger": "3.679.0", - "@aws-sdk/middleware-recursion-detection": "3.679.0", - "@aws-sdk/middleware-user-agent": "3.679.0", - "@aws-sdk/region-config-resolver": "3.679.0", - "@aws-sdk/types": "3.679.0", - "@aws-sdk/util-endpoints": "3.679.0", - "@aws-sdk/util-user-agent-browser": "3.679.0", - "@aws-sdk/util-user-agent-node": "3.679.0", - "@smithy/config-resolver": "^3.0.9", - "@smithy/core": "^2.4.8", - "@smithy/fetch-http-handler": "^3.2.9", - "@smithy/hash-node": "^3.0.7", - "@smithy/invalid-dependency": "^3.0.7", - "@smithy/middleware-content-length": "^3.0.9", - "@smithy/middleware-endpoint": "^3.1.4", - "@smithy/middleware-retry": "^3.0.23", - "@smithy/middleware-serde": "^3.0.7", - "@smithy/middleware-stack": "^3.0.7", - "@smithy/node-config-provider": "^3.1.8", - "@smithy/node-http-handler": "^3.2.4", - "@smithy/protocol-http": "^4.1.4", - "@smithy/smithy-client": "^3.4.0", - "@smithy/types": "^3.5.0", - "@smithy/url-parser": "^3.0.7", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.23", - "@smithy/util-defaults-mode-node": "^3.0.23", - "@smithy/util-endpoints": "^2.1.3", - "@smithy/util-middleware": "^3.0.7", - "@smithy/util-retry": "^3.0.7", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@aws-sdk/client-sts": "^3.679.0" - } - }, - "node_modules/@aws-sdk/client-sts": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.679.0.tgz", - "integrity": "sha512-3CvrT8w1RjFu1g8vKA5Azfr5V83r2/b68Ock43WE003Bq/5Y38mwmYX7vk0fPHzC3qejt4YMAWk/C3fSKOy25g==", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.679.0", - "@aws-sdk/core": "3.679.0", - "@aws-sdk/credential-provider-node": "3.679.0", - "@aws-sdk/middleware-host-header": "3.679.0", - "@aws-sdk/middleware-logger": "3.679.0", - "@aws-sdk/middleware-recursion-detection": "3.679.0", - "@aws-sdk/middleware-user-agent": "3.679.0", - "@aws-sdk/region-config-resolver": "3.679.0", - "@aws-sdk/types": "3.679.0", - "@aws-sdk/util-endpoints": "3.679.0", - "@aws-sdk/util-user-agent-browser": "3.679.0", - "@aws-sdk/util-user-agent-node": "3.679.0", - "@smithy/config-resolver": "^3.0.9", - "@smithy/core": "^2.4.8", - "@smithy/fetch-http-handler": "^3.2.9", - "@smithy/hash-node": "^3.0.7", - "@smithy/invalid-dependency": "^3.0.7", - "@smithy/middleware-content-length": "^3.0.9", - "@smithy/middleware-endpoint": "^3.1.4", - "@smithy/middleware-retry": "^3.0.23", - "@smithy/middleware-serde": "^3.0.7", - "@smithy/middleware-stack": "^3.0.7", - "@smithy/node-config-provider": "^3.1.8", - "@smithy/node-http-handler": "^3.2.4", - "@smithy/protocol-http": "^4.1.4", - "@smithy/smithy-client": "^3.4.0", - "@smithy/types": "^3.5.0", - "@smithy/url-parser": "^3.0.7", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.23", - "@smithy/util-defaults-mode-node": "^3.0.23", - "@smithy/util-endpoints": "^2.1.3", - "@smithy/util-middleware": "^3.0.7", - "@smithy/util-retry": "^3.0.7", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/core": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.679.0.tgz", - "integrity": "sha512-CS6PWGX8l4v/xyvX8RtXnBisdCa5+URzKd0L6GvHChype9qKUVxO/Gg6N/y43Hvg7MNWJt9FBPNWIxUB+byJwg==", - "dependencies": { - "@aws-sdk/types": "3.679.0", - "@smithy/core": "^2.4.8", - "@smithy/node-config-provider": "^3.1.8", - "@smithy/property-provider": "^3.1.7", - "@smithy/protocol-http": "^4.1.4", - "@smithy/signature-v4": "^4.2.0", - "@smithy/smithy-client": "^3.4.0", - "@smithy/types": "^3.5.0", - "@smithy/util-middleware": "^3.0.7", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.775.0.tgz", + "integrity": "sha512-8vpW4WihVfz0DX+7WnnLGm3GuQER++b0IwQG35JlQMlgqnc44M//KbJPsIHA0aJUJVwJAEShgfr5dUbY8WUzaA==", + "dependencies": { + "@aws-sdk/types": "3.775.0", + "@smithy/core": "^3.2.0", + "@smithy/node-config-provider": "^4.0.2", + "@smithy/property-provider": "^4.0.2", + "@smithy/protocol-http": "^5.1.0", + "@smithy/signature-v4": "^5.0.2", + "@smithy/smithy-client": "^4.2.0", + "@smithy/types": "^4.2.0", + "@smithy/util-middleware": "^4.0.2", "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.679.0.tgz", - "integrity": "sha512-EdlTYbzMm3G7VUNAMxr9S1nC1qUNqhKlAxFU8E7cKsAe8Bp29CD5HAs3POc56AVo9GC4yRIS+/mtlZSmrckzUA==", - "dependencies": { - "@aws-sdk/core": "3.679.0", - "@aws-sdk/types": "3.679.0", - "@smithy/property-provider": "^3.1.7", - "@smithy/types": "^3.5.0", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.775.0.tgz", + "integrity": "sha512-6ESVxwCbGm7WZ17kY1fjmxQud43vzJFoLd4bmlR+idQSWdqlzGDYdcfzpjDKTcivdtNrVYmFvcH1JBUwCRAZhw==", + "dependencies": { + "@aws-sdk/core": "3.775.0", + "@aws-sdk/types": "3.775.0", + "@smithy/property-provider": "^4.0.2", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.679.0.tgz", - "integrity": "sha512-ZoKLubW5DqqV1/2a3TSn+9sSKg0T8SsYMt1JeirnuLJF0mCoYFUaWMyvxxKuxPoqvUsaycxKru4GkpJ10ltNBw==", - "dependencies": { - "@aws-sdk/core": "3.679.0", - "@aws-sdk/types": "3.679.0", - "@smithy/fetch-http-handler": "^3.2.9", - "@smithy/node-http-handler": "^3.2.4", - "@smithy/property-provider": "^3.1.7", - "@smithy/protocol-http": "^4.1.4", - "@smithy/smithy-client": "^3.4.0", - "@smithy/types": "^3.5.0", - "@smithy/util-stream": "^3.1.9", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.775.0.tgz", + "integrity": "sha512-PjDQeDH/J1S0yWV32wCj2k5liRo0ssXMseCBEkCsD3SqsU8o5cU82b0hMX4sAib/RkglCSZqGO0xMiN0/7ndww==", + "dependencies": { + "@aws-sdk/core": "3.775.0", + "@aws-sdk/types": "3.775.0", + "@smithy/fetch-http-handler": "^5.0.2", + "@smithy/node-http-handler": "^4.0.4", + "@smithy/property-provider": "^4.0.2", + "@smithy/protocol-http": "^5.1.0", + "@smithy/smithy-client": "^4.2.0", + "@smithy/types": "^4.2.0", + "@smithy/util-stream": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.679.0.tgz", - "integrity": "sha512-Rg7t8RwUzKcumpipG4neZqaeJ6DF+Bco1+FHn5BZB68jpvwvjBjcQUuWkxj18B6ctYHr1fkunnzeKEn/+vy7+w==", - "dependencies": { - "@aws-sdk/core": "3.679.0", - "@aws-sdk/credential-provider-env": "3.679.0", - "@aws-sdk/credential-provider-http": "3.679.0", - "@aws-sdk/credential-provider-process": "3.679.0", - "@aws-sdk/credential-provider-sso": "3.679.0", - "@aws-sdk/credential-provider-web-identity": "3.679.0", - "@aws-sdk/types": "3.679.0", - "@smithy/credential-provider-imds": "^3.2.4", - "@smithy/property-provider": "^3.1.7", - "@smithy/shared-ini-file-loader": "^3.1.8", - "@smithy/types": "^3.5.0", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.775.0.tgz", + "integrity": "sha512-0gJc6cALsgrjeC5U3qDjbz4myIC/j49+gPz9nkvY+C0OYWt1KH1tyfiZUuCRGfuFHhQ+3KMMDSL229TkBP3E7g==", + "dependencies": { + "@aws-sdk/core": "3.775.0", + "@aws-sdk/credential-provider-env": "3.775.0", + "@aws-sdk/credential-provider-http": "3.775.0", + "@aws-sdk/credential-provider-process": "3.775.0", + "@aws-sdk/credential-provider-sso": "3.775.0", + "@aws-sdk/credential-provider-web-identity": "3.775.0", + "@aws-sdk/nested-clients": "3.775.0", + "@aws-sdk/types": "3.775.0", + "@smithy/credential-provider-imds": "^4.0.2", + "@smithy/property-provider": "^4.0.2", + "@smithy/shared-ini-file-loader": "^4.0.2", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@aws-sdk/client-sts": "^3.679.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.679.0.tgz", - "integrity": "sha512-E3lBtaqCte8tWs6Rkssc8sLzvGoJ10TLGvpkijOlz43wPd6xCRh1YLwg6zolf9fVFtEyUs/GsgymiASOyxhFtw==", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.679.0", - "@aws-sdk/credential-provider-http": "3.679.0", - "@aws-sdk/credential-provider-ini": "3.679.0", - "@aws-sdk/credential-provider-process": "3.679.0", - "@aws-sdk/credential-provider-sso": "3.679.0", - "@aws-sdk/credential-provider-web-identity": "3.679.0", - "@aws-sdk/types": "3.679.0", - "@smithy/credential-provider-imds": "^3.2.4", - "@smithy/property-provider": "^3.1.7", - "@smithy/shared-ini-file-loader": "^3.1.8", - "@smithy/types": "^3.5.0", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.775.0.tgz", + "integrity": "sha512-D8Zre5W2sXC/ANPqCWPqwYpU1cKY9DF6ckFZyDrqlcBC0gANgpY6fLrBtYo2fwJsbj+1A24iIpBINV7erdprgA==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.775.0", + "@aws-sdk/credential-provider-http": "3.775.0", + "@aws-sdk/credential-provider-ini": "3.775.0", + "@aws-sdk/credential-provider-process": "3.775.0", + "@aws-sdk/credential-provider-sso": "3.775.0", + "@aws-sdk/credential-provider-web-identity": "3.775.0", + "@aws-sdk/types": "3.775.0", + "@smithy/credential-provider-imds": "^4.0.2", + "@smithy/property-provider": "^4.0.2", + "@smithy/shared-ini-file-loader": "^4.0.2", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.679.0.tgz", - "integrity": "sha512-u/p4TV8kQ0zJWDdZD4+vdQFTMhkDEJFws040Gm113VHa/Xo1SYOjbpvqeuFoz6VmM0bLvoOWjxB9MxnSQbwKpQ==", - "dependencies": { - "@aws-sdk/core": "3.679.0", - "@aws-sdk/types": "3.679.0", - "@smithy/property-provider": "^3.1.7", - "@smithy/shared-ini-file-loader": "^3.1.8", - "@smithy/types": "^3.5.0", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.775.0.tgz", + "integrity": "sha512-A6k68H9rQp+2+7P7SGO90Csw6nrUEm0Qfjpn9Etc4EboZhhCLs9b66umUsTsSBHus4FDIe5JQxfCUyt1wgNogg==", + "dependencies": { + "@aws-sdk/core": "3.775.0", + "@aws-sdk/types": "3.775.0", + "@smithy/property-provider": "^4.0.2", + "@smithy/shared-ini-file-loader": "^4.0.2", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.679.0.tgz", - "integrity": "sha512-SAtWonhi9asxn0ukEbcE81jkyanKgqpsrtskvYPpO9Z9KOednM4Cqt6h1bfcS9zaHjN2zu815Gv8O7WiV+F/DQ==", - "dependencies": { - "@aws-sdk/client-sso": "3.679.0", - "@aws-sdk/core": "3.679.0", - "@aws-sdk/token-providers": "3.679.0", - "@aws-sdk/types": "3.679.0", - "@smithy/property-provider": "^3.1.7", - "@smithy/shared-ini-file-loader": "^3.1.8", - "@smithy/types": "^3.5.0", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.775.0.tgz", + "integrity": "sha512-du06V7u9HDmRuwZnRjf85shO3dffeKOkQplV5/2vf3LgTPNEI9caNomi/cCGyxKGOeSUHAKrQ1HvpPfOaI6t5Q==", + "dependencies": { + "@aws-sdk/client-sso": "3.775.0", + "@aws-sdk/core": "3.775.0", + "@aws-sdk/token-providers": "3.775.0", + "@aws-sdk/types": "3.775.0", + "@smithy/property-provider": "^4.0.2", + "@smithy/shared-ini-file-loader": "^4.0.2", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.679.0.tgz", - "integrity": "sha512-a74tLccVznXCaBefWPSysUcLXYJiSkeUmQGtalNgJ1vGkE36W5l/8czFiiowdWdKWz7+x6xf0w+Kjkjlj42Ung==", - "dependencies": { - "@aws-sdk/core": "3.679.0", - "@aws-sdk/types": "3.679.0", - "@smithy/property-provider": "^3.1.7", - "@smithy/types": "^3.5.0", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.775.0.tgz", + "integrity": "sha512-z4XLYui5aHsr78mbd5BtZfm55OM5V55qK/X17OPrEqjYDDk3GlI8Oe2ZjTmOVrKwMpmzXKhsakeFHKfDyOvv1A==", + "dependencies": { + "@aws-sdk/core": "3.775.0", + "@aws-sdk/nested-clients": "3.775.0", + "@aws-sdk/types": "3.775.0", + "@smithy/property-provider": "^4.0.2", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@aws-sdk/client-sts": "^3.679.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/middleware-bucket-endpoint": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.679.0.tgz", - "integrity": "sha512-5EpiPhhGgnF+uJR4DzWUk6Lx3pOn9oM6JGXxeHsiynfoBfq7vHMleq+uABHHSQS+y7XzbyZ7x8tXNQlliMwOsg==", - "dependencies": { - "@aws-sdk/types": "3.679.0", - "@aws-sdk/util-arn-parser": "3.679.0", - "@smithy/node-config-provider": "^3.1.8", - "@smithy/protocol-http": "^4.1.4", - "@smithy/types": "^3.5.0", - "@smithy/util-config-provider": "^3.0.0", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.775.0.tgz", + "integrity": "sha512-qogMIpVChDYr4xiUNC19/RDSw/sKoHkAhouS6Skxiy6s27HBhow1L3Z1qVYXuBmOZGSWPU0xiyZCvOyWrv9s+Q==", + "dependencies": { + "@aws-sdk/types": "3.775.0", + "@aws-sdk/util-arn-parser": "3.723.0", + "@smithy/node-config-provider": "^4.0.2", + "@smithy/protocol-http": "^5.1.0", + "@smithy/types": "^4.2.0", + "@smithy/util-config-provider": "^4.0.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/middleware-expect-continue": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.679.0.tgz", - "integrity": "sha512-nYsh9PdWrF4EahTRdXHGlNud82RPc508CNGdh1lAGfPU3tNveGfMBX3PcGBtPOse3p9ebNKRWVmUc9eXSjGvHA==", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.775.0.tgz", + "integrity": "sha512-Apd3owkIeUW5dnk3au9np2IdW2N0zc9NjTjHiH+Mx3zqwSrc+m+ANgJVgk9mnQjMzU/vb7VuxJ0eqdEbp5gYsg==", "dependencies": { - "@aws-sdk/types": "3.679.0", - "@smithy/protocol-http": "^4.1.4", - "@smithy/types": "^3.5.0", + "@aws-sdk/types": "3.775.0", + "@smithy/protocol-http": "^5.1.0", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/middleware-flexible-checksums": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.679.0.tgz", - "integrity": "sha512-2Nf3rnrcog3GRRdXxc623wkQPH3WXhz8oZ+KHuXBeBKX01zbp7bz22QAZKqw3Oo2lv+LQNEDzIfQYn7leXLZGQ==", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.775.0.tgz", + "integrity": "sha512-OmHLfRIb7IIXsf9/X/pMOlcSV3gzW/MmtPSZTkrz5jCTKzWXd7eRoyOJqewjsaC6KMAxIpNU77FoAd16jOZ21A==", "dependencies": { "@aws-crypto/crc32": "5.2.0", "@aws-crypto/crc32c": "5.2.0", - "@aws-sdk/core": "3.679.0", - "@aws-sdk/types": "3.679.0", - "@smithy/is-array-buffer": "^3.0.0", - "@smithy/node-config-provider": "^3.1.8", - "@smithy/protocol-http": "^4.1.4", - "@smithy/types": "^3.5.0", - "@smithy/util-middleware": "^3.0.7", - "@smithy/util-utf8": "^3.0.0", + "@aws-crypto/util": "5.2.0", + "@aws-sdk/core": "3.775.0", + "@aws-sdk/types": "3.775.0", + "@smithy/is-array-buffer": "^4.0.0", + "@smithy/node-config-provider": "^4.0.2", + "@smithy/protocol-http": "^5.1.0", + "@smithy/types": "^4.2.0", + "@smithy/util-middleware": "^4.0.2", + "@smithy/util-stream": "^4.2.0", + "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.679.0.tgz", - "integrity": "sha512-y176HuQ8JRY3hGX8rQzHDSbCl9P5Ny9l16z4xmaiLo+Qfte7ee4Yr3yaAKd7GFoJ3/Mhud2XZ37fR015MfYl2w==", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.775.0.tgz", + "integrity": "sha512-tkSegM0Z6WMXpLB8oPys/d+umYIocvO298mGvcMCncpRl77L9XkvSLJIFzaHes+o7djAgIduYw8wKIMStFss2w==", "dependencies": { - "@aws-sdk/types": "3.679.0", - "@smithy/protocol-http": "^4.1.4", - "@smithy/types": "^3.5.0", + "@aws-sdk/types": "3.775.0", + "@smithy/protocol-http": "^5.1.0", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/middleware-location-constraint": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.679.0.tgz", - "integrity": "sha512-SA1C1D3XgoKTGxyNsOqd016ONpk46xJLWDgJUd00Zb21Ox5wYCoY6aDRKiaMRW+1VfCJdezs1Do3XLyIU9KxyA==", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.775.0.tgz", + "integrity": "sha512-8TMXEHZXZTFTckQLyBT5aEI8fX11HZcwZseRifvBKKpj0RZDk4F0EEYGxeNSPpUQ7n+PRWyfAEnnZNRdAj/1NQ==", "dependencies": { - "@aws-sdk/types": "3.679.0", - "@smithy/types": "^3.5.0", + "@aws-sdk/types": "3.775.0", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/middleware-logger": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.679.0.tgz", - "integrity": "sha512-0vet8InEj7nvIvGKk+ch7bEF5SyZ7Us9U7YTEgXPrBNStKeRUsgwRm0ijPWWd0a3oz2okaEwXsFl7G/vI0XiEA==", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.775.0.tgz", + "integrity": "sha512-FaxO1xom4MAoUJsldmR92nT1G6uZxTdNYOFYtdHfd6N2wcNaTuxgjIvqzg5y7QIH9kn58XX/dzf1iTjgqUStZw==", "dependencies": { - "@aws-sdk/types": "3.679.0", - "@smithy/types": "^3.5.0", + "@aws-sdk/types": "3.775.0", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.679.0.tgz", - "integrity": "sha512-sQoAZFsQiW/LL3DfKMYwBoGjYDEnMbA9WslWN8xneCmBAwKo6IcSksvYs23PP8XMIoBGe2I2J9BSr654XWygTQ==", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.775.0.tgz", + "integrity": "sha512-GLCzC8D0A0YDG5u3F5U03Vb9j5tcOEFhr8oc6PDk0k0vm5VwtZOE6LvK7hcCSoAB4HXyOUM0sQuXrbaAh9OwXA==", "dependencies": { - "@aws-sdk/types": "3.679.0", - "@smithy/protocol-http": "^4.1.4", - "@smithy/types": "^3.5.0", + "@aws-sdk/types": "3.775.0", + "@smithy/protocol-http": "^5.1.0", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.679.0.tgz", - "integrity": "sha512-4zcT193F7RkEfqlS6ZdwyNQ0UUp9s66msNXgItugasTbjf7oqfWDas7N+BG8ADB/Ql3wvRUh9I+zdrVkxxw3BQ==", - "dependencies": { - "@aws-sdk/core": "3.679.0", - "@aws-sdk/types": "3.679.0", - "@aws-sdk/util-arn-parser": "3.679.0", - "@smithy/core": "^2.4.8", - "@smithy/node-config-provider": "^3.1.8", - "@smithy/protocol-http": "^4.1.4", - "@smithy/signature-v4": "^4.2.0", - "@smithy/smithy-client": "^3.4.0", - "@smithy/types": "^3.5.0", - "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-middleware": "^3.0.7", - "@smithy/util-stream": "^3.1.9", - "@smithy/util-utf8": "^3.0.0", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.775.0.tgz", + "integrity": "sha512-zsvcu7cWB28JJ60gVvjxPCI7ZU7jWGcpNACPiZGyVtjYXwcxyhXbYEVDSWKsSA6ERpz9XrpLYod8INQWfW3ECg==", + "dependencies": { + "@aws-sdk/core": "3.775.0", + "@aws-sdk/types": "3.775.0", + "@aws-sdk/util-arn-parser": "3.723.0", + "@smithy/core": "^3.2.0", + "@smithy/node-config-provider": "^4.0.2", + "@smithy/protocol-http": "^5.1.0", + "@smithy/signature-v4": "^5.0.2", + "@smithy/smithy-client": "^4.2.0", + "@smithy/types": "^4.2.0", + "@smithy/util-config-provider": "^4.0.0", + "@smithy/util-middleware": "^4.0.2", + "@smithy/util-stream": "^4.2.0", + "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/middleware-ssec": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.679.0.tgz", - "integrity": "sha512-4GNUxXbs1M71uFHRiCAZtN0/g23ogI9YjMe5isAuYMHXwDB3MhqF7usKf954mBP6tplvN44vYlbJ84faaLrTtg==", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.775.0.tgz", + "integrity": "sha512-Iw1RHD8vfAWWPzBBIKaojO4GAvQkHOYIpKdAfis/EUSUmSa79QsnXnRqsdcE0mCB0Ylj23yi+ah4/0wh9FsekA==", "dependencies": { - "@aws-sdk/types": "3.679.0", - "@smithy/types": "^3.5.0", + "@aws-sdk/types": "3.775.0", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.679.0.tgz", - "integrity": "sha512-4hdeXhPDURPqQLPd9jCpUEo9fQITXl3NM3W1MwcJpE0gdUM36uXkQOYsTPeeU/IRCLVjK8Htlh2oCaM9iJrLCA==", - "dependencies": { - "@aws-sdk/core": "3.679.0", - "@aws-sdk/types": "3.679.0", - "@aws-sdk/util-endpoints": "3.679.0", - "@smithy/core": "^2.4.8", - "@smithy/protocol-http": "^4.1.4", - "@smithy/types": "^3.5.0", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.775.0.tgz", + "integrity": "sha512-7Lffpr1ptOEDE1ZYH1T78pheEY1YmeXWBfFt/amZ6AGsKSLG+JPXvof3ltporTGR2bhH/eJPo7UHCglIuXfzYg==", + "dependencies": { + "@aws-sdk/core": "3.775.0", + "@aws-sdk/types": "3.775.0", + "@aws-sdk/util-endpoints": "3.775.0", + "@smithy/core": "^3.2.0", + "@smithy/protocol-http": "^5.1.0", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/nested-clients": { + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.775.0.tgz", + "integrity": "sha512-f37jmAzkuIhKyhtA6s0LGpqQvm218vq+RNMUDkGm1Zz2fxJ5pBIUTDtygiI3vXTcmt9DTIB8S6JQhjrgtboktw==", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.775.0", + "@aws-sdk/middleware-host-header": "3.775.0", + "@aws-sdk/middleware-logger": "3.775.0", + "@aws-sdk/middleware-recursion-detection": "3.775.0", + "@aws-sdk/middleware-user-agent": "3.775.0", + "@aws-sdk/region-config-resolver": "3.775.0", + "@aws-sdk/types": "3.775.0", + "@aws-sdk/util-endpoints": "3.775.0", + "@aws-sdk/util-user-agent-browser": "3.775.0", + "@aws-sdk/util-user-agent-node": "3.775.0", + "@smithy/config-resolver": "^4.1.0", + "@smithy/core": "^3.2.0", + "@smithy/fetch-http-handler": "^5.0.2", + "@smithy/hash-node": "^4.0.2", + "@smithy/invalid-dependency": "^4.0.2", + "@smithy/middleware-content-length": "^4.0.2", + "@smithy/middleware-endpoint": "^4.1.0", + "@smithy/middleware-retry": "^4.1.0", + "@smithy/middleware-serde": "^4.0.3", + "@smithy/middleware-stack": "^4.0.2", + "@smithy/node-config-provider": "^4.0.2", + "@smithy/node-http-handler": "^4.0.4", + "@smithy/protocol-http": "^5.1.0", + "@smithy/smithy-client": "^4.2.0", + "@smithy/types": "^4.2.0", + "@smithy/url-parser": "^4.0.2", + "@smithy/util-base64": "^4.0.0", + "@smithy/util-body-length-browser": "^4.0.0", + "@smithy/util-body-length-node": "^4.0.0", + "@smithy/util-defaults-mode-browser": "^4.0.8", + "@smithy/util-defaults-mode-node": "^4.0.8", + "@smithy/util-endpoints": "^3.0.2", + "@smithy/util-middleware": "^4.0.2", + "@smithy/util-retry": "^4.0.2", + "@smithy/util-utf8": "^4.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.679.0.tgz", - "integrity": "sha512-Ybx54P8Tg6KKq5ck7uwdjiKif7n/8g1x+V0V9uTjBjRWqaIgiqzXwKWoPj6NCNkE7tJNtqI4JrNxp/3S3HvmRw==", - "dependencies": { - "@aws-sdk/types": "3.679.0", - "@smithy/node-config-provider": "^3.1.8", - "@smithy/types": "^3.5.0", - "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-middleware": "^3.0.7", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.775.0.tgz", + "integrity": "sha512-40iH3LJjrQS3LKUJAl7Wj0bln7RFPEvUYKFxtP8a+oKFDO0F65F52xZxIJbPn6sHkxWDAnZlGgdjZXM3p2g5wQ==", + "dependencies": { + "@aws-sdk/types": "3.775.0", + "@smithy/node-config-provider": "^4.0.2", + "@smithy/types": "^4.2.0", + "@smithy/util-config-provider": "^4.0.0", + "@smithy/util-middleware": "^4.0.2", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.679.0.tgz", - "integrity": "sha512-g1D57e7YBhgXihCWIRBcTUvKquS3FS27xuA24EynY9teiTIq7vHkASxxDnMMMcmKHnCKLI5pkznjk0PuDJ4uJw==", - "dependencies": { - "@aws-sdk/middleware-sdk-s3": "3.679.0", - "@aws-sdk/types": "3.679.0", - "@smithy/protocol-http": "^4.1.4", - "@smithy/signature-v4": "^4.2.0", - "@smithy/types": "^3.5.0", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.775.0.tgz", + "integrity": "sha512-cnGk8GDfTMJ8p7+qSk92QlIk2bmTmFJqhYxcXZ9PysjZtx0xmfCMxnG3Hjy1oU2mt5boPCVSOptqtWixayM17g==", + "dependencies": { + "@aws-sdk/middleware-sdk-s3": "3.775.0", + "@aws-sdk/types": "3.775.0", + "@smithy/protocol-http": "^5.1.0", + "@smithy/signature-v4": "^5.0.2", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.679.0.tgz", - "integrity": "sha512-1/+Zso/x2jqgutKixYFQEGli0FELTgah6bm7aB+m2FAWH4Hz7+iMUsazg6nSWm714sG9G3h5u42Dmpvi9X6/hA==", - "dependencies": { - "@aws-sdk/types": "3.679.0", - "@smithy/property-provider": "^3.1.7", - "@smithy/shared-ini-file-loader": "^3.1.8", - "@smithy/types": "^3.5.0", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.775.0.tgz", + "integrity": "sha512-Q6MtbEhkOggVSz/dN89rIY/ry80U3v89o0Lrrc+Rpvaiaaz8pEN0DsfEcg0IjpzBQ8Owoa6lNWyglHbzPhaJpA==", + "dependencies": { + "@aws-sdk/nested-clients": "3.775.0", + "@aws-sdk/types": "3.775.0", + "@smithy/property-provider": "^4.0.2", + "@smithy/shared-ini-file-loader": "^4.0.2", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@aws-sdk/client-sso-oidc": "^3.679.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/types": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.679.0.tgz", - "integrity": "sha512-NwVq8YvInxQdJ47+zz4fH3BRRLC6lL+WLkvr242PVBbUOLRyK/lkwHlfiKUoeVIMyK5NF+up6TRg71t/8Bny6Q==", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.775.0.tgz", + "integrity": "sha512-ZoGKwa4C9fC9Av6bdfqcW6Ix5ot05F/S4VxWR2nHuMv7hzfmAjTOcUiWT7UR4hM/U0whf84VhDtXN/DWAk52KA==", "dependencies": { - "@smithy/types": "^3.5.0", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/util-arn-parser": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.679.0.tgz", - "integrity": "sha512-CwzEbU8R8rq9bqUFryO50RFBlkfufV9UfMArHPWlo+lmsC+NlSluHQALoj6Jkq3zf5ppn1CN0c1DDLrEqdQUXg==", + "version": "3.723.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.723.0.tgz", + "integrity": "sha512-ZhEfvUwNliOQROcAk34WJWVYTlTa4694kSVhDSjW6lE1bMataPnIN8A0ycukEzBXmd8ZSoBcQLn6lKGl7XIJ5w==", "dependencies": { "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.679.0.tgz", - "integrity": "sha512-YL6s4Y/1zC45OvddvgE139fjeWSKKPgLlnfrvhVL7alNyY9n7beR4uhoDpNrt5mI6sn9qiBF17790o+xLAXjjg==", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.775.0.tgz", + "integrity": "sha512-yjWmUgZC9tUxAo8Uaplqmq0eUh0zrbZJdwxGRKdYxfm4RG6fMw1tj52+KkatH7o+mNZvg1GDcVp/INktxonJLw==", "dependencies": { - "@aws-sdk/types": "3.679.0", - "@smithy/types": "^3.5.0", - "@smithy/util-endpoints": "^2.1.3", + "@aws-sdk/types": "3.775.0", + "@smithy/types": "^4.2.0", + "@smithy/util-endpoints": "^3.0.2", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/util-locate-window": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.679.0.tgz", - "integrity": "sha512-zKTd48/ZWrCplkXpYDABI74rQlbR0DNHs8nH95htfSLj9/mWRSwaGptoxwcihaq/77vi/fl2X3y0a1Bo8bt7RA==", + "version": "3.723.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.723.0.tgz", + "integrity": "sha512-Yf2CS10BqK688DRsrKI/EO6B8ff5J86NXe4C+VCysK7UOgN0l1zOTeTukZ3H8Q9tYYX3oaF1961o8vRkFm7Nmw==", "dependencies": { "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.679.0.tgz", - "integrity": "sha512-CusSm2bTBG1kFypcsqU8COhnYc6zltobsqs3nRrvYqYaOqtMnuE46K4XTWpnzKgwDejgZGOE+WYyprtAxrPvmQ==", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.775.0.tgz", + "integrity": "sha512-txw2wkiJmZKVdDbscK7VBK+u+TJnRtlUjRTLei+elZg2ADhpQxfVAQl436FUeIv6AhB/oRHW6/K/EAGXUSWi0A==", "dependencies": { - "@aws-sdk/types": "3.679.0", - "@smithy/types": "^3.5.0", + "@aws-sdk/types": "3.775.0", + "@smithy/types": "^4.2.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.679.0.tgz", - "integrity": "sha512-Bw4uXZ+NU5ed6TNfo4tBbhBSW+2eQxXYjYBGl5gLUNUpg2pDFToQAP6rXBFiwcG52V2ny5oLGiD82SoYuYkAVg==", - "dependencies": { - "@aws-sdk/middleware-user-agent": "3.679.0", - "@aws-sdk/types": "3.679.0", - "@smithy/node-config-provider": "^3.1.8", - "@smithy/types": "^3.5.0", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.775.0.tgz", + "integrity": "sha512-N9yhTevbizTOMo3drH7Eoy6OkJ3iVPxhV7dwb6CMAObbLneS36CSfA6xQXupmHWcRvZPTz8rd1JGG3HzFOau+g==", + "dependencies": { + "@aws-sdk/middleware-user-agent": "3.775.0", + "@aws-sdk/types": "3.775.0", + "@smithy/node-config-provider": "^4.0.2", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" }, "peerDependencies": { "aws-crt": ">=1.0.0" @@ -1448,21 +1404,21 @@ } }, "node_modules/@aws-sdk/xml-builder": { - "version": "3.679.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.679.0.tgz", - "integrity": "sha512-nPmhVZb39ty5bcQ7mAwtjezBcsBqTYZ9A2D9v/lE92KCLdu5RhSkPH7O71ZqbZx1mUSg9fAOxHPiG79U5VlpLQ==", + "version": "3.775.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.775.0.tgz", + "integrity": "sha512-b9NGO6FKJeLGYnV7Z1yvcP1TNU4dkD5jNsLWOF1/sygZoASaQhNOlaiJ/1OH331YQ1R1oWk38nBb0frsYkDsOQ==", "dependencies": { - "@smithy/types": "^3.5.0", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@babel/code-frame": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.0.tgz", - "integrity": "sha512-INCKxTtbXtcNbUZ3YXutwMpEleqttcswhAdee7dhuoVrD2cnuc3PqtERBtxkX5nziX9vnBL8WXmSGwv8CuPV6g==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.25.9", @@ -1474,30 +1430,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.0.tgz", - "integrity": "sha512-qETICbZSLe7uXv9VE8T/RWOdIE5qqyTucOt4zLYMafj2MRO271VGgLd4RACJMeBO37UPWhXiKMBk7YlJ0fOzQA==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", + "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", - "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz", + "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.26.0", - "@babel/generator": "^7.26.0", - "@babel/helper-compilation-targets": "^7.25.9", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.10", + "@babel/helper-compilation-targets": "^7.26.5", "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.0", - "@babel/parser": "^7.26.0", - "@babel/template": "^7.25.9", - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.26.0", + "@babel/helpers": "^7.26.10", + "@babel/parser": "^7.26.10", + "@babel/template": "^7.26.9", + "@babel/traverse": "^7.26.10", + "@babel/types": "^7.26.10", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -1522,13 +1478,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.0.tgz", - "integrity": "sha512-/AIkAmInnWwgEAJGQr9vY0c66Mj6kjkE2ZPB1PurTRaRAh3U+J45sAQMjQDJdh4WbR3l0x5xkimXBKyBXXAu2w==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.0.tgz", + "integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==", "dev": true, "dependencies": { - "@babel/parser": "^7.26.0", - "@babel/types": "^7.26.0", + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -1538,12 +1494,12 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", - "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.0.tgz", + "integrity": "sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.25.9", + "@babel/compat-data": "^7.26.8", "@babel/helper-validator-option": "^7.25.9", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", @@ -1602,9 +1558,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", - "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", + "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", "dev": true, "engines": { "node": ">=6.9.0" @@ -1638,25 +1594,25 @@ } }, "node_modules/@babel/helpers": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", - "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz", + "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==", "dev": true, "dependencies": { - "@babel/template": "^7.25.9", - "@babel/types": "^7.26.0" + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.26.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.1.tgz", - "integrity": "sha512-reoQYNiAJreZNsJzyrDNzFQ+IQ5JFiIzAHJg9bn94S3l+4++J7RsIhNMoB+lgP/9tpmiAQqspv+xfdxTSzREOw==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz", + "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", "dev": true, "dependencies": { - "@babel/types": "^7.26.0" + "@babel/types": "^7.27.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -1888,9 +1844,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", - "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz", + "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -1899,30 +1855,30 @@ } }, "node_modules/@babel/template": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", - "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz", + "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.25.9", - "@babel/parser": "^7.25.9", - "@babel/types": "^7.25.9" + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", - "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.0.tgz", + "integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.25.9", - "@babel/generator": "^7.25.9", - "@babel/parser": "^7.25.9", - "@babel/template": "^7.25.9", - "@babel/types": "^7.25.9", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.27.0", + "@babel/parser": "^7.27.0", + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1940,9 +1896,9 @@ } }, "node_modules/@babel/types": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", - "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz", + "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -2091,258 +2047,10 @@ "pbts": "bin/pbts" } }, - "node_modules/@elrondnetwork/bls-wasm": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@elrondnetwork/bls-wasm/-/bls-wasm-0.3.3.tgz", - "integrity": "sha512-neCzWRk8pZsOBeAI3+t8jgiSkqj/y4IJPOMKG4ebL1+MiOFayygmfDvfZrK57RSoMWvDfXHlhTL25DrI+EtH+w==", - "deprecated": "WARNING: This project has been moved to @multiversx/sdk-bls-wasm. Use @multiversx/sdk-bls-wasm instead.", - "dependencies": { - "assert": "^2.0.0", - "perf_hooks": "0.0.1" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/@elrondnetwork/erdjs": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/@elrondnetwork/erdjs/-/erdjs-11.1.2.tgz", - "integrity": "sha512-KHjN2nma0j29hWCJRJO6MlZG2GqH+cebqFmR3exkeHOYINAZbTvf1AVyHjQoo8UQvWBJDz0vejffc1BiaQYjrA==", - "deprecated": "WARNING: This project has been moved to @multiversx/sdk-core. Use @multiversx/sdk-core instead.", - "dependencies": { - "@elrondnetwork/transaction-decoder": "1.0.0", - "bech32": "1.1.4", - "bignumber.js": "9.0.1", - "blake2b": "2.1.3", - "buffer": "6.0.3", - "json-duplicate-key-handle": "1.0.0", - "keccak": "3.0.2", - "protobufjs": "6.11.3" - } - }, - "node_modules/@elrondnetwork/erdjs-dex": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/@elrondnetwork/erdjs-dex/-/erdjs-dex-0.2.14.tgz", - "integrity": "sha512-g7H/PhXCy2pVHPXQ1giB1+p3gB1YlQIFxhWMYMm8tuYQ2vgQj6+6pPhBoS4WYUGagwntZyz97AI5OzBJOt1V2w==", - "deprecated": "WARNING: This project has been moved to @multiversx/sdk-exchange. Use @multiversx/sdk-exchange instead.", - "dependencies": { - "@elrondnetwork/erdjs": "^11.1.0", - "bignumber.js": "9.0.1" - } - }, - "node_modules/@elrondnetwork/erdjs-dex/node_modules/bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", - "engines": { - "node": "*" - } - }, - "node_modules/@elrondnetwork/erdjs-walletcore": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@elrondnetwork/erdjs-walletcore/-/erdjs-walletcore-1.0.0.tgz", - "integrity": "sha512-I+N7rwBs4p9bX6d2Rd9Ck6uwCOsgafDzL9aAaFqwh3NnmEI7JGrXPvFoZxDTOQ9pyd2J9jk4dXS6GAImjd3R8g==", - "deprecated": "WARNING: This project has been moved to @multiversx/sdk-wallet. Use @multiversx/sdk-wallet instead.", - "dependencies": { - "@elrondnetwork/bls-wasm": "0.3.3", - "bech32": "1.1.4", - "bip39": "3.0.2", - "blake2b": "2.1.3", - "ed25519-hd-key": "1.1.2", - "keccak": "3.0.1", - "scryptsy": "2.1.0", - "tweetnacl": "1.0.3", - "uuid": "8.3.2" - } - }, - "node_modules/@elrondnetwork/erdjs-walletcore/node_modules/keccak": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz", - "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==", - "hasInstallScript": true, - "dependencies": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@elrondnetwork/erdjs-walletcore/node_modules/node-gyp-build": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", - "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/@elrondnetwork/erdjs-walletcore/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/@elrondnetwork/erdjs/node_modules/bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", - "engines": { - "node": "*" - } - }, - "node_modules/@elrondnetwork/erdjs/node_modules/protobufjs": { - "version": "6.11.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", - "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", - "hasInstallScript": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" - } - }, - "node_modules/@elrondnetwork/native-auth": { - "version": "0.1.22", - "resolved": "https://registry.npmjs.org/@elrondnetwork/native-auth/-/native-auth-0.1.22.tgz", - "integrity": "sha512-MtQyYaxrkjsxVEIiLC9Hp4/F4PCc3lPmnUWm4aLDYv/coPBoLO4St2J36SvhOiXNzdnTkRaSOpmGYFopJiydkQ==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dependencies": { - "@elrondnetwork/erdjs": "^10.2.7", - "@elrondnetwork/erdjs-walletcore": "^1.0.0", - "axios": "^0.27.2", - "bech32": "^2.0.0" - } - }, - "node_modules/@elrondnetwork/native-auth/node_modules/@elrondnetwork/erdjs": { - "version": "10.2.8", - "resolved": "https://registry.npmjs.org/@elrondnetwork/erdjs/-/erdjs-10.2.8.tgz", - "integrity": "sha512-WOT8J8jhodIiDcjnQjrzsB/2cCq1qigoGp+CloYqOeweL50SWMNN+9QTB2GzoqwAPRBGuZONSs7SYBVNElnhTA==", - "deprecated": "WARNING: This project has been moved to @multiversx/sdk-core. Use @multiversx/sdk-core instead.", - "dependencies": { - "@elrondnetwork/transaction-decoder": "0.1.0", - "bech32": "1.1.4", - "bignumber.js": "9.0.1", - "blake2b": "2.1.3", - "buffer": "6.0.3", - "json-duplicate-key-handle": "1.0.0", - "keccak": "3.0.2", - "protobufjs": "6.11.3" - } - }, - "node_modules/@elrondnetwork/native-auth/node_modules/@elrondnetwork/erdjs/node_modules/bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - }, - "node_modules/@elrondnetwork/native-auth/node_modules/@elrondnetwork/transaction-decoder": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@elrondnetwork/transaction-decoder/-/transaction-decoder-0.1.0.tgz", - "integrity": "sha512-R9YSiJCAgdlSzTKBy7/KjohFghmUhZIGDqWt6NGXrf33EN24QB15Q0LgHEW7lXsqsDSF5GpRYetsS7V3jYZQOg==", - "deprecated": "WARNING: This project has been moved to @multiversx/sdk-transaction-decoder. Use @multiversx/sdk-transaction-decoder instead.", - "dependencies": { - "bech32": "^2.0.0" - } - }, - "node_modules/@elrondnetwork/native-auth/node_modules/axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "dependencies": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - } - }, - "node_modules/@elrondnetwork/native-auth/node_modules/bech32": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", - "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" - }, - "node_modules/@elrondnetwork/native-auth/node_modules/bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", - "engines": { - "node": "*" - } - }, - "node_modules/@elrondnetwork/native-auth/node_modules/protobufjs": { - "version": "6.11.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", - "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", - "hasInstallScript": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" - } - }, - "node_modules/@elrondnetwork/transaction-decoder": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@elrondnetwork/transaction-decoder/-/transaction-decoder-1.0.0.tgz", - "integrity": "sha512-FFUDXffwDNwo4V6Co+S9ur3OPYyAEzwgen7gh7LtQrG7SNPELFHjl+YssABXI8v1+SWmqcrSxervMggAiDDXkg==", - "deprecated": "WARNING: This project has been moved to @multiversx/sdk-transaction-decoder. Use @multiversx/sdk-transaction-decoder instead.", - "dependencies": { - "bech32": "^2.0.0" - } - }, - "node_modules/@elrondnetwork/transaction-decoder/node_modules/bech32": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", - "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" - }, - "node_modules/@elrondnetwork/transaction-processor": { - "version": "0.1.26", - "resolved": "https://registry.npmjs.org/@elrondnetwork/transaction-processor/-/transaction-processor-0.1.26.tgz", - "integrity": "sha512-IBqPaB6mzBok26kYFKF6r017MMPKYJ9u5ayNqzJ+BqKtx+91op92wNwKkJJ6ZuKuV2ertRdtzna8FrSZOEPtYg==", - "deprecated": "WARNING: This project has been moved to @multiversx/sdk-transaction-processor. Use @multiversx/sdk-transaction-processor instead.", - "dependencies": { - "axios": "^0.21.1" - } - }, - "node_modules/@elrondnetwork/transaction-processor/node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dependencies": { - "follow-redirects": "^1.14.0" - } - }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", - "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.5.1.tgz", + "integrity": "sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==", "dev": true, "dependencies": { "eslint-visitor-keys": "^3.4.3" @@ -2421,38 +2129,37 @@ } }, "node_modules/@golevelup/nestjs-common": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@golevelup/nestjs-common/-/nestjs-common-2.0.0.tgz", - "integrity": "sha512-D9RLXgkqn9SDLnZ2VoMER9l/+g5CM9Z7sZXa+10+0rZs6yevMepoiWmMVsFoUXLzYG2GwfixHLExwUr3XBCHFw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@golevelup/nestjs-common/-/nestjs-common-2.0.2.tgz", + "integrity": "sha512-e5pV5MtFDkTNRxWn1+JTh6SUiI0Sld1++yfwcx3k3MHv7iT3AocvjizTcxnKVPb9BHJjZ68jjPxSND3/zi2FSw==", "dependencies": { - "lodash": "^4.17.21", - "nanoid": "^3.3.6" + "lodash": "^4.17.21" }, "peerDependencies": { - "@nestjs/common": "^10.x" + "@nestjs/common": "^10.x || ^11.0.0" } }, "node_modules/@golevelup/nestjs-discovery": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@golevelup/nestjs-discovery/-/nestjs-discovery-4.0.1.tgz", - "integrity": "sha512-HFXBJayEkYcU/bbxOztozONdWaZR34ZeJ2zRbZIWY8d5K26oPZQTvJ4L0STW3XVRGWtoE0WBpmx2YPNgYvcmJQ==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@golevelup/nestjs-discovery/-/nestjs-discovery-4.0.3.tgz", + "integrity": "sha512-8w3CsXHN7+7Sn2i419Eal1Iw/kOjAd6Kb55M/ZqKBBwACCMn4WiEuzssC71LpBMI1090CiDxuelfPRwwIrQK+A==", "dependencies": { "lodash": "^4.17.21" }, "peerDependencies": { - "@nestjs/common": "^10.x", - "@nestjs/core": "^10.x" + "@nestjs/common": "^10.x || ^11.0.0", + "@nestjs/core": "^10.x || ^11.0.0" } }, "node_modules/@golevelup/nestjs-modules": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@golevelup/nestjs-modules/-/nestjs-modules-0.7.1.tgz", - "integrity": "sha512-L5hBuU57ujl73IAyyZYkT+41tbo+9BggLzze7AMSWJhNUJBhvifFvtfSNRy2aTTPsLYuHLH2tmerjjOQkEdgDg==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@golevelup/nestjs-modules/-/nestjs-modules-0.7.2.tgz", + "integrity": "sha512-0u5wNm+jxOmRFHHKNbJci180zhCvGsp0ZW3tJt5m2ZMvFhfYjJiVozF5M3chHxqd3q7hH4cNLSE3/78uhjyaxg==", "dependencies": { "lodash": "^4.17.21" }, "peerDependencies": { - "@nestjs/common": "^10.x", + "@nestjs/common": "^10.x || ^11.0.0", "rxjs": "^7.x" } }, @@ -2511,6 +2218,17 @@ "resolved": "https://registry.npmjs.org/promise-breaker/-/promise-breaker-5.0.0.tgz", "integrity": "sha512-mgsWQuG4kJ1dtO6e/QlNDLFtMkMzzecsC69aI5hlLEjGHFNpHrvGhFi4LiK5jg2SMQj74/diH+wZliL9LpGsyA==" }, + "node_modules/@golevelup/nestjs-rabbitmq/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, "node_modules/@golevelup/nestjs-rabbitmq/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -2530,6 +2248,11 @@ } ] }, + "node_modules/@golevelup/nestjs-rabbitmq/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, "node_modules/@graphql-tools/merge": { "version": "8.4.2", "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.4.2.tgz", @@ -3022,9 +2745,9 @@ "integrity": "sha512-CtzORUwWTTOTqfVtHaKRJ0I1kNQd1bpn3sUh8I3nJDVY+5/M/Oe1DnEWzPQvqq/xPIIkzzzIP7mfCoAjFRvDhg==" }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", "dev": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", @@ -3109,23 +2832,42 @@ } }, "node_modules/@multiversx/sdk-core": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-core/-/sdk-core-13.11.0.tgz", - "integrity": "sha512-/ds0V/pwnppqPyl7HmIGIp4BdIKExDecvncRLvWd+xYaxXOLJ1R4opSXPAV1fpneoeX3lg8903mw2x5dBrHJ+A==", + "version": "13.17.2", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-core/-/sdk-core-13.17.2.tgz", + "integrity": "sha512-X/Ga66Ubx8IpHPM7pk3gl52KxVR0tbxlN2Zhjz7fg4Xxe0fzWAux5lEuDV8sN3SqD55uyz/l2CkstKgoZWpKWg==", "dependencies": { "@multiversx/sdk-transaction-decoder": "1.0.2", + "@noble/ed25519": "1.7.3", + "@noble/hashes": "1.3.0", "bech32": "1.1.4", "blake2b": "2.1.3", "buffer": "6.0.3", + "ed25519-hd-key": "1.1.2", + "ed2curve": "0.3.0", "json-bigint": "1.0.0", - "keccak": "3.0.2" + "keccak": "3.0.2", + "scryptsy": "2.1.0", + "tweetnacl": "1.0.3", + "uuid": "8.3.2" + }, + "optionalDependencies": { + "@multiversx/sdk-bls-wasm": "0.3.5", + "axios": "^1.7.4", + "bip39": "3.1.0" }, "peerDependencies": { - "axios": "^1.7.4", "bignumber.js": "^9.0.1", "protobufjs": "^7.2.6" } }, + "node_modules/@multiversx/sdk-core/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@multiversx/sdk-data-api-client": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/@multiversx/sdk-data-api-client/-/sdk-data-api-client-0.7.0.tgz", @@ -3164,46 +2906,6 @@ "node": "*" } }, - "node_modules/@multiversx/sdk-data-api-client/node_modules/@multiversx/sdk-wallet": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-wallet/-/sdk-wallet-3.0.0.tgz", - "integrity": "sha512-nDVBtva1mpfutXA8TfUnpdeFqhY9O+deNU3U/Z41yPBcju1trHDC9gcKPyQqcQ3qjG/6LwEXmIm7Dc5fIsvVjg==", - "dependencies": { - "@multiversx/sdk-bls-wasm": "0.3.5", - "bech32": "1.1.4", - "bip39": "3.0.2", - "blake2b": "2.1.3", - "ed25519-hd-key": "1.1.2", - "ed2curve": "0.3.0", - "keccak": "3.0.1", - "scryptsy": "2.1.0", - "tweetnacl": "1.0.3", - "uuid": "8.3.2" - } - }, - "node_modules/@multiversx/sdk-data-api-client/node_modules/@multiversx/sdk-wallet/node_modules/keccak": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz", - "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==", - "hasInstallScript": true, - "dependencies": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@multiversx/sdk-data-api-client/node_modules/node-gyp-build": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", - "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, "node_modules/@multiversx/sdk-data-api-client/node_modules/protobufjs": { "version": "6.11.3", "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", @@ -3229,12 +2931,21 @@ "pbts": "bin/pbts" } }, - "node_modules/@multiversx/sdk-data-api-client/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" + "node_modules/@multiversx/sdk-exchange": { + "version": "0.2.21", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-exchange/-/sdk-exchange-0.2.21.tgz", + "integrity": "sha512-ZjaOrpgzF9v504awOC8T+b3lGp4FvHKcIxmA6yuugGcdr45f/hZXd8v6HlZhpR/mRp494zLaPyzgrzkWvJ41wQ==", + "dependencies": { + "@multiversx/sdk-core": "^13.6.3", + "bignumber.js": "9.0.1" + } + }, + "node_modules/@multiversx/sdk-exchange/node_modules/bignumber.js": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", + "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", + "engines": { + "node": "*" } }, "node_modules/@multiversx/sdk-native-auth-client": { @@ -3245,41 +2956,68 @@ "axios": "^1.7.4" } }, - "node_modules/@multiversx/sdk-native-auth-server": { - "version": "1.0.20", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-native-auth-server/-/sdk-native-auth-server-1.0.20.tgz", - "integrity": "sha512-1rfPzYmmsUVmt+9jdY5TG3LQVth1o/KH1zR2g8ZqDQqZV7B6W504CX3XKZbIpkJoSk3XdlsDezX+OdD/emtC5g==", + "node_modules/@multiversx/sdk-nestjs-auth": { + "version": "5.0.2-beta.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-auth/-/sdk-nestjs-auth-5.0.2-beta.0.tgz", + "integrity": "sha512-G+rF1gPY72XzbtX/9RO8SBX6FMEa4DO/gOPCR+AwhUM8wTtDiP3CYE8j8Q0SPtDVVArMkonfMDrHmVmRLY3cJg==", + "dependencies": { + "@multiversx/sdk-core": "^14.0.0", + "@multiversx/sdk-native-auth-server": "^2.0.0", + "jsonwebtoken": "^9.0.0" + }, + "peerDependencies": { + "@multiversx/sdk-nestjs-cache": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-common": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-monitoring": "5.0.2-beta.0", + "@nestjs/common": "^10.x" + } + }, + "node_modules/@multiversx/sdk-nestjs-auth/node_modules/@multiversx/sdk-core": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-core/-/sdk-core-14.0.1.tgz", + "integrity": "sha512-50BinNuAg/JkJC+H3s/IfgliB1o+/XhuPB+B83fdV3z4VMxO0s+1JKDACDrr4lJ0uYT1O6Gb+eToHxZr7kGQEw==", "dependencies": { - "@multiversx/sdk-wallet": "^4.5.0", + "@multiversx/sdk-transaction-decoder": "1.0.2", + "@noble/ed25519": "1.7.3", + "@noble/hashes": "1.3.0", + "bech32": "1.1.4", + "blake2b": "2.1.3", + "buffer": "6.0.3", + "ed25519-hd-key": "1.1.2", + "ed2curve": "0.3.0", + "json-bigint": "1.0.0", + "keccak": "3.0.2", + "scryptsy": "2.1.0", + "tweetnacl": "1.0.3", + "uuid": "8.3.2" + }, + "optionalDependencies": { + "@multiversx/sdk-bls-wasm": "0.3.5", "axios": "^1.7.4", - "bech32": "^2.0.0" + "bip39": "3.1.0" }, "peerDependencies": { - "@multiversx/sdk-core": "^13.x" + "bignumber.js": "^9.0.1", + "protobufjs": "^7.2.6" } }, - "node_modules/@multiversx/sdk-native-auth-server/node_modules/bech32": { + "node_modules/@multiversx/sdk-nestjs-auth/node_modules/@multiversx/sdk-native-auth-server": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", - "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" - }, - "node_modules/@multiversx/sdk-nestjs-auth": { - "version": "4.1.0-beta.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-auth/-/sdk-nestjs-auth-4.1.0-beta.0.tgz", - "integrity": "sha512-cqk8LJgvcUBbQucbGhRRgkBxqmDWEfKtRzv9AVyKKi2PBaFEUWkXcNkNUpHwHsPxd/zMZpVTUy0U+CIZ3ugBKA==", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-native-auth-server/-/sdk-native-auth-server-2.0.0.tgz", + "integrity": "sha512-DdjWyt60Chk6unMVprBV/5zA8rEXjufYdE67UG6XP8RRZiGU1+k6UU14E0TU/iii8K+/5Tj/zfrIrPfbDiASoA==", "dependencies": { - "@multiversx/sdk-core": "^13.4.1", - "@multiversx/sdk-native-auth-server": "^1.0.19", - "@multiversx/sdk-wallet": "^4.5.0", - "jsonwebtoken": "^9.0.0" + "axios": "^1.7.4", + "bech32": "^2.0.0" }, "peerDependencies": { - "@multiversx/sdk-nestjs-cache": "^4.1.0-beta.0", - "@multiversx/sdk-nestjs-common": "^4.1.0-beta.0", - "@multiversx/sdk-nestjs-monitoring": "^4.1.0-beta.0", - "@nestjs/common": "^10.x" + "@multiversx/sdk-core": "^14.x" } }, + "node_modules/@multiversx/sdk-nestjs-auth/node_modules/@multiversx/sdk-native-auth-server/node_modules/bech32": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", + "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" + }, "node_modules/@multiversx/sdk-nestjs-auth/node_modules/jsonwebtoken": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", @@ -3301,10 +3039,18 @@ "npm": ">=6" } }, + "node_modules/@multiversx/sdk-nestjs-auth/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@multiversx/sdk-nestjs-cache": { - "version": "4.1.0-beta.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-cache/-/sdk-nestjs-cache-4.1.0-beta.0.tgz", - "integrity": "sha512-v7D3hW3pNeGYl/MBeRXx+ccXlIBxzebStY51kusoRq/p3bjzXe1u6+YNHpY1FMDedk/IQXyYhS7TO49K0PsDgw==", + "version": "5.0.2-beta.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-cache/-/sdk-nestjs-cache-5.0.2-beta.0.tgz", + "integrity": "sha512-rfEoTwz7SCwdNt+frFUsXkrfJ25WVJwKCrFnwwpqH1mlvct0bi+CtmKzsgmr2fmzcos6fM+8/3XjYVQNnUeBNg==", "dependencies": { "lru-cache": "^8.0.4", "moment": "^2.29.4", @@ -3313,9 +3059,9 @@ "uuid": "^8.3.2" }, "peerDependencies": { - "@multiversx/sdk-nestjs-common": "^4.1.0-beta.0", - "@multiversx/sdk-nestjs-monitoring": "^4.1.0-beta.0", - "@multiversx/sdk-nestjs-redis": "^4.1.0-beta.0", + "@multiversx/sdk-nestjs-common": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-monitoring": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-redis": "5.0.2-beta.0", "@nestjs/common": "^10.x", "@nestjs/core": "^10.x" } @@ -3337,24 +3083,52 @@ } }, "node_modules/@multiversx/sdk-nestjs-common": { - "version": "4.1.0-beta.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-common/-/sdk-nestjs-common-4.1.0-beta.0.tgz", - "integrity": "sha512-GG/9IPJp72wdeAPR7hO4q7Ao8dulYGqfp+lM6WBhPTmqq9a58AH1BPc34l/6eG8p8h1ZI4g8ZzNn9YIGabY+qw==", + "version": "5.0.2-beta.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-common/-/sdk-nestjs-common-5.0.2-beta.0.tgz", + "integrity": "sha512-A0ngCJVeNXe1O6OsiE+cLMwg2SPYZ/9+7xpK+sJiHoruwsKxzZv4BpKBqOHCDPKaXghzwLEKH2oFWxKoYJ37Pw==", "dependencies": { - "@multiversx/sdk-core": "^13.4.1", - "@multiversx/sdk-network-providers": "^2.6.0", + "@multiversx/sdk-core": "^14.0.0", "nest-winston": "^1.6.2", "uuid": "^8.3.2", "winston": "^3.7.2" }, "peerDependencies": { - "@multiversx/sdk-nestjs-monitoring": "^4.1.0-beta.0", + "@multiversx/sdk-nestjs-monitoring": "5.0.2-beta.0", "@nestjs/common": "^10.x", "@nestjs/config": "^3.x", "@nestjs/core": "^10.x", "@nestjs/swagger": "^7.x" } }, + "node_modules/@multiversx/sdk-nestjs-common/node_modules/@multiversx/sdk-core": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-core/-/sdk-core-14.0.1.tgz", + "integrity": "sha512-50BinNuAg/JkJC+H3s/IfgliB1o+/XhuPB+B83fdV3z4VMxO0s+1JKDACDrr4lJ0uYT1O6Gb+eToHxZr7kGQEw==", + "dependencies": { + "@multiversx/sdk-transaction-decoder": "1.0.2", + "@noble/ed25519": "1.7.3", + "@noble/hashes": "1.3.0", + "bech32": "1.1.4", + "blake2b": "2.1.3", + "buffer": "6.0.3", + "ed25519-hd-key": "1.1.2", + "ed2curve": "0.3.0", + "json-bigint": "1.0.0", + "keccak": "3.0.2", + "scryptsy": "2.1.0", + "tweetnacl": "1.0.3", + "uuid": "8.3.2" + }, + "optionalDependencies": { + "@multiversx/sdk-bls-wasm": "0.3.5", + "axios": "^1.7.4", + "bip39": "3.1.0" + }, + "peerDependencies": { + "bignumber.js": "^9.0.1", + "protobufjs": "^7.2.6" + } + }, "node_modules/@multiversx/sdk-nestjs-common/node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -3364,34 +3138,72 @@ } }, "node_modules/@multiversx/sdk-nestjs-elastic": { - "version": "4.1.0-beta.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-elastic/-/sdk-nestjs-elastic-4.1.0-beta.0.tgz", - "integrity": "sha512-6TcaulRYtFxQjCHWIq1JYBnvhYa/W8ID/kWUPb+mhf64DD72zR633LiG1hachQqDbV87sz6bHhYrmVSaQm0QOg==", + "version": "5.0.2-beta.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-elastic/-/sdk-nestjs-elastic-5.0.2-beta.0.tgz", + "integrity": "sha512-CgYhG+J88SPYyXjLA84yT2YM6Vlq6nZOi6EnD1WiAlshitoN+0kyrqYnJvCB7wy1BH+BXgUCS6BXOKhpOGSvrg==", "peerDependencies": { - "@multiversx/sdk-nestjs-http": "^4.1.0-beta.0", + "@multiversx/sdk-nestjs-http": "5.0.2-beta.0", "@nestjs/common": "^10.x" } }, "node_modules/@multiversx/sdk-nestjs-http": { - "version": "4.1.0-beta.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-http/-/sdk-nestjs-http-4.1.0-beta.0.tgz", - "integrity": "sha512-sOiMsMUhcsVSySjeskVu6+ZNzbKzam9e8NODXWXWQ2KkdmsA6PW20feisln8efu0J6OHSqTboVdXi2mHnAhPIQ==", + "version": "5.0.2-beta.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-http/-/sdk-nestjs-http-5.0.2-beta.0.tgz", + "integrity": "sha512-xUiNU0NCiDY08syAz8x1jbdWzd6Y4yaYRB1oyACL0WbVF60xhBV0VrSbsgRsSSh7wzGfvnGIRHJrmOQEyVZUTg==", "dependencies": { + "@multiversx/sdk-core": "^14.0.0", "@multiversx/sdk-native-auth-client": "^1.0.9", "agentkeepalive": "^4.3.0", "axios": "^1.7.4" }, "peerDependencies": { - "@multiversx/sdk-nestjs-common": "^4.1.0-beta.0", - "@multiversx/sdk-nestjs-monitoring": "^4.1.0-beta.0", + "@multiversx/sdk-nestjs-common": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-monitoring": "5.0.2-beta.0", "@nestjs/common": "^10.x", "@nestjs/core": "^10.x" } }, + "node_modules/@multiversx/sdk-nestjs-http/node_modules/@multiversx/sdk-core": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-core/-/sdk-core-14.0.2.tgz", + "integrity": "sha512-bVrKH23NSsfVyIZKujFrc8k+mBMM4pJDNe+8CHG3M0OUPi/kOVBev6VFmLpQyW9/t25VHU1lR6c4A/qhZOl1Mw==", + "dependencies": { + "@multiversx/sdk-transaction-decoder": "1.0.2", + "@noble/ed25519": "1.7.3", + "@noble/hashes": "1.3.0", + "bech32": "1.1.4", + "blake2b": "2.1.3", + "buffer": "6.0.3", + "ed25519-hd-key": "1.1.2", + "ed2curve": "0.3.0", + "json-bigint": "1.0.0", + "keccak": "3.0.2", + "scryptsy": "2.1.0", + "tweetnacl": "1.0.3", + "uuid": "8.3.2" + }, + "optionalDependencies": { + "@multiversx/sdk-bls-wasm": "0.3.5", + "axios": "^1.7.4", + "bip39": "3.1.0" + }, + "peerDependencies": { + "bignumber.js": "^9.0.1", + "protobufjs": "^7.2.6" + } + }, + "node_modules/@multiversx/sdk-nestjs-http/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@multiversx/sdk-nestjs-monitoring": { - "version": "4.1.0-beta.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-monitoring/-/sdk-nestjs-monitoring-4.1.0-beta.0.tgz", - "integrity": "sha512-1j+1PxCdKv5rh6pULVXeepUhf8HTln5oZV8EMCcrusSWS/azMoYmH9cK+p2S8XgL5zHfUNwJLFMiufQpY/MlNA==", + "version": "5.0.2-beta.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-monitoring/-/sdk-nestjs-monitoring-5.0.2-beta.0.tgz", + "integrity": "sha512-fsKRSJxq8UEY/yMa0J4SZUhDwN5OrbrWsJY/F0BZ/UHtlH8mKJhozJft3eh5dhWo0fZB8qkJYDGE5AWOFaagag==", "dependencies": { "prom-client": "^14.0.1", "winston": "^3.7.2", @@ -3402,15 +3214,15 @@ } }, "node_modules/@multiversx/sdk-nestjs-rabbitmq": { - "version": "4.1.0-beta.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-rabbitmq/-/sdk-nestjs-rabbitmq-4.1.0-beta.0.tgz", - "integrity": "sha512-KoQoHkQzPSP8XZSBbI03zoS96quhBCOj/IsmlJ29Fpvot/6Rl2RQ95lRzcIucIaBhUB9sI13AHUEC47uW/ScTA==", + "version": "5.0.2-beta.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-rabbitmq/-/sdk-nestjs-rabbitmq-5.0.2-beta.0.tgz", + "integrity": "sha512-4JXT+tEymdvjlyTU3l2Ydkyy1BG4W+cULTwzT4zZGyUzCTKkNnMvHFHJ+w4YM5zcWllU1JcdsbazwILA5iWYlA==", "dependencies": { "@golevelup/nestjs-rabbitmq": "4.0.0", "uuid": "^8.3.2" }, "peerDependencies": { - "@multiversx/sdk-nestjs-common": "^4.1.0-beta.0", + "@multiversx/sdk-nestjs-common": "5.0.2-beta.0", "@nestjs/common": "^10.x" } }, @@ -3469,6 +3281,17 @@ "resolved": "https://registry.npmjs.org/promise-breaker/-/promise-breaker-5.0.0.tgz", "integrity": "sha512-mgsWQuG4kJ1dtO6e/QlNDLFtMkMzzecsC69aI5hlLEjGHFNpHrvGhFi4LiK5jg2SMQj74/diH+wZliL9LpGsyA==" }, + "node_modules/@multiversx/sdk-nestjs-rabbitmq/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, "node_modules/@multiversx/sdk-nestjs-rabbitmq/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -3488,6 +3311,11 @@ } ] }, + "node_modules/@multiversx/sdk-nestjs-rabbitmq/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, "node_modules/@multiversx/sdk-nestjs-rabbitmq/node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -3497,9 +3325,9 @@ } }, "node_modules/@multiversx/sdk-nestjs-redis": { - "version": "4.1.0-beta.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-redis/-/sdk-nestjs-redis-4.1.0-beta.0.tgz", - "integrity": "sha512-Hm/zRf7U8LmzAGMhlGd8LfPx+f3/e9kPJzjztiGFer5Hv6IAOgzGTLBGiTWo7+LbI0ekLkDd+vo0pAHI4GROgQ==", + "version": "5.0.2-beta.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-redis/-/sdk-nestjs-redis-5.0.2-beta.0.tgz", + "integrity": "sha512-AAwM09WSUjy5RBiuWcFKJAHrbmCLSoH7j2zxc4EnIOWStZABVYU2ErJheMaX/IeAn5yba+U24BJlD75s6KoLHw==", "dependencies": { "ioredis": "^5.2.3" }, @@ -3507,28 +3335,6 @@ "@nestjs/common": "^10.x" } }, - "node_modules/@multiversx/sdk-network-providers": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-network-providers/-/sdk-network-providers-2.9.0.tgz", - "integrity": "sha512-K1aolRg8xCDH/E0bPSIdXZbprKf3fxkEfmxhXN+pYXd2LXoXLdIQazo16b1kraxsRsyDDv8Ovc5oWg32/+Vtcg==", - "dependencies": { - "bech32": "1.1.4", - "bignumber.js": "9.0.1", - "buffer": "6.0.3", - "json-bigint": "1.0.0" - }, - "peerDependencies": { - "axios": "^1.7.4" - } - }, - "node_modules/@multiversx/sdk-network-providers/node_modules/bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", - "engines": { - "node": "*" - } - }, "node_modules/@multiversx/sdk-transaction-decoder": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@multiversx/sdk-transaction-decoder/-/sdk-transaction-decoder-1.0.2.tgz", @@ -3542,16 +3348,22 @@ "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" }, + "node_modules/@multiversx/sdk-transaction-processor": { + "version": "0.1.35", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-transaction-processor/-/sdk-transaction-processor-0.1.35.tgz", + "integrity": "sha512-zbj4zNYhIxjlnxy7/p7so4IroOd+Z3QtIvFkKJEg8HMGSAuF6dObmrmc4dsx8nzG97rFpOLJ7iSyE8Xk9sCvrQ==", + "dependencies": { + "axios": "^1.7.4" + } + }, "node_modules/@multiversx/sdk-wallet": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-wallet/-/sdk-wallet-4.6.0.tgz", - "integrity": "sha512-SxO/hBTnAB+uWH4MJdwKLvfRk8cxdA8zi6JC4I9j1+V+XQJpfs2YHCvMmaVyIAqjmSg9i7Uk61exrDkR3bjPAw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-wallet/-/sdk-wallet-3.0.0.tgz", + "integrity": "sha512-nDVBtva1mpfutXA8TfUnpdeFqhY9O+deNU3U/Z41yPBcju1trHDC9gcKPyQqcQ3qjG/6LwEXmIm7Dc5fIsvVjg==", "dependencies": { "@multiversx/sdk-bls-wasm": "0.3.5", - "@noble/ed25519": "1.7.3", - "@noble/hashes": "1.3.0", "bech32": "1.1.4", - "bip39": "3.1.0", + "bip39": "3.0.2", "blake2b": "2.1.3", "ed25519-hd-key": "1.1.2", "ed2curve": "0.3.0", @@ -3561,12 +3373,20 @@ "uuid": "8.3.2" } }, + "node_modules/@multiversx/sdk-wallet/node_modules/@types/node": { + "version": "11.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz", + "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==" + }, "node_modules/@multiversx/sdk-wallet/node_modules/bip39": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.1.0.tgz", - "integrity": "sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.2.tgz", + "integrity": "sha512-J4E1r2N0tUylTKt07ibXvhpT2c5pyAFgvuA5q1H9uDy6dEGpjV8jmymh3MTYJDLCNbIVClSB9FbND49I6N24MQ==", "dependencies": { - "@noble/hashes": "^1.2.0" + "@types/node": "11.11.6", + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1" } }, "node_modules/@multiversx/sdk-wallet/node_modules/keccak": { @@ -3583,9 +3403,9 @@ } }, "node_modules/@multiversx/sdk-wallet/node_modules/node-gyp-build": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", - "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", @@ -3916,14 +3736,14 @@ } }, "node_modules/@nestjs/graphql": { - "version": "12.2.1", - "resolved": "https://registry.npmjs.org/@nestjs/graphql/-/graphql-12.2.1.tgz", - "integrity": "sha512-eXbme7RcecXaz6pZOc3uR9gR7AEAS20BTkzToWab4ExdDJRLhd7ua4C/uNEPUK+82HbNfd3h3z4Mes29N2R+/w==", - "dependencies": { - "@graphql-tools/merge": "9.0.8", - "@graphql-tools/schema": "10.0.7", - "@graphql-tools/utils": "10.5.5", - "@nestjs/mapped-types": "2.0.5", + "version": "12.2.2", + "resolved": "https://registry.npmjs.org/@nestjs/graphql/-/graphql-12.2.2.tgz", + "integrity": "sha512-lUDy/1uqbRA1kBKpXcmY0aHhcPbfeG52Wg5+9Jzd1d57dwSjCAmuO+mWy5jz9ugopVCZeK0S/kdAMvA+r9fNdA==", + "dependencies": { + "@graphql-tools/merge": "9.0.11", + "@graphql-tools/schema": "10.0.10", + "@graphql-tools/utils": "10.6.1", + "@nestjs/mapped-types": "2.0.6", "chokidar": "4.0.1", "fast-glob": "3.3.2", "graphql-tag": "2.12.6", @@ -3931,8 +3751,8 @@ "lodash": "4.17.21", "normalize-path": "3.0.0", "subscriptions-transport-ws": "0.11.0", - "tslib": "2.8.0", - "uuid": "10.0.0", + "tslib": "2.8.1", + "uuid": "11.0.3", "ws": "8.18.0" }, "peerDependencies": { @@ -3961,11 +3781,11 @@ } }, "node_modules/@nestjs/graphql/node_modules/@graphql-tools/merge": { - "version": "9.0.8", - "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-9.0.8.tgz", - "integrity": "sha512-RG9NEp4fi0MoFi0te4ahqTMYuavQnXlpEZxxMomdCa6CI5tfekcVm/rsLF5Zt8O4HY+esDt9+4dCL+aOKvG79w==", + "version": "9.0.11", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-9.0.11.tgz", + "integrity": "sha512-AJL0XTozn31HoZN8tULzEkbDXyETA5vAFu4Q65kxJDu027p+auaNFYj/y51HP4BhMR4wykoteWyO7/VxKfdpiw==", "dependencies": { - "@graphql-tools/utils": "^10.5.5", + "@graphql-tools/utils": "^10.6.1", "tslib": "^2.4.0" }, "engines": { @@ -3976,12 +3796,12 @@ } }, "node_modules/@nestjs/graphql/node_modules/@graphql-tools/schema": { - "version": "10.0.7", - "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-10.0.7.tgz", - "integrity": "sha512-Cz1o+rf9cd3uMgG+zI9HlM5mPlnHQUlk/UQRZyUlPDfT+944taLaokjvj7AI6GcOFVf4f2D11XthQp+0GY31jQ==", + "version": "10.0.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-10.0.10.tgz", + "integrity": "sha512-TSdDvwgk1Fq3URDuZBMCPXlWLpRpxwaQ+0KqvycVwoHozYnBRZ2Ql9HVgDKnebkGQKmIk2enSeku+ERKxxSG0g==", "dependencies": { - "@graphql-tools/merge": "^9.0.8", - "@graphql-tools/utils": "^10.5.5", + "@graphql-tools/merge": "^9.0.11", + "@graphql-tools/utils": "^10.6.1", "tslib": "^2.4.0", "value-or-promise": "^1.0.12" }, @@ -3993,9 +3813,9 @@ } }, "node_modules/@nestjs/graphql/node_modules/@graphql-tools/utils": { - "version": "10.5.5", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.5.5.tgz", - "integrity": "sha512-LF/UDWmMT0mnobL2UZETwYghV7HYBzNaGj0SAkCYOMy/C3+6sQdbcTksnoFaKR9XIVD78jNXEGfivbB8Zd+cwA==", + "version": "10.6.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.6.1.tgz", + "integrity": "sha512-XHl0/DWkMf/8Dmw1F3RRoMPt6ZwU4J707YWcbPjS+49WZNoTVz6f+prQ4GuwZT8RqTPtrRawnGU93AV73ZLTfQ==", "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "cross-inspect": "1.0.1", @@ -4024,11 +3844,11 @@ } }, "node_modules/@nestjs/graphql/node_modules/readdirp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", - "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "engines": { - "node": ">= 14.16.0" + "node": ">= 14.18.0" }, "funding": { "type": "individual", @@ -4036,21 +3856,21 @@ } }, "node_modules/@nestjs/graphql/node_modules/uuid": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", - "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.3.tgz", + "integrity": "sha512-d0z310fCWv5dJwnX1Y/MncBAqGMKEzlBb1AOf7z9K8ALnd0utBX/msg/fA0+sbyN1ihbMsLhrBlnl1ak7Wa0rg==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], "bin": { - "uuid": "dist/bin/uuid" + "uuid": "dist/esm/bin/uuid" } }, "node_modules/@nestjs/mapped-types": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-2.0.5.tgz", - "integrity": "sha512-bSJv4pd6EY99NX9CjBIyn4TVDoSit82DUZlL4I3bqNfy5Gt+gXTa86i3I/i0iIV9P4hntcGM5GyO+FhZAhxtyg==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-2.0.6.tgz", + "integrity": "sha512-84ze+CPfp1OWdpRi1/lOu59hOhTz38eVzJvRKrg9ykRFwDz+XleKfMsG0gUqNZYFa6v53XYzeD+xItt8uDW7NQ==", "peerDependencies": { "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0", "class-transformer": "^0.4.0 || ^0.5.0", @@ -4460,6 +4280,15 @@ "node": ">=12" } }, + "node_modules/@nestjs/schematics/node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/@nestjs/swagger": { "version": "7.1.16", "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-7.1.16.tgz", @@ -4567,13 +4396,13 @@ } }, "node_modules/@nestjs/websockets": { - "version": "10.4.6", - "resolved": "https://registry.npmjs.org/@nestjs/websockets/-/websockets-10.4.6.tgz", - "integrity": "sha512-53YqDQylPAOudNFiiBvrN8QrRl/sZ9oEjKbD3wBVgrFREbaiuTySoyyy6HwVs60HW29uQwck+Bp7qkKGjhtQKg==", + "version": "10.4.15", + "resolved": "https://registry.npmjs.org/@nestjs/websockets/-/websockets-10.4.15.tgz", + "integrity": "sha512-OmCUJwvtagzXfMVko595O98UI3M9zg+URL+/HV7vd3QPMCZ3uGCKSq15YYJ99LHJn9NyK4e4Szm2KnHtUg2QzA==", "dependencies": { "iterare": "1.2.1", "object-hash": "3.0.0", - "tslib": "2.7.0" + "tslib": "2.8.1" }, "peerDependencies": { "@nestjs/common": "^10.0.0", @@ -4588,11 +4417,6 @@ } } }, - "node_modules/@nestjs/websockets/node_modules/tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" - }, "node_modules/@noble/ed25519": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-1.7.3.tgz", @@ -4786,655 +4610,670 @@ } }, "node_modules/@smithy/abort-controller": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.6.tgz", - "integrity": "sha512-0XuhuHQlEqbNQZp7QxxrFTdVWdwxch4vjxYgfInF91hZFkPxf9QDrdQka0KfxFMPqLNzSw0b95uGTrLliQUavQ==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.0.2.tgz", + "integrity": "sha512-Sl/78VDtgqKxN2+1qduaVE140XF+Xg+TafkncspwM4jFP/LHr76ZHmIY/y3V1M0mMLNk+Je6IGbzxy23RSToMw==", "dependencies": { - "@smithy/types": "^3.6.0", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/chunked-blob-reader": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-4.0.0.tgz", - "integrity": "sha512-jSqRnZvkT4egkq/7b6/QRCNXmmYVcHwnJldqJ3IhVpQE2atObVJ137xmGeuGFhjFUr8gCEVAOKwSY79OvpbDaQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-5.0.0.tgz", + "integrity": "sha512-+sKqDBQqb036hh4NPaUiEkYFkTUGYzRsn3EuFhyfQfMy6oGHEUJDurLP9Ufb5dasr/XiAmPNMr6wa9afjQB+Gw==", "dependencies": { "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@smithy/chunked-blob-reader-native": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-3.0.1.tgz", - "integrity": "sha512-VEYtPvh5rs/xlyqpm5NRnfYLZn+q0SRPELbvBV+C/G7IQ+ouTuo+NKKa3ShG5OaFR8NYVMXls9hPYLTvIKKDrQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-4.0.0.tgz", + "integrity": "sha512-R9wM2yPmfEMsUmlMlIgSzOyICs0x9uu7UTHoccMyt7BWw8shcGM8HqB355+BZCPBcySvbTYMs62EgEQkNxz2ig==", "dependencies": { - "@smithy/util-base64": "^3.0.0", + "@smithy/util-base64": "^4.0.0", "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@smithy/config-resolver": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.10.tgz", - "integrity": "sha512-Uh0Sz9gdUuz538nvkPiyv1DZRX9+D15EKDtnQP5rYVAzM/dnYk3P8cg73jcxyOitPgT3mE3OVj7ky7sibzHWkw==", - "dependencies": { - "@smithy/node-config-provider": "^3.1.9", - "@smithy/types": "^3.6.0", - "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-middleware": "^3.0.8", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.1.0.tgz", + "integrity": "sha512-8smPlwhga22pwl23fM5ew4T9vfLUCeFXlcqNOCD5M5h8VmNPNUE9j6bQSuRXpDSV11L/E/SwEBQuW8hr6+nS1A==", + "dependencies": { + "@smithy/node-config-provider": "^4.0.2", + "@smithy/types": "^4.2.0", + "@smithy/util-config-provider": "^4.0.0", + "@smithy/util-middleware": "^4.0.2", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/core": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.5.1.tgz", - "integrity": "sha512-DujtuDA7BGEKExJ05W5OdxCoyekcKT3Rhg1ZGeiUWaz2BJIWXjZmsG/DIP4W48GHno7AQwRsaCb8NcBgH3QZpg==", - "dependencies": { - "@smithy/middleware-serde": "^3.0.8", - "@smithy/protocol-http": "^4.1.5", - "@smithy/types": "^3.6.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-middleware": "^3.0.8", - "@smithy/util-stream": "^3.2.1", - "@smithy/util-utf8": "^3.0.0", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.2.0.tgz", + "integrity": "sha512-k17bgQhVZ7YmUvA8at4af1TDpl0NDMBuBKJl8Yg0nrefwmValU+CnA5l/AriVdQNthU/33H3nK71HrLgqOPr1Q==", + "dependencies": { + "@smithy/middleware-serde": "^4.0.3", + "@smithy/protocol-http": "^5.1.0", + "@smithy/types": "^4.2.0", + "@smithy/util-body-length-browser": "^4.0.0", + "@smithy/util-middleware": "^4.0.2", + "@smithy/util-stream": "^4.2.0", + "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/credential-provider-imds": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.5.tgz", - "integrity": "sha512-4FTQGAsuwqTzVMmiRVTn0RR9GrbRfkP0wfu/tXWVHd2LgNpTY0uglQpIScXK4NaEyXbB3JmZt8gfVqO50lP8wg==", - "dependencies": { - "@smithy/node-config-provider": "^3.1.9", - "@smithy/property-provider": "^3.1.8", - "@smithy/types": "^3.6.0", - "@smithy/url-parser": "^3.0.8", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.0.2.tgz", + "integrity": "sha512-32lVig6jCaWBHnY+OEQ6e6Vnt5vDHaLiydGrwYMW9tPqO688hPGTYRamYJ1EptxEC2rAwJrHWmPoKRBl4iTa8w==", + "dependencies": { + "@smithy/node-config-provider": "^4.0.2", + "@smithy/property-provider": "^4.0.2", + "@smithy/types": "^4.2.0", + "@smithy/url-parser": "^4.0.2", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/eventstream-codec": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-3.1.7.tgz", - "integrity": "sha512-kVSXScIiRN7q+s1x7BrQtZ1Aa9hvvP9FeCqCdBxv37GimIHgBCOnZ5Ip80HLt0DhnAKpiobFdGqTFgbaJNrazA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.0.2.tgz", + "integrity": "sha512-p+f2kLSK7ZrXVfskU/f5dzksKTewZk8pJLPvER3aFHPt76C2MxD9vNatSfLzzQSQB4FNO96RK4PSXfhD1TTeMQ==", "dependencies": { "@aws-crypto/crc32": "5.2.0", - "@smithy/types": "^3.6.0", - "@smithy/util-hex-encoding": "^3.0.0", + "@smithy/types": "^4.2.0", + "@smithy/util-hex-encoding": "^4.0.0", "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@smithy/eventstream-serde-browser": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.11.tgz", - "integrity": "sha512-Pd1Wnq3CQ/v2SxRifDUihvpXzirJYbbtXfEnnLV/z0OGCTx/btVX74P86IgrZkjOydOASBGXdPpupYQI+iO/6A==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.0.2.tgz", + "integrity": "sha512-CepZCDs2xgVUtH7ZZ7oDdZFH8e6Y2zOv8iiX6RhndH69nlojCALSKK+OXwZUgOtUZEUaZ5e1hULVCHYbCn7pug==", "dependencies": { - "@smithy/eventstream-serde-universal": "^3.0.10", - "@smithy/types": "^3.6.0", + "@smithy/eventstream-serde-universal": "^4.0.2", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/eventstream-serde-config-resolver": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.8.tgz", - "integrity": "sha512-zkFIG2i1BLbfoGQnf1qEeMqX0h5qAznzaZmMVNnvPZz9J5AWBPkOMckZWPedGUPcVITacwIdQXoPcdIQq5FRcg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.1.0.tgz", + "integrity": "sha512-1PI+WPZ5TWXrfj3CIoKyUycYynYJgZjuQo8U+sphneOtjsgrttYybdqESFReQrdWJ+LKt6NEdbYzmmfDBmjX2A==", "dependencies": { - "@smithy/types": "^3.6.0", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/eventstream-serde-node": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.10.tgz", - "integrity": "sha512-hjpU1tIsJ9qpcoZq9zGHBJPBOeBGYt+n8vfhDwnITPhEre6APrvqq/y3XMDEGUT2cWQ4ramNqBPRbx3qn55rhw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.0.2.tgz", + "integrity": "sha512-C5bJ/C6x9ENPMx2cFOirspnF9ZsBVnBMtP6BdPl/qYSuUawdGQ34Lq0dMcf42QTjUZgWGbUIZnz6+zLxJlb9aw==", "dependencies": { - "@smithy/eventstream-serde-universal": "^3.0.10", - "@smithy/types": "^3.6.0", + "@smithy/eventstream-serde-universal": "^4.0.2", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/eventstream-serde-universal": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.10.tgz", - "integrity": "sha512-ewG1GHbbqsFZ4asaq40KmxCmXO+AFSM1b+DcO2C03dyJj/ZH71CiTg853FSE/3SHK9q3jiYQIFjlGSwfxQ9kww==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.0.2.tgz", + "integrity": "sha512-St8h9JqzvnbB52FtckiHPN4U/cnXcarMniXRXTKn0r4b4XesZOGiAyUdj1aXbqqn1icSqBlzzUsCl6nPB018ng==", "dependencies": { - "@smithy/eventstream-codec": "^3.1.7", - "@smithy/types": "^3.6.0", + "@smithy/eventstream-codec": "^4.0.2", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/fetch-http-handler": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.9.tgz", - "integrity": "sha512-hYNVQOqhFQ6vOpenifFME546f0GfJn2OiQ3M0FDmuUu8V/Uiwy2wej7ZXxFBNqdx0R5DZAqWM1l6VRhGz8oE6A==", - "dependencies": { - "@smithy/protocol-http": "^4.1.4", - "@smithy/querystring-builder": "^3.0.7", - "@smithy/types": "^3.5.0", - "@smithy/util-base64": "^3.0.0", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.0.2.tgz", + "integrity": "sha512-+9Dz8sakS9pe7f2cBocpJXdeVjMopUDLgZs1yWeu7h++WqSbjUYv/JAJwKwXw1HV6gq1jyWjxuyn24E2GhoEcQ==", + "dependencies": { + "@smithy/protocol-http": "^5.1.0", + "@smithy/querystring-builder": "^4.0.2", + "@smithy/types": "^4.2.0", + "@smithy/util-base64": "^4.0.0", "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@smithy/hash-blob-browser": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-3.1.7.tgz", - "integrity": "sha512-4yNlxVNJifPM5ThaA5HKnHkn7JhctFUHvcaz6YXxHlYOSIrzI6VKQPTN8Gs1iN5nqq9iFcwIR9THqchUCouIfg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-4.0.2.tgz", + "integrity": "sha512-3g188Z3DyhtzfBRxpZjU8R9PpOQuYsbNnyStc/ZVS+9nVX1f6XeNOa9IrAh35HwwIZg+XWk8bFVtNINVscBP+g==", "dependencies": { - "@smithy/chunked-blob-reader": "^4.0.0", - "@smithy/chunked-blob-reader-native": "^3.0.1", - "@smithy/types": "^3.6.0", + "@smithy/chunked-blob-reader": "^5.0.0", + "@smithy/chunked-blob-reader-native": "^4.0.0", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@smithy/hash-node": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.8.tgz", - "integrity": "sha512-tlNQYbfpWXHimHqrvgo14DrMAgUBua/cNoz9fMYcDmYej7MAmUcjav/QKQbFc3NrcPxeJ7QClER4tWZmfwoPng==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.0.2.tgz", + "integrity": "sha512-VnTpYPnRUE7yVhWozFdlxcYknv9UN7CeOqSrMH+V877v4oqtVYuoqhIhtSjmGPvYrYnAkaM61sLMKHvxL138yg==", "dependencies": { - "@smithy/types": "^3.6.0", - "@smithy/util-buffer-from": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", + "@smithy/types": "^4.2.0", + "@smithy/util-buffer-from": "^4.0.0", + "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/hash-stream-node": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-3.1.7.tgz", - "integrity": "sha512-xMAsvJ3hLG63lsBVi1Hl6BBSfhd8/Qnp8fC06kjOpJvyyCEXdwHITa5Kvdsk6gaAXLhbZMhQMIGvgUbfnJDP6Q==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-4.0.2.tgz", + "integrity": "sha512-POWDuTznzbIwlEXEvvXoPMS10y0WKXK790soe57tFRfvf4zBHyzE529HpZMqmDdwG9MfFflnyzndUQ8j78ZdSg==", "dependencies": { - "@smithy/types": "^3.6.0", - "@smithy/util-utf8": "^3.0.0", + "@smithy/types": "^4.2.0", + "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/invalid-dependency": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.8.tgz", - "integrity": "sha512-7Qynk6NWtTQhnGTTZwks++nJhQ1O54Mzi7fz4PqZOiYXb4Z1Flpb2yRvdALoggTS8xjtohWUM+RygOtB30YL3Q==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.0.2.tgz", + "integrity": "sha512-GatB4+2DTpgWPday+mnUkoumP54u/MDM/5u44KF9hIu8jF0uafZtQLcdfIKkIcUNuF/fBojpLEHZS/56JqPeXQ==", "dependencies": { - "@smithy/types": "^3.6.0", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@smithy/is-array-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz", - "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.0.0.tgz", + "integrity": "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw==", "dependencies": { "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/md5-js": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-3.0.8.tgz", - "integrity": "sha512-LwApfTK0OJ/tCyNUXqnWCKoE2b4rDSr4BJlDAVCkiWYeHESr+y+d5zlAanuLW6fnitVJRD/7d9/kN/ZM9Su4mA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.0.2.tgz", + "integrity": "sha512-Hc0R8EiuVunUewCse2syVgA2AfSRco3LyAv07B/zCOMa+jpXI9ll+Q21Nc6FAlYPcpNcAXqBzMhNs1CD/pP2bA==", "dependencies": { - "@smithy/types": "^3.6.0", - "@smithy/util-utf8": "^3.0.0", + "@smithy/types": "^4.2.0", + "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@smithy/middleware-content-length": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.10.tgz", - "integrity": "sha512-T4dIdCs1d/+/qMpwhJ1DzOhxCZjZHbHazEPJWdB4GDi2HjIZllVzeBEcdJUN0fomV8DURsgOyrbEUzg3vzTaOg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.0.2.tgz", + "integrity": "sha512-hAfEXm1zU+ELvucxqQ7I8SszwQ4znWMbNv6PLMndN83JJN41EPuS93AIyh2N+gJ6x8QFhzSO6b7q2e6oClDI8A==", "dependencies": { - "@smithy/protocol-http": "^4.1.5", - "@smithy/types": "^3.6.0", + "@smithy/protocol-http": "^5.1.0", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/middleware-endpoint": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.2.1.tgz", - "integrity": "sha512-wWO3xYmFm6WRW8VsEJ5oU6h7aosFXfszlz3Dj176pTij6o21oZnzkCLzShfmRaaCHDkBXWBdO0c4sQAvLFP6zA==", - "dependencies": { - "@smithy/core": "^2.5.1", - "@smithy/middleware-serde": "^3.0.8", - "@smithy/node-config-provider": "^3.1.9", - "@smithy/shared-ini-file-loader": "^3.1.9", - "@smithy/types": "^3.6.0", - "@smithy/url-parser": "^3.0.8", - "@smithy/util-middleware": "^3.0.8", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.1.0.tgz", + "integrity": "sha512-xhLimgNCbCzsUppRTGXWkZywksuTThxaIB0HwbpsVLY5sceac4e1TZ/WKYqufQLaUy+gUSJGNdwD2jo3cXL0iA==", + "dependencies": { + "@smithy/core": "^3.2.0", + "@smithy/middleware-serde": "^4.0.3", + "@smithy/node-config-provider": "^4.0.2", + "@smithy/shared-ini-file-loader": "^4.0.2", + "@smithy/types": "^4.2.0", + "@smithy/url-parser": "^4.0.2", + "@smithy/util-middleware": "^4.0.2", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/middleware-retry": { - "version": "3.0.25", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.25.tgz", - "integrity": "sha512-m1F70cPaMBML4HiTgCw5I+jFNtjgz5z5UdGnUbG37vw6kh4UvizFYjqJGHvicfgKMkDL6mXwyPp5mhZg02g5sg==", - "dependencies": { - "@smithy/node-config-provider": "^3.1.9", - "@smithy/protocol-http": "^4.1.5", - "@smithy/service-error-classification": "^3.0.8", - "@smithy/smithy-client": "^3.4.2", - "@smithy/types": "^3.6.0", - "@smithy/util-middleware": "^3.0.8", - "@smithy/util-retry": "^3.0.8", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.1.0.tgz", + "integrity": "sha512-2zAagd1s6hAaI/ap6SXi5T3dDwBOczOMCSkkYzktqN1+tzbk1GAsHNAdo/1uzxz3Ky02jvZQwbi/vmDA6z4Oyg==", + "dependencies": { + "@smithy/node-config-provider": "^4.0.2", + "@smithy/protocol-http": "^5.1.0", + "@smithy/service-error-classification": "^4.0.2", + "@smithy/smithy-client": "^4.2.0", + "@smithy/types": "^4.2.0", + "@smithy/util-middleware": "^4.0.2", + "@smithy/util-retry": "^4.0.2", "tslib": "^2.6.2", "uuid": "^9.0.1" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/middleware-serde": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.8.tgz", - "integrity": "sha512-Xg2jK9Wc/1g/MBMP/EUn2DLspN8LNt+GMe7cgF+Ty3vl+Zvu+VeZU5nmhveU+H8pxyTsjrAkci8NqY6OuvZnjA==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.0.3.tgz", + "integrity": "sha512-rfgDVrgLEVMmMn0BI8O+8OVr6vXzjV7HZj57l0QxslhzbvVfikZbVfBVthjLHqib4BW44QhcIgJpvebHlRaC9A==", "dependencies": { - "@smithy/types": "^3.6.0", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/middleware-stack": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.8.tgz", - "integrity": "sha512-d7ZuwvYgp1+3682Nx0MD3D/HtkmZd49N3JUndYWQXfRZrYEnCWYc8BHcNmVsPAp9gKvlurdg/mubE6b/rPS9MA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.0.2.tgz", + "integrity": "sha512-eSPVcuJJGVYrFYu2hEq8g8WWdJav3sdrI4o2c6z/rjnYDd3xH9j9E7deZQCzFn4QvGPouLngH3dQ+QVTxv5bOQ==", "dependencies": { - "@smithy/types": "^3.6.0", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/node-config-provider": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.9.tgz", - "integrity": "sha512-qRHoah49QJ71eemjuS/WhUXB+mpNtwHRWQr77J/m40ewBVVwvo52kYAmb7iuaECgGTTcYxHS4Wmewfwy++ueew==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.0.2.tgz", + "integrity": "sha512-WgCkILRZfJwJ4Da92a6t3ozN/zcvYyJGUTmfGbgS/FkCcoCjl7G4FJaCDN1ySdvLvemnQeo25FdkyMSTSwulsw==", "dependencies": { - "@smithy/property-provider": "^3.1.8", - "@smithy/shared-ini-file-loader": "^3.1.9", - "@smithy/types": "^3.6.0", + "@smithy/property-provider": "^4.0.2", + "@smithy/shared-ini-file-loader": "^4.0.2", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/node-http-handler": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.2.5.tgz", - "integrity": "sha512-PkOwPNeKdvX/jCpn0A8n9/TyoxjGZB8WVoJmm9YzsnAgggTj4CrjpRHlTQw7dlLZ320n1mY1y+nTRUDViKi/3w==", - "dependencies": { - "@smithy/abort-controller": "^3.1.6", - "@smithy/protocol-http": "^4.1.5", - "@smithy/querystring-builder": "^3.0.8", - "@smithy/types": "^3.6.0", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.0.4.tgz", + "integrity": "sha512-/mdqabuAT3o/ihBGjL94PUbTSPSRJ0eeVTdgADzow0wRJ0rN4A27EOrtlK56MYiO1fDvlO3jVTCxQtQmK9dZ1g==", + "dependencies": { + "@smithy/abort-controller": "^4.0.2", + "@smithy/protocol-http": "^5.1.0", + "@smithy/querystring-builder": "^4.0.2", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/property-provider": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.8.tgz", - "integrity": "sha512-ukNUyo6rHmusG64lmkjFeXemwYuKge1BJ8CtpVKmrxQxc6rhUX0vebcptFA9MmrGsnLhwnnqeH83VTU9hwOpjA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.0.2.tgz", + "integrity": "sha512-wNRoQC1uISOuNc2s4hkOYwYllmiyrvVXWMtq+TysNRVQaHm4yoafYQyjN/goYZS+QbYlPIbb/QRjaUZMuzwQ7A==", "dependencies": { - "@smithy/types": "^3.6.0", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/protocol-http": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.5.tgz", - "integrity": "sha512-hsjtwpIemmCkm3ZV5fd/T0bPIugW1gJXwZ/hpuVubt2hEUApIoUTrf6qIdh9MAWlw0vjMrA1ztJLAwtNaZogvg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.1.0.tgz", + "integrity": "sha512-KxAOL1nUNw2JTYrtviRRjEnykIDhxc84qMBzxvu1MUfQfHTuBlCG7PA6EdVwqpJjH7glw7FqQoFxUJSyBQgu7g==", "dependencies": { - "@smithy/types": "^3.6.0", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/querystring-builder": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.8.tgz", - "integrity": "sha512-btYxGVqFUARbUrN6VhL9c3dnSviIwBYD9Rz1jHuN1hgh28Fpv2xjU1HeCeDJX68xctz7r4l1PBnFhGg1WBBPuA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.0.2.tgz", + "integrity": "sha512-NTOs0FwHw1vimmQM4ebh+wFQvOwkEf/kQL6bSM1Lock+Bv4I89B3hGYoUEPkmvYPkDKyp5UdXJYu+PoTQ3T31Q==", "dependencies": { - "@smithy/types": "^3.6.0", - "@smithy/util-uri-escape": "^3.0.0", + "@smithy/types": "^4.2.0", + "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/querystring-parser": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.8.tgz", - "integrity": "sha512-BtEk3FG7Ks64GAbt+JnKqwuobJNX8VmFLBsKIwWr1D60T426fGrV2L3YS5siOcUhhp6/Y6yhBw1PSPxA5p7qGg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.0.2.tgz", + "integrity": "sha512-v6w8wnmZcVXjfVLjxw8qF7OwESD9wnpjp0Dqry/Pod0/5vcEA3qxCr+BhbOHlxS8O+29eLpT3aagxXGwIoEk7Q==", "dependencies": { - "@smithy/types": "^3.6.0", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/service-error-classification": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.8.tgz", - "integrity": "sha512-uEC/kCCFto83bz5ZzapcrgGqHOh/0r69sZ2ZuHlgoD5kYgXJEThCoTuw/y1Ub3cE7aaKdznb+jD9xRPIfIwD7g==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.0.2.tgz", + "integrity": "sha512-LA86xeFpTKn270Hbkixqs5n73S+LVM0/VZco8dqd+JT75Dyx3Lcw/MraL7ybjmz786+160K8rPOmhsq0SocoJQ==", "dependencies": { - "@smithy/types": "^3.6.0" + "@smithy/types": "^4.2.0" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/shared-ini-file-loader": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.9.tgz", - "integrity": "sha512-/+OsJRNtoRbtsX0UpSgWVxFZLsJHo/4sTr+kBg/J78sr7iC+tHeOvOJrS5hCpVQ6sWBbhWLp1UNiuMyZhE6pmA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.0.2.tgz", + "integrity": "sha512-J9/gTWBGVuFZ01oVA6vdb4DAjf1XbDhK6sLsu3OS9qmLrS6KB5ygpeHiM3miIbj1qgSJ96GYszXFWv6ErJ8QEw==", "dependencies": { - "@smithy/types": "^3.6.0", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/signature-v4": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.2.1.tgz", - "integrity": "sha512-NsV1jF4EvmO5wqmaSzlnTVetemBS3FZHdyc5CExbDljcyJCEEkJr8ANu2JvtNbVg/9MvKAWV44kTrGS+Pi4INg==", - "dependencies": { - "@smithy/is-array-buffer": "^3.0.0", - "@smithy/protocol-http": "^4.1.5", - "@smithy/types": "^3.6.0", - "@smithy/util-hex-encoding": "^3.0.0", - "@smithy/util-middleware": "^3.0.8", - "@smithy/util-uri-escape": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.0.2.tgz", + "integrity": "sha512-Mz+mc7okA73Lyz8zQKJNyr7lIcHLiPYp0+oiqiMNc/t7/Kf2BENs5d63pEj7oPqdjaum6g0Fc8wC78dY1TgtXw==", + "dependencies": { + "@smithy/is-array-buffer": "^4.0.0", + "@smithy/protocol-http": "^5.1.0", + "@smithy/types": "^4.2.0", + "@smithy/util-hex-encoding": "^4.0.0", + "@smithy/util-middleware": "^4.0.2", + "@smithy/util-uri-escape": "^4.0.0", + "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/smithy-client": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.4.2.tgz", - "integrity": "sha512-dxw1BDxJiY9/zI3cBqfVrInij6ShjpV4fmGHesGZZUiP9OSE/EVfdwdRz0PgvkEvrZHpsj2htRaHJfftE8giBA==", - "dependencies": { - "@smithy/core": "^2.5.1", - "@smithy/middleware-endpoint": "^3.2.1", - "@smithy/middleware-stack": "^3.0.8", - "@smithy/protocol-http": "^4.1.5", - "@smithy/types": "^3.6.0", - "@smithy/util-stream": "^3.2.1", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.2.0.tgz", + "integrity": "sha512-Qs65/w30pWV7LSFAez9DKy0Koaoh3iHhpcpCCJ4waj/iqwsuSzJna2+vYwq46yBaqO5ZbP9TjUsATUNxrKeBdw==", + "dependencies": { + "@smithy/core": "^3.2.0", + "@smithy/middleware-endpoint": "^4.1.0", + "@smithy/middleware-stack": "^4.0.2", + "@smithy/protocol-http": "^5.1.0", + "@smithy/types": "^4.2.0", + "@smithy/util-stream": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/types": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.6.0.tgz", - "integrity": "sha512-8VXK/KzOHefoC65yRgCn5vG1cysPJjHnOVt9d0ybFQSmJgQj152vMn4EkYhGuaOmnnZvCPav/KnYyE6/KsNZ2w==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.2.0.tgz", + "integrity": "sha512-7eMk09zQKCO+E/ivsjQv+fDlOupcFUCSC/L2YUPgwhvowVGWbPQHjEFcmjt7QQ4ra5lyowS92SV53Zc6XD4+fg==", "dependencies": { "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/url-parser": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.8.tgz", - "integrity": "sha512-4FdOhwpTW7jtSFWm7SpfLGKIBC9ZaTKG5nBF0wK24aoQKQyDIKUw3+KFWCQ9maMzrgTJIuOvOnsV2lLGW5XjTg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.0.2.tgz", + "integrity": "sha512-Bm8n3j2ScqnT+kJaClSVCMeiSenK6jVAzZCNewsYWuZtnBehEz4r2qP0riZySZVfzB+03XZHJeqfmJDkeeSLiQ==", "dependencies": { - "@smithy/querystring-parser": "^3.0.8", - "@smithy/types": "^3.6.0", + "@smithy/querystring-parser": "^4.0.2", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@smithy/util-base64": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", - "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.0.0.tgz", + "integrity": "sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg==", "dependencies": { - "@smithy/util-buffer-from": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", + "@smithy/util-buffer-from": "^4.0.0", + "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/util-body-length-browser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-3.0.0.tgz", - "integrity": "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.0.0.tgz", + "integrity": "sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA==", "dependencies": { "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@smithy/util-body-length-node": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-3.0.0.tgz", - "integrity": "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.0.0.tgz", + "integrity": "sha512-q0iDP3VsZzqJyje8xJWEJCNIu3lktUGVoSy1KB0UWym2CL1siV3artm+u1DFYTLejpsrdGyCSWBdGNjJzfDPjg==", "dependencies": { "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/util-buffer-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz", - "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.0.0.tgz", + "integrity": "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug==", "dependencies": { - "@smithy/is-array-buffer": "^3.0.0", + "@smithy/is-array-buffer": "^4.0.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/util-config-provider": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-3.0.0.tgz", - "integrity": "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.0.0.tgz", + "integrity": "sha512-L1RBVzLyfE8OXH+1hsJ8p+acNUSirQnWQ6/EgpchV88G6zGBTDPdXiiExei6Z1wR2RxYvxY/XLw6AMNCCt8H3w==", "dependencies": { "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "3.0.25", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.25.tgz", - "integrity": "sha512-fRw7zymjIDt6XxIsLwfJfYUfbGoO9CmCJk6rjJ/X5cd20+d2Is7xjU5Kt/AiDt6hX8DAf5dztmfP5O82gR9emA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.8.tgz", + "integrity": "sha512-ZTypzBra+lI/LfTYZeop9UjoJhhGRTg3pxrNpfSTQLd3AJ37r2z4AXTKpq1rFXiiUIJsYyFgNJdjWRGP/cbBaQ==", "dependencies": { - "@smithy/property-provider": "^3.1.8", - "@smithy/smithy-client": "^3.4.2", - "@smithy/types": "^3.6.0", + "@smithy/property-provider": "^4.0.2", + "@smithy/smithy-client": "^4.2.0", + "@smithy/types": "^4.2.0", "bowser": "^2.11.0", "tslib": "^2.6.2" }, "engines": { - "node": ">= 10.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "3.0.25", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.25.tgz", - "integrity": "sha512-H3BSZdBDiVZGzt8TG51Pd2FvFO0PAx/A0mJ0EH8a13KJ6iUCdYnw/Dk/MdC1kTd0eUuUGisDFaxXVXo4HHFL1g==", - "dependencies": { - "@smithy/config-resolver": "^3.0.10", - "@smithy/credential-provider-imds": "^3.2.5", - "@smithy/node-config-provider": "^3.1.9", - "@smithy/property-provider": "^3.1.8", - "@smithy/smithy-client": "^3.4.2", - "@smithy/types": "^3.6.0", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.8.tgz", + "integrity": "sha512-Rgk0Jc/UDfRTzVthye/k2dDsz5Xxs9LZaKCNPgJTRyoyBoeiNCnHsYGOyu1PKN+sDyPnJzMOz22JbwxzBp9NNA==", + "dependencies": { + "@smithy/config-resolver": "^4.1.0", + "@smithy/credential-provider-imds": "^4.0.2", + "@smithy/node-config-provider": "^4.0.2", + "@smithy/property-provider": "^4.0.2", + "@smithy/smithy-client": "^4.2.0", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">= 10.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/util-endpoints": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.1.4.tgz", - "integrity": "sha512-kPt8j4emm7rdMWQyL0F89o92q10gvCUa6sBkBtDJ7nV2+P7wpXczzOfoDJ49CKXe5CCqb8dc1W+ZdLlrKzSAnQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.0.2.tgz", + "integrity": "sha512-6QSutU5ZyrpNbnd51zRTL7goojlcnuOB55+F9VBD+j8JpRY50IGamsjlycrmpn8PQkmJucFW8A0LSfXj7jjtLQ==", "dependencies": { - "@smithy/node-config-provider": "^3.1.9", - "@smithy/types": "^3.6.0", + "@smithy/node-config-provider": "^4.0.2", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/util-hex-encoding": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz", - "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.0.0.tgz", + "integrity": "sha512-Yk5mLhHtfIgW2W2WQZWSg5kuMZCVbvhFmC7rV4IO2QqnZdbEFPmQnCcGMAX2z/8Qj3B9hYYNjZOhWym+RwhePw==", "dependencies": { "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/util-middleware": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.8.tgz", - "integrity": "sha512-p7iYAPaQjoeM+AKABpYWeDdtwQNxasr4aXQEA/OmbOaug9V0odRVDy3Wx4ci8soljE/JXQo+abV0qZpW8NX0yA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.0.2.tgz", + "integrity": "sha512-6GDamTGLuBQVAEuQ4yDQ+ti/YINf/MEmIegrEeg7DdB/sld8BX1lqt9RRuIcABOhAGTA50bRbPzErez7SlDtDQ==", "dependencies": { - "@smithy/types": "^3.6.0", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/util-retry": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.8.tgz", - "integrity": "sha512-TCEhLnY581YJ+g1x0hapPz13JFqzmh/pMWL2KEFASC51qCfw3+Y47MrTmea4bUE5vsdxQ4F6/KFbUeSz22Q1ow==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.0.2.tgz", + "integrity": "sha512-Qryc+QG+7BCpvjloFLQrmlSd0RsVRHejRXd78jNO3+oREueCjwG1CCEH1vduw/ZkM1U9TztwIKVIi3+8MJScGg==", "dependencies": { - "@smithy/service-error-classification": "^3.0.8", - "@smithy/types": "^3.6.0", + "@smithy/service-error-classification": "^4.0.2", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/util-stream": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.2.1.tgz", - "integrity": "sha512-R3ufuzJRxSJbE58K9AEnL/uSZyVdHzud9wLS8tIbXclxKzoe09CRohj2xV8wpx5tj7ZbiJaKYcutMm1eYgz/0A==", - "dependencies": { - "@smithy/fetch-http-handler": "^4.0.0", - "@smithy/node-http-handler": "^3.2.5", - "@smithy/types": "^3.6.0", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-buffer-from": "^3.0.0", - "@smithy/util-hex-encoding": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.2.0.tgz", + "integrity": "sha512-Vj1TtwWnuWqdgQI6YTUF5hQ/0jmFiOYsc51CSMgj7QfyO+RF4EnT2HNjoviNlOOmgzgvf3f5yno+EiC4vrnaWQ==", + "dependencies": { + "@smithy/fetch-http-handler": "^5.0.2", + "@smithy/node-http-handler": "^4.0.4", + "@smithy/types": "^4.2.0", + "@smithy/util-base64": "^4.0.0", + "@smithy/util-buffer-from": "^4.0.0", + "@smithy/util-hex-encoding": "^4.0.0", + "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-stream/node_modules/@smithy/fetch-http-handler": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-4.0.0.tgz", - "integrity": "sha512-MLb1f5tbBO2X6K4lMEKJvxeLooyg7guq48C2zKr4qM7F2Gpkz4dc+hdSgu77pCJ76jVqFBjZczHYAs6dp15N+g==", - "dependencies": { - "@smithy/protocol-http": "^4.1.5", - "@smithy/querystring-builder": "^3.0.8", - "@smithy/types": "^3.6.0", - "@smithy/util-base64": "^3.0.0", - "tslib": "^2.6.2" + "node": ">=18.0.0" } }, "node_modules/@smithy/util-uri-escape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", - "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.0.0.tgz", + "integrity": "sha512-77yfbCbQMtgtTylO9itEAdpPXSog3ZxMe09AEhm0dU0NLTalV70ghDZFR+Nfi1C60jnJoh/Re4090/DuZh2Omg==", "dependencies": { "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/util-utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz", - "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.0.0.tgz", + "integrity": "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow==", "dependencies": { - "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-buffer-from": "^4.0.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@smithy/util-waiter": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-3.1.7.tgz", - "integrity": "sha512-d5yGlQtmN/z5eoTtIYgkvOw27US2Ous4VycnXatyoImIF9tzlcpnKqQ/V7qhvJmb2p6xZne1NopCLakdTnkBBQ==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.0.3.tgz", + "integrity": "sha512-JtaY3FxmD+te+KSI2FJuEcfNC9T/DGGVf551babM7fAaXhjJUt7oSYurH1Devxd2+BOSUACCgt3buinx4UnmEA==", "dependencies": { - "@smithy/abort-controller": "^3.1.6", - "@smithy/types": "^3.6.0", + "@smithy/abort-controller": "^4.0.2", + "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@socket.io/component-emitter": { @@ -5566,9 +5405,9 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", - "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz", + "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==", "dev": true, "dependencies": { "@babel/types": "^7.20.7" @@ -5644,9 +5483,9 @@ } }, "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", "dev": true }, "node_modules/@types/express": { @@ -5719,9 +5558,9 @@ } }, "node_modules/@types/jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.0.tgz", - "integrity": "sha512-3Emr5VOl/aoBwnWcH/EFQvlSAmjV+XtV9GGu5mwdYew5vhQh0IUZx/60x0TzHDu09Bi7HMx10t/namdJw5QIcg==", + "version": "29.5.14", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", + "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==", "dev": true, "dependencies": { "expect": "^29.0.0", @@ -5756,9 +5595,9 @@ } }, "node_modules/@types/lodash": { - "version": "4.17.12", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.12.tgz", - "integrity": "sha512-sviUmCE8AYdaF/KIHLDJBQgeYzPBI0vf/17NaYehBJfYD1j6/L95Slh07NlyK2iNyBNaEkb3En2jRt+a8y3xZQ==" + "version": "4.17.16", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.16.tgz", + "integrity": "sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==" }, "node_modules/@types/long": { "version": "4.0.2", @@ -5782,9 +5621,9 @@ "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" }, "node_modules/@types/node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", "peer": true, "dependencies": { "@types/node": "*", @@ -5798,9 +5637,9 @@ "dev": true }, "node_modules/@types/qs": { - "version": "6.9.16", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", - "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==" + "version": "6.9.18", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.18.tgz", + "integrity": "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==" }, "node_modules/@types/range-parser": { "version": "1.2.7", @@ -5826,9 +5665,9 @@ } }, "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.0.tgz", + "integrity": "sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==", "dev": true }, "node_modules/@types/send": { @@ -6101,154 +5940,154 @@ } }, "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", "dev": true }, "node_modules/@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "dev": true, "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", "dev": true }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", "dev": true }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", "dev": true }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "dev": true, "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", "dev": true }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "dev": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "dev": true, "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", "dev": true }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" } }, @@ -6264,17 +6103,6 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -6296,9 +6124,9 @@ } }, "node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", "bin": { "acorn": "bin/acorn" }, @@ -6310,6 +6138,7 @@ "version": "1.9.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "deprecated": "package has been renamed to acorn-import-attributes", "dev": true, "peerDependencies": { "acorn": "^8" @@ -6345,9 +6174,9 @@ } }, "node_modules/agentkeepalive": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", - "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", + "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", "dependencies": { "humanize-ms": "^1.2.1" }, @@ -6388,6 +6217,18 @@ } } }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, "node_modules/amqp-connection-manager": { "version": "4.1.14", "resolved": "https://registry.npmjs.org/amqp-connection-manager/-/amqp-connection-manager-4.1.14.tgz", @@ -6404,13 +6245,12 @@ } }, "node_modules/amqplib": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.10.4.tgz", - "integrity": "sha512-DMZ4eCEjAVdX1II2TfIUpJhfKAuoCeDIo/YyETbfAqehHTXxxs7WOOd+N1Xxr4cKhx12y23zk8/os98FxlZHrw==", + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.10.5.tgz", + "integrity": "sha512-Dx5zmy0Ur+Q7LPPdhz+jx5IzmJBoHd15tOeAfQ8SuvEtyPJ20hBemhOBA4b1WeORCRa0ENM/kHCzmem1w/zHvQ==", "dependencies": { "@acuminous/bitsyntax": "^0.1.2", "buffer-more-ints": "~1.0.0", - "readable-stream": "1.x >=1.1.9", "url-parse": "~1.5.10" }, "engines": { @@ -6963,18 +6803,6 @@ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "dev": true }, - "node_modules/assert": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", - "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", - "dependencies": { - "call-bind": "^1.0.2", - "is-nan": "^1.3.2", - "object-is": "^1.1.5", - "object.assign": "^4.1.4", - "util": "^0.12.5" - } - }, "node_modules/async": { "version": "0.2.10", "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", @@ -7004,24 +6832,10 @@ "node": ">= 4.5.0" } }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/axios": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", - "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", + "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -7168,44 +6982,70 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/bare-events": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.0.tgz", - "integrity": "sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.4.tgz", + "integrity": "sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==", "optional": true }, "node_modules/bare-fs": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.5.tgz", - "integrity": "sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.0.2.tgz", + "integrity": "sha512-S5mmkMesiduMqnz51Bfh0Et9EX0aTCJxhsI4bvzFFLs8Z1AV8RDHadfY5CyLwdoLHgXbNBEN1gQcbEtGwuvixw==", "optional": true, "dependencies": { - "bare-events": "^2.0.0", - "bare-path": "^2.0.0", - "bare-stream": "^2.0.0" + "bare-events": "^2.5.4", + "bare-path": "^3.0.0", + "bare-stream": "^2.6.4" + }, + "engines": { + "bare": ">=1.16.0" + }, + "peerDependencies": { + "bare-buffer": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + } } }, "node_modules/bare-os": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.4.tgz", - "integrity": "sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==", - "optional": true + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.1.tgz", + "integrity": "sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==", + "optional": true, + "engines": { + "bare": ">=1.14.0" + } }, "node_modules/bare-path": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", - "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", + "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", "optional": true, "dependencies": { - "bare-os": "^2.1.0" + "bare-os": "^3.0.1" } }, "node_modules/bare-stream": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.3.2.tgz", - "integrity": "sha512-EFZHSIBkDgSHIwj2l2QZfP4U5OcD4xFAOwhSb/vlr9PIqyGJGvB/nfClJbcnh3EY4jtPE4zsb5ztae96bVF79A==", + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.6.5.tgz", + "integrity": "sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==", "optional": true, "dependencies": { - "streamx": "^2.20.0" + "streamx": "^2.21.0" + }, + "peerDependencies": { + "bare-buffer": "*", + "bare-events": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + }, + "bare-events": { + "optional": true + } } }, "node_modules/base64-js": { @@ -7266,21 +7106,14 @@ "integrity": "sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==" }, "node_modules/bip39": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.2.tgz", - "integrity": "sha512-J4E1r2N0tUylTKt07ibXvhpT2c5pyAFgvuA5q1H9uDy6dEGpjV8jmymh3MTYJDLCNbIVClSB9FbND49I6N24MQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.1.0.tgz", + "integrity": "sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==", + "optional": true, "dependencies": { - "@types/node": "11.11.6", - "create-hash": "^1.1.0", - "pbkdf2": "^3.0.9", - "randombytes": "^2.0.1" + "@noble/hashes": "^1.2.0" } }, - "node_modules/bip39/node_modules/@types/node": { - "version": "11.11.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz", - "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==" - }, "node_modules/bitsyntax": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/bitsyntax/-/bitsyntax-0.1.0.tgz", @@ -7427,9 +7260,9 @@ } }, "node_modules/browserslist": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", - "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", "dev": true, "funding": [ { @@ -7446,9 +7279,9 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001669", - "electron-to-chromium": "^1.5.41", - "node-releases": "^2.0.18", + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.1" }, "bin": { @@ -7544,16 +7377,25 @@ "node": ">= 0.8" } }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "dependencies": { - "es-define-property": "^1.0.0", "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" @@ -7581,9 +7423,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001673", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001673.tgz", - "integrity": "sha512-WTrjUCSMp3LYX0nE12ECkV0a+e6LC85E0Auz75555/qr78Oc8YWhEPNfDd6SHdtlCMSzqtuXY0uyEMNRcsKpKw==", + "version": "1.0.30001707", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001707.tgz", + "integrity": "sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==", "dev": true, "funding": [ { @@ -7687,18 +7529,40 @@ } }, "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.6.tgz", + "integrity": "sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==", "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.10" } }, + "node_modules/cipher-base/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/cjs-module-lexer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz", - "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==" + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==" }, "node_modules/cli-color": { "version": "2.0.4", @@ -8218,11 +8082,11 @@ } }, "node_modules/cross-fetch": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", - "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz", + "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==", "dependencies": { - "node-fetch": "^2.6.12" + "node-fetch": "^2.7.0" } }, "node_modules/cross-inspect": { @@ -8237,9 +8101,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "dependencies": { "path-key": "^3.1.0", @@ -8284,9 +8148,9 @@ } }, "node_modules/dataloader": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-2.2.2.tgz", - "integrity": "sha512-8YnDaaf7N3k/q5HnTJVuzSyLETjoZjVmHc4AeKAzOvKHEFQKcn64OKBfzHYtE9zGjctNM7V9I0MfnUVLpi7M5g==" + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-2.2.3.tgz", + "integrity": "sha512-y2krtASINtPFS1rSDjacrFgn1dcUuoREVabwlOGOe4SdxenREqwjwjElAdwvbGM7kgZz9a3KVicWR7vcz8rnzA==" }, "node_modules/date-fns": { "version": "2.30.0", @@ -8351,13 +8215,14 @@ } }, "node_modules/dd-trace/node_modules/form-data": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.2.tgz", - "integrity": "sha512-sJe+TQb2vIaIyO783qN6BlMYWMw3WBOHA1Ay2qxsnjuafEOQFJ2JakedOQirT6D5XPRxDvS7AHYyem9fTpb4LQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.3.tgz", + "integrity": "sha512-q5YBMeWy6E2Un0nMGWMgI65MAKtaylxfNJGJxpGh45YDciZB4epbWpaAfImil6CPAPTYB4sh0URQNDRIZG5F2w==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "es-set-tostringtag": "^2.1.0", + "mime-types": "^2.1.35" }, "engines": { "node": ">= 6" @@ -8383,9 +8248,20 @@ } }, "node_modules/dd-trace/node_modules/path-to-regexp": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.11.tgz", - "integrity": "sha512-c0t+KCuUkO/YDLPG4WWzEwx3J5F/GHXsD1h/SNZfySqAIKe/BaP95x8fWtOfRJokpS5yYHRJjMtYlXD8jxnpbw==" + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==" + }, + "node_modules/dd-trace/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } }, "node_modules/dd-trace/node_modules/retry": { "version": "0.10.1", @@ -8403,10 +8279,15 @@ "semver": "bin/semver" } }, + "node_modules/dd-trace/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dependencies": { "ms": "^2.1.3" }, @@ -8489,38 +8370,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/delay": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", @@ -8604,6 +8453,17 @@ "node": ">=0.8.0" } }, + "node_modules/dicer/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, "node_modules/dicer/node_modules/streamsearch": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", @@ -8612,6 +8472,11 @@ "node": ">=0.8.0" } }, + "node_modules/dicer/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -8709,6 +8574,19 @@ "node": ">=4" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -8727,6 +8605,22 @@ "tweetnacl": "1.0.3" } }, + "node_modules/ed25519-hd-key/node_modules/@types/node": { + "version": "11.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz", + "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==" + }, + "node_modules/ed25519-hd-key/node_modules/bip39": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.2.tgz", + "integrity": "sha512-J4E1r2N0tUylTKt07ibXvhpT2c5pyAFgvuA5q1H9uDy6dEGpjV8jmymh3MTYJDLCNbIVClSB9FbND49I6N24MQ==", + "dependencies": { + "@types/node": "11.11.6", + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1" + } + }, "node_modules/ed2curve": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/ed2curve/-/ed2curve-0.3.0.tgz", @@ -8740,10 +8634,25 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/electron-to-chromium": { - "version": "1.5.47", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.47.tgz", - "integrity": "sha512-zS5Yer0MOYw4rtK2iq43cJagHZ8sXN0jDHDKzB+86gSBSAI4v07S97mcq+Gs2vclAxSh1j7vOAHxSVgduiiuVQ==", + "version": "1.5.124", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.124.tgz", + "integrity": "sha512-riELkpDUqBi00gqreV3RIGoowxGrfueEKBd6zPdOk/I8lvuFpBGNkYoHof3zUHbiTBsIU8oxdIIL/WNrAG1/7A==", "dev": true }, "node_modules/emittery": { @@ -8821,6 +8730,22 @@ "node": ">= 0.6" } }, + "node_modules/engine.io/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/engine.io/node_modules/ws": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", @@ -8842,9 +8767,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", - "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "version": "5.18.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", + "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -8864,12 +8789,9 @@ } }, "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "engines": { "node": ">= 0.4" } @@ -8883,11 +8805,36 @@ } }, "node_modules/es-module-lexer": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", - "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", + "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", "dev": true }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es5-ext": { "version": "0.10.64", "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", @@ -9255,14 +9202,6 @@ "es5-ext": "~0.10.14" } }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "engines": { - "node": ">=6" - } - }, "node_modules/eventemitter2": { "version": "6.4.9", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", @@ -9277,6 +9216,7 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, "engines": { "node": ">=0.8.x" } @@ -9338,9 +9278,9 @@ } }, "node_modules/express": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", - "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", "peer": true, "dependencies": { "accepts": "~1.3.8", @@ -9362,7 +9302,7 @@ "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.10", + "path-to-regexp": "0.1.12", "proxy-addr": "~2.0.7", "qs": "6.13.0", "range-parser": "~1.2.1", @@ -9377,6 +9317,10 @@ }, "engines": { "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/express/node_modules/body-parser": { @@ -9419,9 +9363,9 @@ "peer": true }, "node_modules/express/node_modules/path-to-regexp": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", - "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", "peer": true }, "node_modules/express/node_modules/qs": { @@ -9562,9 +9506,9 @@ } }, "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "dependencies": { "reusify": "^1.0.4" } @@ -9627,6 +9571,36 @@ "moment": "^2.29.1" } }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -9710,9 +9684,9 @@ } }, "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", "dev": true }, "node_modules/fluent-ffmpeg": { @@ -9762,14 +9736,6 @@ } } }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dependencies": { - "is-callable": "^1.1.3" - } - }, "node_modules/fork-ts-checker-webpack-plugin": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-8.0.0.tgz", @@ -9799,12 +9765,13 @@ } }, "node_modules/form-data": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", - "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", + "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", "mime-types": "^2.1.12" }, "engines": { @@ -9920,15 +9887,20 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -9946,6 +9918,18 @@ "node": ">=8.0.0" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -10036,11 +10020,11 @@ } }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -10059,17 +10043,17 @@ "dev": true }, "node_modules/graphql": { - "version": "16.9.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.9.0.tgz", - "integrity": "sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==", + "version": "16.10.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.10.0.tgz", + "integrity": "sha512-AjqGKbDGUFRKIRCP9tCKiIGHyriz2oHEbPIbEtcSLSs4YjReZOIPQQWek4+6hjw62H9QShXHyaGivGiYVLeYFQ==", "engines": { "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } }, "node_modules/graphql-fields-list": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/graphql-fields-list/-/graphql-fields-list-2.2.4.tgz", - "integrity": "sha512-dhsMajI/7FMeZ8UWJDiw7iZlwacW5eBM02IVJ6IldFNgmVSDeuS+0+wF3ZOB0zcpYl3Q1spuegPLAFKcriPOCw==" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/graphql-fields-list/-/graphql-fields-list-2.3.0.tgz", + "integrity": "sha512-psnXCYTjZH46FAvIw0MelMwQg1IFI2uEl8rYAGXxTjFPLxd1UW0W5eaQb4kuNBh7Hh4FzQQ+I/TYtjLIPtXI1A==" }, "node_modules/graphql-request": { "version": "4.3.0", @@ -10085,13 +10069,14 @@ } }, "node_modules/graphql-request/node_modules/form-data": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.2.tgz", - "integrity": "sha512-sJe+TQb2vIaIyO783qN6BlMYWMw3WBOHA1Ay2qxsnjuafEOQFJ2JakedOQirT6D5XPRxDvS7AHYyem9fTpb4LQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.3.tgz", + "integrity": "sha512-q5YBMeWy6E2Un0nMGWMgI65MAKtaylxfNJGJxpGh45YDciZB4epbWpaAfImil6CPAPTYB4sh0URQNDRIZG5F2w==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "es-set-tostringtag": "^2.1.0", + "mime-types": "^2.1.35" }, "engines": { "node": ">= 6" @@ -10123,6 +10108,9 @@ "version": "5.16.0", "resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.16.0.tgz", "integrity": "sha512-Ju2RCU2dQMgSKtArPbEtsK5gNLnsQyTNIo/T7cZNp96niC1x0KdJNZV0TIoilceBPQwfb5itrGl8pkFeOUMl4A==", + "workspaces": [ + "website" + ], "engines": { "node": ">=10" }, @@ -10147,32 +10135,10 @@ "node": ">=8" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "engines": { "node": ">= 0.4" }, @@ -10207,19 +10173,6 @@ "node": ">=4" } }, - "node_modules/hash-base/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/hash-base/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -10239,14 +10192,6 @@ } ] }, - "node_modules/hash-base/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -10358,9 +10303,9 @@ } }, "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, "dependencies": { "parent-module": "^1.0.0", @@ -10374,11 +10319,11 @@ } }, "node_modules/import-in-the-middle": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.11.2.tgz", - "integrity": "sha512-gK6Rr6EykBcc6cVWRSBR5TWf8nn6hZMYSRYqCcHa0l0d1fPK7JSYo6+Mlmck76jIX9aL/IZ71c06U2VpFwl1zA==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.13.1.tgz", + "integrity": "sha512-k2V9wNm9B+ysuelDTHjI9d5KPc4l8zAZTGqj+pcynvWkypZd857ryzN8jNC7Pg2YZXNMJcHRPpaDyCBbNyVRpA==", "dependencies": { - "acorn": "^8.8.2", + "acorn": "^8.14.0", "acorn-import-attributes": "^1.9.5", "cjs-module-lexer": "^1.2.2", "module-details-from-path": "^1.0.3" @@ -10477,9 +10422,9 @@ } }, "node_modules/ioredis": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.4.1.tgz", - "integrity": "sha512-2YZsvl7jopIa1gaePkeMtd9rAcSjOOjPtpcLlOeusyO+XH2SK5ZcT+UCrElPP+WVIInh2TzeI4XW9ENaSLVVHA==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.6.0.tgz", + "integrity": "sha512-tBZlIIWbndeWBWCXWZiqtOF/yxf6yZX3tAlTJ7nfo5jhd6dctNxF7QnYlZLZ1a0o0pDoen7CgZqO+zjNaFbJAg==", "dependencies": { "@ioredis/commands": "^1.1.1", "cluster-key-slot": "^1.1.0", @@ -10512,21 +10457,6 @@ "resolved": "https://registry.npmjs.org/is_js/-/is_js-0.9.0.tgz", "integrity": "sha512-8Y5EHSH+TonfUHX2g3pMJljdbGavg55q4jmHzghJCdqYDbdNROC8uw/YFQwIRCRqRJT1EY3pJefz+kglw+o7sg==" }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -10545,21 +10475,10 @@ "node": ">=8" } }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, "dependencies": { "hasown": "^2.0.2" @@ -10596,20 +10515,6 @@ "node": ">=6" } }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -10622,27 +10527,12 @@ } }, "node_modules/is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - }, + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, "node_modules/is-number": { @@ -10683,20 +10573,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dependencies": { - "which-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -10807,6 +10683,30 @@ "node": ">=6" } }, + "node_modules/jake": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "dev": true, + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true + }, "node_modules/jest": { "version": "29.5.0", "resolved": "https://registry.npmjs.org/jest/-/jest-29.5.0.tgz", @@ -11399,9 +11299,9 @@ } }, "node_modules/jsesc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "dev": true, "bin": { "jsesc": "bin/jsesc" @@ -11559,55 +11459,15 @@ } }, "node_modules/keccak/node_modules/node-gyp-build": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", - "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", "node-gyp-build-test": "build-test.js" } }, - "node_modules/keccak/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/keccak/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/keccak/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -11730,6 +11590,7 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", "dev": true }, "node_modules/lodash.isinteger": { @@ -11772,7 +11633,8 @@ "node_modules/lodash.omit": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", - "integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==" + "integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==", + "deprecated": "This package is deprecated. Use destructuring assignment syntax instead." }, "node_modules/lodash.once": { "version": "4.1.1", @@ -11782,7 +11644,8 @@ "node_modules/lodash.pick": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", - "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==" + "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==", + "deprecated": "This package is deprecated. Use destructuring assignment syntax instead." }, "node_modules/lodash.sortby": { "version": "4.7.0", @@ -11811,9 +11674,9 @@ } }, "node_modules/logform": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.1.tgz", - "integrity": "sha512-CdaO738xRapbKIMVn2m4F6KTj4j7ooJ8POVnebSgKo3KBz5axNXRAL7ZdRjIV6NOr2Uf4vjtRkxrFETOioCqSA==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz", + "integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==", "dependencies": { "@colors/colors": "1.6.0", "@types/triple-beam": "^1.3.2", @@ -11868,9 +11731,9 @@ } }, "node_modules/luxon": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.5.0.tgz", - "integrity": "sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.6.0.tgz", + "integrity": "sha512-WE7p0p7W1xji9qxkLYsvcIxZyfP48GuFrWIBQZIsbjCyf65dG1rv4n83HcOyEyhvzxJCrUoObCRNFgRNIQ5KNA==", "engines": { "node": ">=12" } @@ -11929,6 +11792,14 @@ "tmpl": "1.0.5" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -12283,9 +12154,9 @@ } }, "node_modules/nan": { - "version": "2.22.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.0.tgz", - "integrity": "sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw==" + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.2.tgz", + "integrity": "sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==" }, "node_modules/nanoassert": { "version": "1.1.0", @@ -12297,27 +12168,10 @@ "resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz", "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==" }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, "node_modules/napi-build-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", + "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==" }, "node_modules/natural-compare": { "version": "1.4.0", @@ -12347,14 +12201,14 @@ "dev": true }, "node_modules/nest-winston": { - "version": "1.9.7", - "resolved": "https://registry.npmjs.org/nest-winston/-/nest-winston-1.9.7.tgz", - "integrity": "sha512-pTTgImRgv7urojsDvaTlenAjyJNLj7ywamfjzrhWKhLhp80AKLYNwf103dVHeqZWe+nzp/vd9DGRs/UN/YadOQ==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/nest-winston/-/nest-winston-1.10.2.tgz", + "integrity": "sha512-Z9IzL/nekBOF/TEwBHUJDiDPMaXUcFquUQOFavIRet6xF0EbuWnOzslyN/ksgzG+fITNgXhMdrL/POp9SdaFxA==", "dependencies": { "fast-safe-stringify": "^2.1.1" }, "peerDependencies": { - "@nestjs/common": "^5.0.0 || ^6.6.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0", + "@nestjs/common": "^5.0.0 || ^6.6.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0", "winston": "^3.0.0" } }, @@ -12364,9 +12218,9 @@ "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" }, "node_modules/node-abi": { - "version": "3.71.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.71.0.tgz", - "integrity": "sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw==", + "version": "3.74.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.74.0.tgz", + "integrity": "sha512-c5XK0MjkGBrQPGYG24GBADZud0NCbznxNx0ZkS+ebUTrmV1qTDxPxSL8zEAPURXSbLRWVexxmP4986BziahL5w==", "dependencies": { "semver": "^7.3.5" }, @@ -12437,9 +12291,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "dev": true }, "node_modules/normalize-path": { @@ -12479,49 +12333,9 @@ } }, "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-is": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", - "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "engines": { "node": ">= 0.4" }, @@ -12665,49 +12479,6 @@ "ieee754": "^1.1.13" } }, - "node_modules/ora/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/ora/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/ora/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/os-name": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/os-name/-/os-name-4.0.1.tgz", @@ -12919,24 +12690,19 @@ "node": ">=0.12" } }, - "node_modules/perf_hooks": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/perf_hooks/-/perf_hooks-0.0.1.tgz", - "integrity": "sha512-qG/D9iA4KDme+KF4vCObJy6Bouu3BlQnmJ8jPydVPm32NJBD9ZK1ZNgXSYaZKHkVC1sKSqUiLgFvAZPUiIEnBw==" - }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" }, "node_modules/pg": { - "version": "8.13.1", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.13.1.tgz", - "integrity": "sha512-OUir1A0rPNZlX//c7ksiu7crsGZTKSOXJPgtNiHGIlC9H0lO+NC6ZDYksSgBYY/thSWhnSRBv8w1lieNNGATNQ==", + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.14.1.tgz", + "integrity": "sha512-0TdbqfjwIun9Fm/r89oB7RFQ0bLgduAhiIqIXOsyKoiC/L54DbuAAzIEN/9Op0f1Po9X7iCPXGoa/Ah+2aI8Xw==", "dependencies": { "pg-connection-string": "^2.7.0", - "pg-pool": "^3.7.0", - "pg-protocol": "^1.7.0", + "pg-pool": "^3.8.0", + "pg-protocol": "^1.8.0", "pg-types": "^2.1.0", "pgpass": "1.x" }, @@ -12975,17 +12741,17 @@ } }, "node_modules/pg-pool": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.7.0.tgz", - "integrity": "sha512-ZOBQForurqh4zZWjrgSwwAtzJ7QiRX0ovFkZr2klsen3Nm0aoh33Ls0fzfv3imeH/nw/O27cjdz5kzYJfeGp/g==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.8.0.tgz", + "integrity": "sha512-VBw3jiVm6ZOdLBTIcXLNdSotb6Iy3uOCwDGFAksZCXmi10nyRvnP2v3jl4d+IsLYRyXf6o9hIm/ZtUzlByNUdw==", "peerDependencies": { "pg": ">=8.0" } }, "node_modules/pg-protocol": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.7.0.tgz", - "integrity": "sha512-hTK/mE36i8fDDhgDFjy6xNOG+LCorxLG3WO17tku+ij6sVHXh1jQUJ8hYAnRhNla4QVD2H8er/FOjc/+EgC6yQ==" + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.8.0.tgz", + "integrity": "sha512-jvuYlEkL03NRvOoyoRktBK7+qU5kOvlAwvmrH8sr3wbLrOdVWsRxQfz8mMy9sZFsqJ1hEWNfdWKI4SAmoL+j7g==" }, "node_modules/pg-types": { "version": "2.2.0", @@ -13120,14 +12886,6 @@ "node": ">=4" } }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "engines": { - "node": ">= 0.4" - } - }, "node_modules/postgres-array": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", @@ -13164,16 +12922,16 @@ } }, "node_modules/prebuild-install": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", - "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", + "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", + "napi-build-utils": "^2.0.0", "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", @@ -13221,50 +12979,10 @@ "ieee754": "^1.1.13" } }, - "node_modules/prebuild-install/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/prebuild-install/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/prebuild-install/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/prebuild-install/node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz", + "integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==", "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", @@ -13348,14 +13066,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -13420,9 +13130,9 @@ } }, "node_modules/protobufjs/node_modules/long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.1.tgz", + "integrity": "sha512-ka87Jz3gcx/I7Hal94xaN2tZEOPoUOEVftkQqZx2EeQRN7LGdfLlI3FvZ+7WDplm+vK2Urx9ULrvSowtdCieng==", "peer": true }, "node_modules/proxy-addr": { @@ -13514,11 +13224,6 @@ } ] }, - "node_modules/queue-tick": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", - "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" - }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -13578,14 +13283,16 @@ "dev": true }, "node_modules/readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" } }, "node_modules/readdirp": { @@ -13733,18 +13440,21 @@ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "dev": true, "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -13780,9 +13490,9 @@ } }, "node_modules/resolve.exports": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", - "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", + "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", "dev": true, "engines": { "node": ">=10" @@ -13810,9 +13520,9 @@ } }, "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -13884,9 +13594,9 @@ } }, "node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "dependencies": { "tslib": "^2.1.0" } @@ -13981,9 +13691,9 @@ "integrity": "sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w==" }, "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "bin": { "semver": "bin/semver.js" }, @@ -14058,30 +13768,14 @@ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "peer": true, - "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.19.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" }, "engines": { - "node": ">= 0.4" + "node": ">= 0.8.0" } }, "node_modules/setprototypeof": { @@ -14167,14 +13861,65 @@ } }, "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -14300,6 +14045,22 @@ "ws": "~8.17.1" } }, + "node_modules/socket.io-adapter/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/socket.io-adapter/node_modules/ws": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", @@ -14332,6 +14093,38 @@ "node": ">=10.0.0" } }, + "node_modules/socket.io-parser/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", @@ -14462,12 +14255,11 @@ } }, "node_modules/streamx": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz", - "integrity": "sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==", + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.0.tgz", + "integrity": "sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==", "dependencies": { "fast-fifo": "^1.3.2", - "queue-tick": "^1.0.1", "text-decoder": "^1.1.0" }, "optionalDependencies": { @@ -14475,9 +14267,31 @@ } }, "node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, "node_modules/string-length": { "version": "4.0.2", @@ -14559,9 +14373,15 @@ } }, "node_modules/strnum": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", + "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ] }, "node_modules/subscriptions-transport-ws": { "version": "0.11.0", @@ -14715,16 +14535,16 @@ } }, "node_modules/tar-fs": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", - "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.8.tgz", + "integrity": "sha512-ZoROL70jptorGAlgAYiLoBLItEKw/fUxg9BSYK/dF/GAGYFJOJJJMvjPAKDJraCXFwadD456FCuvLWgfhMsPwg==", "dependencies": { "pump": "^3.0.0", "tar-stream": "^3.1.5" }, "optionalDependencies": { - "bare-fs": "^2.1.1", - "bare-path": "^2.1.0" + "bare-fs": "^4.0.1", + "bare-path": "^3.0.0" } }, "node_modules/tar-stream": { @@ -14746,9 +14566,9 @@ } }, "node_modules/terser": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.36.0.tgz", - "integrity": "sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==", + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz", + "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -14764,16 +14584,16 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", + "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", "dev": true, "dependencies": { - "@jridgewell/trace-mapping": "^0.3.20", + "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" }, "engines": { "node": ">= 10.13.0" @@ -14811,6 +14631,25 @@ "node": ">= 10.13.0" } }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", + "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, "node_modules/terser-webpack-plugin/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -14847,9 +14686,12 @@ } }, "node_modules/text-decoder": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.1.tgz", - "integrity": "sha512-x9v3H/lTKIJKQQe7RPQkLfKAnc9lUTkWDypIQgTzPJAq+5/GCDHonmshfvlsNSj58yyshbIJJDLmU15qNERrXQ==" + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "dependencies": { + "b4a": "^1.6.4" + } }, "node_modules/text-hex": { "version": "1.0.0", @@ -14979,37 +14821,43 @@ } }, "node_modules/ts-jest": { - "version": "29.0.5", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.5.tgz", - "integrity": "sha512-PL3UciSgIpQ7f6XjVOmbi96vmDHUqAyqDr8YxzopDqX3kfgYtX1cuNeBjP+L9sFXi6nzsGGA6R3fP3DDDJyrxA==", + "version": "29.3.0", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.3.0.tgz", + "integrity": "sha512-4bfGBX7Gd1Aqz3SyeDS9O276wEU/BInZxskPrbhZLyv+c1wskDCqDFMJQJLWrIr/fKoAH4GE5dKUlrdyvo+39A==", "dev": true, "dependencies": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", + "bs-logger": "^0.2.6", + "ejs": "^3.1.10", + "fast-json-stable-stringify": "^2.1.0", "jest-util": "^29.0.0", "json5": "^2.2.3", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "^21.0.1" + "lodash.memoize": "^4.1.2", + "make-error": "^1.3.6", + "semver": "^7.7.1", + "type-fest": "^4.37.0", + "yargs-parser": "^21.1.1" }, "bin": { "ts-jest": "cli.js" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" }, "peerDependencies": { "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/transform": "^29.0.0", "@jest/types": "^29.0.0", "babel-jest": "^29.0.0", "jest": "^29.0.0", - "typescript": ">=4.3" + "typescript": ">=4.3 <6" }, "peerDependenciesMeta": { "@babel/core": { "optional": true }, + "@jest/transform": { + "optional": true + }, "@jest/types": { "optional": true }, @@ -15021,6 +14869,18 @@ } } }, + "node_modules/ts-jest/node_modules/type-fest": { + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.38.0.tgz", + "integrity": "sha512-2dBz5D5ycHIoliLYLi0Q2V7KRaDlH0uWIvmk7TYlAg5slqwiPv1ezJdZm1QEM0xgk29oYWMCbIG7E6gHpvChlg==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ts-loader": { "version": "9.4.2", "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.2.tgz", @@ -15121,9 +14981,9 @@ } }, "node_modules/tslib": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", - "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==" + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, "node_modules/tsutils": { "version": "3.21.0", @@ -15385,9 +15245,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", - "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", "dev": true, "funding": [ { @@ -15405,7 +15265,7 @@ ], "dependencies": { "escalade": "^3.2.0", - "picocolors": "^1.1.0" + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -15432,18 +15292,6 @@ "requires-port": "^1.0.0" } }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -15542,18 +15390,18 @@ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/webpack": { - "version": "5.95.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.95.0.tgz", - "integrity": "sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==", + "version": "5.98.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.98.0.tgz", + "integrity": "sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==", "dev": true, "dependencies": { - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.12.1", - "@webassemblyjs/wasm-edit": "^1.12.1", - "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-attributes": "^1.9.5", - "browserslist": "^4.21.10", + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", @@ -15565,9 +15413,9 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", + "schema-utils": "^4.3.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", + "terser-webpack-plugin": "^5.3.11", "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, @@ -15605,6 +15453,25 @@ "node": ">=10.13.0" } }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", + "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, "node_modules/whatwg-mimetype": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", @@ -15637,24 +15504,6 @@ "node": ">= 8" } }, - "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/windows-release": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-4.0.0.tgz", @@ -15718,21 +15567,21 @@ } }, "node_modules/winston": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.15.0.tgz", - "integrity": "sha512-RhruH2Cj0bV0WgNL+lOfoUBI4DVfdUNjVnJGVovWZmrcKtrFTTRzgXYK2O9cymSGjrERCtaAeHwMNnUWXlwZow==", + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz", + "integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==", "dependencies": { "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.2", "async": "^3.2.3", "is-stream": "^2.0.0", - "logform": "^2.6.0", + "logform": "^2.7.0", "one-time": "^1.0.0", "readable-stream": "^3.4.0", "safe-stable-stringify": "^2.3.1", "stack-trace": "0.0.x", "triple-beam": "^1.3.0", - "winston-transport": "^4.7.0" + "winston-transport": "^4.9.0" }, "engines": { "node": ">= 12.0.0" @@ -15764,60 +15613,18 @@ } }, "node_modules/winston-transport": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.8.0.tgz", - "integrity": "sha512-qxSTKswC6llEMZKgCQdaWgDuMJQnhuvF5f2Nk3SNXc4byfQ+voo2mX1Px9dkNOuR8p0KAjfPG29PuYUSIb+vSA==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.9.0.tgz", + "integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==", "dependencies": { - "logform": "^2.6.1", - "readable-stream": "^4.5.2", + "logform": "^2.7.0", + "readable-stream": "^3.6.2", "triple-beam": "^1.3.0" }, "engines": { "node": ">= 12.0.0" } }, - "node_modules/winston-transport/node_modules/readable-stream": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", - "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", - "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/winston-transport/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/winston-transport/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/winston/node_modules/@colors/colors": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", @@ -15831,46 +15638,6 @@ "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==" }, - "node_modules/winston/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/winston/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/winston/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", diff --git a/package.json b/package.json index a12b6ca7a..d1d3dbaa2 100644 --- a/package.json +++ b/package.json @@ -80,25 +80,24 @@ "copy-e2e-mocked-mainnet-config:windows": "copy .\\config\\config.e2e-mocked.mainnet.yaml .\\config\\config.yaml", "start-chain-simulator": "docker compose -f \"src/test/chain-simulator/docker/docker-compose.yml\" up -d --build", "stop-chain-simulator": "docker compose -f \"src/test/chain-simulator/docker/docker-compose.yml\" down", - "prepare:test-data": "ts-node src/test/chain-simulator/utils/prepare-test-data.ts" + "prepare:test-data": "ts-node src/test/chain-simulator/utils/prepare-test-data.ts", + "test:ppu": "ts-node src/test/chain-simulator/utils/test-ppu-calculation.ts" }, "dependencies": { "@aws-sdk/client-s3": "^3.54.0", - "@elrondnetwork/erdjs-dex": "^0.2.12-alpha", - "@elrondnetwork/native-auth": "^0.1.19", - "@elrondnetwork/transaction-processor": "^0.1.26", "@golevelup/nestjs-rabbitmq": "^4.0.0", "@multiversx/sdk-core": "^13.2.2", "@multiversx/sdk-data-api-client": "^0.7.0", - "@multiversx/sdk-nestjs-auth": "4.1.0-beta.0", - "@multiversx/sdk-nestjs-cache": "4.1.0-beta.0", - "@multiversx/sdk-nestjs-common": "4.1.0-beta.0", - "@multiversx/sdk-nestjs-elastic": "4.1.0-beta.0", - "@multiversx/sdk-nestjs-http": "4.1.0-beta.0", - "@multiversx/sdk-nestjs-monitoring": "4.1.0-beta.0", - "@multiversx/sdk-nestjs-rabbitmq": "4.1.0-beta.0", - "@multiversx/sdk-nestjs-redis": "4.1.0-beta.0", - "@multiversx/sdk-wallet": "^4.0.0", + "@multiversx/sdk-exchange": "^0.2.21", + "@multiversx/sdk-nestjs-auth": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-cache": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-common": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-elastic": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-http": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-monitoring": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-rabbitmq": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-redis": "5.0.2-beta.0", + "@multiversx/sdk-transaction-processor": "^0.1.35", "@nestjs/apollo": "12.0.11", "@nestjs/common": "10.2.0", "@nestjs/config": "3.0.1", diff --git a/src/common/api-config/api.config.service.ts b/src/common/api-config/api.config.service.ts index 1b74001a6..b0471a5f2 100644 --- a/src/common/api-config/api.config.service.ts +++ b/src/common/api-config/api.config.service.ts @@ -2,12 +2,13 @@ import { Constants } from '@multiversx/sdk-nestjs-common'; import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { DatabaseConnectionOptions } from '../persistence/entities/connection.options'; -import { LogTopic } from '@elrondnetwork/transaction-processor'; import { StatusCheckerThresholds } from './entities/status-checker-thresholds'; +import { LogTopic } from '@multiversx/sdk-transaction-processor/lib/types/log-topic'; @Injectable() export class ApiConfigService { - constructor(private readonly configService: ConfigService) { } + constructor(private readonly configService: ConfigService) { + } getConfig(configKey: string): T | undefined { return this.configService.get(configKey); @@ -389,6 +390,23 @@ export class ApiConfigService { return isApiActive; } + isElasticCircuitBreakerEnabled(): boolean { + const isEnabled = this.configService.get('features.elasticCircuitBreaker.enabled'); + return isEnabled !== undefined ? isEnabled : false; + } + + getElasticCircuitBreakerConfig(): { + durationThresholdMs: number, + failureCountThreshold: number, + resetTimeoutMs: number + } { + return { + durationThresholdMs: this.configService.get('features.elasticCircuitBreaker.durationThresholdMs') ?? 5000, + failureCountThreshold: this.configService.get('features.elasticCircuitBreaker.failureCountThreshold') ?? 5000, + resetTimeoutMs: this.configService.get('features.elasticCircuitBreaker.resetTimeoutMs') ?? 5000, + }; + } + getIsWebsocketApiActive(): boolean { return this.configService.get('api.websocket') ?? true; } @@ -875,6 +893,14 @@ export class ApiConfigService { return this.configService.get('chainSettings.hrp') ?? 'erd'; } + isChainAndromedaEnabled(): boolean { + return this.configService.get('features.chainAndromeda.enabled') ?? false; + } + + getChainAndromedaActivationEpoch(): number { + return this.configService.get('features.chainAndromeda.activationEpoch') ?? 99999; + } + isAssetsCdnFeatureEnabled(): boolean { return this.configService.get('features.assetsFetch.enabled') ?? false; } @@ -925,4 +951,12 @@ export class ApiConfigService { getCacheDuration(): number { return this.configService.get('caching.cacheDuration') ?? 3; } + + isMediaRedirectFeatureEnabled(): boolean { + return this.configService.get('features.mediaRedirect.enabled') ?? false; + } + + getMediaRedirectFileStorageUrls(): string[] { + return this.configService.get('features.mediaRedirect.storageUrls') ?? []; + } } diff --git a/src/common/indexer/elastic/circuit-breaker/circuit.breaker.proxy.module.ts b/src/common/indexer/elastic/circuit-breaker/circuit.breaker.proxy.module.ts new file mode 100644 index 000000000..86b124a65 --- /dev/null +++ b/src/common/indexer/elastic/circuit-breaker/circuit.breaker.proxy.module.ts @@ -0,0 +1,15 @@ +import { Global, Module } from "@nestjs/common"; +import { ApiConfigModule } from "src/common/api-config/api.config.module"; +import { DynamicModuleUtils } from "src/utils/dynamic.module.utils"; +import { EsCircuitBreakerProxy } from "./circuit.breaker.proxy.service"; + +@Global() +@Module({ + imports: [ + ApiConfigModule, + DynamicModuleUtils.getElasticModule(), + ], + providers: [EsCircuitBreakerProxy], + exports: [EsCircuitBreakerProxy], +}) +export class EsCircuitBreakerProxyModule { } diff --git a/src/common/indexer/elastic/circuit-breaker/circuit.breaker.proxy.service.ts b/src/common/indexer/elastic/circuit-breaker/circuit.breaker.proxy.service.ts new file mode 100644 index 000000000..7cff25aea --- /dev/null +++ b/src/common/indexer/elastic/circuit-breaker/circuit.breaker.proxy.service.ts @@ -0,0 +1,109 @@ +import { OriginLogger } from "@multiversx/sdk-nestjs-common"; +import { ElasticQuery, ElasticService } from "@multiversx/sdk-nestjs-elastic"; +import { Injectable, ServiceUnavailableException } from "@nestjs/common"; +import { ApiConfigService } from "../../../api-config/api.config.service"; + +@Injectable() +export class EsCircuitBreakerProxy { + private failureCount = 0; + private lastFailureTime = 0; + private isCircuitOpen = false; + private readonly logger = new OriginLogger(EsCircuitBreakerProxy.name); + private readonly enabled: boolean; + private readonly config: { durationThresholdMs: number, failureCountThreshold: number, resetTimeoutMs: number }; + + constructor( + readonly apiConfigService: ApiConfigService, + private readonly elasticService: ElasticService, + ) { + this.enabled = apiConfigService.isElasticCircuitBreakerEnabled(); + this.config = apiConfigService.getElasticCircuitBreakerConfig(); + this.logger.log(`ES Circuit Breaker. Enabled: ${this.enabled}. Duration threshold: ${this.config.durationThresholdMs}ms. + FailureCountThreshold: ${this.config.failureCountThreshold}ms. FailureCountThreshold: ${this.config.failureCountThreshold}`); + } + + private async withCircuitBreaker(operation: () => Promise): Promise { + if (!this.enabled) { + return operation(); + } + + if (this.isCircuitOpen) { + const now = Date.now(); + if (now - this.lastFailureTime >= this.config.resetTimeoutMs) { + this.logger.log('Circuit is half-open, attempting reset'); + this.isCircuitOpen = false; + this.failureCount = 0; + } else { + throw new ServiceUnavailableException(); + } + } + + try { + const timeoutPromise = new Promise((_, reject) => { + setTimeout(() => reject(new Error('Operation timed out')), this.config.durationThresholdMs); + }); + + const result = await Promise.race([operation(), timeoutPromise]); + this.failureCount = 0; + return result; + } catch (error) { + this.failureCount++; + this.lastFailureTime = Date.now(); + + if (this.failureCount >= this.config.failureCountThreshold) { + if (!this.isCircuitOpen) { + this.logger.log('Circuit breaker opened due to multiple failures'); + } + + this.isCircuitOpen = true; + } + + throw new ServiceUnavailableException(); + } + } + + // eslint-disable-next-line require-await + async getCount(index: string, query: ElasticQuery): Promise { + return this.withCircuitBreaker(() => this.elasticService.getCount(index, query)); + } + + // eslint-disable-next-line require-await + async getList(index: string, id: string, query: ElasticQuery): Promise { + return this.withCircuitBreaker(() => this.elasticService.getList(index, id, query)); + } + + // eslint-disable-next-line require-await + async getItem(index: string, id: string, value: string): Promise { + return this.withCircuitBreaker(() => this.elasticService.getItem(index, id, value)); + } + + // eslint-disable-next-line require-await + async getCustomValue(index: string, id: string, key: string): Promise { + return this.withCircuitBreaker(() => this.elasticService.getCustomValue(index, id, key)); + } + + // eslint-disable-next-line require-await + async setCustomValue(index: string, id: string, key: string, value: any): Promise { + return this.withCircuitBreaker(() => this.elasticService.setCustomValue(index, id, key, value)); + } + + // eslint-disable-next-line require-await + async setCustomValues(index: string, id: string, values: Record): Promise { + return this.withCircuitBreaker(() => this.elasticService.setCustomValues(index, id, values)); + } + + // eslint-disable-next-line require-await + async getScrollableList(index: string, id: string, query: ElasticQuery, action: (items: any[]) => Promise): Promise { + return this.withCircuitBreaker(() => this.elasticService.getScrollableList(index, id, query, action)); + } + + // eslint-disable-next-line require-await + async get(url: string): Promise { + return this.withCircuitBreaker(() => this.elasticService.get(url)); + } + + // eslint-disable-next-line require-await + async post(url: string, data: any): Promise { + return this.withCircuitBreaker(() => this.elasticService.post(url, data)); + } +} diff --git a/src/common/indexer/elastic/elastic.indexer.module.ts b/src/common/indexer/elastic/elastic.indexer.module.ts index 254fcae40..e95d46720 100644 --- a/src/common/indexer/elastic/elastic.indexer.module.ts +++ b/src/common/indexer/elastic/elastic.indexer.module.ts @@ -1,16 +1,16 @@ import { forwardRef, Global, Module } from "@nestjs/common"; import { ApiConfigModule } from "src/common/api-config/api.config.module"; import { BlsModule } from "src/endpoints/bls/bls.module"; -import { DynamicModuleUtils } from "src/utils/dynamic.module.utils"; import { ElasticIndexerHelper } from "./elastic.indexer.helper"; import { ElasticIndexerService } from "./elastic.indexer.service"; +import { EsCircuitBreakerProxyModule } from "./circuit-breaker/circuit.breaker.proxy.module"; @Global() @Module({ imports: [ ApiConfigModule, forwardRef(() => BlsModule), - DynamicModuleUtils.getElasticModule(), + EsCircuitBreakerProxyModule, ], providers: [ElasticIndexerService, ElasticIndexerHelper], exports: [ElasticIndexerService, ElasticIndexerHelper], diff --git a/src/common/indexer/elastic/elastic.indexer.service.ts b/src/common/indexer/elastic/elastic.indexer.service.ts index 661012cb1..ada83218e 100644 --- a/src/common/indexer/elastic/elastic.indexer.service.ts +++ b/src/common/indexer/elastic/elastic.indexer.service.ts @@ -1,6 +1,6 @@ import { HttpStatus, Injectable } from "@nestjs/common"; import { BinaryUtils } from "@multiversx/sdk-nestjs-common"; -import { ElasticService, ElasticQuery, QueryOperator, QueryType, QueryConditionOptions, ElasticSortOrder, ElasticSortProperty, TermsQuery, RangeGreaterThanOrEqual, MatchQuery } from "@multiversx/sdk-nestjs-elastic"; +import { ElasticQuery, QueryOperator, QueryType, QueryConditionOptions, ElasticSortOrder, ElasticSortProperty, TermsQuery, RangeGreaterThanOrEqual, MatchQuery } from "@multiversx/sdk-nestjs-elastic"; import { IndexerInterface } from "../indexer.interface"; import { ApiConfigService } from "src/common/api-config/api.config.service"; import { CollectionFilter } from "src/endpoints/collections/entities/collection.filter"; @@ -29,6 +29,7 @@ import { ApplicationFilter } from "src/endpoints/applications/entities/applicati import { NftType } from "../entities/nft.type"; import { EventsFilter } from "src/endpoints/events/entities/events.filter"; import { Events } from "../entities/events"; +import { EsCircuitBreakerProxy } from "./circuit-breaker/circuit.breaker.proxy.service"; @Injectable() export class ElasticIndexerService implements IndexerInterface { @@ -38,7 +39,7 @@ export class ElasticIndexerService implements IndexerInterface { constructor( private readonly apiConfigService: ApiConfigService, - private readonly elasticService: ElasticService, + private readonly elasticService: EsCircuitBreakerProxy, private readonly indexerHelper: ElasticIndexerHelper, ) { } @@ -890,7 +891,7 @@ export class ElasticIndexerService implements IndexerInterface { async getAllFungibleTokens(): Promise { const query = ElasticQuery.create() .withMustMatchCondition('type', TokenType.FungibleESDT) - .withFields(["name", "type", "currentOwner", "numDecimals", "properties", "timestamp", "ownersHistory"]) + .withFields(["name", "type", "currentOwner", "numDecimals", "properties", "timestamp", "ownersHistory", "paused"]) .withMustNotExistCondition('identifier') .withPagination({ from: 0, size: 1000 }); @@ -1011,4 +1012,30 @@ export class ElasticIndexerService implements IndexerInterface { return await this.elasticService.getCount('events', elasticQuery); } + + async getAccountNftReceivedTimestamps(address: string, identifiers: string[]): Promise> { + if (!identifiers || identifiers.length === 0) { + return {}; + } + + const identifierToTimestamp: Record = {}; + + const elasticQuery = ElasticQuery.create() + .withMustMatchCondition('address', address) + .withMustMultiShouldCondition(identifiers, identifier => QueryType.Match('identifier', identifier, QueryOperator.AND)) + .withSort([{ name: 'timestamp', order: ElasticSortOrder.ascending }]) + .withPagination({ from: 0, size: 10000 }); + + const history = await this.elasticService.getList('accountsesdthistory', 'address', elasticQuery); + + for (const entry of history) { + if (entry.identifier) { + if (!identifierToTimestamp[entry.identifier] || entry.timestamp < identifierToTimestamp[entry.identifier]) { + identifierToTimestamp[entry.identifier] = entry.timestamp; + } + } + } + + return identifierToTimestamp; + } } diff --git a/src/common/indexer/indexer.interface.ts b/src/common/indexer/indexer.interface.ts index d22317bff..355dfc0d6 100644 --- a/src/common/indexer/indexer.interface.ts +++ b/src/common/indexer/indexer.interface.ts @@ -197,4 +197,6 @@ export interface IndexerInterface { getEvent(txHash: string): Promise getEventsCount(filter: EventsFilter): Promise + + getAccountNftReceivedTimestamps(address: string, identifiers: string[]): Promise> } diff --git a/src/common/indexer/indexer.service.ts b/src/common/indexer/indexer.service.ts index 715670321..ac168ed75 100644 --- a/src/common/indexer/indexer.service.ts +++ b/src/common/indexer/indexer.service.ts @@ -474,4 +474,9 @@ export class IndexerService implements IndexerInterface { async getEventsCount(filter: EventsFilter): Promise { return await this.indexerInterface.getEventsCount(filter); } + + @LogPerformanceAsync(MetricsEvents.SetIndexerDuration) + async getAccountNftReceivedTimestamps(address: string, identifiers: string[]): Promise> { + return await this.indexerInterface.getAccountNftReceivedTimestamps(address, identifiers); + } } diff --git a/src/common/locked-asset/locked-asset.service.ts b/src/common/locked-asset/locked-asset.service.ts index baec56c52..f20a36169 100644 --- a/src/common/locked-asset/locked-asset.service.ts +++ b/src/common/locked-asset/locked-asset.service.ts @@ -1,5 +1,4 @@ import { Injectable } from '@nestjs/common'; -import { LockedAssetAttributes, UnlockMilestone, LockedTokenAttributes } from '@elrondnetwork/erdjs-dex'; import { ApiConfigService } from '../api-config/api.config.service'; import { VmQueryService } from '../../endpoints/vm.query/vm.query.service'; import { CacheInfo } from '../../utils/cache.info'; @@ -10,6 +9,7 @@ import { GatewayService } from '../gateway/gateway.service'; import { MexSettingsService } from 'src/endpoints/mex/mex.settings.service'; import { LockedTokensInterface } from './entities/locked.tokens.interface'; import { UnlockMileStoneModel } from './entities/unlock.milestone.model'; +import { LockedAssetAttributes, UnlockMilestone, LockedTokenAttributes } from '@multiversx/sdk-exchange'; @Injectable() export class LockedAssetService { diff --git a/src/common/rabbitmq/rabbitmq.nft.handler.service.ts b/src/common/rabbitmq/rabbitmq.nft.handler.service.ts index 8195bb09b..b2377e73b 100644 --- a/src/common/rabbitmq/rabbitmq.nft.handler.service.ts +++ b/src/common/rabbitmq/rabbitmq.nft.handler.service.ts @@ -28,7 +28,7 @@ export class RabbitMqNftHandlerService { return null; } - await this.cachingService.setLocal( + this.cachingService.setLocal( CacheInfo.CollectionType(collectionIdentifier).key, type, CacheInfo.CollectionType(collectionIdentifier).ttl diff --git a/src/common/websockets/web-socket-publisher-controller.ts b/src/common/websockets/web-socket-publisher-controller.ts index 17a9addc0..5eba56647 100644 --- a/src/common/websockets/web-socket-publisher-controller.ts +++ b/src/common/websockets/web-socket-publisher-controller.ts @@ -1,5 +1,5 @@ import { OriginLogger } from "@multiversx/sdk-nestjs-common"; -import { ShardTransaction } from "@elrondnetwork/transaction-processor"; +import { ShardTransaction } from "@multiversx/sdk-transaction-processor"; import { Controller } from "@nestjs/common"; import { EventPattern } from "@nestjs/microservices"; import { WebSocketPublisherService } from "src/common/websockets/web-socket-publisher-service"; diff --git a/src/common/websockets/web-socket-publisher-service.ts b/src/common/websockets/web-socket-publisher-service.ts index 7a3cf824b..4ded7caff 100644 --- a/src/common/websockets/web-socket-publisher-service.ts +++ b/src/common/websockets/web-socket-publisher-service.ts @@ -1,5 +1,5 @@ import { AddressUtils } from "@multiversx/sdk-nestjs-common"; -import { ShardTransaction } from "@elrondnetwork/transaction-processor"; +import { ShardTransaction } from "@multiversx/sdk-transaction-processor"; import { Injectable } from "@nestjs/common"; import { WebSocketGateway, WebSocketServer } from "@nestjs/websockets"; import { Server, Socket } from 'socket.io'; diff --git a/src/crons/cache.warmer/cache.warmer.service.ts b/src/crons/cache.warmer/cache.warmer.service.ts index 0649e7c81..5a5f7c44e 100644 --- a/src/crons/cache.warmer/cache.warmer.service.ts +++ b/src/crons/cache.warmer/cache.warmer.service.ts @@ -407,10 +407,10 @@ export class CacheWarmerService { private async invalidateKey(key: string, data: any, ttl: number) { await this.cachingService.set(key, data, ttl); - await this.refreshCacheKey(key, ttl); + this.refreshCacheKey(key, ttl); } - private async refreshCacheKey(key: string, ttl: number) { - await this.clientProxy.emit('refreshCacheKey', { key, ttl }); + private refreshCacheKey(key: string, ttl: number) { + this.clientProxy.emit('refreshCacheKey', { key, ttl }); } } diff --git a/src/crons/transaction.processor/batch.transaction.processor.service.ts b/src/crons/transaction.processor/batch.transaction.processor.service.ts index bce75620f..69da7a2bf 100644 --- a/src/crons/transaction.processor/batch.transaction.processor.service.ts +++ b/src/crons/transaction.processor/batch.transaction.processor.service.ts @@ -1,5 +1,5 @@ import { CacheService } from "@multiversx/sdk-nestjs-cache"; -import { ShardTransaction, TransactionProcessor } from "@elrondnetwork/transaction-processor"; +import { ShardTransaction, TransactionProcessor } from "@multiversx/sdk-transaction-processor"; import { Inject, Injectable, Logger } from "@nestjs/common"; import { ClientProxy } from "@nestjs/microservices"; import { Cron } from "@nestjs/schedule"; diff --git a/src/crons/transaction.processor/extractor/nft.create.transaction.extractor.ts b/src/crons/transaction.processor/extractor/nft.create.transaction.extractor.ts index 7c6956130..eed35d42d 100644 --- a/src/crons/transaction.processor/extractor/nft.create.transaction.extractor.ts +++ b/src/crons/transaction.processor/extractor/nft.create.transaction.extractor.ts @@ -1,5 +1,5 @@ import { AddressUtils, BinaryUtils, OriginLogger } from "@multiversx/sdk-nestjs-common"; -import { ShardTransaction } from "@elrondnetwork/transaction-processor"; +import { ShardTransaction } from "@multiversx/sdk-transaction-processor"; import { Logger } from "@nestjs/common"; import { TransactionDetailed } from "src/endpoints/transactions/entities/transaction.detailed"; import { TransactionExtractorInterface } from "./transaction.extractor.interface"; diff --git a/src/crons/transaction.processor/extractor/nft.update.attributes.transaction.extractor.ts b/src/crons/transaction.processor/extractor/nft.update.attributes.transaction.extractor.ts index 5db86c532..481ae0209 100644 --- a/src/crons/transaction.processor/extractor/nft.update.attributes.transaction.extractor.ts +++ b/src/crons/transaction.processor/extractor/nft.update.attributes.transaction.extractor.ts @@ -1,5 +1,5 @@ import { BinaryUtils } from "@multiversx/sdk-nestjs-common"; -import { ShardTransaction } from "@elrondnetwork/transaction-processor"; +import { ShardTransaction } from "@multiversx/sdk-transaction-processor"; import { Logger } from "@nestjs/common"; import { TransactionExtractorInterface } from "./transaction.extractor.interface"; diff --git a/src/crons/transaction.processor/extractor/sft.change.transaction.extractor.ts b/src/crons/transaction.processor/extractor/sft.change.transaction.extractor.ts index 61cef81f4..2a69111e1 100644 --- a/src/crons/transaction.processor/extractor/sft.change.transaction.extractor.ts +++ b/src/crons/transaction.processor/extractor/sft.change.transaction.extractor.ts @@ -1,5 +1,5 @@ import { BinaryUtils } from "@multiversx/sdk-nestjs-common"; -import { ShardTransaction } from "@elrondnetwork/transaction-processor"; +import { ShardTransaction } from "@multiversx/sdk-transaction-processor"; import { Logger } from "@nestjs/common"; import { TransactionExtractorInterface } from "./transaction.extractor.interface"; diff --git a/src/crons/transaction.processor/extractor/transaction.extractor.interface.ts b/src/crons/transaction.processor/extractor/transaction.extractor.interface.ts index e3ccc6cf4..4d468134f 100644 --- a/src/crons/transaction.processor/extractor/transaction.extractor.interface.ts +++ b/src/crons/transaction.processor/extractor/transaction.extractor.interface.ts @@ -1,4 +1,4 @@ -import { ShardTransaction } from "@elrondnetwork/transaction-processor"; +import { ShardTransaction } from "@multiversx/sdk-transaction-processor"; import { TransactionDetailed } from "src/endpoints/transactions/entities/transaction.detailed"; export interface TransactionExtractorInterface { diff --git a/src/crons/transaction.processor/extractor/transfer.ownership.extractor.ts b/src/crons/transaction.processor/extractor/transfer.ownership.extractor.ts index e5d368e0c..340c68e37 100644 --- a/src/crons/transaction.processor/extractor/transfer.ownership.extractor.ts +++ b/src/crons/transaction.processor/extractor/transfer.ownership.extractor.ts @@ -1,5 +1,5 @@ import { BinaryUtils } from "@multiversx/sdk-nestjs-common"; -import { ShardTransaction } from "@elrondnetwork/transaction-processor"; +import { ShardTransaction } from "@multiversx/sdk-transaction-processor"; import { Logger } from "@nestjs/common"; import { TransactionExtractorInterface } from "./transaction.extractor.interface"; diff --git a/src/crons/transaction.processor/transaction.completed.service.ts b/src/crons/transaction.processor/transaction.completed.service.ts index 2aadb00b4..635c23ced 100644 --- a/src/crons/transaction.processor/transaction.completed.service.ts +++ b/src/crons/transaction.processor/transaction.completed.service.ts @@ -1,5 +1,4 @@ import { CacheService } from "@multiversx/sdk-nestjs-cache"; -import { LogTopic, TransactionProcessor } from "@elrondnetwork/transaction-processor"; import { Inject, Injectable, Logger } from "@nestjs/common"; import { ClientProxy } from "@nestjs/microservices"; import { Cron } from "@nestjs/schedule"; @@ -8,6 +7,8 @@ import { CacheInfo } from "src/utils/cache.info"; import { LogMetricsEvent } from "src/common/entities/log.metrics.event"; import { EventEmitter2 } from "@nestjs/event-emitter"; import { MetricsEvents } from "src/utils/metrics-events.constants"; +import { TransactionProcessor } from "@multiversx/sdk-transaction-processor"; +import { LogTopic } from "@multiversx/sdk-transaction-processor/lib/types/log-topic"; @Injectable() export class TransactionCompletedService { diff --git a/src/crons/transaction.processor/transaction.processor.service.ts b/src/crons/transaction.processor/transaction.processor.service.ts index 4b05c5f4d..511f67982 100644 --- a/src/crons/transaction.processor/transaction.processor.service.ts +++ b/src/crons/transaction.processor/transaction.processor.service.ts @@ -3,7 +3,6 @@ import { ClientProxy } from "@nestjs/microservices"; import { Cron } from "@nestjs/schedule"; import { ApiConfigService } from "src/common/api-config/api.config.service"; import { NodeService } from "src/endpoints/nodes/node.service"; -import { ShardTransaction, TransactionProcessor } from "@elrondnetwork/transaction-processor"; import { CacheInfo } from "src/utils/cache.info"; import { EventEmitter2 } from '@nestjs/event-emitter'; import { SftChangeTransactionExtractor } from "./extractor/sft.change.transaction.extractor"; @@ -15,7 +14,7 @@ import { CacheService } from "@multiversx/sdk-nestjs-cache"; import { BinaryUtils, OriginLogger } from "@multiversx/sdk-nestjs-common"; import { PerformanceProfiler } from "@multiversx/sdk-nestjs-monitoring"; import { StakeFunction } from "src/endpoints/transactions/transaction-action/recognizers/staking/entities/stake.function"; - +import { ShardTransaction, TransactionProcessor } from "@multiversx/sdk-transaction-processor"; @Injectable() export class TransactionProcessorService { diff --git a/src/endpoints/accounts/account.controller.ts b/src/endpoints/accounts/account.controller.ts index acdc346b6..ca608697f 100644 --- a/src/endpoints/accounts/account.controller.ts +++ b/src/endpoints/accounts/account.controller.ts @@ -637,6 +637,7 @@ export class AccountController { @ApiQuery({ name: 'isScam', description: 'Filter by scam status', required: false, type: Boolean }) @ApiQuery({ name: 'scamType', description: 'Filter by type (scam/potentialScam)', required: false }) @ApiQuery({ name: 'timestamp', description: 'Retrieve entry from timestamp', required: false, type: Number }) + @ApiQuery({ name: 'withReceivedAt', description: 'Include receivedAt timestamp in the response (when the NFT was received by the address)', required: false, type: Boolean }) async getAccountNfts( @Param('address', ParseAddressPipe) address: string, @Query('from', new DefaultValuePipe(0), ParseIntPipe) from: number, @@ -659,7 +660,12 @@ export class AccountController { @Query('isScam', ParseBoolPipe) isScam?: boolean, @Query('scamType', new ParseEnumPipe(ScamType)) scamType?: ScamType, @Query('timestamp', ParseIntPipe) _timestamp?: number, + @Query('withReceivedAt', ParseBoolPipe) withReceivedAt?: boolean, ): Promise { + // Validăm opțiunile de interogare + const queryOptions = new NftQueryOptions({ withSupply, withReceivedAt }); + queryOptions.validate(size); + return await this.nftService.getNftsForAddress( address, new QueryPagination({ from, size }), @@ -680,8 +686,8 @@ export class AccountController { scamType, }), fields, - new NftQueryOptions({ withSupply }), - source + queryOptions, + source, ); } diff --git a/src/endpoints/blocks/block.service.ts b/src/endpoints/blocks/block.service.ts index 735dbdacf..16ae5edbe 100644 --- a/src/endpoints/blocks/block.service.ts +++ b/src/endpoints/blocks/block.service.ts @@ -9,6 +9,7 @@ import { CacheService } from "@multiversx/sdk-nestjs-cache"; import { IndexerService } from "src/common/indexer/indexer.service"; import { NodeService } from "../nodes/node.service"; import { IdentitiesService } from "../identities/identities.service"; +import { ApiConfigService } from "../../common/api-config/api.config.service"; @Injectable() export class BlockService { @@ -20,13 +21,14 @@ export class BlockService { private readonly nodeService: NodeService, @Inject(forwardRef(() => IdentitiesService)) private readonly identitiesService: IdentitiesService, + private readonly apiConfigService: ApiConfigService, ) { } async getBlocksCount(filter: BlockFilter): Promise { return await this.cachingService.getOrSet( CacheInfo.BlocksCount(filter).key, async () => await this.indexerService.getBlocksCount(filter), - CacheInfo.BlocksCount(filter).ttl + CacheInfo.BlocksCount(filter).ttl, ); } @@ -87,7 +89,7 @@ export class BlockService { if (!blses || blses.length === 0) { blses = await this.blsService.getPublicKeys(shardId, epoch); if (blses.length > 0) { - await this.cachingService.setLocal(CacheInfo.ShardAndEpochBlses(shardId, epoch).key, blses, CacheInfo.ShardAndEpochBlses(shardId, epoch).ttl); + this.cachingService.setLocal(CacheInfo.ShardAndEpochBlses(shardId, epoch).key, blses, CacheInfo.ShardAndEpochBlses(shardId, epoch).ttl); } } @@ -97,21 +99,27 @@ export class BlockService { validators = validators.map((index: number) => blses[index]); } - return { shardId, epoch, validators, ...rest, proposer }; + return {shardId, epoch, validators, ...rest, proposer}; } async getBlock(hash: string): Promise { const result = await this.indexerService.getBlock(hash) as any; + const isChainAndromedaEnabled = this.apiConfigService.isChainAndromedaEnabled() + && result.epoch >= this.apiConfigService.getChainAndromedaActivationEpoch(); + if (result.round > 0) { const publicKeys = await this.blsService.getPublicKeys(result.shardId, result.epoch); result.proposer = publicKeys[result.proposer]; - result.validators = result.validators.map((validator: number) => publicKeys[validator]); + if (!isChainAndromedaEnabled) { + result.validators = result.validators.map((validator: number) => publicKeys[validator]); + } else { + result.validators = publicKeys; + } } else { result.validators = []; } - const block = BlockDetailed.mergeWithElasticResponse(new BlockDetailed(), result); await this.applyProposerIdentity([block]); @@ -132,7 +140,7 @@ export class BlockService { CacheInfo.BlocksLatest(ttl).key, async () => await this.getLatestBlockRaw(), CacheInfo.BlocksLatest(ttl).ttl, - Math.round(CacheInfo.BlocksLatest(ttl).ttl / 10) + Math.round(CacheInfo.BlocksLatest(ttl).ttl / 10), ); } diff --git a/src/endpoints/blocks/entities/block.proof.ts b/src/endpoints/blocks/entities/block.proof.ts new file mode 100644 index 000000000..74a772239 --- /dev/null +++ b/src/endpoints/blocks/entities/block.proof.ts @@ -0,0 +1,37 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export class BlockProofDto { + constructor(init?: Partial) { + Object.assign(this, init); + } + + @ApiProperty({ + type: String, + description: "Bitmap representing public keys involved in the proof", + example: "7702", + }) + pubKeysBitmap?: string; + + @ApiProperty({ + type: String, + description: "Aggregated BLS signature for the proof", + example: "50224d66a42a019991d16f25dba375b581f279d4394d4c254876c1484f61bed90fb20456f8af107c54e4eed1763e2a92", + }) + aggregatedSignature?: string; + + @ApiProperty({ + type: String, + description: "Hash of the block header being proven", + example: "414d526161587ae9f53453aa0392971272c48dbb3cc54a33448972d388e0deeb", + }) + headerHash?: string; + + @ApiProperty({type: Number, description: "Epoch number of the block header", example: 130}) + headerEpoch?: number; + + @ApiProperty({type: Number, description: "Nonce value of the block header", example: 13137}) + headerNonce?: number; + + @ApiProperty({type: Number, description: "Round number of the block header", example: 13163}) + headerRound?: number; +} diff --git a/src/endpoints/blocks/entities/block.ts b/src/endpoints/blocks/entities/block.ts index 52ed4e1e7..ed5dc51e7 100644 --- a/src/endpoints/blocks/entities/block.ts +++ b/src/endpoints/blocks/entities/block.ts @@ -1,6 +1,7 @@ import { ApiUtils } from "@multiversx/sdk-nestjs-http"; import { ApiProperty } from "@nestjs/swagger"; import { Identity } from "src/endpoints/identities/entities/identity"; +import { BlockProofDto } from "./block.proof"; export class Block { constructor(init?: Partial) { @@ -64,6 +65,12 @@ export class Block { @ApiProperty({ type: String, nullable: true, required: false }) scheduledRootHash: string | undefined = undefined; + @ApiProperty({ type: BlockProofDto, nullable: true, required: false }) + previousHeaderProof: BlockProofDto | undefined = undefined; + + @ApiProperty({ type: BlockProofDto, nullable: true, required: false }) + proof: BlockProofDto | undefined = undefined; + static mergeWithElasticResponse(newBlock: T, blockRaw: any): T { blockRaw.shard = blockRaw.shardId; diff --git a/src/endpoints/caching/local.cache.controller.ts b/src/endpoints/caching/local.cache.controller.ts index c278c05f5..1d492c8d7 100644 --- a/src/endpoints/caching/local.cache.controller.ts +++ b/src/endpoints/caching/local.cache.controller.ts @@ -36,8 +36,8 @@ export class LocalCacheController { status: 200, description: 'Key has been updated', }) - async setCache(@Param('key') key: string, @Body() cacheValue: CacheValue) { - await this.cachingService.setLocal(key, cacheValue.value, cacheValue.ttl); + setCache(@Param('key') key: string, @Body() cacheValue: CacheValue) { + this.cachingService.setLocal(key, cacheValue.value, cacheValue.ttl); } @UseGuards(NativeAuthGuard, JwtAdminGuard) diff --git a/src/endpoints/collections/collection.service.ts b/src/endpoints/collections/collection.service.ts index 8e5e79133..cd318cfd0 100644 --- a/src/endpoints/collections/collection.service.ts +++ b/src/endpoints/collections/collection.service.ts @@ -248,8 +248,8 @@ export class CollectionService { } } - async getNftCollectionRoles(elasticCollection: any): Promise { - return await this.getNftCollectionRolesFromElasticResponse(elasticCollection); + getNftCollectionRoles(elasticCollection: any): CollectionRoles[] { + return this.getNftCollectionRolesFromElasticResponse(elasticCollection); } async getNftCollectionRolesFromGateway(elasticCollection: any): Promise { diff --git a/src/endpoints/dapp-config/dapp.config.controller.ts b/src/endpoints/dapp-config/dapp.config.controller.ts index d782ce123..4702138ce 100644 --- a/src/endpoints/dapp-config/dapp.config.controller.ts +++ b/src/endpoints/dapp-config/dapp.config.controller.ts @@ -14,8 +14,8 @@ export class DappConfigController { @ApiOperation({ summary: 'Dapp configuration', description: 'Returns configuration used in dapps' }) @ApiOkResponse({ type: DappConfig }) @ApiNotFoundResponse({ description: 'Network configuration not found' }) - getDappConfiguration(): DappConfig { - const configuration = this.dappConfigService.getDappConfiguration(); + async getDappConfiguration(): Promise { + const configuration = await this.dappConfigService.getDappConfiguration(); if (!configuration) { throw new NotFoundException(`Network configuration not found`); } diff --git a/src/endpoints/dapp-config/dapp.config.service.ts b/src/endpoints/dapp-config/dapp.config.service.ts index bbc324871..1e6a00712 100644 --- a/src/endpoints/dapp-config/dapp.config.service.ts +++ b/src/endpoints/dapp-config/dapp.config.service.ts @@ -2,6 +2,7 @@ import { FileUtils } from "@multiversx/sdk-nestjs-common"; import { Injectable } from "@nestjs/common"; import { ApiConfigService } from "src/common/api-config/api.config.service"; import { DappConfig } from "./entities/dapp-config"; +import { GatewayService } from "src/common/gateway/gateway.service"; @Injectable() export class DappConfigService { @@ -9,11 +10,26 @@ export class DappConfigService { constructor( private readonly apiConfigService: ApiConfigService, + private readonly gatewayService: GatewayService, ) { this.dappConfig = this.getDappConfigurationRaw(); } - getDappConfiguration(): DappConfig | undefined { + async getDappConfiguration(): Promise { + if (!this.dappConfig) { + return undefined; + } + + const networkConfig = await this.gatewayService.getNetworkConfig(); + const refreshRate = networkConfig.erd_round_duration; + + if (refreshRate) { + return { + ...this.dappConfig, + refreshRate, + }; + } + return this.dappConfig; } diff --git a/src/endpoints/dapp-config/entities/dapp-config.ts b/src/endpoints/dapp-config/entities/dapp-config.ts index 4044f06ef..3dbd0e34c 100644 --- a/src/endpoints/dapp-config/entities/dapp-config.ts +++ b/src/endpoints/dapp-config/entities/dapp-config.ts @@ -43,4 +43,7 @@ export class DappConfig { @ApiProperty({ type: String, example: '1' }) chainId: string = ''; + + @ApiProperty({ type: Number, example: 6000 }) + refreshRate: number = 0; } diff --git a/src/endpoints/endpoints.controllers.module.ts b/src/endpoints/endpoints.controllers.module.ts index 318e527f0..de157bc75 100644 --- a/src/endpoints/endpoints.controllers.module.ts +++ b/src/endpoints/endpoints.controllers.module.ts @@ -39,6 +39,7 @@ import { PoolController } from "./pool/pool.controller"; import { TpsController } from "./tps/tps.controller"; import { ApplicationController } from "./applications/application.controller"; import { EventsController } from "./events/events.controller"; +import { MediaController } from "./media/media.controller"; @Module({}) export class EndpointsControllersModule { @@ -50,6 +51,7 @@ export class EndpointsControllersModule { TokenController, TransactionController, UsernameController, VmQueryController, WaitingListController, HealthCheckController, DappConfigController, WebsocketController, TransferController, ProcessNftsPublicController, TransactionsBatchController, ApplicationController, EventsController, + MediaController, ]; const isMarketplaceFeatureEnabled = configuration().features?.marketplace?.enabled ?? false; diff --git a/src/endpoints/endpoints.services.module.ts b/src/endpoints/endpoints.services.module.ts index fc8531828..7c56d4b5a 100644 --- a/src/endpoints/endpoints.services.module.ts +++ b/src/endpoints/endpoints.services.module.ts @@ -36,6 +36,7 @@ import { PoolModule } from "./pool/pool.module"; import { TpsModule } from "./tps/tps.module"; import { ApplicationModule } from "./applications/application.module"; import { EventsModule } from "./events/events.module"; +import { MediaModule } from "./media/media.module"; @Module({ imports: [ @@ -77,13 +78,14 @@ import { EventsModule } from "./events/events.module"; TpsModule, ApplicationModule, EventsModule, + MediaModule, ], exports: [ AccountModule, CollectionModule, BlockModule, DelegationModule, DelegationLegacyModule, IdentitiesModule, KeysModule, MiniBlockModule, NetworkModule, NftModule, NftMediaModule, TagModule, NodeModule, ProviderModule, RoundModule, SmartContractResultModule, ShardModule, StakeModule, TokenModule, RoundModule, TransactionModule, UsernameModule, VmQueryModule, WaitingListModule, EsdtModule, BlsModule, DappConfigModule, TransferModule, PoolModule, TransactionActionModule, WebsocketModule, MexModule, - ProcessNftsModule, NftMarketplaceModule, TransactionsBatchModule, TpsModule, ApplicationModule, EventsModule, + ProcessNftsModule, NftMarketplaceModule, TransactionsBatchModule, TpsModule, ApplicationModule, EventsModule, MediaModule, ], }) export class EndpointsServicesModule { } diff --git a/src/endpoints/esdt/esdt.address.service.ts b/src/endpoints/esdt/esdt.address.service.ts index 514ce0641..80d8eac3a 100644 --- a/src/endpoints/esdt/esdt.address.service.ts +++ b/src/endpoints/esdt/esdt.address.service.ts @@ -24,6 +24,7 @@ import { IndexerService } from "src/common/indexer/indexer.service"; import { TrieOperationsTimeoutError } from "./exceptions/trie.operations.timeout.error"; import { CacheInfo } from "src/utils/cache.info"; import { AssetsService } from "src/common/assets/assets.service"; +import { NftQueryOptions } from "../nfts/entities/nft.query.options"; @Injectable() export class EsdtAddressService { @@ -46,16 +47,16 @@ export class EsdtAddressService { this.NFT_THUMBNAIL_PREFIX = this.apiConfigService.getExternalMediaUrl() + '/nfts/asset'; } - async getNftsForAddress(address: string, filter: NftFilter, pagination: QueryPagination, source?: EsdtDataSource): Promise { + async getNftsForAddress(address: string, filter: NftFilter, pagination: QueryPagination, source?: EsdtDataSource, options?: NftQueryOptions): Promise { if (filter.identifiers && filter.identifiers.length === 1) { - return await this.getNftsForAddressFromGatewayWithElasticFallback(address, filter, pagination); + return await this.getNftsForAddressFromGatewayWithElasticFallback(address, filter, pagination, options); } if (source === EsdtDataSource.elastic || AddressUtils.isSmartContractAddress(address)) { - return await this.getNftsForAddressFromElastic(address, filter, pagination); + return await this.getNftsForAddressFromElastic(address, filter, pagination, options); } - return await this.getNftsForAddressFromGatewayWithElasticFallback(address, filter, pagination); + return await this.getNftsForAddressFromGatewayWithElasticFallback(address, filter, pagination, options); } async getNftCountForAddressFromElastic(address: string, filter: NftFilter): Promise { @@ -66,7 +67,7 @@ export class EsdtAddressService { return await this.indexerService.getCollectionCountForAddress(address, filter); } - private async getNftsForAddressFromElastic(address: string, filter: NftFilter, pagination: QueryPagination): Promise { + private async getNftsForAddressFromElastic(address: string, filter: NftFilter, pagination: QueryPagination, options?: NftQueryOptions): Promise { const esdts = await this.indexerService.getNftsForAddress(address, filter, pagination) as any; const gatewayNfts: GatewayNft[] = []; @@ -93,7 +94,7 @@ export class EsdtAddressService { const nfts: GatewayNft[] = Object.values(gatewayNfts).map(x => x as any).filter(x => x.tokenIdentifier.split('-').length === 3); - const nftAccounts: NftAccount[] = await this.mapToNftAccount(nfts); + const nftAccounts: NftAccount[] = await this.mapToNftAccount(nfts, address, pagination, options); return nftAccounts; } @@ -190,25 +191,25 @@ export class EsdtAddressService { } } - private async getNftsForAddressFromGatewayWithElasticFallback(address: string, filter: NftFilter, pagination: QueryPagination): Promise { + private async getNftsForAddressFromGatewayWithElasticFallback(address: string, filter: NftFilter, pagination: QueryPagination, options?: NftQueryOptions): Promise { const isTrieTimeout = await this.cachingService.get(CacheInfo.AddressEsdtTrieTimeout(address).key); if (isTrieTimeout) { - return await this.getNftsForAddressFromElastic(address, filter, pagination); + return await this.getNftsForAddressFromElastic(address, filter, pagination, options); } try { - return await this.getNftsForAddressFromGateway(address, filter, pagination); + return await this.getNftsForAddressFromGateway(address, filter, pagination, options); } catch (error) { if (error instanceof TrieOperationsTimeoutError) { await this.cachingService.set(CacheInfo.AddressEsdtTrieTimeout(address).key, true, CacheInfo.AddressEsdtTrieTimeout(address).ttl); - return await this.getNftsForAddressFromElastic(address, filter, pagination); + return await this.getNftsForAddressFromElastic(address, filter, pagination, options); } throw error; } } - private async getNftsForAddressFromGateway(address: string, filter: NftFilter, pagination: QueryPagination): Promise { + private async getNftsForAddressFromGateway(address: string, filter: NftFilter, pagination: QueryPagination, options?: NftQueryOptions): Promise { let esdts: Record = {}; let collection: string | undefined; let nonceHex: string | undefined; @@ -258,12 +259,12 @@ export class EsdtAddressService { const collator = new Intl.Collator('en', { sensitivity: 'base' }); nfts.sort((a: GatewayNft, b: GatewayNft) => collator.compare(a.tokenIdentifier, b.tokenIdentifier)); - const nftAccounts: NftAccount[] = await this.mapToNftAccount(nfts); + const nftAccounts: NftAccount[] = await this.mapToNftAccount(nfts, address, pagination, options); return this.filterEsdtsForAddressFromGateway(filter, pagination, nftAccounts); } - private async mapToNftAccount(nfts: GatewayNft[]): Promise { + private async mapToNftAccount(nfts: GatewayNft[], address?: string, pagination?: QueryPagination, options?: NftQueryOptions): Promise { const nftAccounts: NftAccount[] = []; for (const dataSourceNft of nfts) { @@ -281,6 +282,7 @@ export class EsdtAddressService { nft.uris = dataSourceNft.uris ? dataSourceNft.uris.filter((x: any) => x) : []; nft.name = dataSourceNft.name; nft.timestamp = dataSourceNft.timestamp; + nft.hash = TokenHelpers.getNftProof(dataSourceNft.hash) ?? ''; if (nft.uris && nft.uris.length > 0) { try { @@ -329,9 +331,33 @@ export class EsdtAddressService { nftAccounts.push(nft); } + if (address && pagination) { + await this.batchFetchReceivedAtTimestamps(nftAccounts, address, options); + } + return nftAccounts; } + private async batchFetchReceivedAtTimestamps(nftAccounts: NftAccount[], address: string, options?: NftQueryOptions): Promise { + try { + if (!options || !options.withReceivedAt || nftAccounts.length === 0) { + return; + } + + const identifiers = nftAccounts.map(nft => nft.identifier); + + const identifierToTimestamp = await this.indexerService.getAccountNftReceivedTimestamps(address, identifiers); + + for (const nft of nftAccounts) { + if (identifierToTimestamp[nft.identifier]) { + nft.receivedAt = identifierToTimestamp[nft.identifier]; + } + } + } catch (error) { + this.logger.error('Error in batchFetchReceivedAtTimestamps', error); + } + } + private async getAllEsdtsForAddressFromGatewayRaw(address: string): Promise<{ [key: string]: any }> { // eslint-disable-next-line require-await const esdtResult = await this.gatewayService.get(`address/${address}/esdt`, GatewayComponentRequest.addressEsdt, async (error) => { @@ -385,7 +411,7 @@ export class EsdtAddressService { const ttl = await this.protocolService.getSecondsRemainingUntilNextRound(); - await this.cachingService.setLocal(`address:${address}:esdts`, esdts, ttl); + this.cachingService.setLocal(`address:${address}:esdts`, esdts, ttl); return esdts; } diff --git a/src/endpoints/esdt/esdt.service.ts b/src/endpoints/esdt/esdt.service.ts index 8f3b117e8..8489db69e 100644 --- a/src/endpoints/esdt/esdt.service.ts +++ b/src/endpoints/esdt/esdt.service.ts @@ -227,7 +227,7 @@ export class EsdtService { canAddSpecialRoles: elasticProperties.properties?.canAddSpecialRoles ?? false, canTransferNFTCreateRole: elasticProperties.properties?.canTransferNFTCreateRole ?? false, NFTCreateStopped: elasticProperties.properties?.NFTCreateStopped ?? false, - isPaused: elasticProperties.properties?.isPaused ?? false, + isPaused: elasticProperties.paused ?? false, timestamp: elasticProperties.timestamp, }); diff --git a/src/endpoints/identities/entities/identity.sort.criteria.ts b/src/endpoints/identities/entities/identity.sort.criteria.ts index 6b5231941..531f1ad3d 100644 --- a/src/endpoints/identities/entities/identity.sort.criteria.ts +++ b/src/endpoints/identities/entities/identity.sort.criteria.ts @@ -1,4 +1,5 @@ export enum IdentitySortCriteria { validators = 'validators', - stake = 'stake' + stake = 'stake', + locked = 'locked' } diff --git a/src/endpoints/identities/identities.controller.ts b/src/endpoints/identities/identities.controller.ts index cc9c7bcc6..9a3c15034 100644 --- a/src/endpoints/identities/identities.controller.ts +++ b/src/endpoints/identities/identities.controller.ts @@ -1,4 +1,4 @@ -import { ParseArrayPipe, ParseEnumPipe } from "@multiversx/sdk-nestjs-common"; +import { ParseArrayPipe, ParseEnumArrayPipe } from "@multiversx/sdk-nestjs-common"; import { Controller, DefaultValuePipe, Get, HttpException, HttpStatus, Param, ParseIntPipe, Query, Res } from "@nestjs/common"; import { ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiQuery, ApiTags } from "@nestjs/swagger"; import { Identity } from "./entities/identity"; @@ -18,12 +18,12 @@ export class IdentitiesController { @ApiQuery({ name: 'from', description: 'Number of items to skip for the result set', required: false }) @ApiQuery({ name: 'size', description: 'Number of items to retrieve', required: false }) @ApiQuery({ name: 'identities', description: 'Filter by comma-separated list of identities', required: false }) - @ApiQuery({ name: 'sort', description: 'Sort criteria (validators)', required: false, enum: IdentitySortCriteria }) + @ApiQuery({ name: 'sort', description: 'Sort criteria (comma-separated list: validators,stake,locked)', required: false }) async getIdentities( @Query('from', new DefaultValuePipe(0), ParseIntPipe) from: number, @Query('size', new DefaultValuePipe(10000), ParseIntPipe) size: number, @Query('identities', ParseArrayPipe) identities: string[] = [], - @Query('sort', new ParseEnumPipe(IdentitySortCriteria)) sort?: IdentitySortCriteria, + @Query('sort', new ParseEnumArrayPipe(IdentitySortCriteria)) sort?: IdentitySortCriteria[], ): Promise { return await this.identitiesService.getIdentities(new QueryPagination({ from, size }), identities, sort); } diff --git a/src/endpoints/identities/identities.service.ts b/src/endpoints/identities/identities.service.ts index 74bb032b1..37215be60 100644 --- a/src/endpoints/identities/identities.service.ts +++ b/src/endpoints/identities/identities.service.ts @@ -40,22 +40,47 @@ export class IdentitiesService { return identity ? identity.avatar : undefined; } - async getIdentities(queryPagination: QueryPagination, ids: string[], sort?: IdentitySortCriteria): Promise { + async getIdentities(queryPagination: QueryPagination, ids: string[], sort?: IdentitySortCriteria[]): Promise { const { from, size } = queryPagination; let identities = await this.getAllIdentities(); if (ids.length > 0) { identities = identities.filter(x => x.identity && ids.includes(x.identity)); } - switch (sort) { + if (sort && sort.length > 0) { + identities = identities.sort((a, b) => this.compareWithCriteria(a, b, sort, 0)); + } + + return identities.slice(from, from + size); + } + + private compareWithCriteria(a: Identity, b: Identity, criteria: IdentitySortCriteria[], currentIndex: number): number { + if (currentIndex >= criteria.length) { + return 0; + } + + const currentCriterion = criteria[currentIndex]; + let comparison: number; + + switch (currentCriterion) { case IdentitySortCriteria.validators: - identities = identities.sortedDescending(x => x.validators ?? 0); + comparison = (b.validators ?? 0) - (a.validators ?? 0); break; case IdentitySortCriteria.stake: - identities = identities.sortedDescending(x => Number(x.stake) ?? 0); + comparison = Number(b.stake ?? '0') - Number(a.stake ?? '0'); + break; + case IdentitySortCriteria.locked: + comparison = Number(b.locked ?? '0') - Number(a.locked ?? '0'); + break; + default: + comparison = 0; } - return identities.slice(from, from + size); + if (comparison === 0 && currentIndex < criteria.length - 1) { + return this.compareWithCriteria(a, b, criteria, currentIndex + 1); + } + + return comparison; } async getAllIdentities(): Promise { diff --git a/src/endpoints/media/media.controller.ts b/src/endpoints/media/media.controller.ts new file mode 100644 index 000000000..e4ece3ead --- /dev/null +++ b/src/endpoints/media/media.controller.ts @@ -0,0 +1,66 @@ +import { Controller, Get, InternalServerErrorException, NotFoundException, Param, Req, Res } from "@nestjs/common"; +import { ApiTags } from "@nestjs/swagger"; +import { Request, Response } from "express"; +import { MediaService } from "./media.service"; +import { ApiService } from "@multiversx/sdk-nestjs-http"; +import { OriginLogger } from "@multiversx/sdk-nestjs-common"; +import https from 'https'; + +@Controller() +@ApiTags('media') +export class MediaController { + private readonly logger = new OriginLogger(MediaController.name); + + constructor( + private readonly mediaService: MediaService, + private readonly apiService: ApiService, + ) { } + + @Get("/media/:uri(*)") + async redirectToMediaUri( + @Param('uri') uri: string, + @Req() req: Request, + @Res() res: Response + ) { + const redirectUrl = await this.mediaService.getRedirectUrl(uri); + if (!redirectUrl) { + throw new NotFoundException('Not found'); + } + + try { + const response = await this.apiService.get(redirectUrl, { + // @ts-ignore + responseType: 'stream', + timeout: 60_000, // 60 seconds timeout + httpsAgent: new https.Agent({ rejectUnauthorized: false }), + headers: { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36', + }, + }); + + res.setHeader('content-type', response.headers['content-type']); + res.setHeader('content-length', response.headers['content-length']); + res.setHeader('cache-control', 'max-age=60'); + res.setHeader('Access-Control-Allow-Origin', '*'); + + response.data.pipe(res); + + response.data.on('error', (error: any) => { + this.logger?.error(`Error streaming the resource: ${redirectUrl}`); + this.logger?.error(error); + + throw new InternalServerErrorException('Failed to fetch URL'); + }); + + req.on('close', () => { + response.data?.destroy(); + }); + + return; + } catch (error) { + this.logger.error(`Failed to fetch URL: ${redirectUrl}`); + + throw new InternalServerErrorException('Failed to fetch URL'); + } + } +} diff --git a/src/endpoints/media/media.module.ts b/src/endpoints/media/media.module.ts new file mode 100644 index 000000000..95360285a --- /dev/null +++ b/src/endpoints/media/media.module.ts @@ -0,0 +1,13 @@ +import { Module } from "@nestjs/common"; +import { MediaService } from "./media.service"; + +@Module({ + imports: [], + providers: [ + MediaService, + ], + exports: [ + MediaService, + ], +}) +export class MediaModule { } diff --git a/src/endpoints/media/media.service.ts b/src/endpoints/media/media.service.ts new file mode 100644 index 000000000..8f357c654 --- /dev/null +++ b/src/endpoints/media/media.service.ts @@ -0,0 +1,67 @@ +import { OriginLogger } from "@multiversx/sdk-nestjs-common"; +import { ApiService } from "@multiversx/sdk-nestjs-http"; +import { Injectable } from "@nestjs/common"; +import { ApiConfigService } from "src/common/api-config/api.config.service"; + +@Injectable() +export class MediaService { + private readonly logger = new OriginLogger(MediaService.name); + + private readonly fallbackThumbnail = 'nfts/thumbnail/default.png'; + + constructor( + private readonly apiConfigService: ApiConfigService, + private readonly apiService: ApiService, + ) { } + + public async getRedirectUrl(uri: string): Promise { + const isFeatureEnabled = this.apiConfigService.isMediaRedirectFeatureEnabled(); + if (!isFeatureEnabled) { + // TODO: throw error + // throw new BadRequestException('Media redirect is not allowed'); + } + + // providers logos + if (uri.startsWith('providers/asset/')) { + const awsUri = uri.replace('providers/asset/', 'keybase_processed_uploads/'); + return `https://s3.amazonaws.com/${awsUri}`; + } + + // esdts logos + if (uri.startsWith('tokens/asset/')) { + const network = this.apiConfigService.getNetwork(); + const tokenUri = network === 'mainnet' + ? uri.replace('tokens/asset/', 'multiversx/mx-assets/master/tokens/') + : uri.replace('tokens/asset/', `multiversx/mx-assets/master/${network}/tokens/`); + return `https://raw.githubusercontent.com/${tokenUri}`; + } + + const fileStorageUrls = this.apiConfigService.getMediaRedirectFileStorageUrls(); + for (const fileStorageUrl of fileStorageUrls) { + try { + const { status } = await this.apiService.head(`${fileStorageUrl}/${uri}`, { + validateStatus: () => true, + }); + if (200 <= status && status <= 300) { + return `${fileStorageUrl}/${uri}`; + } + } catch { + this.logger.error(`Could not fetch ${fileStorageUrl}/${uri}`); + continue; + } + } + + // nfts assets' ipfs mirror + if (uri.startsWith('nfts/asset/')) { + const ipfsUri = uri.replace('nfts/asset/', 'ipfs/'); + return `https://ipfs.io/${ipfsUri}`; + } + + // fallback for nft thumbnails + if (uri.startsWith('nfts/thumbnail/') && uri !== this.fallbackThumbnail && fileStorageUrls.length > 0) { + return `${fileStorageUrls[0]}/${this.fallbackThumbnail}`; + } + + return undefined; + } +} diff --git a/src/endpoints/mex/mex.controller.ts b/src/endpoints/mex/mex.controller.ts index 988ef755d..b520de22a 100644 --- a/src/endpoints/mex/mex.controller.ts +++ b/src/endpoints/mex/mex.controller.ts @@ -178,13 +178,15 @@ export class MexController { } @Get('mex/tokens/prices/daily/:identifier') - @ApiOperation({ summary: 'xExchange token prices daily', description: 'Returns token prices daily' }) + @ApiOperation({ + summary: 'xExchange token prices daily', + description: 'Returns token prices daily, ordered by timestamp in ascending order. The entries represent the latest complete daily values for the given token series.', + }) @ApiOkResponse({ type: [MexTokenChart] }) @ApiNotFoundResponse({ description: 'Price not available for given token identifier' }) async getTokenPricesDayResolution( - @Param('identifier', ParseTokenPipe) identifier: string, - @Query('after') after: string): Promise { - const charts = await this.mexTokenChartsService.getTokenPricesDayResolution(identifier, after); + @Param('identifier', ParseTokenPipe) identifier: string): Promise { + const charts = await this.mexTokenChartsService.getTokenPricesDayResolution(identifier); if (!charts) { throw new NotFoundException('Price not available for given token identifier'); } diff --git a/src/endpoints/mex/mex.farm.service.ts b/src/endpoints/mex/mex.farm.service.ts index 4cebd7b1f..d907766d2 100644 --- a/src/endpoints/mex/mex.farm.service.ts +++ b/src/endpoints/mex/mex.farm.service.ts @@ -24,7 +24,7 @@ export class MexFarmService { async refreshMexFarms(): Promise { const farms = await this.getAllMexFarmsRaw(); await this.cachingService.setRemote(CacheInfo.MexFarms.key, farms, CacheInfo.MexFarms.ttl); - await this.cachingService.setLocal(CacheInfo.MexFarms.key, farms, Constants.oneSecond() * 30); + this.cachingService.setLocal(CacheInfo.MexFarms.key, farms, Constants.oneSecond() * 30); } async getMexFarms(pagination: QueryPagination): Promise { diff --git a/src/endpoints/mex/mex.pair.service.ts b/src/endpoints/mex/mex.pair.service.ts index a3ad3824c..21a1960e7 100644 --- a/src/endpoints/mex/mex.pair.service.ts +++ b/src/endpoints/mex/mex.pair.service.ts @@ -28,7 +28,7 @@ export class MexPairService { async refreshMexPairs(): Promise { const pairs = await this.getAllMexPairsRaw(false); await this.cachingService.setRemote(CacheInfo.MexPairs.key, pairs, CacheInfo.MexPairs.ttl); - await this.cachingService.setLocal(CacheInfo.MexPairs.key, pairs, Constants.oneSecond() * 30); + this.cachingService.setLocal(CacheInfo.MexPairs.key, pairs, Constants.oneSecond() * 30); } async getMexPairs(from: number, size: number, filter?: MexPairsFilter): Promise { diff --git a/src/endpoints/mex/mex.settings.service.ts b/src/endpoints/mex/mex.settings.service.ts index 243c8a6f9..1a53b84aa 100644 --- a/src/endpoints/mex/mex.settings.service.ts +++ b/src/endpoints/mex/mex.settings.service.ts @@ -37,11 +37,11 @@ export class MexSettingsService { async refreshSettings(): Promise { const settings = await this.getSettingsRaw(); await this.cachingService.setRemote(CacheInfo.MexSettings.key, settings, CacheInfo.MexSettings.ttl); - await this.cachingService.setLocal(CacheInfo.MexSettings.key, settings, Constants.oneMinute() * 10); + this.cachingService.setLocal(CacheInfo.MexSettings.key, settings, Constants.oneMinute() * 10); const contracts = await this.getMexContractsRaw(); await this.cachingService.setRemote(CacheInfo.MexContracts.key, contracts, CacheInfo.MexContracts.ttl); - await this.cachingService.setLocal(CacheInfo.MexContracts.key, contracts, Constants.oneMinute() * 10); + this.cachingService.setLocal(CacheInfo.MexContracts.key, contracts, Constants.oneMinute() * 10); } async getSettings(): Promise { @@ -65,7 +65,7 @@ export class MexSettingsService { let contracts = await this.cachingService.getLocal>(CacheInfo.MexContracts.key); if (!contracts) { contracts = await this.getMexContractsRaw(); - await this.cachingService.setLocal(CacheInfo.MexContracts.key, contracts, Constants.oneMinute() * 10); + this.cachingService.setLocal(CacheInfo.MexContracts.key, contracts, Constants.oneMinute() * 10); } return contracts; diff --git a/src/endpoints/mex/mex.token.charts.service.ts b/src/endpoints/mex/mex.token.charts.service.ts index 0b3dde374..0c4090947 100644 --- a/src/endpoints/mex/mex.token.charts.service.ts +++ b/src/endpoints/mex/mex.token.charts.service.ts @@ -42,15 +42,15 @@ export class MexTokenChartsService { } } - async getTokenPricesDayResolution(tokenIdentifier: string, after: string): Promise { + async getTokenPricesDayResolution(tokenIdentifier: string): Promise { return await this.cachingService.getOrSet( - CacheInfo.TokenDailyChart(tokenIdentifier, after).key, - async () => await this.getTokenPricesDayResolutionRaw(tokenIdentifier, after), - CacheInfo.TokenDailyChart(tokenIdentifier, after).ttl, + CacheInfo.TokenDailyChart(tokenIdentifier).key, + async () => await this.getTokenPricesDayResolutionRaw(tokenIdentifier), + CacheInfo.TokenDailyChart(tokenIdentifier).ttl, ); } - async getTokenPricesDayResolutionRaw(tokenIdentifier: string, after: string): Promise { + async getTokenPricesDayResolutionRaw(tokenIdentifier: string): Promise { const isMexToken = await this.isMexToken(tokenIdentifier); if (!isMexToken) { return undefined; @@ -61,7 +61,6 @@ export class MexTokenChartsService { latestCompleteValues( series: "${tokenIdentifier}", metric: "priceUSD", - start: "${after}" ) { timestamp value diff --git a/src/endpoints/mex/mex.token.service.ts b/src/endpoints/mex/mex.token.service.ts index 7907bf258..7bb8f1dc2 100644 --- a/src/endpoints/mex/mex.token.service.ts +++ b/src/endpoints/mex/mex.token.service.ts @@ -31,19 +31,19 @@ export class MexTokenService { async refreshMexTokens(): Promise { const tokens = await this.getAllMexTokensRaw(); await this.cachingService.setRemote(CacheInfo.MexTokens.key, tokens, CacheInfo.MexTokens.ttl); - await this.cachingService.setLocal(CacheInfo.MexTokens.key, tokens, Constants.oneSecond() * 30); + this.cachingService.setLocal(CacheInfo.MexTokens.key, tokens, Constants.oneSecond() * 30); const tokenTypes = await this.getAllMexTokenTypesRaw(); await this.cachingService.setRemote(CacheInfo.MexTokenTypes.key, tokenTypes, CacheInfo.MexTokenTypes.ttl); - await this.cachingService.setLocal(CacheInfo.MexTokenTypes.key, tokenTypes, Constants.oneSecond() * 30); + this.cachingService.setLocal(CacheInfo.MexTokenTypes.key, tokenTypes, Constants.oneSecond() * 30); const indexedTokens = await this.getIndexedMexTokensRaw(); await this.cachingService.setRemote(CacheInfo.MexTokensIndexed.key, indexedTokens, CacheInfo.MexTokensIndexed.ttl); - await this.cachingService.setLocal(CacheInfo.MexTokensIndexed.key, indexedTokens, Constants.oneSecond() * 30); + this.cachingService.setLocal(CacheInfo.MexTokensIndexed.key, indexedTokens, Constants.oneSecond() * 30); const indexedPrices = await this.getMexPricesRaw(); await this.cachingService.setRemote(CacheInfo.MexPrices.key, indexedPrices, CacheInfo.MexPrices.ttl); - await this.cachingService.setLocal(CacheInfo.MexPrices.key, indexedPrices, Constants.oneSecond() * 30); + this.cachingService.setLocal(CacheInfo.MexPrices.key, indexedPrices, Constants.oneSecond() * 30); } async getMexTokens(queryPagination: QueryPagination): Promise { diff --git a/src/endpoints/mex/mex.warmer.service.ts b/src/endpoints/mex/mex.warmer.service.ts index 96f4fd6be..b32a00d95 100644 --- a/src/endpoints/mex/mex.warmer.service.ts +++ b/src/endpoints/mex/mex.warmer.service.ts @@ -56,10 +56,10 @@ export class MexWarmerService { private async invalidateKey(key: string, data: any, ttl: number) { await this.cachingService.set(key, data, ttl); - await this.refreshCacheKey(key, ttl); + this.refreshCacheKey(key, ttl); } - private async refreshCacheKey(key: string, ttl: number) { - await this.clientProxy.emit('refreshCacheKey', { key, ttl }); + private refreshCacheKey(key: string, ttl: number) { + this.clientProxy.emit('refreshCacheKey', { key, ttl }); } } diff --git a/src/endpoints/network/entities/constants.ts b/src/endpoints/network/entities/constants.ts index 5c309419c..92d0fc38b 100644 --- a/src/endpoints/network/entities/constants.ts +++ b/src/endpoints/network/entities/constants.ts @@ -19,4 +19,7 @@ export class NetworkConstants { @ApiProperty({ description: 'Minimum transaction version' }) minTransactionVersion: number = 0; + + @ApiProperty({ description: 'Gas price modifier' }) + gasPriceModifier: string = ''; } diff --git a/src/endpoints/network/network.service.ts b/src/endpoints/network/network.service.ts index f8a5a2670..8c8358782 100644 --- a/src/endpoints/network/network.service.ts +++ b/src/endpoints/network/network.service.ts @@ -66,6 +66,7 @@ export class NetworkService { const minGasLimit = networkConfig.erd_min_gas_limit; const minGasPrice = networkConfig.erd_min_gas_price; const minTransactionVersion = networkConfig.erd_min_transaction_version; + const gasPriceModifier = networkConfig.erd_gas_price_modifier; return { chainId, @@ -73,6 +74,7 @@ export class NetworkService { minGasLimit, minGasPrice, minTransactionVersion, + gasPriceModifier, }; } diff --git a/src/endpoints/nfts/entities/nft.account.ts b/src/endpoints/nfts/entities/nft.account.ts index 66cdb2221..399025815 100644 --- a/src/endpoints/nfts/entities/nft.account.ts +++ b/src/endpoints/nfts/entities/nft.account.ts @@ -15,4 +15,7 @@ export class NftAccount extends Nft { @ApiProperty({ type: Number, nullable: true, required: false }) valueUsd: number | undefined = undefined; + + @ApiProperty({ type: Number, nullable: true, required: false, description: 'Timestamp when the NFT was received by the address' }) + receivedAt: number | undefined = undefined; } diff --git a/src/endpoints/nfts/entities/nft.query.options.ts b/src/endpoints/nfts/entities/nft.query.options.ts index e9a46ee45..66b01f7aa 100644 --- a/src/endpoints/nfts/entities/nft.query.options.ts +++ b/src/endpoints/nfts/entities/nft.query.options.ts @@ -1,3 +1,4 @@ +import { BadRequestException } from "@nestjs/common"; export class NftQueryOptions { constructor(init?: Partial) { @@ -6,4 +7,11 @@ export class NftQueryOptions { withOwner?: boolean; withSupply?: boolean; + withReceivedAt?: boolean; + + validate(size: number): void { + if (this.withReceivedAt && size > 25) { + throw new BadRequestException('withReceivedAt can only be used with a size of 25'); + } + } } diff --git a/src/endpoints/nfts/entities/nft.ts b/src/endpoints/nfts/entities/nft.ts index d8af5956c..8470e4ebd 100644 --- a/src/endpoints/nfts/entities/nft.ts +++ b/src/endpoints/nfts/entities/nft.ts @@ -20,6 +20,9 @@ export class Nft { @ApiProperty({ type: String }) collection: string = ''; + @ApiProperty({ type: String }) + hash: string = ''; + @ApiProperty({ type: Number, nullable: true }) timestamp?: number = undefined; diff --git a/src/endpoints/nfts/nft.service.ts b/src/endpoints/nfts/nft.service.ts index 5e669f992..ed357acbc 100644 --- a/src/endpoints/nfts/nft.service.ts +++ b/src/endpoints/nfts/nft.service.ts @@ -18,13 +18,12 @@ import { EsdtDataSource } from "../esdt/entities/esdt.data.source"; import { EsdtAddressService } from "../esdt/esdt.address.service"; import { PersistenceService } from "src/common/persistence/persistence.service"; import { MexTokenService } from "../mex/mex.token.service"; -import { BinaryUtils, NumberUtils, RecordUtils, BatchUtils, TokenUtils } from "@multiversx/sdk-nestjs-common"; +import { BinaryUtils, NumberUtils, RecordUtils, BatchUtils, TokenUtils, OriginLogger } from "@multiversx/sdk-nestjs-common"; import { ApiUtils } from "@multiversx/sdk-nestjs-http"; import { CacheService } from "@multiversx/sdk-nestjs-cache"; import { IndexerService } from "src/common/indexer/indexer.service"; import { LockedAssetService } from "../../common/locked-asset/locked-asset.service"; import { CollectionAccount } from "../collections/entities/collection.account"; -import { OriginLogger } from "@multiversx/sdk-nestjs-common"; import { NftRankAlgorithm } from "src/common/assets/entities/nft.rank.algorithm"; import { NftRarity } from "./entities/nft.rarity"; import { NftRarities } from "./entities/nft.rarities"; @@ -56,9 +55,9 @@ export class NftService { this.NFT_THUMBNAIL_PREFIX = this.apiConfigService.getExternalMediaUrl() + '/nfts/asset'; this.DEFAULT_MEDIA = [ { - url: NftMediaService.NFT_THUMBNAIL_DEFAULT, - originalUrl: NftMediaService.NFT_THUMBNAIL_DEFAULT, - thumbnailUrl: NftMediaService.NFT_THUMBNAIL_DEFAULT, + url: this.nftMediaService.NFT_THUMBNAIL_DEFAULT, + originalUrl: this.nftMediaService.NFT_THUMBNAIL_DEFAULT, + thumbnailUrl: this.nftMediaService.NFT_THUMBNAIL_DEFAULT, fileType: 'image/png', fileSize: 29512, }, @@ -154,6 +153,8 @@ export class NftService { if (TokenHelpers.needsDefaultMedia(nft)) { nft.media = this.DEFAULT_MEDIA; } + + this.applyRedirectMedia(nft); } } @@ -273,6 +274,8 @@ export class NftService { private async applyMedia(nft: Nft) { nft.media = await this.nftMediaService.getMedia(nft.identifier) ?? undefined; + + this.applyRedirectMedia(nft); } private async applyMetadata(nft: Nft) { @@ -345,6 +348,7 @@ export class NftService { const elasticNftData = elasticNft.data; if (elasticNftData) { nft.name = elasticNftData.name; + nft.hash = TokenHelpers.getNftProof(elasticNftData.hash) ?? ''; nft.creator = elasticNftData.creator; nft.royalties = elasticNftData.royalties ? elasticNftData.royalties / 100 : undefined; // 10.000 => 100% nft.attributes = elasticNftData.attributes; @@ -443,8 +447,7 @@ export class NftService { } async getNftsForAddress(address: string, queryPagination: QueryPagination, filter: NftFilter, fields?: string[], queryOptions?: NftQueryOptions, source?: EsdtDataSource): Promise { - let nfts = await this.esdtAddressService.getNftsForAddress(address, filter, queryPagination, source); - + let nfts = await this.esdtAddressService.getNftsForAddress(address, filter, queryPagination, source, queryOptions); for (const nft of nfts) { await this.applyAssetsAndTicker(nft, fields); await this.applyPriceUsd(nft, fields); @@ -591,6 +594,16 @@ export class NftService { return await this.indexerService.getAccountsEsdtByCollection([identifier], pagination); } + // TODO: use this function to determine if a MetaESDT is a proof if we decide to add API filters to extract all the proofs + getNftProofHash(nft: Nft): string | undefined { + const hashField = BinaryUtils.base64Decode(nft.hash); + if (nft.type !== NftType.MetaESDT || !hashField.startsWith('proof:')) { + return undefined; + } + + return hashField.split('proof:')[1]; + } + private getNftRarity(elasticNft: any, algorithm: NftRankAlgorithm): NftRarity | undefined { const score = elasticNft[this.getNftScoreElasticKey(algorithm)]; const rank = elasticNft[this.getNftRankElasticKey(algorithm)]; @@ -633,4 +646,33 @@ export class NftService { private getNftScoreElasticKey(algorithm: NftRankAlgorithm) { return `nft_score_${algorithm}`; } + + private applyRedirectMedia(nft: Nft) { + // FIXME: This is a temporary fix to avoid breaking the API + const isMediaRedirectFeatureEnabled = this.apiConfigService.isMediaRedirectFeatureEnabled(); + if (!isMediaRedirectFeatureEnabled) { + // return; + } + + if (!nft.media || nft.media.length === 0) { + return; + } + + try { + const network = this.apiConfigService.getNetwork(); + // const defaultMediaUrl = `https://${network === 'mainnet' ? '' : `${network}-`}media.elrond.com`; + const defaultMediaUrl = `https://${network === 'mainnet' ? '' : `${network}-`}api.multiversx.com/media`; + + for (const media of nft.media) { + if (media.url) { + media.url = media.url.replace(defaultMediaUrl, this.apiConfigService.getMediaUrl()); + } + if (media.thumbnailUrl) { + media.thumbnailUrl = media.thumbnailUrl.replace(defaultMediaUrl, this.apiConfigService.getMediaUrl()); + } + } + } catch { + // TODO: there are some cases where the nft.media is an empty object, we should investigate why + } + } } diff --git a/src/endpoints/nodes/node.service.ts b/src/endpoints/nodes/node.service.ts index 55acc303a..2738011f4 100644 --- a/src/endpoints/nodes/node.service.ts +++ b/src/endpoints/nodes/node.service.ts @@ -391,7 +391,7 @@ export class NodeService { const currentEpoch = await this.blockService.getCurrentEpoch(); if (this.apiConfigService.isStakingV4Enabled() && currentEpoch >= this.apiConfigService.getStakingV4ActivationEpoch()) { const auctions = await this.gatewayService.getValidatorAuctions(); - await this.processAuctions(nodes, auctions); + this.processAuctions(nodes, auctions); } await this.applyNodeUnbondingPeriods(nodes); @@ -412,8 +412,8 @@ export class NodeService { } } - async processAuctions(nodes: Node[], auctions: Auction[]) { - const minimumAuctionStake = await this.stakeService.getMinimumAuctionStake(auctions); + processAuctions(nodes: Node[], auctions: Auction[]) { + const minimumAuctionStake = this.stakeService.getMinimumAuctionStake(auctions); const dangerZoneThreshold = BigInt(minimumAuctionStake) * BigInt(105) / BigInt(100); for (const node of nodes) { let position = 1; diff --git a/src/endpoints/pool/pool.service.ts b/src/endpoints/pool/pool.service.ts index 4bfd15eb1..f45ef5957 100644 --- a/src/endpoints/pool/pool.service.ts +++ b/src/endpoints/pool/pool.service.ts @@ -26,35 +26,38 @@ export class PoolService { ) { } async getTransactionFromPool(txHash: string): Promise { - const pool = await this.getEntirePool(); + const pool = await this.getPoolWithFilters(); return pool.find(tx => tx.txHash === txHash); } async getPoolCount(filter: PoolFilter): Promise { - const pool = await this.getEntirePool(); - return this.applyFilters(pool, filter).length; + const pool = await this.getPoolWithFilters(filter); + return pool.length; } async getPool( queryPagination: QueryPagination, - filter: PoolFilter, + filter?: PoolFilter, ): Promise { if (!this.apiConfigService.isTransactionPoolEnabled()) { return []; } const { from, size } = queryPagination; - const entirePool = await this.getEntirePool(); - const pool = this.applyFilters(entirePool, filter); + const pool = await this.getPoolWithFilters(filter); return pool.slice(from, from + size); } - async getEntirePool(): Promise { - return await this.cacheService.getOrSet( + async getPoolWithFilters( + filter?: PoolFilter, + ): Promise { + const pool = await this.cacheService.getOrSet( CacheInfo.TransactionPool.key, async () => await this.getTxPoolRaw(), CacheInfo.TransactionPool.ttl, ); + + return this.applyFilters(pool, filter); } async getTxPoolRaw(): Promise { @@ -117,7 +120,11 @@ export class PoolService { return transaction; } - private applyFilters(pool: TransactionInPool[], filters: PoolFilter): TransactionInPool[] { + private applyFilters(pool: TransactionInPool[], filters: PoolFilter | undefined): TransactionInPool[] { + if (!filters) { + return pool; + } + return pool.filter((transaction) => { return ( (!filters.sender || transaction.sender === filters.sender) && diff --git a/src/endpoints/providers/provider.module.ts b/src/endpoints/providers/provider.module.ts index c04f99383..11ba6823a 100644 --- a/src/endpoints/providers/provider.module.ts +++ b/src/endpoints/providers/provider.module.ts @@ -10,7 +10,7 @@ import { ProviderService } from "./provider.service"; forwardRef(() => KeybaseModule), forwardRef(() => NodeModule), VmQueryModule, - IdentitiesModule, + forwardRef(() => IdentitiesModule), ], providers: [ ProviderService, diff --git a/src/endpoints/rounds/round.module.ts b/src/endpoints/rounds/round.module.ts index 5536aa952..748bc71ad 100644 --- a/src/endpoints/rounds/round.module.ts +++ b/src/endpoints/rounds/round.module.ts @@ -1,10 +1,12 @@ import { Module } from "@nestjs/common"; import { BlsModule } from "../bls/bls.module"; import { RoundService } from "./round.service"; +import { BlockModule } from "../blocks/block.module"; @Module({ imports: [ BlsModule, + BlockModule, ], providers: [ RoundService, diff --git a/src/endpoints/rounds/round.service.ts b/src/endpoints/rounds/round.service.ts index 10c29f39e..357b8fe0c 100644 --- a/src/endpoints/rounds/round.service.ts +++ b/src/endpoints/rounds/round.service.ts @@ -6,12 +6,16 @@ import { BlsService } from "src/endpoints/bls/bls.service"; import { RoundUtils } from "@multiversx/sdk-nestjs-common"; import { ApiUtils } from "@multiversx/sdk-nestjs-http"; import { IndexerService } from "src/common/indexer/indexer.service"; +import { ApiConfigService } from "../../common/api-config/api.config.service"; +import { BlockService } from "../blocks/block.service"; @Injectable() export class RoundService { constructor( private readonly indexerService: IndexerService, private readonly blsService: BlsService, + private readonly apiConfigService: ApiConfigService, + private readonly blockService: BlockService, ) { } async getRoundCount(filter: RoundFilter): Promise { @@ -19,6 +23,14 @@ export class RoundService { } async getRounds(filter: RoundFilter): Promise { + const epoch = filter.epoch ? filter.epoch : await this.blockService.getCurrentEpoch(); + const isAndromedaEnabled = this.apiConfigService.isChainAndromedaEnabled() + && epoch >= this.apiConfigService.getChainAndromedaActivationEpoch(); + + if (isAndromedaEnabled) { + filter.validator = undefined; + } + const result = await this.indexerService.getRounds(filter) as any; for (const item of result) { @@ -33,9 +45,15 @@ export class RoundService { const epoch = RoundUtils.roundToEpoch(round); const publicKeys = await this.blsService.getPublicKeys(shard, epoch); + const isChainAndromedaEnabled = this.apiConfigService.isChainAndromedaEnabled() + && epoch >= this.apiConfigService.getChainAndromedaActivationEpoch(); result.shard = result.shardId; - result.signers = result.signersIndexes.map((index: number) => publicKeys[index]); + if (!isChainAndromedaEnabled) { + result.signers = result.signersIndexes.map((index: number) => publicKeys[index]); + } else { + result.signers = publicKeys; + } return ApiUtils.mergeObjects(new RoundDetailed(), result); } diff --git a/src/endpoints/tokens/token.service.ts b/src/endpoints/tokens/token.service.ts index 33597dbd9..c0d3873b8 100644 --- a/src/endpoints/tokens/token.service.ts +++ b/src/endpoints/tokens/token.service.ts @@ -91,7 +91,7 @@ export class TokenService { token = ApiUtils.mergeObjects(new TokenDetailed(), token); - await this.applyTickerFromAssets(token); + this.applyTickerFromAssets(token); await this.applySupply(token, supplyOptions); @@ -391,7 +391,7 @@ export class TokenService { tokenWithBalance.identifier = token.identifier; - await this.applyTickerFromAssets(tokenWithBalance); + this.applyTickerFromAssets(tokenWithBalance); await this.applySupply(tokenWithBalance); @@ -748,7 +748,7 @@ export class TokenService { const tokens = await this.getAllTokens(); for (const token of tokens) { - if (token.price && token.marketCap && !token.isLowLiquidity) { + if (token.price && token.marketCap && !token.isLowLiquidity && token.assets?.priceSource?.type !== TokenAssetsPriceSourceType.customUrl) { totalMarketCap += token.marketCap; } } @@ -852,7 +852,8 @@ export class TokenService { tokens = tokens.sortedDescending( token => token.assets ? 1 : 0, - token => token.isLowLiquidity ? 0 : (token.marketCap ?? 0), + token => token.marketCap ? 1 : 0, + token => token.isLowLiquidity || token.assets?.priceSource?.type === TokenAssetsPriceSourceType.customUrl ? 0 : (token.marketCap ?? 0), token => token.transactions ?? 0, ); diff --git a/src/endpoints/transactions/constants/gas.bucket.constants.ts b/src/endpoints/transactions/constants/gas.bucket.constants.ts new file mode 100644 index 000000000..acf8ef974 --- /dev/null +++ b/src/endpoints/transactions/constants/gas.bucket.constants.ts @@ -0,0 +1,11 @@ +/** + * Constants used for gas bucket distribution and PPU calculation + */ +export const GasBucketConstants = { + + GAS_BUCKET_SIZE: 6000000000, + + FAST_BUCKET_INDEX: 2, + + FASTER_BUCKET_INDEX: 0, +}; diff --git a/src/endpoints/transactions/entities/gas.bucket.ts b/src/endpoints/transactions/entities/gas.bucket.ts new file mode 100644 index 000000000..42911bd57 --- /dev/null +++ b/src/endpoints/transactions/entities/gas.bucket.ts @@ -0,0 +1,29 @@ +/** + * Represents a gas bucket for PPU calculation + */ +export interface GasBucket { + /** + * Bucket index + */ + index: number; + + /** + * Total gas accumulated in this bucket + */ + gasAccumulated: number; + + /** + * PPU of the first transaction in the bucket + */ + ppuBegin: number; + + /** + * PPU of the last transaction in the bucket + */ + ppuEnd?: number; + + /** + * Number of transactions in the bucket + */ + numTransactions: number; +} diff --git a/src/endpoints/transactions/entities/ppu.metadata.ts b/src/endpoints/transactions/entities/ppu.metadata.ts new file mode 100644 index 000000000..21dca8d5f --- /dev/null +++ b/src/endpoints/transactions/entities/ppu.metadata.ts @@ -0,0 +1,25 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export class PpuMetadata { + @ApiProperty({ + description: 'Last processed block number', + example: 47428477, + }) + lastBlock: number = 0; + + @ApiProperty({ + description: 'Price per unit for standard (medium priority) transactions', + example: 20000000, + }) + fast: number = 0; + + @ApiProperty({ + description: 'Price per unit for fast (high priority) transactions', + example: 40000000, + }) + faster: number = 0; + + constructor(init?: Partial) { + Object.assign(this, init); + } +} diff --git a/src/endpoints/transactions/entities/transaction.create.ts b/src/endpoints/transactions/entities/transaction.create.ts index 4d8dd7cb4..08672e74f 100644 --- a/src/endpoints/transactions/entities/transaction.create.ts +++ b/src/endpoints/transactions/entities/transaction.create.ts @@ -49,4 +49,10 @@ export class TransactionCreate { @ApiProperty() guardianSignature?: string = undefined; + + @ApiProperty() + relayer?: string = undefined; + + @ApiProperty() + relayerSignature?: string = undefined; } diff --git a/src/endpoints/transactions/entities/transaction.ts b/src/endpoints/transactions/entities/transaction.ts index ffd1cb99a..250917604 100644 --- a/src/endpoints/transactions/entities/transaction.ts +++ b/src/endpoints/transactions/entities/transaction.ts @@ -45,6 +45,9 @@ export class Transaction { @ApiProperty({ type: Number }) round: number | undefined = undefined; + @ApiProperty({ type: Number }) + epoch: number | undefined = undefined; + @ApiProperty({ type: String }) sender: string = ''; diff --git a/src/endpoints/transactions/entities/transaction.with.ppu.ts b/src/endpoints/transactions/entities/transaction.with.ppu.ts new file mode 100644 index 000000000..e570e587b --- /dev/null +++ b/src/endpoints/transactions/entities/transaction.with.ppu.ts @@ -0,0 +1,8 @@ +import { TransactionInPool } from '../../pool/entities/transaction.in.pool.dto'; + +/** + * Represents a transaction with price per unit calculated + */ +export interface TransactionWithPpu extends TransactionInPool { + ppu: number; +} diff --git a/src/endpoints/transactions/transaction-action/recognizers/staking/transaction.action.stake.recognizer.service.ts b/src/endpoints/transactions/transaction-action/recognizers/staking/transaction.action.stake.recognizer.service.ts index 607a42205..429c7cf72 100644 --- a/src/endpoints/transactions/transaction-action/recognizers/staking/transaction.action.stake.recognizer.service.ts +++ b/src/endpoints/transactions/transaction-action/recognizers/staking/transaction.action.stake.recognizer.service.ts @@ -46,7 +46,7 @@ export class StakeActionRecognizerService implements TransactionActionRecognizer providersDetails[provider.provider] = { providerName, providerAvatar }; } - await this.cachingService.setLocal('plugins:staking:providerAddresses', providersDetails, Constants.oneHour()); + this.cachingService.setLocal('plugins:staking:providerAddresses', providersDetails, Constants.oneHour()); } return providersDetails; diff --git a/src/endpoints/transactions/transaction.controller.ts b/src/endpoints/transactions/transaction.controller.ts index 2d77daef4..e9cccbd36 100644 --- a/src/endpoints/transactions/transaction.controller.ts +++ b/src/endpoints/transactions/transaction.controller.ts @@ -14,6 +14,7 @@ import { TransactionStatus } from './entities/transaction.status'; import { TransactionQueryOptions } from './entities/transactions.query.options'; import { TransactionService } from './transaction.service'; import { ParseArrayPipeOptions } from '@multiversx/sdk-nestjs-common/lib/pipes/entities/parse.array.options'; +import { PpuMetadata } from './entities/ppu.metadata'; @Controller() @ApiTags('transactions') @@ -282,4 +283,20 @@ export class TransactionController { return await this.transactionService.decodeTransaction(transaction); } + + @Get('/transactions/ppu/:shardId') + @ApiOperation({ summary: 'Price per unit by shard', description: 'Returns price per unit metadata for a specific shard' }) + @ApiOkResponse({ type: PpuMetadata }) + @ApiNotFoundResponse({ description: 'Price per unit data for shard not found' }) + async getPpuByShardId( + @Param('shardId', ParseIntPipe) shardId: number, + ): Promise { + const ppuMetadata = await this.transactionService.getPpuByShardId(shardId); + + if (ppuMetadata === null) { + throw new NotFoundException(`Price per unit data for shard ${shardId} not found`); + } + + return ppuMetadata; + } } diff --git a/src/endpoints/transactions/transaction.module.ts b/src/endpoints/transactions/transaction.module.ts index 4b406f4d2..f5fbf6cfd 100644 --- a/src/endpoints/transactions/transaction.module.ts +++ b/src/endpoints/transactions/transaction.module.ts @@ -2,6 +2,9 @@ import { forwardRef, Module } from "@nestjs/common"; import { AssetsModule } from "src/common/assets/assets.module"; import { DataApiModule } from "src/common/data-api/data-api.module"; import { PluginModule } from "src/plugins/plugin.module"; +import { BlockModule } from "../blocks/block.module"; +import { NetworkModule } from "../network/network.module"; +import { PoolModule } from "../pool/pool.module"; import { TokenModule } from "../tokens/token.module"; import { UsernameModule } from "../usernames/username.module"; import { TransactionActionModule } from "./transaction-action/transaction.action.module"; @@ -14,6 +17,9 @@ import { TransactionService } from "./transaction.service"; forwardRef(() => TokenModule), forwardRef(() => PluginModule), forwardRef(() => TransactionActionModule), + forwardRef(() => BlockModule), + forwardRef(() => PoolModule), + forwardRef(() => NetworkModule), AssetsModule, UsernameModule, DataApiModule, diff --git a/src/endpoints/transactions/transaction.service.ts b/src/endpoints/transactions/transaction.service.ts index 3fb2770a9..968c70fc3 100644 --- a/src/endpoints/transactions/transaction.service.ts +++ b/src/endpoints/transactions/transaction.service.ts @@ -33,6 +33,15 @@ import { UsernameService } from '../usernames/username.service'; import { MiniBlock } from 'src/common/indexer/entities/miniblock'; import { Block } from 'src/common/indexer/entities/block'; import { ProtocolService } from 'src/common/protocol/protocol.service'; +import { PpuMetadata } from './entities/ppu.metadata'; +import { BlockService } from '../blocks/block.service'; +import { BlockFilter } from '../blocks/entities/block.filter'; +import { SortOrder } from 'src/common/entities/sort.order'; +import { PoolService } from '../pool/pool.service'; +import { NetworkService } from 'src/endpoints/network/network.service'; +import { TransactionWithPpu } from './entities/transaction.with.ppu'; +import { GasBucket } from './entities/gas.bucket'; +import { GasBucketConstants } from './constants/gas.bucket.constants'; @Injectable() export class TransactionService { @@ -54,6 +63,12 @@ export class TransactionService { private readonly apiConfigService: ApiConfigService, private readonly usernameService: UsernameService, private readonly protocolService: ProtocolService, + @Inject(forwardRef(() => BlockService)) + private readonly blockService: BlockService, + @Inject(forwardRef(() => PoolService)) + private readonly poolService: PoolService, + @Inject(forwardRef(() => NetworkService)) + private readonly networkService: NetworkService, ) { } async getTransactionCountForAddress(address: string): Promise { @@ -569,4 +584,165 @@ export class TransactionService { return undefined; } + + async getPpuByShardId(shardId: number): Promise { + return await this.cachingService.getOrSet( + CacheInfo.PpuMetadataByShard(shardId).key, + async () => await this.getPpuByShardIdRaw(shardId), + CacheInfo.PpuMetadataByShard(shardId).ttl, + Constants.oneSecond(), + ); + } + + async getPpuByShardIdRaw(shardId: number): Promise { + try { + if (shardId < 0 || shardId > 2) { + return null; + } + + const blocks = await this.blockService.getBlocks( + new BlockFilter({ shard: shardId, order: SortOrder.desc }), + new QueryPagination({ from: 0, size: 1 }) + ); + + if (!blocks || blocks.length === 0) { + this.logger.error(`No blocks found for shard ${shardId}`); + return null; + } + + const lastBlock = blocks[0].nonce; + const networkConstants = await this.networkService.getConstants(); + const { minGasLimit, gasPerDataByte, gasPriceModifier } = networkConstants; + const gasPriceModifierNumber = Number(gasPriceModifier); + const { GAS_BUCKET_SIZE, FAST_BUCKET_INDEX, FASTER_BUCKET_INDEX } = GasBucketConstants; + + const poolTransactions = await this.poolService.getPoolWithFilters({ senderShard: shardId }); + + if (!poolTransactions || poolTransactions.length === 0) { + return new PpuMetadata({ + lastBlock: lastBlock, + fast: 0, + faster: 0, + }); + } + + const transactionsWithPpu = this.calculatePpuForTransactions( + poolTransactions, + minGasLimit, + gasPerDataByte, + gasPriceModifierNumber + ); + + const sortedTransactions = this.sortTransactionsByPriority(transactionsWithPpu); + const gasBuckets = this.distributeTransactionsIntoGasBuckets(sortedTransactions, GAS_BUCKET_SIZE); + + const fastPpu = gasBuckets.length > FAST_BUCKET_INDEX && gasBuckets[FAST_BUCKET_INDEX].ppuEnd + ? gasBuckets[FAST_BUCKET_INDEX].ppuEnd + : 0; + + const fasterPpu = gasBuckets.length > FASTER_BUCKET_INDEX && gasBuckets[FASTER_BUCKET_INDEX].ppuEnd + ? gasBuckets[FASTER_BUCKET_INDEX].ppuEnd + : 0; + + return new PpuMetadata({ + lastBlock: lastBlock, + fast: fastPpu, + faster: fasterPpu, + }); + } catch (error) { + this.logger.error(`Error getting price per unit metadata for shard ${shardId}`, { + path: 'transactionService.getPpuByShardIdRaw', + shardId, + error, + }); + return null; + } + } + + private calculatePpuForTransactions( + transactions: any[], + minGasLimit: number, + gasPerDataByte: number, + gasPriceModifier: number + ): TransactionWithPpu[] { + return transactions.map(tx => { + const data = tx.data ? BinaryUtils.base64Decode(tx.data) : ''; + const gasLimit = Number(tx.gasLimit); + const gasPrice = Number(tx.gasPrice); + + const dataCost = minGasLimit + data.length * gasPerDataByte; + const executionCost = gasLimit - dataCost; + const initiallyPaidFee = dataCost * gasPrice + executionCost * gasPrice * gasPriceModifier; + const ppu = Math.floor(initiallyPaidFee / gasLimit); + + return { ...tx, ppu }; + }); + } + + private sortTransactionsByPriority(transactions: TransactionWithPpu[]): TransactionWithPpu[] { + return [...transactions].sort((a, b) => { + // Same sender - sort by nonce + if (a.sender === b.sender) { + return a.nonce - b.nonce; + } + + // Different PPU - sort by PPU (descending) + if (a.ppu !== b.ppu) { + return b.ppu - a.ppu; + } + + // Different gas limit - sort by gas limit (descending) + if (a.gasLimit !== b.gasLimit) { + return b.gasLimit - a.gasLimit; + } + + // Otherwise sort by hash (lexicographically) + return a.txHash.localeCompare(b.txHash); + }); + } + + private distributeTransactionsIntoGasBuckets( + transactions: TransactionWithPpu[], + gasBucketSize: number + ): GasBucket[] { + const buckets: GasBucket[] = []; + let currentBucket: GasBucket = { + index: 0, + gasAccumulated: 0, + ppuBegin: 0, + numTransactions: 0, + }; + + for (const transaction of transactions) { + const gasLimit = Number(transaction.gasLimit); + currentBucket.gasAccumulated += gasLimit; + currentBucket.numTransactions += 1; + + if (currentBucket.numTransactions === 1) { + currentBucket.ppuBegin = transaction.ppu; + } + + if (currentBucket.gasAccumulated >= gasBucketSize) { + currentBucket.ppuEnd = transaction.ppu; + buckets.push(currentBucket); + + currentBucket = { + index: currentBucket.index + 1, + gasAccumulated: 0, + ppuBegin: 0, + numTransactions: 0, + }; + } + } + + if (currentBucket.numTransactions > 0) { + currentBucket.ppuEnd = transactions[transactions.length - 1].ppu; + buckets.push(currentBucket); + } + for (const bucket of buckets) { + this.logger.log(`Bucket ${bucket.index}, gas = ${bucket.gasAccumulated}, num_txs = ${bucket.numTransactions}, ppu: ${bucket.ppuBegin} .. ${bucket.ppuEnd}`); + } + + return buckets; + } } diff --git a/src/endpoints/usernames/username.service.ts b/src/endpoints/usernames/username.service.ts index 761c1da34..c9367ee7c 100644 --- a/src/endpoints/usernames/username.service.ts +++ b/src/endpoints/usernames/username.service.ts @@ -34,6 +34,9 @@ export class UsernameService { } async getUsernameForAddress(address: string): Promise { + if (!this.apiConfigService.getMaiarIdUrl()) { + return null; + } return await this.cachingService.getOrSet( CacheInfo.Username(address).key, async () => await this.getUsernameForAddressRaw(address), diff --git a/src/queue.worker/nft.worker/queue/job-services/media/nft.media.service.ts b/src/queue.worker/nft.worker/queue/job-services/media/nft.media.service.ts index 5c05f2e5b..66d3b0cf3 100644 --- a/src/queue.worker/nft.worker/queue/job-services/media/nft.media.service.ts +++ b/src/queue.worker/nft.worker/queue/job-services/media/nft.media.service.ts @@ -18,8 +18,8 @@ import { CachingUtils } from "src/utils/caching.utils"; export class NftMediaService { private readonly logger = new OriginLogger(NftMediaService.name); private readonly IPFS_REQUEST_TIMEOUT = Constants.oneSecond() * 30 * 1000; - private readonly NFT_THUMBNAIL_PREFIX; - public static readonly NFT_THUMBNAIL_DEFAULT = 'https://media.elrond.com/nfts/thumbnail/default.png'; + private readonly NFT_THUMBNAIL_PREFIX: string; + public readonly NFT_THUMBNAIL_DEFAULT: string; constructor( private readonly cachingService: CacheService, @@ -28,7 +28,8 @@ export class NftMediaService { private readonly persistenceService: PersistenceService, @Inject('PUBSUB_SERVICE') private clientProxy: ClientProxy, ) { - this.NFT_THUMBNAIL_PREFIX = this.apiConfigService.getExternalMediaUrl() + '/nfts/asset'; + this.NFT_THUMBNAIL_PREFIX = `${this.apiConfigService.getExternalMediaUrl()}/nfts/asset`; + this.NFT_THUMBNAIL_DEFAULT = `${this.apiConfigService.getMediaUrl()}/nfts/thumbnail/default.png`; } async getMedia(identifier: string): Promise { @@ -53,7 +54,7 @@ export class NftMediaService { CacheInfo.NftMedia(nft.identifier).ttl ); - await this.clientProxy.emit('refreshCacheKey', { + this.clientProxy.emit('refreshCacheKey', { key: CacheInfo.NftMedia(nft.identifier).key, ttl: CacheInfo.NftMedia(nft.identifier).ttl, }); @@ -112,7 +113,7 @@ export class NftMediaService { nftMedia.thumbnailUrl = `${this.apiConfigService.getExternalMediaUrl()}/nfts/thumbnail/${nft.collection}-${TokenHelpers.getUrlHash(nftMedia.url)}`; } else { this.logger.log(`File size '${fileProperties.contentLength}' not accepted for NFT with identifier '${nft.identifier}'`); - nftMedia.thumbnailUrl = NftMediaService.NFT_THUMBNAIL_DEFAULT; + nftMedia.thumbnailUrl = this.NFT_THUMBNAIL_DEFAULT; } nftMedia.fileType = fileProperties.contentType; diff --git a/src/queue.worker/nft.worker/queue/job-services/metadata/nft.metadata.service.ts b/src/queue.worker/nft.worker/queue/job-services/metadata/nft.metadata.service.ts index 78599bb43..8ab83454b 100644 --- a/src/queue.worker/nft.worker/queue/job-services/metadata/nft.metadata.service.ts +++ b/src/queue.worker/nft.worker/queue/job-services/metadata/nft.metadata.service.ts @@ -56,7 +56,7 @@ export class NftMetadataService { CacheInfo.NftMetadata(nft.identifier).ttl ); - await this.clientProxy.emit('refreshCacheKey', { + this.clientProxy.emit('refreshCacheKey', { key: CacheInfo.NftMetadata(nft.identifier).key, ttl: CacheInfo.NftMetadata(nft.identifier).ttl, }); diff --git a/src/queue.worker/nft.worker/queue/nft.queue.controller.ts b/src/queue.worker/nft.worker/queue/nft.queue.controller.ts index 36989710b..e81b2029b 100644 --- a/src/queue.worker/nft.worker/queue/nft.queue.controller.ts +++ b/src/queue.worker/nft.worker/queue/nft.queue.controller.ts @@ -135,7 +135,7 @@ export class NftQueueController { } if (nft.media && !settings.skipRefreshThumbnail) { - const mediaItems = nft.media.filter(x => x.thumbnailUrl !== NftMediaService.NFT_THUMBNAIL_DEFAULT); + const mediaItems = nft.media.filter(x => x.thumbnailUrl !== this.nftMediaService.NFT_THUMBNAIL_DEFAULT); await Promise.all(mediaItems.map(media => this.generateThumbnail(nft, media, settings.forceRefreshThumbnail))); } diff --git a/src/test/chain-simulator/accounts.cs-e2e.ts b/src/test/chain-simulator/accounts.cs-e2e.ts index 431516f4b..f1182d86e 100644 --- a/src/test/chain-simulator/accounts.cs-e2e.ts +++ b/src/test/chain-simulator/accounts.cs-e2e.ts @@ -2,6 +2,7 @@ import axios from "axios"; import { config } from "./config/env.config"; import { NftType } from "src/endpoints/nfts/entities/nft.type"; import { NftSubType } from "src/endpoints/nfts/entities/nft.sub.type"; +import { transferNftFromTo } from "./utils/chain.simulator.operations"; describe('Accounts e2e tests with chain simulator', () => { describe('GET /accounts with query parameters', () => { @@ -1985,5 +1986,36 @@ describe('Accounts e2e tests with chain simulator', () => { expect(response.data).toHaveProperty(field); } }); + + it('should return the NFT received at timestamp when transferred from one address to another and withReceivedAt parameter is true', async () => { + const accountNfts = await axios.get(`${config.apiServiceUrl}/accounts/${config.aliceAddress}/nfts?size=1&type=${NftType.NonFungibleESDT}`); + const nft = accountNfts.data[0]; + const sendNftTx = await transferNftFromTo(config.chainSimulatorUrl, config.aliceAddress, config.bobAddress, nft.collection, nft.nonce); + + const transaction = await axios.get(`${config.apiServiceUrl}/transactions/${sendNftTx}`); + await new Promise(resolve => setTimeout(resolve, 2000)); + + expect(transaction.status).toBe(200); + + const checkBobNft = await axios.get(`${config.apiServiceUrl}/accounts/${config.bobAddress}/nfts?withReceivedAt=true`); + const bobNft = checkBobNft.data; + + expect(bobNft.length).toBeGreaterThanOrEqual(1); + expect(bobNft[0].receivedAt).toBeDefined(); + }); + + it('should not return the NFT received at timestamp when transferred from one address to another and withReceivedAt parameter is false', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.bobAddress}/nfts?withReceivedAt=false`); + const responseData = response.data; + + expect(responseData.every((nft: any) => nft.receivedAt === undefined)).toBe(true); + }); + + it('should throw an error with 400 Bad Request if size parameter is greater than 25 and withReceivedAt parameter is true', async () => { + const response = await axios.get(`${config.apiServiceUrl}/accounts/${config.bobAddress}/nfts?withReceivedAt=true&size=30`) + .catch(err => err.response); + + expect(response.status).toBe(400); + }); }); }); diff --git a/src/test/chain-simulator/transactions.cs-e2e.ts b/src/test/chain-simulator/transactions.cs-e2e.ts index 620880805..c4a9b2e6b 100644 --- a/src/test/chain-simulator/transactions.cs-e2e.ts +++ b/src/test/chain-simulator/transactions.cs-e2e.ts @@ -194,6 +194,8 @@ describe('Transactions e2e tests with chain simulator', () => { 'receiver', 'receiverShard', 'round', + // TODO: we should also validate the existence of the epoch field after upgrading the CS image + // 'epoch', 'sender', 'senderShard', 'status', diff --git a/src/test/chain-simulator/utils/chain.simulator.operations.ts b/src/test/chain-simulator/utils/chain.simulator.operations.ts index 1b39153fa..683b32110 100644 --- a/src/test/chain-simulator/utils/chain.simulator.operations.ts +++ b/src/test/chain-simulator/utils/chain.simulator.operations.ts @@ -184,6 +184,7 @@ export class SendTransactionArgs { value?: string = '0'; gasLimit?: number = 100_000_000; nonceOffset?: number = 0; // useful for scenarios where a higher nonce is desired + gasPrice?: string; constructor(options: Partial = {}) { Object.assign(this, options); @@ -548,4 +549,77 @@ export async function issueMultipleMetaESDTCollections( return metaEsdtCollectionIdentifiers.map(x => x.identifier); } +export async function transferNft(args: TransferNftArgs) { + // Format nonce as hex string with at least 2 digits + const nonceHex = typeof args.nonce === 'number' + ? args.nonce.toString(16).padStart(2, '0') + : args.nonce; + // Format quantity as hex string, always specify it (even for quantity=1) + const quantityHex = args.quantity.toString(16).padStart(2, '0'); + + // Convert receiver address from bech32 to hex format + const receiverHex = AddressUtils.bech32Decode(args.receiver); + + // Prepare data field components + const dataField = [ + 'ESDTNFTTransfer', + Buffer.from(args.collectionIdentifier).toString('hex'), + nonceHex, + quantityHex, // Always specify quantity + receiverHex, + ].join('@'); + + // Log the data field for debugging + console.log(`NFT Transfer data field: ${dataField}`); + + return await sendTransaction( + new SendTransactionArgs({ + chainSimulatorUrl: args.chainSimulatorUrl, + sender: args.sender, + receiver: args.sender, + dataField: dataField, + value: '0', + gasLimit: 1000000, + }), + ); +} + +export class TransferNftArgs { + chainSimulatorUrl: string = ''; + sender: string = ''; + receiver: string = ''; + collectionIdentifier: string = ''; + nonce: string | number = ''; + quantity: number = 1; + + constructor(options: Partial = {}) { + Object.assign(this, options); + } +} + +export async function transferNftFromTo( + chainSimulatorUrl: string, + senderAddress: string, + receiverAddress: string, + collectionIdentifier: string, + nftNonce: string | number, + quantity: number = 1 +): Promise { + console.log(`Transferring NFT from ${senderAddress} to ${receiverAddress}`); + console.log(`Collection: ${collectionIdentifier}, Nonce: ${nftNonce}, Quantity: ${quantity}`); + + const txHash = await transferNft( + new TransferNftArgs({ + chainSimulatorUrl, + sender: senderAddress, + receiver: receiverAddress, + collectionIdentifier, + nonce: nftNonce, + quantity, + }) + ); + + console.log(`NFT transfer completed. Transaction hash: ${txHash}`); + return txHash; +} diff --git a/src/test/chain-simulator/utils/test-ppu-calculation.ts b/src/test/chain-simulator/utils/test-ppu-calculation.ts new file mode 100644 index 000000000..d35f527dc --- /dev/null +++ b/src/test/chain-simulator/utils/test-ppu-calculation.ts @@ -0,0 +1,482 @@ +import axios from 'axios'; +import { config } from '../config/env.config'; +import { fundAddress, sendTransaction, SendTransactionArgs } from './chain.simulator.operations'; +import { ChainSimulatorUtils } from './test.utils'; +import { BinaryUtils } from '@multiversx/sdk-nestjs-common'; +import * as fs from 'fs'; +import * as path from 'path'; + +async function testPpuCalculation() { + try { + console.log('Starting PPU calculation test...'); + + // Wait for chain simulator to be ready + console.log('Waiting for epoch 2...'); + await ChainSimulatorUtils.waitForEpoch(2); + console.log('✓ Chain simulator reached epoch 2'); + + // Fund test addresses + const addresses = { + shard0: config.aliceAddress, + shard1: config.bobAddress, + }; + + // Fund all addresses + for (const [shardName, address] of Object.entries(addresses)) { + await fundAddress(config.chainSimulatorUrl, address); + console.log(`✓ Funded address for ${shardName}: ${address}`); + } + + // Deploy smart contract + const pingPongAddress = await deployPingPongSmartContract(addresses.shard0); + console.log(`✓ Deployed PingPong smart contract at address: ${pingPongAddress}`); + + // Start PPU monitoring in background + const stopMonitoring = startContinuousPpuMonitoring(); + + try { + // Create transactions in batches to maintain continuous congestion + await createContinuousCongestion(addresses, pingPongAddress); + } finally { + // Stop the monitoring when we're done + stopMonitoring(); + } + + // Wait a bit for last transactions to be processed + console.log('\nWaiting for final transactions to be processed...'); + await new Promise(resolve => setTimeout(resolve, 5000)); + + // Generate final report + await getFinalPpuReport(); + + console.log('\nPPU calculation test completed successfully!'); + } catch (error) { + console.error('Error testing PPU calculation:', error); + process.exit(1); + } +} + +/** + * Deploy PingPong smart contract for testing contract interactions + */ +async function deployPingPongSmartContract(deployerAddress: string): Promise { + console.log('Deploying PingPong smart contract...'); + + // Deploy the PingPong contract + const scAddress = await ChainSimulatorUtils.deployPingPongSc(deployerAddress); + + // Wait a bit for deployment to be processed + await new Promise(resolve => setTimeout(resolve, 3000)); + + return scAddress; +} + +interface PpuActivityReport { + timestamp: string; + shardId: number; + lastBlock: number; + fastPpu: number; + fasterPpu: number; + totalTransactions: number; + mempoolAnalysis?: { + calculatedFastPpu: number; + calculatedFasterPpu: number; + fastPpuDifference: number; + fasterPpuDifference: number; + transactionCount: number; + }; +} + +function startContinuousPpuMonitoring() { + let shouldContinue = true; + + const monitor = async () => { + while (shouldContinue) { + for (let shardId = 0; shardId <= 2; shardId++) { + try { + const response = await axios.get(`${config.apiServiceUrl}/transactions/ppu/${shardId}`); + const ppuData = response.data; + + if (ppuData.Fast > 0 || ppuData.Faster > 0) { + const timestamp = new Date().toISOString(); + console.log(`\nDetected PPU activity in shard ${shardId} at ${timestamp}:`); + console.log(`- Last Block: ${ppuData.LastBlock}`); + console.log(`- Fast PPU: ${ppuData.Fast}`); + console.log(`- Faster PPU: ${ppuData.Faster}`); + + const activityReport: PpuActivityReport = { + timestamp, + shardId, + lastBlock: ppuData.LastBlock, + fastPpu: ppuData.Fast, + fasterPpu: ppuData.Faster, + totalTransactions: 0, + }; + + // Get mempool transactions for validation + const poolResponse = await axios.get(`${config.apiServiceUrl}/pool?senderShard=${shardId}&size=10000`); + const transactions = poolResponse.data; + + if (transactions.length > 0) { + // Get network constants + const networkResponse = await axios.get(`${config.apiServiceUrl}/constants`); + const { minGasLimit, gasPerDataByte, gasPriceModifier } = networkResponse.data; + + // Calculate PPU for all transactions + const ppuValues = transactions.map((tx: { data?: string; gasLimit: string; gasPrice: string }) => { + const data = tx.data ? BinaryUtils.base64Decode(tx.data) : ''; + const gasLimit = Number(tx.gasLimit); + const gasPrice = Number(tx.gasPrice); + + const dataCost = minGasLimit + data.length * gasPerDataByte; + const executionCost = gasLimit - dataCost; + const initiallyPaidFee = dataCost * gasPrice + executionCost * gasPrice * Number(gasPriceModifier); + return Math.floor(initiallyPaidFee / gasLimit); + }); + + // Sort PPU values and calculate percentiles + const sortedPpuValues = [...ppuValues].sort((a, b) => b - a); + const fastIndex = Math.floor(transactions.length * 0.2); // 20th percentile + const fasterIndex = Math.floor(transactions.length * 0.1); // 10th percentile + + console.log(`\nMempool Analysis for shard ${shardId}:`); + console.log(`- Total transactions: ${transactions.length}`); + console.log(`- Calculated Fast PPU (20th percentile): ${sortedPpuValues[fastIndex]}`); + console.log(`- Calculated Faster PPU (10th percentile): ${sortedPpuValues[fasterIndex]}`); + + // Calculate and log the difference + const fastDiff = ppuData.Fast > 0 ? Math.abs(ppuData.Fast - sortedPpuValues[fastIndex]) / ppuData.Fast : 0; + const fasterDiff = ppuData.Faster > 0 ? Math.abs(ppuData.Faster - sortedPpuValues[fasterIndex]) / ppuData.Faster : 0; + + console.log(`- Fast PPU difference: ${(fastDiff * 100).toFixed(2)}%`); + console.log(`- Faster PPU difference: ${(fasterDiff * 100).toFixed(2)}%`); + + activityReport.totalTransactions = transactions.length; + activityReport.mempoolAnalysis = { + calculatedFastPpu: sortedPpuValues[fastIndex], + calculatedFasterPpu: sortedPpuValues[fasterIndex], + fastPpuDifference: fastDiff, + fasterPpuDifference: fasterDiff, + transactionCount: transactions.length, + }; + + // Save the activity report + const reportsDir = path.join(__dirname, '../../../reports/ppu-activity'); + if (!fs.existsSync(reportsDir)) { + fs.mkdirSync(reportsDir, { recursive: true }); + } + + const safeTimestamp = timestamp.replace(/[:.]/g, '-'); + const filename = path.join(reportsDir, `ppu-activity-shard-${shardId}-${safeTimestamp}.json`); + fs.writeFileSync(filename, JSON.stringify(activityReport, null, 2)); + console.log(`\nActivity report saved to: ${filename}`); + } + } + } catch (error) { + console.error(`Error monitoring PPU for shard ${shardId}:`, error); + } + } + // Wait before next check + await new Promise(resolve => setTimeout(resolve, 2000)); + } + }; + + // Start the monitoring process + void monitor(); + + // Return function to stop monitoring + return () => { + shouldContinue = false; + }; +} + +interface PpuReportData { + timestamp: string; + batchNumber: number; + shards: { + [key: number]: { + lastBlock: number; + fastPpu: number; + fasterPpu: number; + totalTransactions: number; + ppuDistribution?: { + highest: number; + fast: number; + faster: number; + lowest: number; + }; + validation?: { + fastDiff: number; + fasterDiff: number; + }; + transactionDistribution?: { + regular: number; + smartContract: number; + }; + }; + }; +} + +function calculatePpuDifference(actualPpu: number, calculatedPpu: number): number { + if (actualPpu === 0 || calculatedPpu === 0) { + return 0; + } + + // Calculate the relative difference as a percentage + const relativeDiff = Math.abs(actualPpu - calculatedPpu) / Math.max(actualPpu, calculatedPpu); + + // We consider differences of less than 1% as acceptable + return relativeDiff; +} + +async function getFinalPpuReport(batchNumber?: number): Promise { + const reportData: PpuReportData = { + timestamp: new Date().toISOString(), + batchNumber: batchNumber || 0, + shards: {}, + }; + + console.log('\n=== PPU Report' + (batchNumber ? ` after batch ${batchNumber}` : '') + ' ==='); + + for (let shardId = 0; shardId <= 2; shardId++) { + try { + console.log(`\nShard ${shardId}:`); + console.log('------------------------'); + + // Get PPU data + const ppuResponse = await axios.get(`${config.apiServiceUrl}/transactions/ppu/${shardId}`); + const ppuData = ppuResponse.data; + + // Get mempool transactions + const poolResponse = await axios.get(`${config.apiServiceUrl}/pool?senderShard=${shardId}&size=10000`); + const transactions = poolResponse.data; + + reportData.shards[shardId] = { + lastBlock: ppuData.LastBlock, + fastPpu: ppuData.Fast, + fasterPpu: ppuData.Faster, + totalTransactions: transactions.length, + }; + + console.log(`Last Block: ${ppuData.LastBlock}`); + console.log(`Fast PPU: ${ppuData.Fast}`); + console.log(`Faster PPU: ${ppuData.Faster}`); + console.log(`Total transactions in mempool: ${transactions.length}`); + + if (transactions.length > 0) { + // Get network constants + const networkResponse = await axios.get(`${config.apiServiceUrl}/constants`); + const { minGasLimit, gasPerDataByte, gasPriceModifier } = networkResponse.data; + + // Calculate PPU distribution + const ppuValues = transactions.map((tx: { data?: string; gasLimit: string; gasPrice: string }) => { + const data = tx.data ? BinaryUtils.base64Decode(tx.data) : ''; + const gasLimit = Number(tx.gasLimit); + const gasPrice = Number(tx.gasPrice); + + const dataCost = minGasLimit + data.length * gasPerDataByte; + const executionCost = gasLimit - dataCost; + const initiallyPaidFee = dataCost * gasPrice + executionCost * gasPrice * Number(gasPriceModifier); + return Math.floor(initiallyPaidFee / gasLimit); + }); + + // Sort and get statistics + const sortedPpuValues = [...ppuValues].sort((a, b) => b - a); + const fastIndex = Math.floor(transactions.length * 0.2); + const fasterIndex = Math.floor(transactions.length * 0.1); + + console.log('\nPPU Distribution:'); + console.log(`Highest PPU: ${sortedPpuValues[0]}`); + console.log(`Calculated Fast PPU (20th percentile): ${sortedPpuValues[fastIndex]}`); + console.log(`Calculated Faster PPU (10th percentile): ${sortedPpuValues[fasterIndex]}`); + console.log(`Lowest PPU: ${sortedPpuValues[sortedPpuValues.length - 1]}`); + + reportData.shards[shardId].ppuDistribution = { + highest: sortedPpuValues[0], + fast: sortedPpuValues[fastIndex], + faster: sortedPpuValues[fasterIndex], + lowest: sortedPpuValues[sortedPpuValues.length - 1], + }; + + // Calculate differences using the new method + const fastDiff = calculatePpuDifference(ppuData.Fast, sortedPpuValues[fastIndex]); + const fasterDiff = calculatePpuDifference(ppuData.Faster, sortedPpuValues[fasterIndex]); + + console.log('\nPPU Analysis:'); + console.log(`Fast PPU from API: ${ppuData.Fast}`); + console.log(`Fast PPU calculated (20th percentile): ${sortedPpuValues[fastIndex]}`); + console.log(`Fast PPU difference: ${(fastDiff * 100).toFixed(2)}%`); + + console.log(`\nFaster PPU from API: ${ppuData.Faster}`); + console.log(`Faster PPU calculated (10th percentile): ${sortedPpuValues[fasterIndex]}`); + console.log(`Faster PPU difference: ${(fasterDiff * 100).toFixed(2)}%`); + + if (fastDiff > 0.1 || fasterDiff > 0.1) { + console.log('\n⚠️ Warning: Large PPU difference detected!'); + console.log('This might indicate:'); + console.log('1. High mempool congestion'); + console.log('2. Rapid changes in gas prices'); + console.log('3. Potential calculation discrepancies'); + } + + reportData.shards[shardId].validation = { + fastDiff: fastDiff, + fasterDiff: fasterDiff, + }; + + // Transaction type distribution + const scTransactions = transactions.filter((tx: { data?: string }) => + tx.data && BinaryUtils.base64Decode(tx.data).startsWith('ping') + ).length; + const regularTransactions = transactions.length - scTransactions; + + console.log('\nTransaction Distribution:'); + console.log(`Regular transactions: ${regularTransactions}`); + console.log(`Smart Contract transactions: ${scTransactions}`); + + reportData.shards[shardId].transactionDistribution = { + regular: regularTransactions, + smartContract: scTransactions, + }; + } + } catch (error) { + console.error(`Error getting final report for shard ${shardId}:`, error); + } + } + + // Save report to file + const reportsDir = path.join(__dirname, '../../../reports'); + if (!fs.existsSync(reportsDir)) { + fs.mkdirSync(reportsDir, { recursive: true }); + } + + const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); + const filename = path.join(reportsDir, `ppu-report-${batchNumber ? `batch-${batchNumber}-` : ''}${timestamp}.json`); + + fs.writeFileSync(filename, JSON.stringify(reportData, null, 2)); + console.log(`\nReport saved to: ${filename}`); + + return reportData; +} + +async function createContinuousCongestion(addresses: Record, pingPongAddress: string) { + console.log('Starting continuous congestion generation...'); + + let batchNumber = 1; + + // Create transactions with realistic gas prices, including higher values + const gasPrices = [ + 1000000000, + 2000000000, + 3000000000, + 5000000000, + 7000000000, + 10000000000, + 15000000000, + 20000000000, + ]; + + // Create transactions with different data sizes, including larger ones + const dataSizes = [ + '', // Empty data + 'small data field', // Small data + 'a'.repeat(100), // Medium data + 'a'.repeat(500), // Large data + 'a'.repeat(1000), // Very large data + 'a'.repeat(2000), // Extra large data + 'a'.repeat(5000), // Huge data + 'a'.repeat(10000), // Massive data + ]; + + // Smart contract function calls with varying complexity + const scCalls = [ + 'ping', + 'ping@01', + 'ping@0123456789', + 'ping@' + 'a'.repeat(100), // Large argument + 'ping@' + 'a'.repeat(500), // Very large argument + 'ping@' + 'a'.repeat(1000), // Massive argument + ]; + + // Gas limits for smart contracts, including higher values + const scGasLimits = [ + 150000000, // 150M + 200000000, // 200M + 300000000, // 300M + 400000000, // 400M + ]; + + while (batchNumber <= 4) { + console.log(`\nCreating transaction batch ${batchNumber}...`); + + // Create a mix of regular and smart contract transactions + for (const [, sender] of Object.entries(addresses)) { + // Regular transactions - create more heavy ones + for (const gasPrice of gasPrices) { + for (const dataField of dataSizes) { + for (const receiver of Object.values(addresses)) { + if (sender !== receiver) { + // Add more transactions for higher gas prices + const repeatCount = gasPrice >= 10000000000 ? 3 : 1; // Create more high-gas-price transactions + + for (let i = 0; i < repeatCount; i++) { + await sendTransaction( + new SendTransactionArgs({ + chainSimulatorUrl: config.chainSimulatorUrl, + sender: sender, + receiver: receiver, + dataField: dataField, + value: '1000000000000000000', + gasLimit: 50000000 + (dataField.length * 1500), // Adjust gas limit based on data size + nonceOffset: Math.floor(Math.random() * 5), + gasPrice: gasPrice.toString(), + }) + ); + } + } + } + } + } + + // Smart contract transactions - create more heavy ones + for (const gasPrice of gasPrices) { + for (const scCall of scCalls) { + for (const gasLimit of scGasLimits) { + // Add more transactions for higher gas prices + const repeatCount = gasPrice >= 10000000000 ? 3 : 1; + + for (let i = 0; i < repeatCount; i++) { + await sendTransaction( + new SendTransactionArgs({ + chainSimulatorUrl: config.chainSimulatorUrl, + sender: sender, + receiver: pingPongAddress, + dataField: scCall, + value: '1000000000000000000', + gasLimit: gasLimit, + nonceOffset: Math.floor(Math.random() * 5), + gasPrice: gasPrice.toString(), + }) + ); + } + } + } + } + } + + console.log(`✓ Batch ${batchNumber} created`); + + // Generate and save report after each batch + console.log('\nGenerating report for this batch...'); + await getFinalPpuReport(batchNumber); + + // Wait a bit before next batch to allow some transactions to be processed + console.log('\nWaiting for transactions to be processed before next batch...'); + await new Promise(resolve => setTimeout(resolve, 5000)); + + batchNumber++; + } +} + +// Run the test +void testPpuCalculation(); diff --git a/src/test/unit/controllers/identities.controller.spec.ts b/src/test/unit/controllers/identities.controller.spec.ts index b159977b1..e92305430 100644 --- a/src/test/unit/controllers/identities.controller.spec.ts +++ b/src/test/unit/controllers/identities.controller.spec.ts @@ -5,6 +5,7 @@ import { mockIdentityService } from "./services.mock/identity.services.mock"; import { IdentitiesController } from "src/endpoints/identities/identities.controller"; import { PublicAppModule } from "src/public.app.module"; import { IdentitiesService } from "src/endpoints/identities/identities.service"; +import { IdentitySortCriteria } from "src/endpoints/identities/entities/identity.sort.criteria"; describe('IdentityController', () => { let app: INestApplication; @@ -38,6 +39,54 @@ describe('IdentityController', () => { expect(response.body.length).toBe(5); }); }); + + it('should properly handle single sort criteria', async () => { + const mockIdentitiesList = createMockIdentitiesList(5); + identitiesServiceMocks.getIdentities.mockResolvedValue(mockIdentitiesList); + + await request(app.getHttpServer()) + .get(`${path}?sort=validators`) + .expect(200) + .expect(() => { + expect(identitiesServiceMocks.getIdentities).toHaveBeenCalledWith( + expect.any(Object), + expect.any(Array), + [IdentitySortCriteria.validators] + ); + }); + }); + + it('should properly handle multiple sort criteria', async () => { + const mockIdentitiesList = createMockIdentitiesList(5); + identitiesServiceMocks.getIdentities.mockResolvedValue(mockIdentitiesList); + + await request(app.getHttpServer()) + .get(`${path}?sort=validators,locked`) + .expect(200) + .expect(() => { + expect(identitiesServiceMocks.getIdentities).toHaveBeenCalledWith( + expect.any(Object), + expect.any(Array), + [IdentitySortCriteria.validators, IdentitySortCriteria.locked] + ); + }); + }); + + it('should properly handle the stake sort criterion', async () => { + const mockIdentitiesList = createMockIdentitiesList(5); + identitiesServiceMocks.getIdentities.mockResolvedValue(mockIdentitiesList); + + await request(app.getHttpServer()) + .get(`${path}?sort=stake`) + .expect(200) + .expect(() => { + expect(identitiesServiceMocks.getIdentities).toHaveBeenCalledWith( + expect.any(Object), + expect.any(Array), + [IdentitySortCriteria.stake] + ); + }); + }); }); describe("GET /identities/:identifier", () => { diff --git a/src/test/unit/controllers/media.controller.spec.ts b/src/test/unit/controllers/media.controller.spec.ts new file mode 100644 index 000000000..1570042d4 --- /dev/null +++ b/src/test/unit/controllers/media.controller.spec.ts @@ -0,0 +1,55 @@ +import { INestApplication } from "@nestjs/common"; +import { Test } from "@nestjs/testing"; +import request = require('supertest'); +import { MediaController } from "src/endpoints/media/media.controller"; +import { PublicAppModule } from "src/public.app.module"; +import { MediaService } from "src/endpoints/media/media.service"; + +describe('MediaController', () => { + let app: INestApplication; + const path: string = "/media"; + + const mediaService = { + getRedirectUrl: jest.fn(), + }; + + beforeAll(async () => { + const moduleRef = await Test.createTestingModule({ + controllers: [MediaController], + imports: [PublicAppModule], + }) + .overrideProvider(MediaService) + .useValue(mediaService) + .compile(); + + app = moduleRef.createNestApplication(); + await app.init(); + }); + + it(`/GET media/:uri(*)`, async () => { + const mockUrl = 'https://s3.amazonaws.com/media.elrond.com/nfts/thumbnail/XPACHIEVE-5a0519-e302a15d'; + + mediaService.getRedirectUrl.mockResolvedValue(mockUrl); + + await request(app.getHttpServer()) + .get(`${path}/nfts/thumbnail/XPACHIEVE-5a0519-e302a15d`) + .expect(200) + .expect('content-type', 'image/jpeg') + .expect('cache-control', 'max-age=60') + .expect('Access-Control-Allow-Origin', '*'); + + expect(mediaService.getRedirectUrl).toHaveBeenCalled(); + }); + + it(`/GET media/:uri(*) - not found`, async () => { + mediaService.getRedirectUrl.mockResolvedValue(undefined); + + await request(app.getHttpServer()) + .get(`${path}/nfts/thumbnail/XPACHIEVE-5a0519-e302a15d`) + .expect(404); + }); + + afterAll(async () => { + await app.close(); + }); +}); diff --git a/src/test/unit/controllers/network.controller.spec.ts b/src/test/unit/controllers/network.controller.spec.ts index af96f8d30..1629d85c4 100644 --- a/src/test/unit/controllers/network.controller.spec.ts +++ b/src/test/unit/controllers/network.controller.spec.ts @@ -36,6 +36,7 @@ describe("NetworkController", () => { minGasLimit: 50000, minGasPrice: 1000000000, minTransactionVersion: 1, + gasPriceModifier: "0.000000000000000000", }; networkServiceMocks.getConstants.mockResolvedValue(mockConstants); diff --git a/src/test/unit/controllers/scresults.controller.spec.ts b/src/test/unit/controllers/scresults.controller.spec.ts index c2e6bc3e2..5e9e5738f 100644 --- a/src/test/unit/controllers/scresults.controller.spec.ts +++ b/src/test/unit/controllers/scresults.controller.spec.ts @@ -9,11 +9,14 @@ import { SmartContractResultFilter } from "src/endpoints/sc-results/entities/sma import { ConfigModule } from "@nestjs/config"; import { PublicAppModule } from "src/public.app.module"; import { SmartContractResultOptions } from "src/endpoints/sc-results/entities/smart.contract.result.options"; +import { PoolService } from "src/endpoints/pool/pool.service"; +import { mockPoolService } from "./services.mock/pool.services.mock"; describe('CollectionController', () => { let app: INestApplication; const path = '/results'; const scResultsServiceMocks = mockScResultsService(); + const poolServiceMocks = mockPoolService(); beforeEach(async () => { jest.resetAllMocks(); @@ -24,6 +27,7 @@ describe('CollectionController', () => { ], }) .overrideProvider(SmartContractResultService).useValue(scResultsServiceMocks) + .overrideProvider(PoolService).useValue(poolServiceMocks) .compile(); app = moduleFixture.createNestApplication(); diff --git a/src/test/unit/controllers/services.mock/account.services.mock.ts b/src/test/unit/controllers/services.mock/account.services.mock.ts index 954062ae2..df379edfd 100644 --- a/src/test/unit/controllers/services.mock/account.services.mock.ts +++ b/src/test/unit/controllers/services.mock/account.services.mock.ts @@ -75,6 +75,9 @@ export const mockApiConfigService = () => ({ getPoolLimit: jest.fn().mockReturnValue(''), getProcessTtl: jest.fn().mockReturnValue(''), getExternalMediaUrl: jest.fn().mockReturnValue(''), + getMediaUrl: jest.fn().mockReturnValue(''), + isElasticCircuitBreakerEnabled: jest.fn().mockReturnValue(false), + getElasticCircuitBreakerConfig: jest.fn().mockReturnValue({}), getConfig: jest.fn(), }); diff --git a/src/test/unit/controllers/web.socket.publiser.controller.spec.ts b/src/test/unit/controllers/web.socket.publiser.controller.spec.ts index 91fc3bb9c..a9edc0fb1 100644 --- a/src/test/unit/controllers/web.socket.publiser.controller.spec.ts +++ b/src/test/unit/controllers/web.socket.publiser.controller.spec.ts @@ -1,4 +1,4 @@ -import { ShardTransaction } from "@elrondnetwork/transaction-processor"; +import { ShardTransaction } from "@multiversx/sdk-transaction-processor"; import { TestingModule, Test } from "@nestjs/testing"; import { EventEmitter2 } from "@nestjs/event-emitter"; import { WebSocketPublisherController } from "src/common/websockets/web-socket-publisher-controller"; diff --git a/src/test/unit/services/api.config.spec.ts b/src/test/unit/services/api.config.spec.ts index 80dce0ab5..a0c5650d8 100644 --- a/src/test/unit/services/api.config.spec.ts +++ b/src/test/unit/services/api.config.spec.ts @@ -1096,7 +1096,7 @@ describe('API Config', () => { expect(results).toEqual('https://media.elrond.com'); }); - it("should throw error because test simulates that media url is not defined", () => { + it.skip("should throw error because test simulates that media url is not defined", () => { jest .spyOn(ConfigService.prototype, 'get') .mockImplementation(jest.fn(() => undefined)); @@ -1111,7 +1111,7 @@ describe('API Config', () => { .spyOn(ConfigService.prototype, "get") .mockImplementation(jest.fn(() => 'https://media-internal.elrond.com')); - const results = apiConfigService.getMediaUrl(); + const results = apiConfigService.getMediaInternalUrl(); expect(results).toEqual('https://media-internal.elrond.com'); }); diff --git a/src/test/unit/services/blocks.spec.ts b/src/test/unit/services/blocks.spec.ts index 2c65d6a5f..6d6e05587 100644 --- a/src/test/unit/services/blocks.spec.ts +++ b/src/test/unit/services/blocks.spec.ts @@ -9,6 +9,8 @@ import { BlsService } from "src/endpoints/bls/bls.service"; import { IdentitiesService } from "src/endpoints/identities/identities.service"; import { NodeService } from "src/endpoints/nodes/node.service"; import { CacheInfo } from "src/utils/cache.info"; +import { BlockProofDto } from "../../../endpoints/blocks/entities/block.proof"; +import { ApiConfigService } from "../../../common/api-config/api.config.service"; describe('Block Service', () => { let blockService: BlockService; @@ -56,6 +58,13 @@ describe('Block Service', () => { getIdentity: jest.fn(), }, }, + { + provide: ApiConfigService, + useValue: { + isChainAndromedaEnabled: jest.fn(), + getChainAndromedaActivationEpoch: jest.fn(), + }, + }, ], }).compile(); @@ -128,6 +137,15 @@ describe('Block Service', () => { gasPenalized: 0, maxGasLimit: 15000000000, scheduledRootHash: undefined, + proof: undefined, + previousHeaderProof: new BlockProofDto({ + pubKeysBitmap: '7702', + aggregatedSignature: '50224d66a42a019991d16f25dba375b581f279d4394d4c254876c1484f61bed90fb20456f8af107c54e4eed1763e2a92', + headerHash: '414d526161587ae9f53453aa0392971272c48dbb3cc54a33448972d388e0deeb', + headerEpoch: 100, + headerRound: 12500, + headerNonce: 10500, + }), }; it('should call cachingService.getOrSet with the correct arguments and return the result', async () => { @@ -173,7 +191,7 @@ describe('Block Service', () => { ); }); - it('should retur current epoch', async () => { + it('should return current epoch', async () => { blockService.getBlocks = jest.fn().mockResolvedValue([block]); const result = await blockService.getCurrentEpoch(); diff --git a/src/test/unit/services/media.spec.ts b/src/test/unit/services/media.spec.ts new file mode 100644 index 000000000..da602aeae --- /dev/null +++ b/src/test/unit/services/media.spec.ts @@ -0,0 +1,135 @@ +import { ApiService } from "@multiversx/sdk-nestjs-http"; +import { Test } from "@nestjs/testing"; +import { ApiConfigService } from "src/common/api-config/api.config.service"; +import { MediaService } from "src/endpoints/media/media.service"; + +describe('MediaService', () => { + let mediaService: MediaService; + let apiConfigService: ApiConfigService; + let apiService: ApiService; + + beforeEach(async () => { + const moduleRef = await Test.createTestingModule({ + providers: [ + MediaService, + { + provide: ApiConfigService, + useValue: { + getNetwork: jest.fn(), + isMediaRedirectFeatureEnabled: jest.fn(), + getMediaRedirectFileStorageUrls: jest.fn(), + }, + }, + { + provide: ApiService, + useValue: { + head: jest.fn(), + }, + }, + ], + }).compile(); + + mediaService = moduleRef.get(MediaService); + apiConfigService = moduleRef.get(ApiConfigService); + apiService = moduleRef.get(ApiService); + }); + + describe('redirectToMediaUri', () => { + it.skip('should throw BadRequestException when media redirect feature is disabled', async () => { + jest.spyOn(apiConfigService, 'isMediaRedirectFeatureEnabled').mockReturnValueOnce(false); + + await expect(mediaService.getRedirectUrl('url')).rejects.toThrowError('Media redirect is not allowed'); + }); + + it('should return redirect url for providers logos', async () => { + jest.spyOn(apiConfigService, 'isMediaRedirectFeatureEnabled').mockReturnValueOnce(true); + + const uri = 'providers/asset/test.png'; + const expectedUri = 'keybase_processed_uploads/test.png'; + const expectedUrl = `https://s3.amazonaws.com/${expectedUri}`; + + const result = await mediaService.getRedirectUrl(uri); + + expect(result).toBe(expectedUrl); + }); + + it('should return redirect url for tokens logos', async () => { + jest.spyOn(apiConfigService, 'isMediaRedirectFeatureEnabled').mockReturnValueOnce(true); + + const network = 'devnet'; + jest.spyOn(apiConfigService, 'getNetwork').mockReturnValueOnce(network); + + const uri = 'tokens/asset/test.png'; + const expectedUri = `multiversx/mx-assets/master/${network}/tokens/test.png`; + const expectedUrl = `https://raw.githubusercontent.com/${expectedUri}`; + + const result = await mediaService.getRedirectUrl(uri); + + expect(result).toBe(expectedUrl); + }); + + it('should return redirect url for tokens logos on mainnet', async () => { + jest.spyOn(apiConfigService, 'isMediaRedirectFeatureEnabled').mockReturnValueOnce(true); + jest.spyOn(apiConfigService, 'getNetwork').mockReturnValueOnce('mainnet'); + + const uri = 'tokens/asset/test.png'; + const expectedUri = `multiversx/mx-assets/master/tokens/test.png`; + const expectedUrl = `https://raw.githubusercontent.com/${expectedUri}`; + + const result = await mediaService.getRedirectUrl(uri); + + expect(result).toBe(expectedUrl); + }); + + it('should return redirect url to storage urls', async () => { + jest.spyOn(apiConfigService, 'isMediaRedirectFeatureEnabled').mockReturnValueOnce(true); + jest.spyOn(apiConfigService, 'getMediaRedirectFileStorageUrls').mockReturnValueOnce(['https://s3.amazonaws.com']); + jest.spyOn(apiService, 'head').mockResolvedValueOnce({ status: 200 }); + + const uri = 'test.png'; + const expectedUrl = `https://s3.amazonaws.com/${uri}`; + + const result = await mediaService.getRedirectUrl(uri); + + expect(result).toBe(expectedUrl); + }); + + it('should return undefined when not found in file storage urls', async () => { + jest.spyOn(apiConfigService, 'isMediaRedirectFeatureEnabled').mockReturnValueOnce(true); + jest.spyOn(apiConfigService, 'getMediaRedirectFileStorageUrls').mockReturnValueOnce(['https://s3.amazonaws.com']); + jest.spyOn(apiService, 'head').mockResolvedValueOnce({ status: 404 }); + + const uri = 'test.png'; + + const result = await mediaService.getRedirectUrl(uri); + + expect(result).toBeUndefined(); + }); + + it('should return redirect url for nfts assets', async () => { + jest.spyOn(apiConfigService, 'isMediaRedirectFeatureEnabled').mockReturnValueOnce(true); + jest.spyOn(apiConfigService, 'getMediaRedirectFileStorageUrls').mockReturnValueOnce([]); + + const uri = 'nfts/asset/test.png'; + const expectedUri = `ipfs/test.png`; + const expectedUrl = `https://ipfs.io/${expectedUri}`; + + const result = await mediaService.getRedirectUrl(uri); + + expect(result).toBe(expectedUrl); + }); + + it('should return redirect to fallback thumbnail if not found in file storage urls', async () => { + jest.spyOn(apiConfigService, 'isMediaRedirectFeatureEnabled').mockReturnValueOnce(true); + jest.spyOn(apiConfigService, 'getMediaRedirectFileStorageUrls').mockReturnValueOnce(['https://s3.amazonaws.com']); + jest.spyOn(apiService, 'head').mockResolvedValueOnce({ status: 404 }); + + const uri = 'nfts/thumbnail/random'; + const expectedUrl = `https://s3.amazonaws.com/nfts/thumbnail/default.png`; + + const result = await mediaService.getRedirectUrl(uri); + + expect(result).toBe(expectedUrl); + }); + }); +}); diff --git a/src/test/unit/services/mex.token.charts.spec.ts b/src/test/unit/services/mex.token.charts.spec.ts index 2c41bc2cc..1f18810cf 100644 --- a/src/test/unit/services/mex.token.charts.spec.ts +++ b/src/test/unit/services/mex.token.charts.spec.ts @@ -94,7 +94,7 @@ describe('MexTokenChartsService', () => { jest.spyOn(mexTokenService, 'getMexTokenByIdentifier').mockResolvedValue(mockToken); jest.spyOn(mexTokenChartsService as any, 'isMexToken').mockReturnValue(true); - const result = await mexTokenChartsService.getTokenPricesDayResolutionRaw('TOKEN-123456', '1683561648'); + const result = await mexTokenChartsService.getTokenPricesDayResolutionRaw('TOKEN-123456'); if (result) { expect(result).toHaveLength(2); @@ -107,7 +107,7 @@ describe('MexTokenChartsService', () => { it('should return an empty array when no data is available', async () => { jest.spyOn(graphQlService, 'getExchangeServiceData').mockResolvedValue({}); jest.spyOn(mexTokenChartsService as any, 'isMexToken').mockReturnValue(true); - const result = await mexTokenChartsService.getTokenPricesDayResolutionRaw('TOKEN-123456', '1683561648'); + const result = await mexTokenChartsService.getTokenPricesDayResolutionRaw('TOKEN-123456'); expect(result).toEqual([]); }); diff --git a/src/test/unit/services/rounds.spec.ts b/src/test/unit/services/rounds.spec.ts index ee328eeeb..755c8fbbf 100644 --- a/src/test/unit/services/rounds.spec.ts +++ b/src/test/unit/services/rounds.spec.ts @@ -5,10 +5,14 @@ import { BlsService } from "src/endpoints/bls/bls.service"; import { RoundDetailed } from "src/endpoints/rounds/entities/round.detailed"; import { RoundFilter } from "src/endpoints/rounds/entities/round.filter"; import { RoundService } from "src/endpoints/rounds/round.service"; +import { ApiConfigService } from "../../../common/api-config/api.config.service"; +import { BlockService } from "../../../endpoints/blocks/block.service"; describe('RoundService', () => { let roundService: RoundService; let indexerService: IndexerService; + let blockService: BlockService; + let apiConfigService: ApiConfigService; beforeEach(async () => { const moduleRef = await Test.createTestingModule({ @@ -28,12 +32,26 @@ describe('RoundService', () => { getPublicKeys: jest.fn(), }, }, - + { + provide: ApiConfigService, + useValue: { + isChainAndromedaEnabled: jest.fn(), + getChainAndromedaActivationEpoch: jest.fn(), + }, + }, + { + provide: BlockService, + useValue: { + getCurrentEpoch: jest.fn(), + }, + }, ], }).compile(); roundService = moduleRef.get(RoundService); indexerService = moduleRef.get(IndexerService); + blockService = moduleRef.get(BlockService); + apiConfigService = moduleRef.get(ApiConfigService); }); describe('getRoundCount', () => { @@ -97,6 +115,74 @@ describe('RoundService', () => { expect(indexerService.getRounds).toHaveBeenCalledWith(filter); expect(result).toEqual(expectedRounds); }); + + it('should remove validator filter if Andromeda is active', async () => { + const filter = new RoundFilter(); + filter.shard = 0; + filter.validator = 'should not exist'; + + jest.spyOn(blockService, 'getCurrentEpoch').mockResolvedValue(10); + jest.spyOn(apiConfigService, 'isChainAndromedaEnabled').mockReturnValue(true); + jest.spyOn(apiConfigService, 'getChainAndromedaActivationEpoch').mockReturnValue(9); + + const indexerRoundsMock: Round[] = [ + { + round: 1, + signersIndexes: [], + blockWasProposed: true, + shardId: 0, + epoch: 0, + timestamp: 1596117606, + }, + { + round: 1, + signersIndexes: [], + blockWasProposed: true, + shardId: 0, + epoch: 0, + timestamp: 1596117116, + }, + ]; + jest.spyOn(indexerService, 'getRounds').mockResolvedValue(indexerRoundsMock); + + await roundService.getRounds(filter); + + expect(indexerService.getRounds).toHaveBeenCalledWith(new RoundFilter({ shard: 0, validator: undefined })); + }); + + it('should keep validator filter if Andromeda is active', async () => { + const filter = new RoundFilter(); + filter.shard = 0; + filter.validator = 'should exist'; + + jest.spyOn(blockService, 'getCurrentEpoch').mockResolvedValue(10); + jest.spyOn(apiConfigService, 'isChainAndromedaEnabled').mockReturnValue(true); + jest.spyOn(apiConfigService, 'getChainAndromedaActivationEpoch').mockReturnValue(11); + + const indexerRoundsMock: Round[] = [ + { + round: 1, + signersIndexes: [], + blockWasProposed: true, + shardId: 0, + epoch: 0, + timestamp: 1596117606, + }, + { + round: 1, + signersIndexes: [], + blockWasProposed: true, + shardId: 0, + epoch: 0, + timestamp: 1596117116, + }, + ]; + jest.spyOn(indexerService, 'getRounds').mockResolvedValue(indexerRoundsMock); + + await roundService.getRounds(filter); + + expect(indexerService.getRounds).toHaveBeenCalledWith(new RoundFilter({ shard: 0, validator: 'should exist' })); + }); }); describe('getRound', () => { @@ -113,14 +199,14 @@ describe('RoundService', () => { }; const expectedRound: RoundDetailed = - { - round: 10, - signers: [], - blockWasProposed: true, - shard: 0, - epoch: 0, - timestamp: 1596117606, - }; + { + round: 10, + signers: [], + blockWasProposed: true, + shard: 0, + epoch: 0, + timestamp: 1596117606, + }; jest.spyOn(indexerService, 'getRound').mockResolvedValue(indexerRoundMock); diff --git a/src/test/unit/services/tokens.spec.ts b/src/test/unit/services/tokens.spec.ts index f025eaddb..064939059 100644 --- a/src/test/unit/services/tokens.spec.ts +++ b/src/test/unit/services/tokens.spec.ts @@ -31,6 +31,7 @@ import { NftCollection } from "src/endpoints/collections/entities/nft.collection import { EsdtSupply } from "src/endpoints/esdt/entities/esdt.supply"; import { TokenDetailed } from "src/endpoints/tokens/entities/token.detailed"; import { NumberUtils } from "@multiversx/sdk-nestjs-common"; +import { TokenAssetsPriceSourceType } from "../../../common/assets/entities/token.assets.price.source.type"; describe('Token Service', () => { let tokenService: TokenService; @@ -592,6 +593,25 @@ describe('Token Service', () => { expect(result).toBeGreaterThanOrEqual(261151384.6163954); expect(getAllTokensMock).toHaveBeenCalledTimes(1); }); + + it('should not include custom priced tokens in market cap', async () => { + const mockTokens = JSON.parse(fs.readFileSync(path.join(__dirname, '../../mocks/tokens.mock.json'), 'utf-8')); + const getAllTokensMock = jest.spyOn(tokenService, 'getAllTokens').mockResolvedValue(mockTokens); + + const result = await tokenService.getTokenMarketCapRaw(); + expect(result).toBeGreaterThanOrEqual(261151384.6163954); + expect(getAllTokensMock).toHaveBeenCalledTimes(1); + + const secondToken = mockTokens[1]; + secondToken.assets.priceSource = {type: 'customUrl'}; + const newExpectedMarketCap = result - secondToken.marketCap; + mockTokens[1] = secondToken; + + jest.spyOn(tokenService, 'getAllTokens').mockResolvedValue(mockTokens); + + const newResult = await tokenService.getTokenMarketCapRaw(); + expect(newResult).toBe(newExpectedMarketCap); + }); }); describe('getAllTokens', () => { @@ -787,6 +807,109 @@ describe('Token Service', () => { }); }); + it('adjusts the order depending on the price source and market cap', async () => { + jest.spyOn(tokenService['apiConfigService'], 'isTokensFetchFeatureEnabled').mockReturnValue(false); + jest.spyOn(tokenService['esdtService'], 'getAllFungibleTokenProperties').mockResolvedValue([ + new TokenProperties({ identifier: 'token1' }), + new TokenProperties({ identifier: 'token2' }), // <- will have custom price source + new TokenProperties({ identifier: 'token3' }), + new TokenProperties({ identifier: 'token4' }), + new TokenProperties({ identifier: 'token5' }), + ]); + + // Only token2 has a custom price source + // eslint-disable-next-line require-await + jest.spyOn(tokenService['assetsService'], 'getTokenAssets').mockImplementation(async (identifier: string) => { + if (identifier === 'token2') { + return new TokenAssets({ + name: `Token ${identifier}`, + priceSource: { + type: TokenAssetsPriceSourceType.customUrl, + path: '0.usdPrice', + url: 'url', + }, + }); + } + return new TokenAssets({ + name: `Token ${identifier}`, + // No priceSource + }); + }); + + jest.spyOn(tokenService['collectionService'], 'getNftCollections').mockResolvedValue([]); + + jest.spyOn(tokenService['dataApiService'], 'getEgldPrice').mockResolvedValue(0); + jest.spyOn(tokenService['dataApiService'], 'getEsdtTokenPrice').mockResolvedValue(1); + jest.spyOn(tokenService['esdtService'], 'getTokenSupply').mockResolvedValue({ + minted: '1000000', + initialMinted: '1000000', + burned: '0', + totalSupply: '1000000', + circulatingSupply: '1000000', + lockedAccounts: undefined, + }); + + // Fake other dependencies + jest.spyOn(tokenService as any, 'applyMexLiquidity').mockResolvedValue(undefined); + jest.spyOn(tokenService as any, 'applyMexPrices').mockResolvedValue(undefined); + jest.spyOn(tokenService as any, 'applyMexPairType').mockResolvedValue(undefined); + jest.spyOn(tokenService as any, 'applyMexPairTradesCount').mockResolvedValue(undefined); + jest.spyOn(tokenService['apiService'] as any, 'get').mockResolvedValue({data: [{usdPrice: 1.0}]}); + jest.spyOn(tokenService['cachingService'], 'batchApplyAll').mockImplementation( + // eslint-disable-next-line require-await + async (...args: unknown[]) => { + const tokens = args[0] as TokenDetailed[]; + const apply = args[3] as (token: TokenDetailed, assets: TokenAssets, fromGetter: boolean) => void; + + for (const token of tokens) { + if (token.identifier === 'token2') { + apply(token, new TokenAssets({ + name: `Token ${token.identifier}`, + priceSource: { + type: TokenAssetsPriceSourceType.customUrl, + path: '0.usdPrice', + url: 'url', + }, + }), true); + } else { + apply(token, new TokenAssets({ + name: `Token ${token.identifier}`, + // No priceSource + }), true); + } + } + } + ); + + // eslint-disable-next-line require-await + jest.spyOn(tokenService as any, 'batchProcessTokens').mockImplementation(async (tokens: any) => { + const marketCaps = { + token1: 500, + token2: 400, + token3: 300, + token4: 200, + token5: 100, + }; + for (const [index, token] of tokens.entries()) { + token.decimals = 18; + token.isLowLiquidity = false; + token.transactions = 10; + if (index === 3) { + continue; // make one of the tokens (token4) not to have any price or market cap at all + } + // @ts-ignore + token.marketCap = marketCaps[token.identifier]; + token.price = 1; + } + }); + + const result = await tokenService.getAllTokensRaw(); + const sortedIdentifiers = result.map(t => t.identifier); + + // token2 has custom price source, token4 does not have price/market cap at all + expect(sortedIdentifiers.slice(0, 5)).toEqual(['token5', 'token3', 'token1', 'token2', 'token4']); + }); + it('should return values from cache', async () => { const cachedValueMock = jest.spyOn(tokenService['cachingService'], 'getOrSet').mockResolvedValue(mockTokens); diff --git a/src/test/unit/services/transactions.spec.ts b/src/test/unit/services/transactions.spec.ts index 996ae2808..f943a2637 100644 --- a/src/test/unit/services/transactions.spec.ts +++ b/src/test/unit/services/transactions.spec.ts @@ -9,6 +9,9 @@ import { Transaction } from "src/common/indexer/entities/transaction"; import { IndexerService } from "src/common/indexer/indexer.service"; import { PluginService } from "src/common/plugins/plugin.service"; import { ProtocolService } from "src/common/protocol/protocol.service"; +import { BlockService } from "src/endpoints/blocks/block.service"; +import { NetworkService } from "src/endpoints/network/network.service"; +import { PoolService } from "src/endpoints/pool/pool.service"; import { TokenTransferService } from "src/endpoints/tokens/token.transfer.service"; import { TransactionFilter } from "src/endpoints/transactions/entities/transaction.filter"; import { TransactionActionService } from "src/endpoints/transactions/transaction-action/transaction.action.service"; @@ -110,6 +113,25 @@ describe('TransactionService', () => { getShardCount: jest.fn(), }, }, + { + provide: BlockService, + useValue: { + getBlockByHash: jest.fn(), + }, + }, + { + provide: PoolService, + useValue: { + getPool: jest.fn(), + }, + }, + { + provide: NetworkService, + useValue: { + getConstants: jest.fn(), + }, + }, + ], }).compile(); diff --git a/src/test/unit/services/username.spec.ts b/src/test/unit/services/username.spec.ts index 941f06efe..e350b3d32 100644 --- a/src/test/unit/services/username.spec.ts +++ b/src/test/unit/services/username.spec.ts @@ -93,6 +93,8 @@ describe('UsernameService', () => { const address = 'erd1qga7ze0l03chfgru0a32wxqf2226nzrxnyhzer9lmudqhjgy7ycqjjyknz'; const cachedUsername = 'alice'; + // @ts-ignore + jest.spyOn(service["apiConfigService"], "getMaiarIdUrl").mockReturnValue("https://id-api.com"); const cachingServiceSpy = jest.spyOn(service['cachingService'], 'getOrSet').mockResolvedValue(cachedUsername); const result = await service.getUsernameForAddress(address); @@ -103,6 +105,8 @@ describe('UsernameService', () => { it('should return null if getUsernameForAddressRaw fails', async () => { const address = 'erd1Invalid'; + // @ts-ignore + jest.spyOn(service["apiConfigService"], "getMaiarIdUrl").mockReturnValue("https://id-api.com"); const cachingServiceSpy = jest.spyOn(service['cachingService'], 'getOrSet').mockResolvedValue(null); jest.spyOn(service, 'getUsernameForAddressRaw').mockRejectedValue(new Error('Failed to get username')); @@ -114,6 +118,8 @@ describe('UsernameService', () => { it('should return null when getUsernameForAddressRaw returns null', async () => { const address = 'erd1qga7ze0l03chfgru0a32wxqf2226nzrxnyhzer9lmudqhjgy7ycqjjyknz'; + // @ts-ignore + jest.spyOn(service["apiConfigService"], "getMaiarIdUrl").mockReturnValue("https://id-api.com"); const getUsernameForAddressRawMock = jest.spyOn(service as any, 'getUsernameForAddressRaw').mockResolvedValue(null); const cachingServiceSpy = jest.spyOn(service['cachingService'], 'getOrSet').mockImplementation((_key, func) => func()); @@ -123,6 +129,26 @@ describe('UsernameService', () => { expect(cachingServiceSpy).toHaveBeenCalledWith(expect.any(String), expect.any(Function), CacheInfo.Username(address).ttl); expect(result).toBeNull(); }); + + it('should return null if ID api is empty', async () => { + const address = 'erd1qga7ze0l03chfgru0a32wxqf2226nzrxnyhzer9lmudqhjgy7ycqjjyknz1'; + + // @ts-ignore + jest.spyOn(service["apiConfigService"], "getMaiarIdUrl").mockReturnValue(""); + + const result = await service.getUsernameForAddress(address); + expect(result).toBeNull(); + }); + + it('should return null if ID api is undefined', async () => { + const address = 'erd1qga7ze0l03chfgru0a32wxqf2226nzrxnyhzer9lmudqhjgy7ycqjjyknz1'; + + // @ts-ignore + jest.spyOn(service["apiConfigService"], "getMaiarIdUrl").mockReturnValue(undefined); + + const result = await service.getUsernameForAddress(address); + expect(result).toBeNull(); + }); }); describe('getAddressForUsername', () => { diff --git a/src/test/unit/utils/circuit.breaker.proxy.spec.ts b/src/test/unit/utils/circuit.breaker.proxy.spec.ts new file mode 100644 index 000000000..e92d88f1d --- /dev/null +++ b/src/test/unit/utils/circuit.breaker.proxy.spec.ts @@ -0,0 +1,316 @@ +import { ElasticService } from "@multiversx/sdk-nestjs-elastic"; +import { ApiConfigService } from "src/common/api-config/api.config.service"; +import { ElasticQuery } from "@multiversx/sdk-nestjs-elastic"; +import { EsCircuitBreakerProxy } from "../../../common/indexer/elastic/circuit-breaker/circuit.breaker.proxy.service"; + +describe('EsCircuitBreakerProxy', () => { + let proxy: EsCircuitBreakerProxy; + let mockElasticService: jest.Mocked; + let mockApiConfigService: jest.Mocked; + + const defaultConfig = { + durationThresholdMs: 1000, + failureCountThreshold: 2, + resetTimeoutMs: 2000, + }; + + beforeEach(() => { + mockElasticService = { + getCount: jest.fn(), + getList: jest.fn(), + getItem: jest.fn(), + getCustomValue: jest.fn(), + setCustomValue: jest.fn(), + setCustomValues: jest.fn(), + getScrollableList: jest.fn(), + get: jest.fn(), + post: jest.fn(), + } as any; + + mockApiConfigService = { + getElasticUrl: jest.fn().mockReturnValue('http://localhost:9200'), + isElasticCircuitBreakerEnabled: jest.fn().mockReturnValue(true), + getElasticCircuitBreakerConfig: jest.fn().mockReturnValue(defaultConfig), + } as any; + + proxy = new EsCircuitBreakerProxy(mockApiConfigService, mockElasticService); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + describe('Circuit Breaker State Management', () => { + it('should start with closed circuit', () => { + expect(proxy['isCircuitOpen']).toBe(false); + expect(proxy['failureCount']).toBe(0); + }); + + it('should open circuit after reaching failure threshold', async () => { + const failureThreshold = 2; + mockApiConfigService.getElasticCircuitBreakerConfig.mockReturnValue({ + ...defaultConfig, + failureCountThreshold: failureThreshold, + }); + + mockElasticService.getCount.mockRejectedValue(new Error('Service unavailable')); + + for (let i = 0; i < failureThreshold; i++) { + try { + await proxy.getCount('test', new ElasticQuery()); + } catch (error) { + // Expected error + } + } + + expect(proxy['isCircuitOpen']).toBe(true); + expect(proxy['failureCount']).toBe(failureThreshold); + + await expect(proxy.getCount('test', new ElasticQuery())) + .rejects + .toThrow('Service Unavailable'); + }); + + it('should reject requests when circuit is open', async () => { + proxy['isCircuitOpen'] = true; + proxy['lastFailureTime'] = Date.now(); + + await expect(proxy.getCount('test', new ElasticQuery())) + .rejects + .toThrow('Service Unavailable'); + }); + + it('should attempt to reset circuit after reset timeout', async () => { + const resetTimeout = 1000; + mockApiConfigService.getElasticCircuitBreakerConfig.mockReturnValue({ + ...defaultConfig, + resetTimeoutMs: resetTimeout, + }); + + // Force circuit to open and set last failure time to be older than reset timeout + proxy['isCircuitOpen'] = true; + proxy['lastFailureTime'] = Date.now() - (resetTimeout + 1000); + proxy['failureCount'] = 2; // Set failure count to simulate previous failures + + // Mock a successful response + mockElasticService.getCount.mockResolvedValue(10); + + // The circuit should be reset and the request should succeed + const result = await proxy.getCount('test', new ElasticQuery()); + expect(result).toBe(10); + expect(proxy['isCircuitOpen']).toBe(false); + expect(proxy['failureCount']).toBe(0); + }); + }); + + describe('Timeout Handling', () => { + it('should timeout requests that take too long', async () => { + const timeout = 500; + mockApiConfigService.getElasticCircuitBreakerConfig.mockReturnValue({ + ...defaultConfig, + durationThresholdMs: timeout, + }); + + mockElasticService.getCount.mockImplementation(() => + new Promise(() => { }) + ); + + await expect(Promise.race([ + proxy.getCount('test', new ElasticQuery()), + new Promise((_, reject) => setTimeout(() => reject(new Error('Operation timed out')), timeout + 100)), + ])).rejects.toThrow('Operation timed out'); + }); + + it('should complete requests within timeout', async () => { + const timeout = 500; + mockApiConfigService.getElasticCircuitBreakerConfig.mockReturnValue({ + ...defaultConfig, + durationThresholdMs: timeout, + }); + + mockElasticService.getCount.mockImplementation(() => + new Promise(resolve => setTimeout(() => resolve(10), timeout - 100)) + ); + + const result = await proxy.getCount('test', new ElasticQuery()); + expect(result).toBe(10); + }); + }); + + describe('Method Proxying', () => { + it('should proxy getCount calls', async () => { + mockElasticService.getCount.mockResolvedValue(10); + const query = new ElasticQuery(); + + const result = await proxy.getCount('test', query); + expect(result).toBe(10); + expect(mockElasticService.getCount).toHaveBeenCalledWith('test', query); + }); + + it('should proxy getList calls', async () => { + const mockData = [{ id: 1 }, { id: 2 }]; + mockElasticService.getList.mockResolvedValue(mockData); + const query = new ElasticQuery(); + + const result = await proxy.getList('test', 'id', query); + expect(result).toEqual(mockData); + expect(mockElasticService.getList).toHaveBeenCalledWith('test', 'id', query); + }); + + it('should proxy getItem calls', async () => { + const mockItem = { id: 1, name: 'test' }; + mockElasticService.getItem.mockResolvedValue(mockItem); + + const result = await proxy.getItem('test', 'id', '1'); + expect(result).toEqual(mockItem); + expect(mockElasticService.getItem).toHaveBeenCalledWith('test', 'id', '1'); + }); + + it('should proxy getCustomValue calls', async () => { + const mockValue = { key: 'value' }; + mockElasticService.getCustomValue.mockResolvedValue(mockValue); + + const result = await proxy.getCustomValue('test', 'id', 'key'); + expect(result).toEqual(mockValue); + expect(mockElasticService.getCustomValue).toHaveBeenCalledWith('test', 'id', 'key'); + }); + + it('should proxy setCustomValue calls', async () => { + mockElasticService.setCustomValue.mockResolvedValue(undefined); + + await proxy.setCustomValue('test', 'id', 'key', 'value'); + expect(mockElasticService.setCustomValue).toHaveBeenCalledWith('test', 'id', 'key', 'value'); + }); + + it('should proxy setCustomValues calls', async () => { + mockElasticService.setCustomValues.mockResolvedValue(undefined); + const values = { key1: 'value1', key2: 'value2' }; + + await proxy.setCustomValues('test', 'id', values); + expect(mockElasticService.setCustomValues).toHaveBeenCalledWith('test', 'id', values); + }); + + it('should proxy getScrollableList calls', async () => { + const mockAction = jest.fn(); + mockElasticService.getScrollableList.mockResolvedValue(undefined); + const query = new ElasticQuery(); + + await proxy.getScrollableList('test', 'id', query, mockAction); + expect(mockElasticService.getScrollableList).toHaveBeenCalledWith('test', 'id', query, mockAction); + }); + + it('should proxy get calls', async () => { + const mockResponse = { data: 'test' }; + mockElasticService.get.mockResolvedValue(mockResponse); + + const result = await proxy.get('test'); + expect(result).toEqual(mockResponse); + expect(mockElasticService.get).toHaveBeenCalledWith('test'); + }); + + it('should proxy post calls', async () => { + const mockResponse = { data: 'test' }; + mockElasticService.post.mockResolvedValue(mockResponse); + const data = { key: 'value' }; + + const result = await proxy.post('test', data); + expect(result).toEqual(mockResponse); + expect(mockElasticService.post).toHaveBeenCalledWith('test', data); + }); + }); + + describe('Error Handling', () => { + it('should handle and propagate errors', async () => { + const error = new Error('Test error'); + mockElasticService.getCount.mockRejectedValue(error); + + await expect(proxy.getCount('test', new ElasticQuery())) + .rejects + .toThrow('Service Unavailable'); + }); + + it('should increment failure count on errors', async () => { + mockElasticService.getCount.mockRejectedValue(new Error('Test error')); + + try { + await proxy.getCount('test', new ElasticQuery()); + } catch (error) { + // Expected error + } + + expect(proxy['failureCount']).toBe(1); + }); + + it('should reset failure count on successful request', async () => { + mockElasticService.getCount.mockRejectedValueOnce(new Error('Test error')); + try { + await proxy.getCount('test', new ElasticQuery()); + } catch (error) { + // Expected error + } + + mockElasticService.getCount.mockResolvedValueOnce(10); + await proxy.getCount('test', new ElasticQuery()); + + expect(proxy['failureCount']).toBe(0); + }); + }); + + describe('Configuration Updates', () => { + it('should use updated timeout value', async () => { + const newTimeout = 500; + mockApiConfigService.getElasticCircuitBreakerConfig.mockReturnValue({ + ...defaultConfig, + durationThresholdMs: newTimeout, + }); + + mockElasticService.getCount.mockImplementation(() => + new Promise(resolve => setTimeout(() => resolve(10), newTimeout - 100)) + ); + + const result = await proxy.getCount('test', new ElasticQuery()); + expect(result).toBe(10); + }); + + it('should use updated failure threshold', async () => { + const newThreshold = 1; + mockApiConfigService.getElasticCircuitBreakerConfig.mockReturnValue({ + ...defaultConfig, + failureCountThreshold: newThreshold, + }); + mockElasticService.getCount.mockRejectedValue(new Error('Service unavailable')); + + for (let i = 0; i < newThreshold; i++) { + try { + await proxy.getCount('test', new ElasticQuery()); + } catch (error) { + // Expected error + } + } + + expect(proxy['failureCount']).toBe(newThreshold); + }); + + it('should use updated reset timeout', async () => { + const newResetTimeout = 1000; + mockApiConfigService.getElasticCircuitBreakerConfig.mockReturnValue({ + ...defaultConfig, + resetTimeoutMs: newResetTimeout, + }); + + // Force circuit to open and set last failure time to be older than reset timeout + proxy['isCircuitOpen'] = true; + proxy['lastFailureTime'] = Date.now() - (newResetTimeout + 1000); + proxy['failureCount'] = 2; // Set failure count to simulate previous failures + + // Mock a successful response + mockElasticService.getCount.mockResolvedValue(10); + + // The circuit should be reset and the request should succeed + const result = await proxy.getCount('test', new ElasticQuery()); + expect(result).toBe(10); + expect(proxy['isCircuitOpen']).toBe(false); + expect(proxy['failureCount']).toBe(0); + }); + }); +}); diff --git a/src/test/unit/utils/transaction.utils.spec.ts b/src/test/unit/utils/transaction.utils.spec.ts index 45f131a38..3421f495e 100644 --- a/src/test/unit/utils/transaction.utils.spec.ts +++ b/src/test/unit/utils/transaction.utils.spec.ts @@ -1,4 +1,4 @@ -import { ShardTransaction } from "@elrondnetwork/transaction-processor"; +import { ShardTransaction } from "@multiversx/sdk-transaction-processor"; import { TransferOwnershipExtractor } from "src/crons/transaction.processor/extractor/transfer.ownership.extractor"; import { NftCreateTransactionExtractor } from "src/crons/transaction.processor/extractor/nft.create.transaction.extractor"; import { NftUpdateAttributesTransactionExtractor } from "src/crons/transaction.processor/extractor/nft.update.attributes.transaction.extractor"; diff --git a/src/utils/cache.info.ts b/src/utils/cache.info.ts index 7af510671..6ca7e69ac 100644 --- a/src/utils/cache.info.ts +++ b/src/utils/cache.info.ts @@ -162,9 +162,9 @@ export class CacheInfo { }; } - static TokenDailyChart(tokenIdentifier: string, after: string): CacheInfo { + static TokenDailyChart(tokenIdentifier: string): CacheInfo { return { - key: `tokenDailyChart:${tokenIdentifier}:${after}`, + key: `tokenDailyChart:${tokenIdentifier}`, ttl: Constants.oneDay(), }; } @@ -638,11 +638,7 @@ export class CacheInfo { const isCurrentDate = priceDate.toISODateString() === new Date().toISODateString(); const ttl = isCurrentDate ? Constants.oneMinute() * 5 : Constants.oneWeek(); - let key = priceDate.toISODateString(); - if (!isCurrentDate) { - key = priceDate.startOfDay().addDays(1).toISODateString(); - } - + const key = priceDate.toISODateString(); return { key: `data-api:price:${identifier}:${key}`, ttl, @@ -707,4 +703,11 @@ export class CacheInfo { ttl: Constants.oneMinute() * 10, }; } + + static PpuMetadataByShard(shardId: number): CacheInfo { + return { + key: `ppuMetadata:shard:${shardId}`, + ttl: Constants.oneSecond() * 30, + }; + } } diff --git a/src/utils/token.helpers.ts b/src/utils/token.helpers.ts index 39c2c8086..e55f7e6c9 100644 --- a/src/utils/token.helpers.ts +++ b/src/utils/token.helpers.ts @@ -5,7 +5,7 @@ import { CollectionRoles } from "src/endpoints/tokens/entities/collection.roles" import { TokenRoles } from "src/endpoints/tokens/entities/token.roles"; import { ApiUtils } from '@multiversx/sdk-nestjs-http'; import '@multiversx/sdk-nestjs-common/lib/utils/extensions/string.extensions'; -import { TokenUtils } from "@multiversx/sdk-nestjs-common"; +import { TokenUtils, BinaryUtils } from "@multiversx/sdk-nestjs-common"; export class TokenHelpers { static canBool(string: string) { @@ -100,4 +100,17 @@ export class TokenHelpers { static getCollectionIdentifier(nftIdentifier: string): string { return nftIdentifier.split('-').slice(0, 2).join('-'); } + + static getNftProof(hash: string): string | undefined { + if (!hash) { + return undefined; + } + + const decodedHex = BinaryUtils.base64Decode(hash); + if (decodedHex.startsWith('proof:')) { + return decodedHex; + } else { + return hash; + } + } } From 57ca7eee6acc482ac39ff629a01ff9a4eb8f86b3 Mon Sep 17 00:00:00 2001 From: Gabriel Matei Date: Tue, 13 May 2025 15:24:31 +0300 Subject: [PATCH 18/25] fixes --- src/endpoints/nfts/nft.service.ts | 4 ++++ .../nft.worker/queue/job-services/thumbnails/aws.service.ts | 1 + 2 files changed, 5 insertions(+) diff --git a/src/endpoints/nfts/nft.service.ts b/src/endpoints/nfts/nft.service.ts index 3d4dd476e..2cab3f75e 100644 --- a/src/endpoints/nfts/nft.service.ts +++ b/src/endpoints/nfts/nft.service.ts @@ -333,7 +333,11 @@ export class NftService { const nft = new Nft(); nft.identifier = elasticNft.identifier; nft.collection = elasticNft.token; + nft.nonce = parseInt('0x' + nft.identifier.split('-')[2]); + if (TokenUtils.isSovereignIdentifier(nft.identifier)) { + nft.nonce = parseInt('0x' + nft.identifier.split('-')[3]); + } nft.timestamp = elasticNft.timestamp; if (elasticNft.nft_scamInfoType && elasticNft.nft_scamInfoType !== 'none') { diff --git a/src/queue.worker/nft.worker/queue/job-services/thumbnails/aws.service.ts b/src/queue.worker/nft.worker/queue/job-services/thumbnails/aws.service.ts index 6e487db93..632619b72 100644 --- a/src/queue.worker/nft.worker/queue/job-services/thumbnails/aws.service.ts +++ b/src/queue.worker/nft.worker/queue/job-services/thumbnails/aws.service.ts @@ -22,6 +22,7 @@ export class AWSService { Key: path, Body: buffer, ContentType: type, + ACL: 'public-read', }); return this.getItemPath(path); From 242de22bc033140ba801de83ebe827a42abe03eb Mon Sep 17 00:00:00 2001 From: Gabriel Matei Date: Tue, 13 May 2025 15:38:51 +0300 Subject: [PATCH 19/25] add logs --- src/common/rabbitmq/rabbitmq.consumer.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/common/rabbitmq/rabbitmq.consumer.ts b/src/common/rabbitmq/rabbitmq.consumer.ts index 44e578d2e..117e3e671 100644 --- a/src/common/rabbitmq/rabbitmq.consumer.ts +++ b/src/common/rabbitmq/rabbitmq.consumer.ts @@ -36,9 +36,11 @@ export class RabbitMqConsumer { private async handleEvent(event: NotifierEvent): Promise { switch (event.identifier) { case NotifierEventIdentifier.ESDTNFTCreate: + this.logger.log(`Detected 'ESDTNFTCreate' event`); await this.nftHandlerService.handleNftCreateEvent(event); break; case NotifierEventIdentifier.ESDTNFTUpdateAttributes: + this.logger.log(`Detected 'ESDTNFTUpdateAttributes' event`); await this.nftHandlerService.handleNftUpdateAttributesEvent(event); break; case NotifierEventIdentifier.transferOwnership: From 39f3b66b76989a5ac381638be3a7c7ebf26abb71 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Fri, 30 May 2025 16:11:48 +0300 Subject: [PATCH 20/25] extra logs --- .../queue/job-services/thumbnails/aws.service.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/queue.worker/nft.worker/queue/job-services/thumbnails/aws.service.ts b/src/queue.worker/nft.worker/queue/job-services/thumbnails/aws.service.ts index 632619b72..072ccf4da 100644 --- a/src/queue.worker/nft.worker/queue/job-services/thumbnails/aws.service.ts +++ b/src/queue.worker/nft.worker/queue/job-services/thumbnails/aws.service.ts @@ -1,9 +1,12 @@ import { S3 } from "@aws-sdk/client-s3"; import { Injectable } from "@nestjs/common"; import { ApiConfigService } from "src/common/api-config/api.config.service"; +import { OriginLogger } from '@multiversx/sdk-nestjs-common'; @Injectable() export class AWSService { + private readonly logger = new OriginLogger(AWSService.name); + constructor( private readonly apiConfigService: ApiConfigService, ) { } @@ -17,7 +20,7 @@ export class AWSService { region: this.apiConfigService.getAwsS3Region(), }); - await s3.putObject({ + const awsResponse = await s3.putObject({ Bucket: this.apiConfigService.getAwsS3Bucket(), Key: path, Body: buffer, @@ -25,6 +28,14 @@ export class AWSService { ACL: 'public-read', }); + this.logger.log(`Uploaded ${path} to S3. Response: ${JSON.stringify(awsResponse)} (empty means no error)`); + + const head = await s3.headObject({ + Bucket: this.apiConfigService.getAwsS3Bucket(), + Key: path, + }); + this.logger.log(`S3 ${path} HeadObject result: ${JSON.stringify(head)}`); + return this.getItemPath(path); } From f879ec8d60531714421530157fb7a603ba7ae13b Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Fri, 30 May 2025 16:30:04 +0300 Subject: [PATCH 21/25] more logs --- .../queue/job-services/thumbnails/nft.thumbnail.service.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/queue.worker/nft.worker/queue/job-services/thumbnails/nft.thumbnail.service.ts b/src/queue.worker/nft.worker/queue/job-services/thumbnails/nft.thumbnail.service.ts index 711580387..26f2af958 100644 --- a/src/queue.worker/nft.worker/queue/job-services/thumbnails/nft.thumbnail.service.ts +++ b/src/queue.worker/nft.worker/queue/job-services/thumbnails/nft.thumbnail.service.ts @@ -163,12 +163,15 @@ export class NftThumbnailService { } async hasThumbnailGenerated(identifier: string, fileUrl: string): Promise { + this.logger.log(`hasThumbnailGenerated: identifier=${identifier}, fileUrl=${fileUrl}`); const urlIdentifier = TokenHelpers.getThumbnailUrlIdentifier(identifier, fileUrl); const url = this.getFullThumbnailUrl(urlIdentifier); + this.logger.log(`hasThumbnailGenerated: urlIdentifier=${identifier}, fileUrl=${url}`); let hasThumbnail = true; // eslint-disable-next-line require-await - await this.apiService.head(url, { skipRedirects: true }, async (error) => { + const response = await this.apiService.head(url, { skipRedirects: true }, async (error) => { + this.logger.log(`hasThumbnailGenerated error: ${error.response}.`); const status = error.response?.status; if ([HttpStatus.FOUND, HttpStatus.NOT_FOUND, HttpStatus.FORBIDDEN].includes(status)) { hasThumbnail = false; @@ -178,6 +181,8 @@ export class NftThumbnailService { return false; }); + this.logger.log(`hasThumbnailGenerated response: ${JSON.stringify(response.data)}`); + return hasThumbnail; } From bd3fb46a32fbba66b037907e4382cbd7f80f0993 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Fri, 30 May 2025 16:50:45 +0300 Subject: [PATCH 22/25] fix aws service --- src/common/api-config/api.config.service.ts | 5 +++++ .../queue/job-services/thumbnails/aws.service.ts | 14 ++------------ 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/common/api-config/api.config.service.ts b/src/common/api-config/api.config.service.ts index ce232a25e..a141254ad 100644 --- a/src/common/api-config/api.config.service.ts +++ b/src/common/api-config/api.config.service.ts @@ -559,6 +559,11 @@ export class ApiConfigService { return s3Region; } + getAwsS3Endpoint(): string | undefined { + const s3Endpoint = this.configService.get('aws.s3Endpoint'); + return s3Endpoint ?? undefined; + } + getMetaChainShardId(): number { const metaChainShardId = this.configService.get('metaChainShardId'); if (metaChainShardId === undefined) { diff --git a/src/queue.worker/nft.worker/queue/job-services/thumbnails/aws.service.ts b/src/queue.worker/nft.worker/queue/job-services/thumbnails/aws.service.ts index 072ccf4da..97174df97 100644 --- a/src/queue.worker/nft.worker/queue/job-services/thumbnails/aws.service.ts +++ b/src/queue.worker/nft.worker/queue/job-services/thumbnails/aws.service.ts @@ -1,12 +1,9 @@ import { S3 } from "@aws-sdk/client-s3"; import { Injectable } from "@nestjs/common"; import { ApiConfigService } from "src/common/api-config/api.config.service"; -import { OriginLogger } from '@multiversx/sdk-nestjs-common'; @Injectable() export class AWSService { - private readonly logger = new OriginLogger(AWSService.name); - constructor( private readonly apiConfigService: ApiConfigService, ) { } @@ -18,9 +15,10 @@ export class AWSService { secretAccessKey: this.apiConfigService.getAwsS3Secret(), }, region: this.apiConfigService.getAwsS3Region(), + endpoint: this.apiConfigService.getAwsS3Endpoint(), }); - const awsResponse = await s3.putObject({ + await s3.putObject({ Bucket: this.apiConfigService.getAwsS3Bucket(), Key: path, Body: buffer, @@ -28,14 +26,6 @@ export class AWSService { ACL: 'public-read', }); - this.logger.log(`Uploaded ${path} to S3. Response: ${JSON.stringify(awsResponse)} (empty means no error)`); - - const head = await s3.headObject({ - Bucket: this.apiConfigService.getAwsS3Bucket(), - Key: path, - }); - this.logger.log(`S3 ${path} HeadObject result: ${JSON.stringify(head)}`); - return this.getItemPath(path); } From 1e1a4954b9082ffa2fae523be7c6f20a4637f231 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Mon, 2 Jun 2025 11:50:29 +0300 Subject: [PATCH 23/25] update thumbnail check --- .../thumbnails/nft.thumbnail.service.ts | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/queue.worker/nft.worker/queue/job-services/thumbnails/nft.thumbnail.service.ts b/src/queue.worker/nft.worker/queue/job-services/thumbnails/nft.thumbnail.service.ts index 26f2af958..7f0dab8a2 100644 --- a/src/queue.worker/nft.worker/queue/job-services/thumbnails/nft.thumbnail.service.ts +++ b/src/queue.worker/nft.worker/queue/job-services/thumbnails/nft.thumbnail.service.ts @@ -166,24 +166,31 @@ export class NftThumbnailService { this.logger.log(`hasThumbnailGenerated: identifier=${identifier}, fileUrl=${fileUrl}`); const urlIdentifier = TokenHelpers.getThumbnailUrlIdentifier(identifier, fileUrl); const url = this.getFullThumbnailUrl(urlIdentifier); + this.logger.log(`hasThumbnailGenerated: urlIdentifier=${identifier}, fileUrl=${url}`); + try { + const response = await this.apiService.head(url, { skipRedirects: true }); + + // Check ETag - if it matches the default image ETag, it's not a real thumbnail + const etag = response.headers?.['etag']; + if (etag === '"66b09e7683da961daefe255f5bec743d"' || etag === '66b09e7683da961daefe255f5bec743d') { + return false; + } + + // If none of the above conditions indicate a default image, assume it's real + return true; - let hasThumbnail = true; - // eslint-disable-next-line require-await - const response = await this.apiService.head(url, { skipRedirects: true }, async (error) => { + } catch (error: any) { this.logger.log(`hasThumbnailGenerated error: ${error.response}.`); const status = error.response?.status; + // Traditional S3-style behavior - treat these as no thumbnail if ([HttpStatus.FOUND, HttpStatus.NOT_FOUND, HttpStatus.FORBIDDEN].includes(status)) { - hasThumbnail = false; - return true; + return false; } + // For any other error, assume no thumbnail return false; - }); - - this.logger.log(`hasThumbnailGenerated response: ${JSON.stringify(response.data)}`); - - return hasThumbnail; + } } async generateThumbnail(nft: Nft, fileUrl: string, fileType: string, forceRefresh: boolean = false): Promise { From d2a925cd5e70ca2fc8b65c9c21712398cb2711a3 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Mon, 2 Jun 2025 14:42:15 +0300 Subject: [PATCH 24/25] fix duplicated config entries --- config/config.e2e.mainnet.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/config/config.e2e.mainnet.yaml b/config/config.e2e.mainnet.yaml index 2c4547c04..dcb926f8e 100644 --- a/config/config.e2e.mainnet.yaml +++ b/config/config.e2e.mainnet.yaml @@ -142,10 +142,6 @@ urls: tmp: '/tmp' ipfs: 'https://ipfs.io/ipfs' socket: 'socket-api-fra.multiversx.com' - tmp: '/tmp' - ipfs: 'https://ipfs.io/ipfs' - socket: 'socket-api-fra.multiversx.com' - maiarId: 'https://id-api.multiversx.com' indexer: type: 'elastic' maxPagination: 10000 From cc36e2c41f1bda05d30d2e9fcb30cc020e1731d6 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu <51945539+bogdan-rosianu@users.noreply.github.com> Date: Mon, 25 Aug 2025 17:06:50 +0300 Subject: [PATCH 25/25] Merge development into feat/sovereign (#1529) * Enhance MexTokenService to calculate and store token volumes for base and quote tokens in getAllMexTokensRaw method * extend aws s3 config * update configs * update s3 configs * add support for new NFT events * add maximum process retries * add unit tests * ferch token price from highest liquidity pool * emit also deleteCacheKeys * undo process reries * fix tests * Proposer fix (#1498) * proposer fix * proposer fix * proposer fix * fix getBlock * fixes after review Co-authored-by: bogdan-rosianu * add execution order sorting using miniBlocksDetails from Elasticsearch (#1504) * add execution order sorting using miniBlocksDetails from Elasticsearch * fixes after review * fixes after review * fix userUndelegatedList field (#1507) * fix userUndelegatedList field * use ?? instead of [] to handle undefined case * collections count subType required false fix (#1509) * tokens supply format from plugin (#1505) * fix collection set fields (#1510) * fix collection set fields * fixes after review * add configurable response compression with gzip deflate support + update package json (#1512) * add configurable response compresion * set true compression for testnet env * refactor processNFtCollections method * update package * update version of node * update unit test yaml * getNfts parallel execution * compression flag false by default * improve getSingleNFt * getNftsCollection increase performance * undo last commit * Integrate last sdk nestjs (#1516) * update to latest sdk version * fixes for latest sdk version * add package-lock * fix unit tests * Packages security issues 2 (#1517) * fix packages * add package-lock * add missing packages * remove unneeded package * fix mongo connection * Api 672 add timestampMs field into transaction response (#1518) * Add timestampMs field to Transaction interface and class * update specs * update accounts spec * Add normalizeTimestampMs method for timestamp conversion (#1519) * Enhance account filtering by adding 'withBalance' query option to account endpoints and update ElasticIndexerHelper to support balance filtering. This allows users to filter accounts based on their balance status. (#1521) * add events filtered by order (#1523) * Refactor content type validation in NftMediaService to handle media types correctly by stripping parameters from the content type string. (#1527) * use events index instead of logs (#1514) * use events index instead of logs * configurable migrated indices * added protection for empty fields * fix log address * add transaction get unit tests (#1525) --------- Co-authored-by: cfaur09 Co-authored-by: Catalin Faur <52102171+cfaur09@users.noreply.github.com> * fixes after merge + new sdknestjs versions * remove test file * fix tx value parsing * treat missing receiver --------- Co-authored-by: cfaur09 Co-authored-by: Gabriel Matei Co-authored-by: Rebegea Dragos-Alexandru <42241923+dragos-rebegea@users.noreply.github.com> Co-authored-by: Catalin Faur <52102171+cfaur09@users.noreply.github.com> Co-authored-by: Gutica Stefan <123564494+GuticaStefan@users.noreply.github.com> --- .github/workflows/lint.yml | 2 +- .github/workflows/unit.tests.yml | 2 +- config/config.devnet-old.yaml | 1 + config/config.devnet.yaml | 8 + config/config.e2e.mainnet.yaml | 3 + config/config.mainnet.yaml | 8 + config/config.testnet.yaml | 8 + package-lock.json | 7766 ++++++++++------- package.json | 51 +- src/common/api-config/api.config.service.ts | 22 +- .../entities/token.assets.price.source.ts | 2 +- src/common/assets/entities/token.assets.ts | 2 +- .../indexer/elastic/elastic.indexer.helper.ts | 14 +- .../elastic/elastic.indexer.service.ts | 15 +- src/common/indexer/entities/block.ts | 13 + src/common/indexer/entities/index.ts | 4 +- .../indexer/entities/transaction.log.ts | 12 + src/common/indexer/entities/transaction.ts | 1 + src/common/indexer/indexer.interface.ts | 6 +- src/common/indexer/indexer.service.ts | 11 +- src/common/persistence/persistence.module.ts | 4 +- src/common/plugins/plugin.service.ts | 3 + .../pubsub/pub.sub.listener.controller.ts | 4 +- .../entities/notifier.event.identifier.ts | 4 + src/common/rabbitmq/rabbitmq.consumer.ts | 10 + .../rabbitmq/rabbitmq.nft.handler.service.ts | 111 +- .../cache.warmer/cache.warmer.service.ts | 10 +- src/endpoints/accounts/account.controller.ts | 5 + .../entities/account.query.options.ts | 4 +- src/endpoints/blocks/block.service.ts | 16 +- .../caching/local.cache.controller.ts | 4 +- .../collections/collection.controller.ts | 1 + .../delegation/delegation.service.ts | 6 +- src/endpoints/esdt/esdt.address.service.ts | 2 +- src/endpoints/esdt/esdt.module.ts | 2 + src/endpoints/esdt/esdt.service.ts | 6 +- .../events/entities/events.filter.ts | 1 + src/endpoints/events/events.controller.ts | 4 +- src/endpoints/mex/mex.settings.service.ts | 2 +- src/endpoints/mex/mex.token.service.ts | 38 +- src/endpoints/nfts/nft.service.ts | 128 +- .../entities/transaction.log.event.ts | 3 + .../transactions/entities/transaction.ts | 3 + .../entities/transactions.query.options.ts | 1 + ...tion.action.sc-calls.recognizer.service.ts | 4 + ...saction.action.stake.recognizer.service.ts | 2 +- .../transaction.action.service.ts | 3 +- .../transactions/transaction.get.service.ts | 47 +- .../transactions/transaction.service.ts | 12 + .../transfers/transfer.controller.ts | 4 +- src/endpoints/transfers/transfer.service.ts | 81 +- src/main.ts | 24 +- .../job-services/media/nft.media.service.ts | 3 +- .../job-services/thumbnails/aws.service.ts | 2 +- .../unit/controllers/media.controller.spec.ts | 55 - src/test/unit/services/accounts.spec.ts | 1 + src/test/unit/services/blocks.spec.ts | 6 +- src/test/unit/services/delegation.spec.ts | 54 + src/test/unit/services/esdt.address.spec.ts | 4 +- src/test/unit/services/events.spec.ts | 44 + .../unit/services/rabbitmq.consumer.spec.ts | 38 +- .../rabbitmq.nft.handler.service.spec.ts | 206 + .../unit/services/transaction.get.spec.ts | 734 ++ src/test/unit/services/transactions.spec.ts | 2 + 64 files changed, 6165 insertions(+), 3484 deletions(-) delete mode 100644 src/test/unit/controllers/media.controller.spec.ts create mode 100644 src/test/unit/services/rabbitmq.nft.handler.service.spec.ts create mode 100644 src/test/unit/services/transaction.get.spec.ts diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index c7e65d5af..bda7f1a37 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: - node-version: [16.x] + node-version: [18.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: diff --git a/.github/workflows/unit.tests.yml b/.github/workflows/unit.tests.yml index 67768a1b1..24e528c3e 100644 --- a/.github/workflows/unit.tests.yml +++ b/.github/workflows/unit.tests.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: - node-version: [16.x] + node-version: [18.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: diff --git a/config/config.devnet-old.yaml b/config/config.devnet-old.yaml index 94998518f..d803cb22e 100644 --- a/config/config.devnet-old.yaml +++ b/config/config.devnet-old.yaml @@ -71,6 +71,7 @@ aws: s3Secret: '' s3Bucket: 'devnet-old-media.elrond.com' s3Region: '' + s3Endpoint: '' urls: self: 'https://devnet-old-api.multiversx.com' elastic: diff --git a/config/config.devnet.yaml b/config/config.devnet.yaml index 5c794ec78..0d0e91016 100644 --- a/config/config.devnet.yaml +++ b/config/config.devnet.yaml @@ -89,6 +89,8 @@ features: durationThresholdMs: 5000 failureCountThreshold: 5 resetTimeoutMs: 30000 + elasticMigratedIndices: + logs: 'events' statusChecker: enabled: false thresholds: @@ -127,6 +129,7 @@ aws: s3Secret: '' s3Bucket: 'devnet-media.elrond.com' s3Region: '' + s3Endpoint: '' urls: self: 'https://devnet-api.multiversx.com' elastic: @@ -183,3 +186,8 @@ chainSettings: nftProcess: parallelism: 1 maxRetries: 3 +compression: + enabled: true + level: 6 + threshold: 1024 + chunkSize: 16384 \ No newline at end of file diff --git a/config/config.e2e.mainnet.yaml b/config/config.e2e.mainnet.yaml index dcb926f8e..0922ace0e 100644 --- a/config/config.e2e.mainnet.yaml +++ b/config/config.e2e.mainnet.yaml @@ -86,6 +86,8 @@ features: durationThresholdMs: 5000 failureCountThreshold: 5 resetTimeoutMs: 30000 + elasticMigratedIndices: + logs: 'events' statusChecker: enabled: false thresholds: @@ -127,6 +129,7 @@ aws: s3Secret: '' s3Bucket: 'media.elrond.com' s3Region: '' + s3Endpoint: '' urls: self: 'http://localhost:3001' elastic: diff --git a/config/config.mainnet.yaml b/config/config.mainnet.yaml index 0b668b990..6632cb7e0 100644 --- a/config/config.mainnet.yaml +++ b/config/config.mainnet.yaml @@ -86,6 +86,8 @@ features: durationThresholdMs: 5000 failureCountThreshold: 5 resetTimeoutMs: 30000 + elasticMigratedIndices: + logs: 'events' statusChecker: enabled: false thresholds: @@ -131,6 +133,7 @@ aws: s3Secret: '' s3Bucket: 'media.elrond.com' s3Region: '' + s3Endpoint: '' urls: self: 'https://api.multiversx.com' elastic: @@ -187,3 +190,8 @@ chainSettings: nftProcess: parallelism: 1 maxRetries: 3 +compression: + enabled: true + level: 6 + threshold: 1024 + chunkSize: 16384 diff --git a/config/config.testnet.yaml b/config/config.testnet.yaml index 1c35f984e..95b091fc8 100644 --- a/config/config.testnet.yaml +++ b/config/config.testnet.yaml @@ -85,6 +85,8 @@ features: durationThresholdMs: 5000 failureCountThreshold: 5 resetTimeoutMs: 30000 + elasticMigratedIndices: + logs: 'events' statusChecker: enabled: false thresholds: @@ -130,6 +132,7 @@ aws: s3Secret: '' s3Bucket: 'testnet-media.elrond.com' s3Region: '' + s3Endpoint: '' urls: self: 'https://testnet-api.multiversx.com' elastic: @@ -186,3 +189,8 @@ chainSettings: nftProcess: parallelism: 1 maxRetries: 3 +compression: + enabled: true + level: 6 + threshold: 1024 + chunkSize: 16384 diff --git a/package-lock.json b/package-lock.json index fe33e043f..9e91db6bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,39 +14,40 @@ "@multiversx/sdk-core": "^13.2.2", "@multiversx/sdk-data-api-client": "^0.7.0", "@multiversx/sdk-exchange": "^0.2.21", - "@multiversx/sdk-nestjs-auth": "5.0.2-beta.0", - "@multiversx/sdk-nestjs-cache": "5.0.2-beta.0", - "@multiversx/sdk-nestjs-common": "5.0.2-beta.0", - "@multiversx/sdk-nestjs-elastic": "5.0.2-beta.0", - "@multiversx/sdk-nestjs-http": "5.0.2-beta.0", - "@multiversx/sdk-nestjs-monitoring": "5.0.2-beta.0", - "@multiversx/sdk-nestjs-rabbitmq": "5.0.2-beta.0", - "@multiversx/sdk-nestjs-redis": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-auth": "6.0.1-beta.0", + "@multiversx/sdk-nestjs-cache": "6.0.1-beta.0", + "@multiversx/sdk-nestjs-common": "6.0.1-beta.0", + "@multiversx/sdk-nestjs-elastic": "6.0.1-beta.0", + "@multiversx/sdk-nestjs-http": "6.0.1-beta.0", + "@multiversx/sdk-nestjs-monitoring": "6.0.1-beta.0", + "@multiversx/sdk-nestjs-rabbitmq": "6.0.1-beta.0", + "@multiversx/sdk-nestjs-redis": "6.0.1-beta.0", "@multiversx/sdk-transaction-processor": "^0.1.35", "@nestjs/apollo": "12.0.11", - "@nestjs/common": "10.2.0", + "@nestjs/common": "^10.2.0", "@nestjs/config": "3.0.1", - "@nestjs/core": "10.2.4", + "@nestjs/core": "10.4.2", "@nestjs/event-emitter": "^2.0.3", "@nestjs/graphql": "^12.0.11", "@nestjs/microservices": "10.2.4", - "@nestjs/platform-express": "10.2.4", - "@nestjs/platform-socket.io": "10.2.4", + "@nestjs/platform-express": "10.4.19", + "@nestjs/platform-socket.io": "^10.2.4", "@nestjs/schedule": "3.0.3", - "@nestjs/swagger": "7.1.16", + "@nestjs/swagger": "7.4.2", "@nestjs/typeorm": "10.0.0", "@nestjs/websockets": "^10.2.8", - "@sendgrid/mail": "^7.7.0", + "@sendgrid/mail": "^8.1.5", "agentkeepalive": "^4.2.1", "amqp-connection-manager": "^4.1.3", "amqplib": "^0.10.0", - "anchorme": "^2.1.2", + "anchorme": "^3.0.8", "apollo-server-core": "^3.13.0", "apollo-server-express": "3.13.0", "bignumber.js": "^9.0.2", + "compression": "^1.8.0", "crypto-js": "^4.1.1", - "dataloader": "^2.1.0", - "dd-trace": "^1.6.0", + "dataloader": "^2.2.2", + "dd-trace": "5.56.0", "fluent-ffmpeg": "^2.1.2", "graphql": "^16.8.1", "graphql-fields-list": "^2.2.4", @@ -55,9 +56,8 @@ "ioredis": "^5.2.3", "js-yaml": "^4.1.0", "json-diff": "^0.7.1", - "jsonwebtoken": "^8.5.1", - "mongodb": "^3.6.4", - "mysql2": "^2.3.3", + "mongodb": "^6.17.0", + "mysql2": "^3.9.8", "nest-winston": "^1.6.2", "node-fetch": "^2.6.7", "node-object-hash": "^2.3.10", @@ -65,14 +65,14 @@ "prom-client": "^14.0.1", "redis": "^3.1.2", "reflect-metadata": "^0.1.13", - "request-ip": "^2.1.3", - "rimraf": "^3.0.2", + "request-ip": "^3.3.0", + "rimraf": "^5.0.0", "rxjs": "^7.1.0", - "sharp": "^0.32.6", + "sharp": "^0.34.2", "simple-git": "^3.16.0", "swagger-ui-express": "^4.3.0", "tiny-async-pool": "^1.2.0", - "typeorm": "0.3.10", + "typeorm": "^0.3.25", "winston": "^3.6.0", "winston-daily-rotate-file": "^4.7.1", "yup": "^0.32.11" @@ -81,10 +81,11 @@ "@automock/adapters.nestjs": "^2.1.0", "@automock/jest": "^2.1.0", "@jest/test-sequencer": "^29.7.0", - "@nestjs/cli": "10.1.17", + "@nestjs/cli": "10.4.9", "@nestjs/schematics": "10.0.2", "@nestjs/testing": "10.2.4", "@testing-library/jest-dom": "6.1.4", + "@types/compression": "^1.8.1", "@types/cron": "^1.7.3", "@types/crypto-js": "^4.0.2", "@types/express": "^4.17.13", @@ -116,30 +117,19 @@ "webpack": "^5.73.0" } }, - "node_modules/@acuminous/bitsyntax": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@acuminous/bitsyntax/-/bitsyntax-0.1.2.tgz", - "integrity": "sha512-29lUK80d1muEQqiUsSo+3A0yP6CdspgC95EnKBMi22Xlwt79i/En4Vr67+cXhU+cZjbti3TgGGC5wy1stIywVQ==", - "dependencies": { - "buffer-more-ints": "~1.0.0", - "debug": "^4.3.4", - "safe-buffer": "~5.1.2" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/@adobe/css-tools": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.2.tgz", - "integrity": "sha512-baYZExFpsdkBNuvGKTKWCwKH57HRZLVtycZS05WTQNVOiXVSeAki3nU35zlRbToeMW8aHlJfyS+1C4BOv27q0A==", - "dev": true + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.3.tgz", + "integrity": "sha512-VQKMkwriZbaOgVCby1UDY/LDk5fIjhQicCvVPFqfe+69fWaPWydbWJ3wRt59/YzIwda1I81loas3oCoHxnqvdA==", + "dev": true, + "license": "MIT" }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -149,19 +139,21 @@ } }, "node_modules/@angular-devkit/core": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.2.0.tgz", - "integrity": "sha512-l1k6Rqm3YM16BEn3CWyQKrk9xfu+2ux7Bw3oS+h1TO4/RoxO2PgHj8LLRh/WNrYVarhaqO7QZ5ePBkXNMkzJ1g==", + "version": "17.3.11", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.11.tgz", + "integrity": "sha512-vTNDYNsLIWpYk2I969LMQFH29GTsLzxNk/0cLw5q56ARF0v5sIWfHYwGTS88jdDqIpuuettcSczbxeA7EuAmqQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "8.12.0", "ajv-formats": "2.1.1", - "jsonc-parser": "3.2.0", + "jsonc-parser": "3.2.1", + "picomatch": "4.0.1", "rxjs": "7.8.1", "source-map": "0.7.4" }, "engines": { - "node": "^16.14.0 || >=18.10.0", + "node": "^18.13.0 || >=20.9.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" }, @@ -179,38 +171,41 @@ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/@angular-devkit/schematics": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.2.0.tgz", - "integrity": "sha512-QMDJXPE0+YQJ9Ap3MMzb0v7rx6ZbBEokmHgpdIjN3eILYmbAdsSGE8HTV8NjS9nKmcyE9OGzFCMb7PFrDTlTAw==", + "version": "17.3.11", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-17.3.11.tgz", + "integrity": "sha512-I5wviiIqiFwar9Pdk30Lujk8FczEEc18i22A5c6Z9lbmhPQdTroDnEQdsfXjy404wPe8H62s0I15o4pmMGfTYQ==", "dev": true, + "license": "MIT", "dependencies": { - "@angular-devkit/core": "16.2.0", - "jsonc-parser": "3.2.0", - "magic-string": "0.30.1", + "@angular-devkit/core": "17.3.11", + "jsonc-parser": "3.2.1", + "magic-string": "0.30.8", "ora": "5.4.1", "rxjs": "7.8.1" }, "engines": { - "node": "^16.14.0 || >=18.10.0", + "node": "^18.13.0 || >=20.9.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" } }, "node_modules/@angular-devkit/schematics-cli": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-16.2.0.tgz", - "integrity": "sha512-f3HjrDvSrRMvESogLsqsZXsEg//trIBySCHRXCglPrWLVdBbIRctGOhXqZoclRxXimIKUx14zLsOWzDwZG8+HQ==", + "version": "17.3.11", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-17.3.11.tgz", + "integrity": "sha512-kcOMqp+PHAKkqRad7Zd7PbpqJ0LqLaNZdY1+k66lLWmkEBozgq8v4ASn/puPWf9Bo0HpCiK+EzLf0VHE8Z/y6Q==", "dev": true, + "license": "MIT", "dependencies": { - "@angular-devkit/core": "16.2.0", - "@angular-devkit/schematics": "16.2.0", + "@angular-devkit/core": "17.3.11", + "@angular-devkit/schematics": "17.3.11", "ansi-colors": "4.1.3", - "inquirer": "8.2.4", + "inquirer": "9.2.15", "symbol-observable": "4.0.0", "yargs-parser": "21.1.1" }, @@ -218,52 +213,79 @@ "schematics": "bin/schematics.js" }, "engines": { - "node": "^16.14.0 || >=18.10.0", + "node": "^18.13.0 || >=20.9.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" } }, + "node_modules/@angular-devkit/schematics-cli/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, "node_modules/@angular-devkit/schematics-cli/node_modules/inquirer": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz", - "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==", + "version": "9.2.15", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.15.tgz", + "integrity": "sha512-vI2w4zl/mDluHt9YEQ/543VTCwPKWiHzKtm9dM2V0NdFcqEexDAjUHzO1oA60HRNaVifGXXM1tRRNluLVHa0Kg==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.1", + "@ljharb/through": "^2.3.12", + "ansi-escapes": "^4.3.2", + "chalk": "^5.3.0", "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", + "cli-width": "^4.1.0", + "external-editor": "^3.1.0", + "figures": "^3.2.0", "lodash": "^4.17.21", - "mute-stream": "0.0.8", + "mute-stream": "1.0.0", "ora": "^5.4.1", - "run-async": "^2.4.0", - "rxjs": "^7.5.5", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6", - "wrap-ansi": "^7.0.0" + "run-async": "^3.0.0", + "rxjs": "^7.8.1", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=18" } }, - "node_modules/@angular-devkit/schematics-cli/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "node_modules/@angular-devkit/schematics-cli/node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, + "license": "ISC", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/run-async": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", + "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" } }, "node_modules/@angular-devkit/schematics/node_modules/rxjs": { @@ -271,6 +293,7 @@ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" } @@ -279,6 +302,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/@apollo/cache-control-types/-/cache-control-types-1.0.3.tgz", "integrity": "sha512-F17/vCp7QVwom9eG7ToauIKdAxpSoadsJnqIfyryLFSkLSOEqu+eC5Z3N8OXcUVStuOMcNHlyraRsA6rRICu4g==", + "license": "MIT", "peer": true, "peerDependencies": { "graphql": "14.x || 15.x || 16.x" @@ -289,6 +313,7 @@ "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.7.tgz", "integrity": "sha512-Lahx5zntHPZia35myYDBRuF58tlwPskwHc5CWBZC/4bMKB6siTBWwtMrkqXcsNwQiFSzSx5hKdRPUmemrEp3Gg==", "hasInstallScript": true, + "license": "BSD-3-Clause", "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -309,9 +334,10 @@ } }, "node_modules/@apollo/server": { - "version": "4.11.3", - "resolved": "https://registry.npmjs.org/@apollo/server/-/server-4.11.3.tgz", - "integrity": "sha512-mW8idE2q0/BN14mimfJU5DAnoPHZRrAWgwsVLBEdACds+mxapIYxIbI6AH4AsOpxfrpvHts3PCYDbopy1XPW1g==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@apollo/server/-/server-4.12.2.tgz", + "integrity": "sha512-jKRlf+sBMMdKYrjMoiWKne42Eb6paBfDOr08KJnUaeaiyWFj+/040FjVPQI7YGLfdwnYIsl1NUUqS2UdgezJDg==", + "license": "MIT", "peer": true, "dependencies": { "@apollo/cache-control-types": "^1.0.3", @@ -350,6 +376,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@apollo/server-gateway-interface/-/server-gateway-interface-1.1.1.tgz", "integrity": "sha512-pGwCl/po6+rxRmDMFgozKQo2pbsSwE91TpsDBAOgf74CRDPXHHtM88wbwjab0wMMZh95QfR45GGyDIdhY24bkQ==", + "license": "MIT", "peer": true, "dependencies": { "@apollo/usage-reporting-protobuf": "^4.1.1", @@ -366,6 +393,7 @@ "resolved": "https://registry.npmjs.org/@apollo/server-plugin-landing-page-graphql-playground/-/server-plugin-landing-page-graphql-playground-4.0.0.tgz", "integrity": "sha512-PBDtKI/chJ+hHeoJUUH9Kuqu58txQl00vUGuxqiC9XcReulIg7RjsyD0G1u3drX4V709bxkL5S0nTeXfRHD0qA==", "deprecated": "The use of GraphQL Playground in Apollo Server was supported in previous versions, but this is no longer the case as of December 31, 2022. This package exists for v4 migration purposes only. We do not intend to resolve security issues or other bugs with this package if they arise, so please migrate away from this to [Apollo Server's default Explorer](https://www.apollographql.com/docs/apollo-server/api/plugin/landing-pages) as soon as possible.", + "license": "MIT", "dependencies": { "@apollographql/graphql-playground-html": "1.6.29" }, @@ -380,6 +408,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/@apollo/usage-reporting-protobuf/-/usage-reporting-protobuf-4.1.1.tgz", "integrity": "sha512-u40dIUePHaSKVshcedO7Wp+mPiZsaU6xjv9J+VyxpoU/zL6Jle+9zWeG98tr/+SZ0nZ4OXhrbb8SNr0rAPpIDA==", + "license": "MIT", "dependencies": { "@apollo/protobufjs": "1.2.7" } @@ -388,6 +417,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/@apollo/utils.createhash/-/utils.createhash-2.0.2.tgz", "integrity": "sha512-UkS3xqnVFLZ3JFpEmU/2cM2iKJotQXMoSTgxXsfQgXLC5gR1WaepoXagmYnPSA7Q/2cmnyTYK5OgAgoC4RULPg==", + "license": "MIT", "peer": true, "dependencies": { "@apollo/utils.isnodelike": "^2.0.1", @@ -401,6 +431,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/@apollo/utils.dropunuseddefinitions/-/utils.dropunuseddefinitions-2.0.1.tgz", "integrity": "sha512-EsPIBqsSt2BwDsv8Wu76LK5R1KtsVkNoO4b0M5aK0hx+dGg9xJXuqlr7Fo34Dl+y83jmzn+UvEW+t1/GP2melA==", + "license": "MIT", "peer": true, "engines": { "node": ">=14" @@ -413,6 +444,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/@apollo/utils.fetcher/-/utils.fetcher-2.0.1.tgz", "integrity": "sha512-jvvon885hEyWXd4H6zpWeN3tl88QcWnHp5gWF5OPF34uhvoR+DFqcNxs9vrRaBBSY3qda3Qe0bdud7tz2zGx1A==", + "license": "MIT", "peer": true, "engines": { "node": ">=14" @@ -422,6 +454,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/@apollo/utils.isnodelike/-/utils.isnodelike-2.0.1.tgz", "integrity": "sha512-w41XyepR+jBEuVpoRM715N2ZD0xMD413UiJx8w5xnAZD2ZkSJnMJBoIzauK83kJpSgNuR6ywbV29jG9NmxjK0Q==", + "license": "MIT", "peer": true, "engines": { "node": ">=14" @@ -431,6 +464,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/@apollo/utils.keyvaluecache/-/utils.keyvaluecache-2.1.1.tgz", "integrity": "sha512-qVo5PvUUMD8oB9oYvq4ViCjYAMWnZ5zZwEjNF37L2m1u528x5mueMlU+Cr1UinupCgdB78g+egA1G98rbJ03Vw==", + "license": "MIT", "peer": true, "dependencies": { "@apollo/utils.logger": "^2.0.1", @@ -444,6 +478,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/@apollo/utils.logger/-/utils.logger-2.0.1.tgz", "integrity": "sha512-YuplwLHaHf1oviidB7MxnCXAdHp3IqYV8n0momZ3JfLniae92eYqMIx+j5qJFX6WKJPs6q7bczmV4lXIsTu5Pg==", + "license": "MIT", "peer": true, "engines": { "node": ">=14" @@ -453,6 +488,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/@apollo/utils.printwithreducedwhitespace/-/utils.printwithreducedwhitespace-2.0.1.tgz", "integrity": "sha512-9M4LUXV/fQBh8vZWlLvb/HyyhjJ77/I5ZKu+NBWV/BmYGyRmoEP9EVAy7LCVoY3t8BDcyCAGfxJaLFCSuQkPUg==", + "license": "MIT", "peer": true, "engines": { "node": ">=14" @@ -465,6 +501,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/@apollo/utils.removealiases/-/utils.removealiases-2.0.1.tgz", "integrity": "sha512-0joRc2HBO4u594Op1nev+mUF6yRnxoUH64xw8x3bX7n8QBDYdeYgY4tF0vJReTy+zdn2xv6fMsquATSgC722FA==", + "license": "MIT", "peer": true, "engines": { "node": ">=14" @@ -477,6 +514,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/@apollo/utils.sortast/-/utils.sortast-2.0.1.tgz", "integrity": "sha512-eciIavsWpJ09za1pn37wpsCGrQNXUhM0TktnZmHwO+Zy9O4fu/WdB4+5BvVhFiZYOXvfjzJUcc+hsIV8RUOtMw==", + "license": "MIT", "peer": true, "dependencies": { "lodash.sortby": "^4.7.0" @@ -492,6 +530,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/@apollo/utils.stripsensitiveliterals/-/utils.stripsensitiveliterals-2.0.1.tgz", "integrity": "sha512-QJs7HtzXS/JIPMKWimFnUMK7VjkGQTzqD9bKD1h3iuPAqLsxd0mUNVbkYOPTsDhUKgcvUOfOqOJWYohAKMvcSA==", + "license": "MIT", "peer": true, "engines": { "node": ">=14" @@ -504,6 +543,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/@apollo/utils.usagereporting/-/utils.usagereporting-2.1.0.tgz", "integrity": "sha512-LPSlBrn+S17oBy5eWkrRSGb98sWmnEzo3DPTZgp8IQc8sJe0prDgDuppGq4NeQlpoqEHz0hQeYHAOA0Z3aQsxQ==", + "license": "MIT", "peer": true, "dependencies": { "@apollo/usage-reporting-protobuf": "^4.1.0", @@ -524,6 +564,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/@apollo/utils.withrequired/-/utils.withrequired-2.0.1.tgz", "integrity": "sha512-YBDiuAX9i1lLc6GeTy1m7DGLFn/gMnvXqlalOIMjM7DeOgIacEjjfwPqb0M1CQ2v11HhR15d1NmxJoRCfrNqcA==", + "license": "MIT", "peer": true, "engines": { "node": ">=14" @@ -533,6 +574,7 @@ "version": "0.5.4", "resolved": "https://registry.npmjs.org/@apollographql/apollo-tools/-/apollo-tools-0.5.4.tgz", "integrity": "sha512-shM3q7rUbNyXVVRkQJQseXv6bnYM3BUma/eZhwXR4xsuM+bqWnJKvW7SAfRjP7LuSCocrexa5AXhjjawNHrIlw==", + "license": "MIT", "engines": { "node": ">=8", "npm": ">=6" @@ -545,6 +587,7 @@ "version": "1.6.29", "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.29.tgz", "integrity": "sha512-xCcXpoz52rI4ksJSdOCxeOCn2DLocxwHf9dVT/Q90Pte1LX+LY+91SFtJF3KXVHH8kEin+g1KKCQPKBjZJfWNA==", + "license": "MIT", "dependencies": { "xss": "^1.0.8" } @@ -555,6 +598,7 @@ "integrity": "sha512-cwolpTMF+frIm6idLC/zD0obgG/Wf5wP6I8FKJBcRy+Cuc9Pyy/E7200zafYlOVzUlZUP16VqchgGWpUyb1U3Q==", "dev": true, "hasInstallScript": true, + "license": "MIT", "dependencies": { "@automock/common": "^3.1.0", "@automock/types": "^2.0.1", @@ -569,6 +613,7 @@ "resolved": "https://registry.npmjs.org/@automock/common/-/common-3.1.0.tgz", "integrity": "sha512-Y7N4YnSZRuSIfGV4/PdG2JyURa9PK1maqGZBYUG2/sIW+H/Mlhc/3NpegnlUyQFRBexEJtgmUsvfzzI1/lm0JA==", "dev": true, + "license": "MIT", "dependencies": { "@automock/types": "^2.0.1" }, @@ -581,6 +626,7 @@ "resolved": "https://registry.npmjs.org/@automock/core/-/core-2.1.0.tgz", "integrity": "sha512-VIaY2woE7nWXhXKlNzk4+xzCuaVBXfGYwowrzdI+MmJBKqi2z0lUjNVix74hZRWhJpkOW+PR3UThFvThgyqIqQ==", "dev": true, + "license": "MIT", "dependencies": { "@automock/common": "^3.1.0", "@automock/types": "^2.0.1", @@ -595,6 +641,7 @@ "resolved": "https://registry.npmjs.org/@automock/jest/-/jest-2.1.0.tgz", "integrity": "sha512-kJuTu/a5bbG8SICIfITgESpIrVbBfbMykDdICmPvJkeI51Ldq+tqiLS2Ded16vLWS9WeFKeTw/+2b/DO8QyV0Q==", "dev": true, + "license": "MIT", "dependencies": { "@automock/core": "^2.1.0", "@automock/types": "^2.0.1" @@ -610,12 +657,14 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/@automock/types/-/types-2.0.1.tgz", "integrity": "sha512-ue35e4im3n7l+Eqq3kCA2nNs8jzJbjYLni+vlPdgJ+9KfsEykJjA1OpnNN/PG1tDaM0iyR2p/uZg27MOC/qiTg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@aws-crypto/crc32": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==", + "license": "Apache-2.0", "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", @@ -629,6 +678,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-5.2.0.tgz", "integrity": "sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==", + "license": "Apache-2.0", "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", @@ -639,6 +689,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-5.2.0.tgz", "integrity": "sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg==", + "license": "Apache-2.0", "dependencies": { "@aws-crypto/supports-web-crypto": "^5.2.0", "@aws-crypto/util": "^5.2.0", @@ -652,6 +703,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -663,6 +715,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" @@ -675,6 +728,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" @@ -687,6 +741,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-js": "^5.2.0", "@aws-crypto/supports-web-crypto": "^5.2.0", @@ -701,6 +756,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -712,6 +768,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" @@ -724,6 +781,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" @@ -736,6 +794,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "license": "Apache-2.0", "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", @@ -749,6 +808,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" } @@ -757,6 +817,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.222.0", "@smithy/util-utf8": "^2.0.0", @@ -767,6 +828,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -778,6 +840,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" @@ -790,6 +853,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" @@ -799,112 +863,116 @@ } }, "node_modules/@aws-sdk/client-s3": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.775.0.tgz", - "integrity": "sha512-Z/BeVmYc3nj4FNE46MtvBYeCVvBZwlujMEvr5UOChP14899QWkBfOvf74RwQY9qy5/DvhVFkHlA8en1L6+0NrA==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.840.0.tgz", + "integrity": "sha512-dRuo03EqGBbl9+PTogpwY9bYmGWIjn8nB82HN5Qj20otgjUvhLOdEkkip9mroYsrvqNoKbMedWdCudIcB/YY1w==", + "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.775.0", - "@aws-sdk/credential-provider-node": "3.775.0", - "@aws-sdk/middleware-bucket-endpoint": "3.775.0", - "@aws-sdk/middleware-expect-continue": "3.775.0", - "@aws-sdk/middleware-flexible-checksums": "3.775.0", - "@aws-sdk/middleware-host-header": "3.775.0", - "@aws-sdk/middleware-location-constraint": "3.775.0", - "@aws-sdk/middleware-logger": "3.775.0", - "@aws-sdk/middleware-recursion-detection": "3.775.0", - "@aws-sdk/middleware-sdk-s3": "3.775.0", - "@aws-sdk/middleware-ssec": "3.775.0", - "@aws-sdk/middleware-user-agent": "3.775.0", - "@aws-sdk/region-config-resolver": "3.775.0", - "@aws-sdk/signature-v4-multi-region": "3.775.0", - "@aws-sdk/types": "3.775.0", - "@aws-sdk/util-endpoints": "3.775.0", - "@aws-sdk/util-user-agent-browser": "3.775.0", - "@aws-sdk/util-user-agent-node": "3.775.0", - "@aws-sdk/xml-builder": "3.775.0", - "@smithy/config-resolver": "^4.1.0", - "@smithy/core": "^3.2.0", - "@smithy/eventstream-serde-browser": "^4.0.2", - "@smithy/eventstream-serde-config-resolver": "^4.1.0", - "@smithy/eventstream-serde-node": "^4.0.2", - "@smithy/fetch-http-handler": "^5.0.2", - "@smithy/hash-blob-browser": "^4.0.2", - "@smithy/hash-node": "^4.0.2", - "@smithy/hash-stream-node": "^4.0.2", - "@smithy/invalid-dependency": "^4.0.2", - "@smithy/md5-js": "^4.0.2", - "@smithy/middleware-content-length": "^4.0.2", - "@smithy/middleware-endpoint": "^4.1.0", - "@smithy/middleware-retry": "^4.1.0", - "@smithy/middleware-serde": "^4.0.3", - "@smithy/middleware-stack": "^4.0.2", - "@smithy/node-config-provider": "^4.0.2", - "@smithy/node-http-handler": "^4.0.4", - "@smithy/protocol-http": "^5.1.0", - "@smithy/smithy-client": "^4.2.0", - "@smithy/types": "^4.2.0", - "@smithy/url-parser": "^4.0.2", + "@aws-sdk/core": "3.840.0", + "@aws-sdk/credential-provider-node": "3.840.0", + "@aws-sdk/middleware-bucket-endpoint": "3.840.0", + "@aws-sdk/middleware-expect-continue": "3.840.0", + "@aws-sdk/middleware-flexible-checksums": "3.840.0", + "@aws-sdk/middleware-host-header": "3.840.0", + "@aws-sdk/middleware-location-constraint": "3.840.0", + "@aws-sdk/middleware-logger": "3.840.0", + "@aws-sdk/middleware-recursion-detection": "3.840.0", + "@aws-sdk/middleware-sdk-s3": "3.840.0", + "@aws-sdk/middleware-ssec": "3.840.0", + "@aws-sdk/middleware-user-agent": "3.840.0", + "@aws-sdk/region-config-resolver": "3.840.0", + "@aws-sdk/signature-v4-multi-region": "3.840.0", + "@aws-sdk/types": "3.840.0", + "@aws-sdk/util-endpoints": "3.840.0", + "@aws-sdk/util-user-agent-browser": "3.840.0", + "@aws-sdk/util-user-agent-node": "3.840.0", + "@aws-sdk/xml-builder": "3.821.0", + "@smithy/config-resolver": "^4.1.4", + "@smithy/core": "^3.6.0", + "@smithy/eventstream-serde-browser": "^4.0.4", + "@smithy/eventstream-serde-config-resolver": "^4.1.2", + "@smithy/eventstream-serde-node": "^4.0.4", + "@smithy/fetch-http-handler": "^5.0.4", + "@smithy/hash-blob-browser": "^4.0.4", + "@smithy/hash-node": "^4.0.4", + "@smithy/hash-stream-node": "^4.0.4", + "@smithy/invalid-dependency": "^4.0.4", + "@smithy/md5-js": "^4.0.4", + "@smithy/middleware-content-length": "^4.0.4", + "@smithy/middleware-endpoint": "^4.1.13", + "@smithy/middleware-retry": "^4.1.14", + "@smithy/middleware-serde": "^4.0.8", + "@smithy/middleware-stack": "^4.0.4", + "@smithy/node-config-provider": "^4.1.3", + "@smithy/node-http-handler": "^4.0.6", + "@smithy/protocol-http": "^5.1.2", + "@smithy/smithy-client": "^4.4.5", + "@smithy/types": "^4.3.1", + "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.8", - "@smithy/util-defaults-mode-node": "^4.0.8", - "@smithy/util-endpoints": "^3.0.2", - "@smithy/util-middleware": "^4.0.2", - "@smithy/util-retry": "^4.0.2", - "@smithy/util-stream": "^4.2.0", + "@smithy/util-defaults-mode-browser": "^4.0.21", + "@smithy/util-defaults-mode-node": "^4.0.21", + "@smithy/util-endpoints": "^3.0.6", + "@smithy/util-middleware": "^4.0.4", + "@smithy/util-retry": "^4.0.6", + "@smithy/util-stream": "^4.2.2", "@smithy/util-utf8": "^4.0.0", - "@smithy/util-waiter": "^4.0.3", - "tslib": "^2.6.2" + "@smithy/util-waiter": "^4.0.6", + "@types/uuid": "^9.0.1", + "tslib": "^2.6.2", + "uuid": "^9.0.1" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.775.0.tgz", - "integrity": "sha512-vqG1S2ap77WP4D5qt4bEPE0duQ4myN+cDr1NeP8QpSTajetbkDGVo7h1VViYMcUoFUVWBj6Qf1X1VfOq+uaxbA==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.840.0.tgz", + "integrity": "sha512-3Zp+FWN2hhmKdpS0Ragi5V2ZPsZNScE3jlbgoJjzjI/roHZqO+e3/+XFN4TlM0DsPKYJNp+1TAjmhxN6rOnfYA==", + "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.775.0", - "@aws-sdk/middleware-host-header": "3.775.0", - "@aws-sdk/middleware-logger": "3.775.0", - "@aws-sdk/middleware-recursion-detection": "3.775.0", - "@aws-sdk/middleware-user-agent": "3.775.0", - "@aws-sdk/region-config-resolver": "3.775.0", - "@aws-sdk/types": "3.775.0", - "@aws-sdk/util-endpoints": "3.775.0", - "@aws-sdk/util-user-agent-browser": "3.775.0", - "@aws-sdk/util-user-agent-node": "3.775.0", - "@smithy/config-resolver": "^4.1.0", - "@smithy/core": "^3.2.0", - "@smithy/fetch-http-handler": "^5.0.2", - "@smithy/hash-node": "^4.0.2", - "@smithy/invalid-dependency": "^4.0.2", - "@smithy/middleware-content-length": "^4.0.2", - "@smithy/middleware-endpoint": "^4.1.0", - "@smithy/middleware-retry": "^4.1.0", - "@smithy/middleware-serde": "^4.0.3", - "@smithy/middleware-stack": "^4.0.2", - "@smithy/node-config-provider": "^4.0.2", - "@smithy/node-http-handler": "^4.0.4", - "@smithy/protocol-http": "^5.1.0", - "@smithy/smithy-client": "^4.2.0", - "@smithy/types": "^4.2.0", - "@smithy/url-parser": "^4.0.2", + "@aws-sdk/core": "3.840.0", + "@aws-sdk/middleware-host-header": "3.840.0", + "@aws-sdk/middleware-logger": "3.840.0", + "@aws-sdk/middleware-recursion-detection": "3.840.0", + "@aws-sdk/middleware-user-agent": "3.840.0", + "@aws-sdk/region-config-resolver": "3.840.0", + "@aws-sdk/types": "3.840.0", + "@aws-sdk/util-endpoints": "3.840.0", + "@aws-sdk/util-user-agent-browser": "3.840.0", + "@aws-sdk/util-user-agent-node": "3.840.0", + "@smithy/config-resolver": "^4.1.4", + "@smithy/core": "^3.6.0", + "@smithy/fetch-http-handler": "^5.0.4", + "@smithy/hash-node": "^4.0.4", + "@smithy/invalid-dependency": "^4.0.4", + "@smithy/middleware-content-length": "^4.0.4", + "@smithy/middleware-endpoint": "^4.1.13", + "@smithy/middleware-retry": "^4.1.14", + "@smithy/middleware-serde": "^4.0.8", + "@smithy/middleware-stack": "^4.0.4", + "@smithy/node-config-provider": "^4.1.3", + "@smithy/node-http-handler": "^4.0.6", + "@smithy/protocol-http": "^5.1.2", + "@smithy/smithy-client": "^4.4.5", + "@smithy/types": "^4.3.1", + "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.8", - "@smithy/util-defaults-mode-node": "^4.0.8", - "@smithy/util-endpoints": "^3.0.2", - "@smithy/util-middleware": "^4.0.2", - "@smithy/util-retry": "^4.0.2", + "@smithy/util-defaults-mode-browser": "^4.0.21", + "@smithy/util-defaults-mode-node": "^4.0.21", + "@smithy/util-endpoints": "^3.0.6", + "@smithy/util-middleware": "^4.0.4", + "@smithy/util-retry": "^4.0.6", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" }, @@ -913,19 +981,24 @@ } }, "node_modules/@aws-sdk/core": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.775.0.tgz", - "integrity": "sha512-8vpW4WihVfz0DX+7WnnLGm3GuQER++b0IwQG35JlQMlgqnc44M//KbJPsIHA0aJUJVwJAEShgfr5dUbY8WUzaA==", - "dependencies": { - "@aws-sdk/types": "3.775.0", - "@smithy/core": "^3.2.0", - "@smithy/node-config-provider": "^4.0.2", - "@smithy/property-provider": "^4.0.2", - "@smithy/protocol-http": "^5.1.0", - "@smithy/signature-v4": "^5.0.2", - "@smithy/smithy-client": "^4.2.0", - "@smithy/types": "^4.2.0", - "@smithy/util-middleware": "^4.0.2", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.840.0.tgz", + "integrity": "sha512-x3Zgb39tF1h2XpU+yA4OAAQlW6LVEfXNlSedSYJ7HGKXqA/E9h3rWQVpYfhXXVVsLdYXdNw5KBUkoAoruoZSZA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.840.0", + "@aws-sdk/xml-builder": "3.821.0", + "@smithy/core": "^3.6.0", + "@smithy/node-config-provider": "^4.1.3", + "@smithy/property-provider": "^4.0.4", + "@smithy/protocol-http": "^5.1.2", + "@smithy/signature-v4": "^5.1.2", + "@smithy/smithy-client": "^4.4.5", + "@smithy/types": "^4.3.1", + "@smithy/util-base64": "^4.0.0", + "@smithy/util-body-length-browser": "^4.0.0", + "@smithy/util-middleware": "^4.0.4", + "@smithy/util-utf8": "^4.0.0", "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" }, @@ -934,14 +1007,15 @@ } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.775.0.tgz", - "integrity": "sha512-6ESVxwCbGm7WZ17kY1fjmxQud43vzJFoLd4bmlR+idQSWdqlzGDYdcfzpjDKTcivdtNrVYmFvcH1JBUwCRAZhw==", - "dependencies": { - "@aws-sdk/core": "3.775.0", - "@aws-sdk/types": "3.775.0", - "@smithy/property-provider": "^4.0.2", - "@smithy/types": "^4.2.0", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.840.0.tgz", + "integrity": "sha512-EzF6VcJK7XvQ/G15AVEfJzN2mNXU8fcVpXo4bRyr1S6t2q5zx6UPH/XjDbn18xyUmOq01t+r8gG+TmHEVo18fA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.840.0", + "@aws-sdk/types": "3.840.0", + "@smithy/property-provider": "^4.0.4", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -949,19 +1023,20 @@ } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.775.0.tgz", - "integrity": "sha512-PjDQeDH/J1S0yWV32wCj2k5liRo0ssXMseCBEkCsD3SqsU8o5cU82b0hMX4sAib/RkglCSZqGO0xMiN0/7ndww==", - "dependencies": { - "@aws-sdk/core": "3.775.0", - "@aws-sdk/types": "3.775.0", - "@smithy/fetch-http-handler": "^5.0.2", - "@smithy/node-http-handler": "^4.0.4", - "@smithy/property-provider": "^4.0.2", - "@smithy/protocol-http": "^5.1.0", - "@smithy/smithy-client": "^4.2.0", - "@smithy/types": "^4.2.0", - "@smithy/util-stream": "^4.2.0", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.840.0.tgz", + "integrity": "sha512-wbnUiPGLVea6mXbUh04fu+VJmGkQvmToPeTYdHE8eRZq3NRDi3t3WltT+jArLBKD/4NppRpMjf2ju4coMCz91g==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.840.0", + "@aws-sdk/types": "3.840.0", + "@smithy/fetch-http-handler": "^5.0.4", + "@smithy/node-http-handler": "^4.0.6", + "@smithy/property-provider": "^4.0.4", + "@smithy/protocol-http": "^5.1.2", + "@smithy/smithy-client": "^4.4.5", + "@smithy/types": "^4.3.1", + "@smithy/util-stream": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -969,22 +1044,23 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.775.0.tgz", - "integrity": "sha512-0gJc6cALsgrjeC5U3qDjbz4myIC/j49+gPz9nkvY+C0OYWt1KH1tyfiZUuCRGfuFHhQ+3KMMDSL229TkBP3E7g==", - "dependencies": { - "@aws-sdk/core": "3.775.0", - "@aws-sdk/credential-provider-env": "3.775.0", - "@aws-sdk/credential-provider-http": "3.775.0", - "@aws-sdk/credential-provider-process": "3.775.0", - "@aws-sdk/credential-provider-sso": "3.775.0", - "@aws-sdk/credential-provider-web-identity": "3.775.0", - "@aws-sdk/nested-clients": "3.775.0", - "@aws-sdk/types": "3.775.0", - "@smithy/credential-provider-imds": "^4.0.2", - "@smithy/property-provider": "^4.0.2", - "@smithy/shared-ini-file-loader": "^4.0.2", - "@smithy/types": "^4.2.0", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.840.0.tgz", + "integrity": "sha512-7F290BsWydShHb+7InXd+IjJc3mlEIm9I0R57F/Pjl1xZB69MdkhVGCnuETWoBt4g53ktJd6NEjzm/iAhFXFmw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.840.0", + "@aws-sdk/credential-provider-env": "3.840.0", + "@aws-sdk/credential-provider-http": "3.840.0", + "@aws-sdk/credential-provider-process": "3.840.0", + "@aws-sdk/credential-provider-sso": "3.840.0", + "@aws-sdk/credential-provider-web-identity": "3.840.0", + "@aws-sdk/nested-clients": "3.840.0", + "@aws-sdk/types": "3.840.0", + "@smithy/credential-provider-imds": "^4.0.6", + "@smithy/property-provider": "^4.0.4", + "@smithy/shared-ini-file-loader": "^4.0.4", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -992,21 +1068,22 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.775.0.tgz", - "integrity": "sha512-D8Zre5W2sXC/ANPqCWPqwYpU1cKY9DF6ckFZyDrqlcBC0gANgpY6fLrBtYo2fwJsbj+1A24iIpBINV7erdprgA==", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.775.0", - "@aws-sdk/credential-provider-http": "3.775.0", - "@aws-sdk/credential-provider-ini": "3.775.0", - "@aws-sdk/credential-provider-process": "3.775.0", - "@aws-sdk/credential-provider-sso": "3.775.0", - "@aws-sdk/credential-provider-web-identity": "3.775.0", - "@aws-sdk/types": "3.775.0", - "@smithy/credential-provider-imds": "^4.0.2", - "@smithy/property-provider": "^4.0.2", - "@smithy/shared-ini-file-loader": "^4.0.2", - "@smithy/types": "^4.2.0", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.840.0.tgz", + "integrity": "sha512-KufP8JnxA31wxklLm63evUPSFApGcH8X86z3mv9SRbpCm5ycgWIGVCTXpTOdgq6rPZrwT9pftzv2/b4mV/9clg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.840.0", + "@aws-sdk/credential-provider-http": "3.840.0", + "@aws-sdk/credential-provider-ini": "3.840.0", + "@aws-sdk/credential-provider-process": "3.840.0", + "@aws-sdk/credential-provider-sso": "3.840.0", + "@aws-sdk/credential-provider-web-identity": "3.840.0", + "@aws-sdk/types": "3.840.0", + "@smithy/credential-provider-imds": "^4.0.6", + "@smithy/property-provider": "^4.0.4", + "@smithy/shared-ini-file-loader": "^4.0.4", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -1014,15 +1091,16 @@ } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.775.0.tgz", - "integrity": "sha512-A6k68H9rQp+2+7P7SGO90Csw6nrUEm0Qfjpn9Etc4EboZhhCLs9b66umUsTsSBHus4FDIe5JQxfCUyt1wgNogg==", - "dependencies": { - "@aws-sdk/core": "3.775.0", - "@aws-sdk/types": "3.775.0", - "@smithy/property-provider": "^4.0.2", - "@smithy/shared-ini-file-loader": "^4.0.2", - "@smithy/types": "^4.2.0", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.840.0.tgz", + "integrity": "sha512-HkDQWHy8tCI4A0Ps2NVtuVYMv9cB4y/IuD/TdOsqeRIAT12h8jDb98BwQPNLAImAOwOWzZJ8Cu0xtSpX7CQhMw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.840.0", + "@aws-sdk/types": "3.840.0", + "@smithy/property-provider": "^4.0.4", + "@smithy/shared-ini-file-loader": "^4.0.4", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -1030,17 +1108,18 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.775.0.tgz", - "integrity": "sha512-du06V7u9HDmRuwZnRjf85shO3dffeKOkQplV5/2vf3LgTPNEI9caNomi/cCGyxKGOeSUHAKrQ1HvpPfOaI6t5Q==", - "dependencies": { - "@aws-sdk/client-sso": "3.775.0", - "@aws-sdk/core": "3.775.0", - "@aws-sdk/token-providers": "3.775.0", - "@aws-sdk/types": "3.775.0", - "@smithy/property-provider": "^4.0.2", - "@smithy/shared-ini-file-loader": "^4.0.2", - "@smithy/types": "^4.2.0", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.840.0.tgz", + "integrity": "sha512-2qgdtdd6R0Z1y0KL8gzzwFUGmhBHSUx4zy85L2XV1CXhpRNwV71SVWJqLDVV5RVWVf9mg50Pm3AWrUC0xb0pcA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/client-sso": "3.840.0", + "@aws-sdk/core": "3.840.0", + "@aws-sdk/token-providers": "3.840.0", + "@aws-sdk/types": "3.840.0", + "@smithy/property-provider": "^4.0.4", + "@smithy/shared-ini-file-loader": "^4.0.4", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -1048,15 +1127,16 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.775.0.tgz", - "integrity": "sha512-z4XLYui5aHsr78mbd5BtZfm55OM5V55qK/X17OPrEqjYDDk3GlI8Oe2ZjTmOVrKwMpmzXKhsakeFHKfDyOvv1A==", - "dependencies": { - "@aws-sdk/core": "3.775.0", - "@aws-sdk/nested-clients": "3.775.0", - "@aws-sdk/types": "3.775.0", - "@smithy/property-provider": "^4.0.2", - "@smithy/types": "^4.2.0", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.840.0.tgz", + "integrity": "sha512-dpEeVXG8uNZSmVXReE4WP0lwoioX2gstk4RnUgrdUE3YaPq8A+hJiVAyc3h+cjDeIqfbsQbZm9qFetKC2LF9dQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.840.0", + "@aws-sdk/nested-clients": "3.840.0", + "@aws-sdk/types": "3.840.0", + "@smithy/property-provider": "^4.0.4", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -1064,15 +1144,16 @@ } }, "node_modules/@aws-sdk/middleware-bucket-endpoint": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.775.0.tgz", - "integrity": "sha512-qogMIpVChDYr4xiUNC19/RDSw/sKoHkAhouS6Skxiy6s27HBhow1L3Z1qVYXuBmOZGSWPU0xiyZCvOyWrv9s+Q==", - "dependencies": { - "@aws-sdk/types": "3.775.0", - "@aws-sdk/util-arn-parser": "3.723.0", - "@smithy/node-config-provider": "^4.0.2", - "@smithy/protocol-http": "^5.1.0", - "@smithy/types": "^4.2.0", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.840.0.tgz", + "integrity": "sha512-+gkQNtPwcSMmlwBHFd4saVVS11In6ID1HczNzpM3MXKXRBfSlbZJbCt6wN//AZ8HMklZEik4tcEOG0qa9UY8SQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.840.0", + "@aws-sdk/util-arn-parser": "3.804.0", + "@smithy/node-config-provider": "^4.1.3", + "@smithy/protocol-http": "^5.1.2", + "@smithy/types": "^4.3.1", "@smithy/util-config-provider": "^4.0.0", "tslib": "^2.6.2" }, @@ -1081,13 +1162,14 @@ } }, "node_modules/@aws-sdk/middleware-expect-continue": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.775.0.tgz", - "integrity": "sha512-Apd3owkIeUW5dnk3au9np2IdW2N0zc9NjTjHiH+Mx3zqwSrc+m+ANgJVgk9mnQjMzU/vb7VuxJ0eqdEbp5gYsg==", - "dependencies": { - "@aws-sdk/types": "3.775.0", - "@smithy/protocol-http": "^5.1.0", - "@smithy/types": "^4.2.0", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.840.0.tgz", + "integrity": "sha512-iJg2r6FKsKKvdiU4oCOuCf7Ro/YE0Q2BT/QyEZN3/Rt8Nr4SAZiQOlcBXOCpGvuIKOEAhvDOUnW3aDHL01PdVw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.840.0", + "@smithy/protocol-http": "^5.1.2", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -1095,21 +1177,22 @@ } }, "node_modules/@aws-sdk/middleware-flexible-checksums": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.775.0.tgz", - "integrity": "sha512-OmHLfRIb7IIXsf9/X/pMOlcSV3gzW/MmtPSZTkrz5jCTKzWXd7eRoyOJqewjsaC6KMAxIpNU77FoAd16jOZ21A==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.840.0.tgz", + "integrity": "sha512-Kg/o2G6o72sdoRH0J+avdcf668gM1bp6O4VeEXpXwUj/urQnV5qiB2q1EYT110INHUKWOLXPND3sQAqh6sTqHw==", + "license": "Apache-2.0", "dependencies": { "@aws-crypto/crc32": "5.2.0", "@aws-crypto/crc32c": "5.2.0", "@aws-crypto/util": "5.2.0", - "@aws-sdk/core": "3.775.0", - "@aws-sdk/types": "3.775.0", + "@aws-sdk/core": "3.840.0", + "@aws-sdk/types": "3.840.0", "@smithy/is-array-buffer": "^4.0.0", - "@smithy/node-config-provider": "^4.0.2", - "@smithy/protocol-http": "^5.1.0", - "@smithy/types": "^4.2.0", - "@smithy/util-middleware": "^4.0.2", - "@smithy/util-stream": "^4.2.0", + "@smithy/node-config-provider": "^4.1.3", + "@smithy/protocol-http": "^5.1.2", + "@smithy/types": "^4.3.1", + "@smithy/util-middleware": "^4.0.4", + "@smithy/util-stream": "^4.2.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" }, @@ -1118,13 +1201,14 @@ } }, "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.775.0.tgz", - "integrity": "sha512-tkSegM0Z6WMXpLB8oPys/d+umYIocvO298mGvcMCncpRl77L9XkvSLJIFzaHes+o7djAgIduYw8wKIMStFss2w==", - "dependencies": { - "@aws-sdk/types": "3.775.0", - "@smithy/protocol-http": "^5.1.0", - "@smithy/types": "^4.2.0", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.840.0.tgz", + "integrity": "sha512-ub+hXJAbAje94+Ya6c6eL7sYujoE8D4Bumu1NUI8TXjUhVVn0HzVWQjpRLshdLsUp1AW7XyeJaxyajRaJQ8+Xg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.840.0", + "@smithy/protocol-http": "^5.1.2", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -1132,12 +1216,13 @@ } }, "node_modules/@aws-sdk/middleware-location-constraint": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.775.0.tgz", - "integrity": "sha512-8TMXEHZXZTFTckQLyBT5aEI8fX11HZcwZseRifvBKKpj0RZDk4F0EEYGxeNSPpUQ7n+PRWyfAEnnZNRdAj/1NQ==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.840.0.tgz", + "integrity": "sha512-KVLD0u0YMF3aQkVF8bdyHAGWSUY6N1Du89htTLgqCcIhSxxAJ9qifrosVZ9jkAzqRW99hcufyt2LylcVU2yoKQ==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.775.0", - "@smithy/types": "^4.2.0", + "@aws-sdk/types": "3.840.0", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -1145,12 +1230,13 @@ } }, "node_modules/@aws-sdk/middleware-logger": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.775.0.tgz", - "integrity": "sha512-FaxO1xom4MAoUJsldmR92nT1G6uZxTdNYOFYtdHfd6N2wcNaTuxgjIvqzg5y7QIH9kn58XX/dzf1iTjgqUStZw==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.840.0.tgz", + "integrity": "sha512-lSV8FvjpdllpGaRspywss4CtXV8M7NNNH+2/j86vMH+YCOZ6fu2T/TyFd/tHwZ92vDfHctWkRbQxg0bagqwovA==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.775.0", - "@smithy/types": "^4.2.0", + "@aws-sdk/types": "3.840.0", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -1158,13 +1244,14 @@ } }, "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.775.0.tgz", - "integrity": "sha512-GLCzC8D0A0YDG5u3F5U03Vb9j5tcOEFhr8oc6PDk0k0vm5VwtZOE6LvK7hcCSoAB4HXyOUM0sQuXrbaAh9OwXA==", - "dependencies": { - "@aws-sdk/types": "3.775.0", - "@smithy/protocol-http": "^5.1.0", - "@smithy/types": "^4.2.0", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.840.0.tgz", + "integrity": "sha512-Gu7lGDyfddyhIkj1Z1JtrY5NHb5+x/CRiB87GjaSrKxkDaydtX2CU977JIABtt69l9wLbcGDIQ+W0uJ5xPof7g==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.840.0", + "@smithy/protocol-http": "^5.1.2", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -1172,22 +1259,23 @@ } }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.775.0.tgz", - "integrity": "sha512-zsvcu7cWB28JJ60gVvjxPCI7ZU7jWGcpNACPiZGyVtjYXwcxyhXbYEVDSWKsSA6ERpz9XrpLYod8INQWfW3ECg==", - "dependencies": { - "@aws-sdk/core": "3.775.0", - "@aws-sdk/types": "3.775.0", - "@aws-sdk/util-arn-parser": "3.723.0", - "@smithy/core": "^3.2.0", - "@smithy/node-config-provider": "^4.0.2", - "@smithy/protocol-http": "^5.1.0", - "@smithy/signature-v4": "^5.0.2", - "@smithy/smithy-client": "^4.2.0", - "@smithy/types": "^4.2.0", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.840.0.tgz", + "integrity": "sha512-rOUji7CayWN3O09zvvgLzDVQe0HiJdZkxoTS6vzOS3WbbdT7joGdVtAJHtn+x776QT3hHzbKU5gnfhel0o6gQA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.840.0", + "@aws-sdk/types": "3.840.0", + "@aws-sdk/util-arn-parser": "3.804.0", + "@smithy/core": "^3.6.0", + "@smithy/node-config-provider": "^4.1.3", + "@smithy/protocol-http": "^5.1.2", + "@smithy/signature-v4": "^5.1.2", + "@smithy/smithy-client": "^4.4.5", + "@smithy/types": "^4.3.1", "@smithy/util-config-provider": "^4.0.0", - "@smithy/util-middleware": "^4.0.2", - "@smithy/util-stream": "^4.2.0", + "@smithy/util-middleware": "^4.0.4", + "@smithy/util-stream": "^4.2.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" }, @@ -1196,12 +1284,13 @@ } }, "node_modules/@aws-sdk/middleware-ssec": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.775.0.tgz", - "integrity": "sha512-Iw1RHD8vfAWWPzBBIKaojO4GAvQkHOYIpKdAfis/EUSUmSa79QsnXnRqsdcE0mCB0Ylj23yi+ah4/0wh9FsekA==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.840.0.tgz", + "integrity": "sha512-CBZP9t1QbjDFGOrtnUEHL1oAvmnCUUm7p0aPNbIdSzNtH42TNKjPRN3TuEIJDGjkrqpL3MXyDSmNayDcw/XW7Q==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.775.0", - "@smithy/types": "^4.2.0", + "@aws-sdk/types": "3.840.0", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -1209,16 +1298,17 @@ } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.775.0.tgz", - "integrity": "sha512-7Lffpr1ptOEDE1ZYH1T78pheEY1YmeXWBfFt/amZ6AGsKSLG+JPXvof3ltporTGR2bhH/eJPo7UHCglIuXfzYg==", - "dependencies": { - "@aws-sdk/core": "3.775.0", - "@aws-sdk/types": "3.775.0", - "@aws-sdk/util-endpoints": "3.775.0", - "@smithy/core": "^3.2.0", - "@smithy/protocol-http": "^5.1.0", - "@smithy/types": "^4.2.0", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.840.0.tgz", + "integrity": "sha512-hiiMf7BP5ZkAFAvWRcK67Mw/g55ar7OCrvrynC92hunx/xhMkrgSLM0EXIZ1oTn3uql9kH/qqGF0nqsK6K555A==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.840.0", + "@aws-sdk/types": "3.840.0", + "@aws-sdk/util-endpoints": "3.840.0", + "@smithy/core": "^3.6.0", + "@smithy/protocol-http": "^5.1.2", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -1226,46 +1316,47 @@ } }, "node_modules/@aws-sdk/nested-clients": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.775.0.tgz", - "integrity": "sha512-f37jmAzkuIhKyhtA6s0LGpqQvm218vq+RNMUDkGm1Zz2fxJ5pBIUTDtygiI3vXTcmt9DTIB8S6JQhjrgtboktw==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.840.0.tgz", + "integrity": "sha512-LXYYo9+n4hRqnRSIMXLBb+BLz+cEmjMtTudwK1BF6Bn2RfdDv29KuyeDRrPCS3TwKl7ZKmXUmE9n5UuHAPfBpA==", + "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.775.0", - "@aws-sdk/middleware-host-header": "3.775.0", - "@aws-sdk/middleware-logger": "3.775.0", - "@aws-sdk/middleware-recursion-detection": "3.775.0", - "@aws-sdk/middleware-user-agent": "3.775.0", - "@aws-sdk/region-config-resolver": "3.775.0", - "@aws-sdk/types": "3.775.0", - "@aws-sdk/util-endpoints": "3.775.0", - "@aws-sdk/util-user-agent-browser": "3.775.0", - "@aws-sdk/util-user-agent-node": "3.775.0", - "@smithy/config-resolver": "^4.1.0", - "@smithy/core": "^3.2.0", - "@smithy/fetch-http-handler": "^5.0.2", - "@smithy/hash-node": "^4.0.2", - "@smithy/invalid-dependency": "^4.0.2", - "@smithy/middleware-content-length": "^4.0.2", - "@smithy/middleware-endpoint": "^4.1.0", - "@smithy/middleware-retry": "^4.1.0", - "@smithy/middleware-serde": "^4.0.3", - "@smithy/middleware-stack": "^4.0.2", - "@smithy/node-config-provider": "^4.0.2", - "@smithy/node-http-handler": "^4.0.4", - "@smithy/protocol-http": "^5.1.0", - "@smithy/smithy-client": "^4.2.0", - "@smithy/types": "^4.2.0", - "@smithy/url-parser": "^4.0.2", + "@aws-sdk/core": "3.840.0", + "@aws-sdk/middleware-host-header": "3.840.0", + "@aws-sdk/middleware-logger": "3.840.0", + "@aws-sdk/middleware-recursion-detection": "3.840.0", + "@aws-sdk/middleware-user-agent": "3.840.0", + "@aws-sdk/region-config-resolver": "3.840.0", + "@aws-sdk/types": "3.840.0", + "@aws-sdk/util-endpoints": "3.840.0", + "@aws-sdk/util-user-agent-browser": "3.840.0", + "@aws-sdk/util-user-agent-node": "3.840.0", + "@smithy/config-resolver": "^4.1.4", + "@smithy/core": "^3.6.0", + "@smithy/fetch-http-handler": "^5.0.4", + "@smithy/hash-node": "^4.0.4", + "@smithy/invalid-dependency": "^4.0.4", + "@smithy/middleware-content-length": "^4.0.4", + "@smithy/middleware-endpoint": "^4.1.13", + "@smithy/middleware-retry": "^4.1.14", + "@smithy/middleware-serde": "^4.0.8", + "@smithy/middleware-stack": "^4.0.4", + "@smithy/node-config-provider": "^4.1.3", + "@smithy/node-http-handler": "^4.0.6", + "@smithy/protocol-http": "^5.1.2", + "@smithy/smithy-client": "^4.4.5", + "@smithy/types": "^4.3.1", + "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.8", - "@smithy/util-defaults-mode-node": "^4.0.8", - "@smithy/util-endpoints": "^3.0.2", - "@smithy/util-middleware": "^4.0.2", - "@smithy/util-retry": "^4.0.2", + "@smithy/util-defaults-mode-browser": "^4.0.21", + "@smithy/util-defaults-mode-node": "^4.0.21", + "@smithy/util-endpoints": "^3.0.6", + "@smithy/util-middleware": "^4.0.4", + "@smithy/util-retry": "^4.0.6", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" }, @@ -1274,15 +1365,16 @@ } }, "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.775.0.tgz", - "integrity": "sha512-40iH3LJjrQS3LKUJAl7Wj0bln7RFPEvUYKFxtP8a+oKFDO0F65F52xZxIJbPn6sHkxWDAnZlGgdjZXM3p2g5wQ==", - "dependencies": { - "@aws-sdk/types": "3.775.0", - "@smithy/node-config-provider": "^4.0.2", - "@smithy/types": "^4.2.0", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.840.0.tgz", + "integrity": "sha512-Qjnxd/yDv9KpIMWr90ZDPtRj0v75AqGC92Lm9+oHXZ8p1MjG5JE2CW0HL8JRgK9iKzgKBL7pPQRXI8FkvEVfrA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.840.0", + "@smithy/node-config-provider": "^4.1.3", + "@smithy/types": "^4.3.1", "@smithy/util-config-provider": "^4.0.0", - "@smithy/util-middleware": "^4.0.2", + "@smithy/util-middleware": "^4.0.4", "tslib": "^2.6.2" }, "engines": { @@ -1290,15 +1382,16 @@ } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.775.0.tgz", - "integrity": "sha512-cnGk8GDfTMJ8p7+qSk92QlIk2bmTmFJqhYxcXZ9PysjZtx0xmfCMxnG3Hjy1oU2mt5boPCVSOptqtWixayM17g==", - "dependencies": { - "@aws-sdk/middleware-sdk-s3": "3.775.0", - "@aws-sdk/types": "3.775.0", - "@smithy/protocol-http": "^5.1.0", - "@smithy/signature-v4": "^5.0.2", - "@smithy/types": "^4.2.0", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.840.0.tgz", + "integrity": "sha512-8AoVgHrkSfhvGPtwx23hIUO4MmMnux2pjnso1lrLZGqxfElM6jm2w4jTNLlNXk8uKHGyX89HaAIuT0lL6dJj9g==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-sdk-s3": "3.840.0", + "@aws-sdk/types": "3.840.0", + "@smithy/protocol-http": "^5.1.2", + "@smithy/signature-v4": "^5.1.2", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -1306,15 +1399,17 @@ } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.775.0.tgz", - "integrity": "sha512-Q6MtbEhkOggVSz/dN89rIY/ry80U3v89o0Lrrc+Rpvaiaaz8pEN0DsfEcg0IjpzBQ8Owoa6lNWyglHbzPhaJpA==", - "dependencies": { - "@aws-sdk/nested-clients": "3.775.0", - "@aws-sdk/types": "3.775.0", - "@smithy/property-provider": "^4.0.2", - "@smithy/shared-ini-file-loader": "^4.0.2", - "@smithy/types": "^4.2.0", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.840.0.tgz", + "integrity": "sha512-6BuTOLTXvmgwjK7ve7aTg9JaWFdM5UoMolLVPMyh3wTv9Ufalh8oklxYHUBIxsKkBGO2WiHXytveuxH6tAgTYg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.840.0", + "@aws-sdk/nested-clients": "3.840.0", + "@aws-sdk/types": "3.840.0", + "@smithy/property-provider": "^4.0.4", + "@smithy/shared-ini-file-loader": "^4.0.4", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -1322,11 +1417,12 @@ } }, "node_modules/@aws-sdk/types": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.775.0.tgz", - "integrity": "sha512-ZoGKwa4C9fC9Av6bdfqcW6Ix5ot05F/S4VxWR2nHuMv7hzfmAjTOcUiWT7UR4hM/U0whf84VhDtXN/DWAk52KA==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.840.0.tgz", + "integrity": "sha512-xliuHaUFZxEx1NSXeLLZ9Dyu6+EJVQKEoD+yM+zqUo3YDZ7medKJWY6fIOKiPX/N7XbLdBYwajb15Q7IL8KkeA==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -1334,9 +1430,10 @@ } }, "node_modules/@aws-sdk/util-arn-parser": { - "version": "3.723.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.723.0.tgz", - "integrity": "sha512-ZhEfvUwNliOQROcAk34WJWVYTlTa4694kSVhDSjW6lE1bMataPnIN8A0ycukEzBXmd8ZSoBcQLn6lKGl7XIJ5w==", + "version": "3.804.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.804.0.tgz", + "integrity": "sha512-wmBJqn1DRXnZu3b4EkE6CWnoWMo1ZMvlfkqU5zPz67xx1GMaXlDCchFvKAXMjk4jn/L1O3tKnoFDNsoLV1kgNQ==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -1345,13 +1442,14 @@ } }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.775.0.tgz", - "integrity": "sha512-yjWmUgZC9tUxAo8Uaplqmq0eUh0zrbZJdwxGRKdYxfm4RG6fMw1tj52+KkatH7o+mNZvg1GDcVp/INktxonJLw==", - "dependencies": { - "@aws-sdk/types": "3.775.0", - "@smithy/types": "^4.2.0", - "@smithy/util-endpoints": "^3.0.2", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.840.0.tgz", + "integrity": "sha512-eqE9ROdg/Kk0rj3poutyRCFauPDXIf/WSvCqFiRDDVi6QOnCv/M0g2XW8/jSvkJlOyaXkNCptapIp6BeeFFGYw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.840.0", + "@smithy/types": "^4.3.1", + "@smithy/util-endpoints": "^3.0.6", "tslib": "^2.6.2" }, "engines": { @@ -1359,9 +1457,10 @@ } }, "node_modules/@aws-sdk/util-locate-window": { - "version": "3.723.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.723.0.tgz", - "integrity": "sha512-Yf2CS10BqK688DRsrKI/EO6B8ff5J86NXe4C+VCysK7UOgN0l1zOTeTukZ3H8Q9tYYX3oaF1961o8vRkFm7Nmw==", + "version": "3.804.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.804.0.tgz", + "integrity": "sha512-zVoRfpmBVPodYlnMjgVjfGoEZagyRF5IPn3Uo6ZvOZp24chnW/FRstH7ESDHDDRga4z3V+ElUQHKpFDXWyBW5A==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -1370,25 +1469,27 @@ } }, "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.775.0.tgz", - "integrity": "sha512-txw2wkiJmZKVdDbscK7VBK+u+TJnRtlUjRTLei+elZg2ADhpQxfVAQl436FUeIv6AhB/oRHW6/K/EAGXUSWi0A==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.840.0.tgz", + "integrity": "sha512-JdyZM3EhhL4PqwFpttZu1afDpPJCCc3eyZOLi+srpX11LsGj6sThf47TYQN75HT1CarZ7cCdQHGzP2uy3/xHfQ==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.775.0", - "@smithy/types": "^4.2.0", + "@aws-sdk/types": "3.840.0", + "@smithy/types": "^4.3.1", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.775.0.tgz", - "integrity": "sha512-N9yhTevbizTOMo3drH7Eoy6OkJ3iVPxhV7dwb6CMAObbLneS36CSfA6xQXupmHWcRvZPTz8rd1JGG3HzFOau+g==", - "dependencies": { - "@aws-sdk/middleware-user-agent": "3.775.0", - "@aws-sdk/types": "3.775.0", - "@smithy/node-config-provider": "^4.0.2", - "@smithy/types": "^4.2.0", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.840.0.tgz", + "integrity": "sha512-Fy5JUEDQU1tPm2Yw/YqRYYc27W5+QD/J4mYvQvdWjUGZLB5q3eLFMGD35Uc28ZFoGMufPr4OCxK/bRfWROBRHQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-user-agent": "3.840.0", + "@aws-sdk/types": "3.840.0", + "@smithy/node-config-provider": "^4.1.3", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -1404,11 +1505,12 @@ } }, "node_modules/@aws-sdk/xml-builder": { - "version": "3.775.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.775.0.tgz", - "integrity": "sha512-b9NGO6FKJeLGYnV7Z1yvcP1TNU4dkD5jNsLWOF1/sygZoASaQhNOlaiJ/1OH331YQ1R1oWk38nBb0frsYkDsOQ==", + "version": "3.821.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.821.0.tgz", + "integrity": "sha512-DIIotRnefVL6DiaHtO6/21DhJ4JZnnIwdNbpwiAhdt/AVbttcE4yw925gsjur0OGv5BTYXQXU3YnANBYnZjuQA==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -1416,44 +1518,47 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", - "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.25.9", + "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", - "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.7.tgz", + "integrity": "sha512-xgu/ySj2mTiUFmdE9yCMfBxLp4DHd5DwmbbD05YAuICfodYT3VvRxbrh81LGQ/8UpSdtMdfKMn3KouYDX59DGQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.26.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz", - "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.7.tgz", + "integrity": "sha512-BU2f9tlKQ5CAthiMIgpzAh4eDTLWo1mqi9jqE2OxMG0E/OM199VJt2q8BztTxpnSW0i1ymdwLXRJnYzvDM5r2w==", "dev": true, + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.10", - "@babel/helper-compilation-targets": "^7.26.5", - "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.10", - "@babel/parser": "^7.26.10", - "@babel/template": "^7.26.9", - "@babel/traverse": "^7.26.10", - "@babel/types": "^7.26.10", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.27.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.27.3", + "@babel/helpers": "^7.27.6", + "@babel/parser": "^7.27.7", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.27.7", + "@babel/types": "^7.27.7", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -1473,18 +1578,20 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.0.tgz", - "integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==", + "version": "7.27.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.5.tgz", + "integrity": "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/parser": "^7.27.0", - "@babel/types": "^7.27.0", + "@babel/parser": "^7.27.5", + "@babel/types": "^7.27.3", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -1494,13 +1601,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.0.tgz", - "integrity": "sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.26.8", - "@babel/helper-validator-option": "^7.25.9", + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -1514,6 +1622,7 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^3.0.2" } @@ -1523,32 +1632,35 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", - "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", - "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", + "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9", - "@babel/traverse": "^7.25.9" + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.3" }, "engines": { "node": ">=6.9.0" @@ -1558,61 +1670,67 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", - "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", - "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", - "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz", - "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==", + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.6.tgz", + "integrity": "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.27.0", - "@babel/types": "^7.27.0" + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz", - "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.7.tgz", + "integrity": "sha512-qnzXzDXdr/po3bOTbTIQZ7+TxNKxpkN5IifVLXS+r7qwynkZfPyjZfE7hCXbo7IoO9TNcSyibgONsf2HauUd3Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.27.0" + "@babel/types": "^7.27.7" }, "bin": { "parser": "bin/babel-parser.js" @@ -1626,6 +1744,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1638,6 +1757,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1650,6 +1770,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, @@ -1662,6 +1783,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -1673,12 +1795,13 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", - "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", + "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1692,6 +1815,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -1704,6 +1828,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1712,12 +1837,13 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz", - "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", + "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1731,6 +1857,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -1743,6 +1870,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1755,6 +1883,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -1767,6 +1896,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1779,6 +1909,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1791,6 +1922,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1803,6 +1935,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -1818,6 +1951,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -1829,12 +1963,13 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz", - "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", + "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1844,41 +1979,41 @@ } }, "node_modules/@babel/runtime": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz", - "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz", + "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/template": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz", - "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.26.2", - "@babel/parser": "^7.27.0", - "@babel/types": "^7.27.0" + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.0.tgz", - "integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==", + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.7.tgz", + "integrity": "sha512-X6ZlfR/O/s5EQ/SnUSLzr+6kGnkg8HXGMzpgsMsrJVcfDtH1vIp6ctCN4eZ1LS5c0+te5Cb6Y514fASjMRJ1nw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.27.0", - "@babel/parser": "^7.27.0", - "@babel/template": "^7.27.0", - "@babel/types": "^7.27.0", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.27.5", + "@babel/parser": "^7.27.7", + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.7", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1891,18 +2026,20 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/types": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz", - "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==", + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.7.tgz", + "integrity": "sha512-8OLQgDScAOHXnAz2cV+RfzzNMipuLVBz2biuAJFMV9bfkNf393je3VM8CLkjQodW5+iWsSJdSgSWT6rsZoXHPw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1912,13 +2049,15 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": ">=0.1.90" @@ -1929,6 +2068,7 @@ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", "devOptional": true, + "license": "BSD-3-Clause", "engines": { "node": ">= 12" } @@ -1938,6 +2078,7 @@ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", "devOptional": true, + "license": "MIT", "dependencies": { "@cspotcode/source-map-consumer": "0.8.0" }, @@ -1949,109 +2090,121 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "license": "MIT", "dependencies": { "colorspace": "1.1.x", "enabled": "2.0.x", "kuler": "^2.0.0" } }, - "node_modules/@datadog/native-metrics": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@datadog/native-metrics/-/native-metrics-1.6.0.tgz", - "integrity": "sha512-+8jBzd0nlLV+ay3Vb87DLwz8JHAS817hRhSRQ6zxhud9TyvvcNTNN+VA2sb2fe5UK4aMDvj/sGVJjEtgr4RHew==", + "node_modules/@datadog/libdatadog": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@datadog/libdatadog/-/libdatadog-0.6.0.tgz", + "integrity": "sha512-Ldu+U59LUnejtd7ceXMKJCAFZeYpNdTEEXr8PISY9HFXMa4DOwepcWMaJAAqCPU7LINJeivVwvSD1Pm14VZy7w==", + "license": "Apache-2.0" + }, + "node_modules/@datadog/native-appsec": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@datadog/native-appsec/-/native-appsec-8.5.2.tgz", + "integrity": "sha512-lETBaVhBk+9o0pc+LDnXvp2ImDyT8K2deuqLf8A6q4/QjzCCXyR/yZO9R5+Kdoc93jZMRTWV9Pr4pBwHEdJSVA==", "hasInstallScript": true, + "license": "Apache-2.0", "dependencies": { "node-gyp-build": "^3.9.0" }, "engines": { - "node": ">=12" + "node": ">=16" } }, - "node_modules/@datadog/pprof": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@datadog/pprof/-/pprof-0.3.0.tgz", - "integrity": "sha512-RskYpLD2mWdvUk2OU9p3gynx8QxHtfPdRPWs3vqlM+PMf+wstibcYMW7auNY4s3gVA1mT7HiBjW7j0m37rOHOQ==", + "node_modules/@datadog/native-iast-taint-tracking": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-taint-tracking/-/native-iast-taint-tracking-4.0.0.tgz", + "integrity": "sha512-2uF8RnQkJO5bmLi26Zkhxg+RFJn/uEsesYTflScI/Cz/BWv+792bxI+OaCKvhgmpLkm8EElenlpidcJyZm7GYw==", "hasInstallScript": true, + "license": "Apache-2.0", "dependencies": { - "delay": "^5.0.0", - "findit2": "^2.2.3", - "nan": "^2.14.0", - "node-gyp-build": "^3.9.0", - "p-limit": "^3.0.0", - "pify": "^5.0.0", - "protobufjs": "~6.11.0", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "source-map": "^0.7.3", - "split": "^1.0.1" + "node-gyp-build": "^3.9.0" + } + }, + "node_modules/@datadog/native-metrics": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@datadog/native-metrics/-/native-metrics-3.1.1.tgz", + "integrity": "sha512-MU1gHrolwryrU4X9g+fylA1KPH3S46oqJPEtVyrO+3Kh29z80fegmtyrU22bNt8LigPUK/EdPCnSbMe88QbnxQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-addon-api": "^6.1.0", + "node-gyp-build": "^3.9.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=16" } }, - "node_modules/@datadog/pprof/node_modules/protobufjs": { - "version": "6.11.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", - "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", + "node_modules/@datadog/pprof": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/@datadog/pprof/-/pprof-5.8.2.tgz", + "integrity": "sha512-M+bO4v4TaxYK6k2qJBxnhf7Vh25Wode64y4LfxzGs5kLTFr8eFTp6HJai3/af7U5gjTHX/4s+CHv2bxja97pbw==", "hasInstallScript": true, + "license": "Apache-2.0", "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" + "delay": "^5.0.0", + "node-gyp-build": "<4.0", + "p-limit": "^3.1.0", + "pprof-format": "^2.1.0", + "source-map": "^0.7.4" }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" + "engines": { + "node": ">=16" } }, "node_modules/@datadog/sketches-js": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@datadog/sketches-js/-/sketches-js-1.0.5.tgz", - "integrity": "sha512-1ZKyHxxgDI+zY0r+7msMUhFdLR7gkRgKGcNLdYjtXVyo5H64q16J/Khfp5+YAXOedKizKzT0Jf0kLwQ/IBU/pA==", - "dependencies": { - "protobufjs": "^6.11.3" - } + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@datadog/sketches-js/-/sketches-js-2.1.1.tgz", + "integrity": "sha512-d5RjycE+MObE/hU+8OM5Zp4VjTwiPLRa8299fj7muOmR16fb942z8byoMbCErnGh0lBevvgkGrLclQDvINbIyg==", + "license": "Apache-2.0" }, - "node_modules/@datadog/sketches-js/node_modules/protobufjs": { - "version": "6.11.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", - "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", - "hasInstallScript": true, + "node_modules/@datadog/wasm-js-rewriter": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@datadog/wasm-js-rewriter/-/wasm-js-rewriter-4.0.1.tgz", + "integrity": "sha512-JRa05Je6gw+9+3yZnm/BroQZrEfNwRYCxms56WCCHzOBnoPihQLB0fWy5coVJS29kneCUueUvBvxGp6NVXgdqw==", + "license": "Apache-2.0", "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" + "js-yaml": "^4.1.0", + "lru-cache": "^7.14.0", + "module-details-from-path": "^1.0.3", + "node-gyp-build": "^4.5.0" }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@datadog/wasm-js-rewriter/node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz", + "integrity": "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.5.1.tgz", - "integrity": "sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", "dev": true, + "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.4.3" }, @@ -2070,6 +2223,7 @@ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, + "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -2079,6 +2233,7 @@ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -2102,6 +2257,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -2117,13 +2273,15 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@eslint/js": { "version": "8.57.1", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -2132,6 +2290,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/@golevelup/nestjs-common/-/nestjs-common-2.0.2.tgz", "integrity": "sha512-e5pV5MtFDkTNRxWn1+JTh6SUiI0Sld1++yfwcx3k3MHv7iT3AocvjizTcxnKVPb9BHJjZ68jjPxSND3/zi2FSw==", + "license": "MIT", "dependencies": { "lodash": "^4.17.21" }, @@ -2143,6 +2302,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/@golevelup/nestjs-discovery/-/nestjs-discovery-4.0.3.tgz", "integrity": "sha512-8w3CsXHN7+7Sn2i419Eal1Iw/kOjAd6Kb55M/ZqKBBwACCMn4WiEuzssC71LpBMI1090CiDxuelfPRwwIrQK+A==", + "license": "MIT", "dependencies": { "lodash": "^4.17.21" }, @@ -2155,6 +2315,7 @@ "version": "0.7.2", "resolved": "https://registry.npmjs.org/@golevelup/nestjs-modules/-/nestjs-modules-0.7.2.tgz", "integrity": "sha512-0u5wNm+jxOmRFHHKNbJci180zhCvGsp0ZW3tJt5m2ZMvFhfYjJiVozF5M3chHxqd3q7hH4cNLSE3/78uhjyaxg==", + "license": "MIT", "dependencies": { "lodash": "^4.17.21" }, @@ -2167,6 +2328,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/@golevelup/nestjs-rabbitmq/-/nestjs-rabbitmq-4.1.0.tgz", "integrity": "sha512-I/5eXZjR/8p6Ld+yt7RE56okLNphDXB02gFS+X0/mfIiwp5mE3AfnMlYM12ciO0e4/kJET9sTUY59VuxWlITTg==", + "license": "MIT", "dependencies": { "@golevelup/nestjs-common": "^2.0.0", "@golevelup/nestjs-discovery": "^4.0.0", @@ -2186,6 +2348,7 @@ "version": "3.9.0", "resolved": "https://registry.npmjs.org/amqp-connection-manager/-/amqp-connection-manager-3.9.0.tgz", "integrity": "sha512-ZKw9ckJKz40Lc2pC7DY0NVocpzPalMaCgv0sBn+N4er2QFAJul9pIiMOm/FsPHeCzB+FulV7PckOpmZvWvewGQ==", + "license": "MIT", "dependencies": { "promise-breaker": "^5.0.0" }, @@ -2201,6 +2364,7 @@ "version": "0.8.0", "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.8.0.tgz", "integrity": "sha512-icU+a4kkq4Y1PS4NNi+YPDMwdlbFcZ1EZTQT2nigW3fvOb6AOgUQ9+Mk4ue0Zu5cBg/XpDzB40oH10ysrk2dmA==", + "license": "MIT", "dependencies": { "bitsyntax": "~0.1.0", "bluebird": "^3.7.2", @@ -2216,12 +2380,14 @@ "node_modules/@golevelup/nestjs-rabbitmq/node_modules/promise-breaker": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/promise-breaker/-/promise-breaker-5.0.0.tgz", - "integrity": "sha512-mgsWQuG4kJ1dtO6e/QlNDLFtMkMzzecsC69aI5hlLEjGHFNpHrvGhFi4LiK5jg2SMQj74/diH+wZliL9LpGsyA==" + "integrity": "sha512-mgsWQuG4kJ1dtO6e/QlNDLFtMkMzzecsC69aI5hlLEjGHFNpHrvGhFi4LiK5jg2SMQj74/diH+wZliL9LpGsyA==", + "license": "MIT" }, "node_modules/@golevelup/nestjs-rabbitmq/node_modules/readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -2229,34 +2395,17 @@ "string_decoder": "~0.10.x" } }, - "node_modules/@golevelup/nestjs-rabbitmq/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/@golevelup/nestjs-rabbitmq/node_modules/string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "license": "MIT" }, "node_modules/@graphql-tools/merge": { "version": "8.4.2", "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.4.2.tgz", "integrity": "sha512-XbrHAaj8yDuINph+sAfuq3QCZ/tKblrTLOpirK0+CAgNlZUCHs0Fa+xtMUURgwCVThLle1AF7svJCxFizygLsw==", + "license": "MIT", "dependencies": { "@graphql-tools/utils": "^9.2.1", "tslib": "^2.4.0" @@ -2269,6 +2418,7 @@ "version": "8.7.20", "resolved": "https://registry.npmjs.org/@graphql-tools/mock/-/mock-8.7.20.tgz", "integrity": "sha512-ljcHSJWjC/ZyzpXd5cfNhPI7YljRVvabKHPzKjEs5ElxWu2cdlLGvyNYepApXDsM/OJG/2xuhGM+9GWu5gEAPQ==", + "license": "MIT", "dependencies": { "@graphql-tools/schema": "^9.0.18", "@graphql-tools/utils": "^9.2.1", @@ -2283,6 +2433,7 @@ "version": "9.0.19", "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-9.0.19.tgz", "integrity": "sha512-oBRPoNBtCkk0zbUsyP4GaIzCt8C0aCI4ycIRUL67KK5pOHljKLBBtGT+Jr6hkzA74C8Gco8bpZPe7aWFjiaK2w==", + "license": "MIT", "dependencies": { "@graphql-tools/merge": "^8.4.1", "@graphql-tools/utils": "^9.2.1", @@ -2297,6 +2448,7 @@ "version": "9.2.1", "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz", "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==", + "license": "MIT", "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "tslib": "^2.4.0" @@ -2309,6 +2461,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", + "license": "MIT", "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } @@ -2319,6 +2472,7 @@ "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", "deprecated": "Use @eslint/config-array instead", "dev": true, + "license": "Apache-2.0", "dependencies": { "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", @@ -2333,6 +2487,7 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -2346,56 +2501,563 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "deprecated": "Use @eslint/object-schema instead", - "dev": true - }, - "node_modules/@ioredis/commands": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", - "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==" - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, + "license": "BSD-3-Clause" + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.2.tgz", + "integrity": "sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=8" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.1.0" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.2.tgz", + "integrity": "sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.1.0" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.1.0.tgz", + "integrity": "sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.1.0.tgz", + "integrity": "sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.1.0.tgz", + "integrity": "sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.1.0.tgz", + "integrity": "sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.1.0.tgz", + "integrity": "sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.1.0.tgz", + "integrity": "sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.1.0.tgz", + "integrity": "sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.1.0.tgz", + "integrity": "sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.1.0.tgz", + "integrity": "sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.2.tgz", + "integrity": "sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.2.tgz", + "integrity": "sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.2.tgz", + "integrity": "sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.2.tgz", + "integrity": "sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.1.0" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.2.tgz", + "integrity": "sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.2.tgz", + "integrity": "sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.1.0" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.2.tgz", + "integrity": "sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.4.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.2.tgz", + "integrity": "sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.2.tgz", + "integrity": "sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.2.tgz", + "integrity": "sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@ioredis/commands": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", + "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==", + "license": "MIT" + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/ttlcache": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@isaacs/ttlcache/-/ttlcache-1.4.1.tgz", + "integrity": "sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -2409,6 +3071,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -2421,6 +3084,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -2436,6 +3100,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -2448,6 +3113,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -2457,6 +3123,7 @@ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -2466,6 +3133,7 @@ "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", @@ -2483,6 +3151,7 @@ "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", "dev": true, + "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", "@jest/reporters": "^29.7.0", @@ -2530,6 +3199,7 @@ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/fake-timers": "^29.7.0", "@jest/types": "^29.6.3", @@ -2545,6 +3215,7 @@ "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", "dev": true, + "license": "MIT", "dependencies": { "expect": "^29.7.0", "jest-snapshot": "^29.7.0" @@ -2558,6 +3229,7 @@ "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", "dev": true, + "license": "MIT", "dependencies": { "jest-get-type": "^29.6.3" }, @@ -2570,6 +3242,7 @@ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@sinonjs/fake-timers": "^10.0.2", @@ -2587,6 +3260,7 @@ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", "@jest/expect": "^29.7.0", @@ -2602,6 +3276,7 @@ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", "dev": true, + "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", "@jest/console": "^29.7.0", @@ -2640,11 +3315,34 @@ } } }, + "node_modules/@jest/reporters/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, + "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.27.8" }, @@ -2657,6 +3355,7 @@ "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.18", "callsites": "^3.0.0", @@ -2671,6 +3370,7 @@ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", "dev": true, + "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", "@jest/types": "^29.6.3", @@ -2686,6 +3386,7 @@ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/test-result": "^29.7.0", "graceful-fs": "^4.2.9", @@ -2701,6 +3402,7 @@ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", "@jest/types": "^29.6.3", @@ -2727,6 +3429,7 @@ "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", @@ -2742,20 +3445,18 @@ "node_modules/@josephg/resolvable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@josephg/resolvable/-/resolvable-1.0.1.tgz", - "integrity": "sha512-CtzORUwWTTOTqfVtHaKRJ0I1kNQd1bpn3sUh8I3nJDVY+5/M/Oe1DnEWzPQvqq/xPIIkzzzIP7mfCoAjFRvDhg==" + "integrity": "sha512-CtzORUwWTTOTqfVtHaKRJ0I1kNQd1bpn3sUh8I3nJDVY+5/M/Oe1DnEWzPQvqq/xPIIkzzzIP7mfCoAjFRvDhg==", + "license": "ISC" }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", - "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.11.tgz", + "integrity": "sha512-C512c1ytBTio4MrpWKlJpyFHT6+qfFL8SZ58zBzJ1OOzUEjHeF1BtjY2fH7n4x/g2OV/KiiMLAivOp1DXmiMMw==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { @@ -2763,40 +3464,35 @@ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.9.tgz", + "integrity": "sha512-amBU75CKOOkcQLfyM6J+DnWwz41yTsWI7o8MQ003LwUIWb4NYX/evAblTx1oBBYJySqL/zHPxHXDw5ewpQaUFw==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.3.tgz", + "integrity": "sha512-AiR5uKpFxP3PjO4R19kQGIMwxyRyPuXmKEEy301V1C0+1rVjS94EZQXf1QKZYN8Q0YM+estSPhmx5JwNftv6nw==", + "dev": true, + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.28", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.28.tgz", + "integrity": "sha512-KNNHHwW3EIp4EDYOvYFGyIFfx36R2dNJYH4knnZlF8T5jdbD5Wx8xmSaQ2gP9URkJ04LGEtlcCtwArKcmFcwKw==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -2806,6 +3502,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "license": "MIT", "dependencies": { "debug": "^4.1.1" } @@ -2813,20 +3510,51 @@ "node_modules/@kwsites/promise-deferred": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", - "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==" + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", + "license": "MIT" + }, + "node_modules/@ljharb/through": { + "version": "2.3.14", + "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.14.tgz", + "integrity": "sha512-ajBvlKpWucBB17FuQYUShqpqy8GRgYEpJW0vWJbUu1CV9lWyrDCapy0lScU8T8Z6qn49sSwJB3+M+evYIdGg+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8" + }, + "engines": { + "node": ">= 0.4" + } }, "node_modules/@lukeed/csprng": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz", "integrity": "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==", + "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/@microsoft/tsdoc": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz", + "integrity": "sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==", + "license": "MIT" + }, + "node_modules/@mongodb-js/saslprep": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.3.0.tgz", + "integrity": "sha512-zlayKCsIjYb7/IdfqxorK5+xUMyi4vOKcFy10wKJYc63NSdKI8mNME+uJqfatkPmOSMMUiojrL58IePKBm3gvQ==", + "license": "MIT", + "dependencies": { + "sparse-bitfield": "^3.0.3" + } + }, "node_modules/@multiversx/sdk-bls-wasm": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@multiversx/sdk-bls-wasm/-/sdk-bls-wasm-0.3.5.tgz", "integrity": "sha512-c0tIdQUnbBLSt6NYU+OpeGPYdL0+GV547HeHT8Xc0BKQ7Cj0v82QUoA2QRtWrR1G4MNZmLsIacZSsf6DrIS2Bw==", + "license": "BSD-3-Clause", "engines": { "node": ">=8.9.0" } @@ -2835,6 +3563,7 @@ "version": "13.17.2", "resolved": "https://registry.npmjs.org/@multiversx/sdk-core/-/sdk-core-13.17.2.tgz", "integrity": "sha512-X/Ga66Ubx8IpHPM7pk3gl52KxVR0tbxlN2Zhjz7fg4Xxe0fzWAux5lEuDV8sN3SqD55uyz/l2CkstKgoZWpKWg==", + "license": "MIT", "dependencies": { "@multiversx/sdk-transaction-decoder": "1.0.2", "@noble/ed25519": "1.7.3", @@ -2864,6 +3593,7 @@ "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } @@ -2932,9 +3662,10 @@ } }, "node_modules/@multiversx/sdk-exchange": { - "version": "0.2.21", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-exchange/-/sdk-exchange-0.2.21.tgz", - "integrity": "sha512-ZjaOrpgzF9v504awOC8T+b3lGp4FvHKcIxmA6yuugGcdr45f/hZXd8v6HlZhpR/mRp494zLaPyzgrzkWvJ41wQ==", + "version": "0.2.22", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-exchange/-/sdk-exchange-0.2.22.tgz", + "integrity": "sha512-mRo1U9Fj9S+O4BNGR4Gs9g9+T7hUw/cGoGe2rzqUsGLimfudaGWtHLlkV20Wm3GITVMe2zcFbDFewxkprnSjhg==", + "license": "MIT", "dependencies": { "@multiversx/sdk-core": "^13.6.3", "bignumber.js": "9.0.1" @@ -2944,6 +3675,7 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", + "license": "MIT", "engines": { "node": "*" } @@ -2952,30 +3684,32 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/@multiversx/sdk-native-auth-client/-/sdk-native-auth-client-1.0.9.tgz", "integrity": "sha512-q1/cDRKz7QQsr8lQskUsfGkqJbIut772/MBX52Td4OTGg/G1HAm2xsELe+06y7L537A2rqz5/W9KkJ5yWt968g==", + "license": "GPL-3.0-or-later", "dependencies": { "axios": "^1.7.4" } }, "node_modules/@multiversx/sdk-nestjs-auth": { - "version": "5.0.2-beta.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-auth/-/sdk-nestjs-auth-5.0.2-beta.0.tgz", - "integrity": "sha512-G+rF1gPY72XzbtX/9RO8SBX6FMEa4DO/gOPCR+AwhUM8wTtDiP3CYE8j8Q0SPtDVVArMkonfMDrHmVmRLY3cJg==", + "version": "6.0.1-beta.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-auth/-/sdk-nestjs-auth-6.0.1-beta.0.tgz", + "integrity": "sha512-HBOiXK++CM+JbdRCzSlWNPGVFJesHGk7hQEVMKx9KqYUfBaJYwWACS+Dl3mW9TK2kQyjRLu65vK2whpVSEUyaQ==", "dependencies": { "@multiversx/sdk-core": "^14.0.0", "@multiversx/sdk-native-auth-server": "^2.0.0", "jsonwebtoken": "^9.0.0" }, "peerDependencies": { - "@multiversx/sdk-nestjs-cache": "5.0.2-beta.0", - "@multiversx/sdk-nestjs-common": "5.0.2-beta.0", - "@multiversx/sdk-nestjs-monitoring": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-cache": "6.0.1-beta.0", + "@multiversx/sdk-nestjs-common": "6.0.1-beta.0", + "@multiversx/sdk-nestjs-monitoring": "6.0.1-beta.0", "@nestjs/common": "^10.x" } }, "node_modules/@multiversx/sdk-nestjs-auth/node_modules/@multiversx/sdk-core": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-core/-/sdk-core-14.0.1.tgz", - "integrity": "sha512-50BinNuAg/JkJC+H3s/IfgliB1o+/XhuPB+B83fdV3z4VMxO0s+1JKDACDrr4lJ0uYT1O6Gb+eToHxZr7kGQEw==", + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-core/-/sdk-core-14.2.3.tgz", + "integrity": "sha512-h52YIJ3udMyQSNX1QaZKbm7YpwIFvRI78QEJTes0UoboAUt5Vx5bTc8kZt8Lrfks7FKHEPaUeMdLochUcQbQ4Q==", + "license": "MIT", "dependencies": { "@multiversx/sdk-transaction-decoder": "1.0.2", "@noble/ed25519": "1.7.3", @@ -3005,6 +3739,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@multiversx/sdk-native-auth-server/-/sdk-native-auth-server-2.0.0.tgz", "integrity": "sha512-DdjWyt60Chk6unMVprBV/5zA8rEXjufYdE67UG6XP8RRZiGU1+k6UU14E0TU/iii8K+/5Tj/zfrIrPfbDiASoA==", + "license": "GPL-3.0-or-later", "dependencies": { "axios": "^1.7.4", "bech32": "^2.0.0" @@ -3016,41 +3751,22 @@ "node_modules/@multiversx/sdk-nestjs-auth/node_modules/@multiversx/sdk-native-auth-server/node_modules/bech32": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", - "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" - }, - "node_modules/@multiversx/sdk-nestjs-auth/node_modules/jsonwebtoken": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", - "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", - "dependencies": { - "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.1.1", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=12", - "npm": ">=6" - } + "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==", + "license": "MIT" }, "node_modules/@multiversx/sdk-nestjs-auth/node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/@multiversx/sdk-nestjs-cache": { - "version": "5.0.2-beta.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-cache/-/sdk-nestjs-cache-5.0.2-beta.0.tgz", - "integrity": "sha512-rfEoTwz7SCwdNt+frFUsXkrfJ25WVJwKCrFnwwpqH1mlvct0bi+CtmKzsgmr2fmzcos6fM+8/3XjYVQNnUeBNg==", + "version": "6.0.1-beta.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-cache/-/sdk-nestjs-cache-6.0.1-beta.0.tgz", + "integrity": "sha512-EgpROlz4enMmZ3bY9U3b5zMIzdTWTd0V4F46f4E5CO+N8+zD6vVKjy8/ggjy+DgYgVSCmGObCSBaC4ZrzK1Xhw==", "dependencies": { "lru-cache": "^8.0.4", "moment": "^2.29.4", @@ -3059,9 +3775,9 @@ "uuid": "^8.3.2" }, "peerDependencies": { - "@multiversx/sdk-nestjs-common": "5.0.2-beta.0", - "@multiversx/sdk-nestjs-monitoring": "5.0.2-beta.0", - "@multiversx/sdk-nestjs-redis": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-common": "6.0.1-beta.0", + "@multiversx/sdk-nestjs-monitoring": "6.0.1-beta.0", + "@multiversx/sdk-nestjs-redis": "6.0.1-beta.0", "@nestjs/common": "^10.x", "@nestjs/core": "^10.x" } @@ -3083,9 +3799,9 @@ } }, "node_modules/@multiversx/sdk-nestjs-common": { - "version": "5.0.2-beta.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-common/-/sdk-nestjs-common-5.0.2-beta.0.tgz", - "integrity": "sha512-A0ngCJVeNXe1O6OsiE+cLMwg2SPYZ/9+7xpK+sJiHoruwsKxzZv4BpKBqOHCDPKaXghzwLEKH2oFWxKoYJ37Pw==", + "version": "6.0.1-beta.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-common/-/sdk-nestjs-common-6.0.1-beta.0.tgz", + "integrity": "sha512-r8yabjZFBxntcon3lrIWVWE9S5ACqogDzv60AOu7CvCqDdvRed1Y7wb3bUEcUlJs5NII1r39jsw6D8ZHCW6FlA==", "dependencies": { "@multiversx/sdk-core": "^14.0.0", "nest-winston": "^1.6.2", @@ -3093,7 +3809,7 @@ "winston": "^3.7.2" }, "peerDependencies": { - "@multiversx/sdk-nestjs-monitoring": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-monitoring": "6.0.1-beta.0", "@nestjs/common": "^10.x", "@nestjs/config": "^3.x", "@nestjs/core": "^10.x", @@ -3101,9 +3817,10 @@ } }, "node_modules/@multiversx/sdk-nestjs-common/node_modules/@multiversx/sdk-core": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-core/-/sdk-core-14.0.1.tgz", - "integrity": "sha512-50BinNuAg/JkJC+H3s/IfgliB1o+/XhuPB+B83fdV3z4VMxO0s+1JKDACDrr4lJ0uYT1O6Gb+eToHxZr7kGQEw==", + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-core/-/sdk-core-14.2.3.tgz", + "integrity": "sha512-h52YIJ3udMyQSNX1QaZKbm7YpwIFvRI78QEJTes0UoboAUt5Vx5bTc8kZt8Lrfks7FKHEPaUeMdLochUcQbQ4Q==", + "license": "MIT", "dependencies": { "@multiversx/sdk-transaction-decoder": "1.0.2", "@noble/ed25519": "1.7.3", @@ -3133,23 +3850,24 @@ "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/@multiversx/sdk-nestjs-elastic": { - "version": "5.0.2-beta.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-elastic/-/sdk-nestjs-elastic-5.0.2-beta.0.tgz", - "integrity": "sha512-CgYhG+J88SPYyXjLA84yT2YM6Vlq6nZOi6EnD1WiAlshitoN+0kyrqYnJvCB7wy1BH+BXgUCS6BXOKhpOGSvrg==", + "version": "6.0.1-beta.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-elastic/-/sdk-nestjs-elastic-6.0.1-beta.0.tgz", + "integrity": "sha512-Szx2+/iKrMlwCcRW9y43GZ/Gu3cW9rk3VpdPqpvixt1mxw0hHPbfTX8Tw16o8eW7ZP7SAjFwwYvPG4h3RolGeQ==", "peerDependencies": { - "@multiversx/sdk-nestjs-http": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-http": "6.0.1-beta.0", "@nestjs/common": "^10.x" } }, "node_modules/@multiversx/sdk-nestjs-http": { - "version": "5.0.2-beta.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-http/-/sdk-nestjs-http-5.0.2-beta.0.tgz", - "integrity": "sha512-xUiNU0NCiDY08syAz8x1jbdWzd6Y4yaYRB1oyACL0WbVF60xhBV0VrSbsgRsSSh7wzGfvnGIRHJrmOQEyVZUTg==", + "version": "6.0.1-beta.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-http/-/sdk-nestjs-http-6.0.1-beta.0.tgz", + "integrity": "sha512-/W44lKeomBUld8QqDz8scsMCmF+4gdOg6xgYE8Bxsnqs7HVlj1iCZGeT7xZ/YA3xa0BT0Wmg6Ywh2uBgsF1jlA==", "dependencies": { "@multiversx/sdk-core": "^14.0.0", "@multiversx/sdk-native-auth-client": "^1.0.9", @@ -3157,16 +3875,16 @@ "axios": "^1.7.4" }, "peerDependencies": { - "@multiversx/sdk-nestjs-common": "5.0.2-beta.0", - "@multiversx/sdk-nestjs-monitoring": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-common": "6.0.1-beta.0", + "@multiversx/sdk-nestjs-monitoring": "6.0.1-beta.0", "@nestjs/common": "^10.x", "@nestjs/core": "^10.x" } }, "node_modules/@multiversx/sdk-nestjs-http/node_modules/@multiversx/sdk-core": { - "version": "14.0.2", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-core/-/sdk-core-14.0.2.tgz", - "integrity": "sha512-bVrKH23NSsfVyIZKujFrc8k+mBMM4pJDNe+8CHG3M0OUPi/kOVBev6VFmLpQyW9/t25VHU1lR6c4A/qhZOl1Mw==", + "version": "14.2.9", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-core/-/sdk-core-14.2.9.tgz", + "integrity": "sha512-tssRDroQpYTLX7ZNQyVzb6Bai4N1Nz3mUuJCW7k0i179bGUKR/VFVa0RviAXkv+d3pUkP/NepxdUaVTyaj5jmg==", "dependencies": { "@multiversx/sdk-transaction-decoder": "1.0.2", "@noble/ed25519": "1.7.3", @@ -3184,7 +3902,7 @@ }, "optionalDependencies": { "@multiversx/sdk-bls-wasm": "0.3.5", - "axios": "^1.7.4", + "axios": "^1.10.0", "bip39": "3.1.0" }, "peerDependencies": { @@ -3201,9 +3919,9 @@ } }, "node_modules/@multiversx/sdk-nestjs-monitoring": { - "version": "5.0.2-beta.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-monitoring/-/sdk-nestjs-monitoring-5.0.2-beta.0.tgz", - "integrity": "sha512-fsKRSJxq8UEY/yMa0J4SZUhDwN5OrbrWsJY/F0BZ/UHtlH8mKJhozJft3eh5dhWo0fZB8qkJYDGE5AWOFaagag==", + "version": "6.0.1-beta.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-monitoring/-/sdk-nestjs-monitoring-6.0.1-beta.0.tgz", + "integrity": "sha512-iEAw1c5iTLakjgBFARFvYm82y2+bXAilWo0inU5WQGsR7rqzKM17FvwXwHmVeluOzNpstQYA/FtOX6RQB87Eww==", "dependencies": { "prom-client": "^14.0.1", "winston": "^3.7.2", @@ -3214,15 +3932,15 @@ } }, "node_modules/@multiversx/sdk-nestjs-rabbitmq": { - "version": "5.0.2-beta.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-rabbitmq/-/sdk-nestjs-rabbitmq-5.0.2-beta.0.tgz", - "integrity": "sha512-4JXT+tEymdvjlyTU3l2Ydkyy1BG4W+cULTwzT4zZGyUzCTKkNnMvHFHJ+w4YM5zcWllU1JcdsbazwILA5iWYlA==", + "version": "6.0.1-beta.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-rabbitmq/-/sdk-nestjs-rabbitmq-6.0.1-beta.0.tgz", + "integrity": "sha512-9IJ95+dpGDUr0V9vm9cSZFhKOl4ONHwxIxzBCwcvsYobKXy2rpIqHSBsBDhLf4+4OH0TIy9Uh4p0PPZH70V1mA==", "dependencies": { "@golevelup/nestjs-rabbitmq": "4.0.0", "uuid": "^8.3.2" }, "peerDependencies": { - "@multiversx/sdk-nestjs-common": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-common": "6.0.1-beta.0", "@nestjs/common": "^10.x" } }, @@ -3230,6 +3948,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/@golevelup/nestjs-rabbitmq/-/nestjs-rabbitmq-4.0.0.tgz", "integrity": "sha512-CQHRq/jyK3GlM7Lv4nVaqd+BJ53tZXsrOtO/8/OZh19i0YOcQxyRM7iDdtULeG8omJB5/aGMZNsbioLuupxoog==", + "license": "MIT", "dependencies": { "@golevelup/nestjs-common": "^2.0.0", "@golevelup/nestjs-discovery": "^4.0.0", @@ -3249,6 +3968,7 @@ "version": "3.9.0", "resolved": "https://registry.npmjs.org/amqp-connection-manager/-/amqp-connection-manager-3.9.0.tgz", "integrity": "sha512-ZKw9ckJKz40Lc2pC7DY0NVocpzPalMaCgv0sBn+N4er2QFAJul9pIiMOm/FsPHeCzB+FulV7PckOpmZvWvewGQ==", + "license": "MIT", "dependencies": { "promise-breaker": "^5.0.0" }, @@ -3264,6 +3984,7 @@ "version": "0.8.0", "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.8.0.tgz", "integrity": "sha512-icU+a4kkq4Y1PS4NNi+YPDMwdlbFcZ1EZTQT2nigW3fvOb6AOgUQ9+Mk4ue0Zu5cBg/XpDzB40oH10ysrk2dmA==", + "license": "MIT", "dependencies": { "bitsyntax": "~0.1.0", "bluebird": "^3.7.2", @@ -3279,12 +4000,14 @@ "node_modules/@multiversx/sdk-nestjs-rabbitmq/node_modules/promise-breaker": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/promise-breaker/-/promise-breaker-5.0.0.tgz", - "integrity": "sha512-mgsWQuG4kJ1dtO6e/QlNDLFtMkMzzecsC69aI5hlLEjGHFNpHrvGhFi4LiK5jg2SMQj74/diH+wZliL9LpGsyA==" + "integrity": "sha512-mgsWQuG4kJ1dtO6e/QlNDLFtMkMzzecsC69aI5hlLEjGHFNpHrvGhFi4LiK5jg2SMQj74/diH+wZliL9LpGsyA==", + "license": "MIT" }, "node_modules/@multiversx/sdk-nestjs-rabbitmq/node_modules/readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -3292,42 +4015,25 @@ "string_decoder": "~0.10.x" } }, - "node_modules/@multiversx/sdk-nestjs-rabbitmq/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/@multiversx/sdk-nestjs-rabbitmq/node_modules/string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "license": "MIT" }, "node_modules/@multiversx/sdk-nestjs-rabbitmq/node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/@multiversx/sdk-nestjs-redis": { - "version": "5.0.2-beta.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-redis/-/sdk-nestjs-redis-5.0.2-beta.0.tgz", - "integrity": "sha512-AAwM09WSUjy5RBiuWcFKJAHrbmCLSoH7j2zxc4EnIOWStZABVYU2ErJheMaX/IeAn5yba+U24BJlD75s6KoLHw==", + "version": "6.0.1-beta.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-redis/-/sdk-nestjs-redis-6.0.1-beta.0.tgz", + "integrity": "sha512-Bu/H3LP2ffbnTJTc0iugf9G0CUWoeifOrRXBRD9v1GSko8szhJ439SLnfoQeD9ATBda6ywNtSwsUtAnqJQp6Ew==", "dependencies": { "ioredis": "^5.2.3" }, @@ -3339,6 +4045,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/@multiversx/sdk-transaction-decoder/-/sdk-transaction-decoder-1.0.2.tgz", "integrity": "sha512-j43QsKquu8N51WLmVlJ7dV2P3A1448R7/ktvl8r3i6wRMpfdtzDPNofTdHmMRT7DdQdvs4+RNgz8hVKL11Etsw==", + "license": "MIT", "dependencies": { "bech32": "^2.0.0" } @@ -3346,12 +4053,14 @@ "node_modules/@multiversx/sdk-transaction-decoder/node_modules/bech32": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", - "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" + "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==", + "license": "MIT" }, "node_modules/@multiversx/sdk-transaction-processor": { "version": "0.1.35", "resolved": "https://registry.npmjs.org/@multiversx/sdk-transaction-processor/-/sdk-transaction-processor-0.1.35.tgz", "integrity": "sha512-zbj4zNYhIxjlnxy7/p7so4IroOd+Z3QtIvFkKJEg8HMGSAuF6dObmrmc4dsx8nzG97rFpOLJ7iSyE8Xk9sCvrQ==", + "license": "GPL-3.0-or-later", "dependencies": { "axios": "^1.7.4" } @@ -3402,6 +4111,11 @@ "node": ">=10.0.0" } }, + "node_modules/@multiversx/sdk-wallet/node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, "node_modules/@multiversx/sdk-wallet/node_modules/node-gyp-build": { "version": "4.8.4", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", @@ -3424,6 +4138,7 @@ "version": "12.0.11", "resolved": "https://registry.npmjs.org/@nestjs/apollo/-/apollo-12.0.11.tgz", "integrity": "sha512-E8kBOyGBZ8Zx4qMLnK3+ECZgmLKqNHyYbtkOi0fXWr8ackosLMkRqGgtDVffXRlVA3eo6G3RgnL0Qyu3VvfD5A==", + "license": "MIT", "dependencies": { "@apollo/server-plugin-landing-page-graphql-playground": "4.0.0", "iterall": "1.3.0", @@ -3453,123 +4168,63 @@ } }, "node_modules/@nestjs/apollo/node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, - "node_modules/@nestjs/cli": { - "version": "10.1.17", - "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.1.17.tgz", - "integrity": "sha512-jUEnR2DgC15Op+IhcRWb6cyJrhec9CUQO+GtxCF2Dv9MwLcr4sTDq1UOkfs09HAhpuI8otgF2LoWGTlW3qRuqg==", - "dev": true, - "dependencies": { - "@angular-devkit/core": "16.2.0", - "@angular-devkit/schematics": "16.2.0", - "@angular-devkit/schematics-cli": "16.2.0", - "@nestjs/schematics": "^10.0.1", - "chalk": "4.1.2", - "chokidar": "3.5.3", - "cli-table3": "0.6.3", - "commander": "4.1.1", - "fork-ts-checker-webpack-plugin": "8.0.0", - "inquirer": "8.2.6", - "node-emoji": "1.11.0", - "ora": "5.4.1", - "os-name": "4.0.1", - "rimraf": "4.4.1", - "shelljs": "0.8.5", - "source-map-support": "0.5.21", - "tree-kill": "1.2.2", - "tsconfig-paths": "4.2.0", - "tsconfig-paths-webpack-plugin": "4.1.0", - "typescript": "5.1.6", - "webpack": "5.88.2", - "webpack-node-externals": "3.0.0" - }, - "bin": { - "nest": "bin/nest.js" - }, - "engines": { - "node": ">= 16" - }, - "peerDependencies": { - "@swc/cli": "^0.1.62", - "@swc/core": "^1.3.62" - }, - "peerDependenciesMeta": { - "@swc/cli": { - "optional": true - }, - "@swc/core": { - "optional": true - } - } - }, - "node_modules/@nestjs/cli/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@nestjs/cli/node_modules/glob": { - "version": "9.3.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", - "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "minimatch": "^8.0.2", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@nestjs/cli/node_modules/minimatch": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", - "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "license": "0BSD" }, - "node_modules/@nestjs/cli/node_modules/rimraf": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz", - "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==", + "node_modules/@nestjs/cli": { + "version": "10.4.9", + "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.4.9.tgz", + "integrity": "sha512-s8qYd97bggqeK7Op3iD49X2MpFtW4LVNLAwXFkfbRxKME6IYT7X0muNTJ2+QfI8hpbNx9isWkrLWIp+g5FOhiA==", "dev": true, + "license": "MIT", "dependencies": { - "glob": "^9.2.0" + "@angular-devkit/core": "17.3.11", + "@angular-devkit/schematics": "17.3.11", + "@angular-devkit/schematics-cli": "17.3.11", + "@nestjs/schematics": "^10.0.1", + "chalk": "4.1.2", + "chokidar": "3.6.0", + "cli-table3": "0.6.5", + "commander": "4.1.1", + "fork-ts-checker-webpack-plugin": "9.0.2", + "glob": "10.4.5", + "inquirer": "8.2.6", + "node-emoji": "1.11.0", + "ora": "5.4.1", + "tree-kill": "1.2.2", + "tsconfig-paths": "4.2.0", + "tsconfig-paths-webpack-plugin": "4.2.0", + "typescript": "5.7.2", + "webpack": "5.97.1", + "webpack-node-externals": "3.0.0" }, "bin": { - "rimraf": "dist/cjs/src/bin.js" + "nest": "bin/nest.js" }, "engines": { - "node": ">=14" + "node": ">= 16.14" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "peerDependencies": { + "@swc/cli": "^0.1.62 || ^0.3.0 || ^0.4.0 || ^0.5.0", + "@swc/core": "^1.3.62" + }, + "peerDependenciesMeta": { + "@swc/cli": { + "optional": true + }, + "@swc/core": { + "optional": true + } } }, "node_modules/@nestjs/cli/node_modules/typescript": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", - "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -3579,34 +4234,34 @@ } }, "node_modules/@nestjs/cli/node_modules/webpack": { - "version": "5.88.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz", - "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==", - "dev": true, - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.0", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", - "browserslist": "^4.14.5", + "version": "5.97.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.97.1.tgz", + "integrity": "sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.15.0", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", "schema-utils": "^3.2.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.7", - "watchpack": "^2.4.0", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "bin": { @@ -3626,12 +4281,14 @@ } }, "node_modules/@nestjs/common": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.2.0.tgz", - "integrity": "sha512-QhoIaekEfXJ48IHdp9pBsZho464XoW8LRNid61Qncxx90qWCbe7oT1tswlT8kxn1HxsqEqZ8sXGY3ozLxZeVJQ==", + "version": "10.4.19", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.4.19.tgz", + "integrity": "sha512-0TZJ8H+7qtaqZt6YfZJkDRp0e+v6jjo5/pevPAjUy0WYxaTy16bNNQxFPRKLMe/v1hUr2oGV9imvL2477zNt5g==", + "license": "MIT", "dependencies": { + "file-type": "20.4.1", "iterare": "1.2.1", - "tslib": "2.6.1", + "tslib": "2.8.1", "uid": "2.0.2" }, "funding": { @@ -3641,7 +4298,7 @@ "peerDependencies": { "class-transformer": "*", "class-validator": "*", - "reflect-metadata": "^0.1.12", + "reflect-metadata": "^0.1.12 || ^0.2.0", "rxjs": "^7.1.0" }, "peerDependenciesMeta": { @@ -3653,15 +4310,11 @@ } } }, - "node_modules/@nestjs/common/node_modules/tslib": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", - "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" - }, "node_modules/@nestjs/config": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@nestjs/config/-/config-3.0.1.tgz", "integrity": "sha512-a98MMkDlgUlXTv9qtDbimYfXsuafn/YZOh/S35afutr0Qc5T6KzjyWP5VjxRkv26yI2JM0RhFruByFTM6ezwHA==", + "license": "MIT", "dependencies": { "dotenv": "16.3.1", "dotenv-expand": "10.0.0", @@ -3677,21 +4330,23 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/@nestjs/core": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.2.4.tgz", - "integrity": "sha512-aWeii2l+3pNCc9kIRdLbXQMvrgSZD0jZgXOZv7bZwVf9mClMMi7TussLI4On12VbqVE7LE3gsNgRTwgQJlVC8g==", + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.4.2.tgz", + "integrity": "sha512-h2sjNzFHzoxOHU5Ag/pCVn0CrYHKTa0HfjGAa6GOrffRAsIa1H2nJaUzg89yHZXkHgWi+UynRsp8A4HJ1JVg9w==", "hasInstallScript": true, + "license": "MIT", "dependencies": { "@nuxtjs/opencollective": "0.3.2", "fast-safe-stringify": "2.1.1", "iterare": "1.2.1", - "path-to-regexp": "3.2.0", - "tslib": "2.6.2", + "path-to-regexp": "3.3.0", + "tslib": "2.7.0", "uid": "2.0.2" }, "funding": { @@ -3703,7 +4358,7 @@ "@nestjs/microservices": "^10.0.0", "@nestjs/platform-express": "^10.0.0", "@nestjs/websockets": "^10.0.0", - "reflect-metadata": "^0.1.12", + "reflect-metadata": "^0.1.12 || ^0.2.0", "rxjs": "^7.1.0" }, "peerDependenciesMeta": { @@ -3719,14 +4374,16 @@ } }, "node_modules/@nestjs/core/node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "license": "0BSD" }, "node_modules/@nestjs/event-emitter": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@nestjs/event-emitter/-/event-emitter-2.1.1.tgz", "integrity": "sha512-6L6fBOZTyfFlL7Ih/JDdqlCzZeCW0RjCX28wnzGyg/ncv5F/EOeT1dfopQr1loBRQ3LTgu8OWM7n4zLN4xigsg==", + "license": "MIT", "dependencies": { "eventemitter2": "6.4.9" }, @@ -3739,6 +4396,7 @@ "version": "12.2.2", "resolved": "https://registry.npmjs.org/@nestjs/graphql/-/graphql-12.2.2.tgz", "integrity": "sha512-lUDy/1uqbRA1kBKpXcmY0aHhcPbfeG52Wg5+9Jzd1d57dwSjCAmuO+mWy5jz9ugopVCZeK0S/kdAMvA+r9fNdA==", + "license": "MIT", "dependencies": { "@graphql-tools/merge": "9.0.11", "@graphql-tools/schema": "10.0.10", @@ -3784,6 +4442,7 @@ "version": "9.0.11", "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-9.0.11.tgz", "integrity": "sha512-AJL0XTozn31HoZN8tULzEkbDXyETA5vAFu4Q65kxJDu027p+auaNFYj/y51HP4BhMR4wykoteWyO7/VxKfdpiw==", + "license": "MIT", "dependencies": { "@graphql-tools/utils": "^10.6.1", "tslib": "^2.4.0" @@ -3799,6 +4458,7 @@ "version": "10.0.10", "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-10.0.10.tgz", "integrity": "sha512-TSdDvwgk1Fq3URDuZBMCPXlWLpRpxwaQ+0KqvycVwoHozYnBRZ2Ql9HVgDKnebkGQKmIk2enSeku+ERKxxSG0g==", + "license": "MIT", "dependencies": { "@graphql-tools/merge": "^9.0.11", "@graphql-tools/utils": "^10.6.1", @@ -3816,6 +4476,7 @@ "version": "10.6.1", "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.6.1.tgz", "integrity": "sha512-XHl0/DWkMf/8Dmw1F3RRoMPt6ZwU4J707YWcbPjS+49WZNoTVz6f+prQ4GuwZT8RqTPtrRawnGU93AV73ZLTfQ==", + "license": "MIT", "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "cross-inspect": "1.0.1", @@ -3833,6 +4494,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", + "license": "MIT", "dependencies": { "readdirp": "^4.0.1" }, @@ -3847,6 +4509,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "license": "MIT", "engines": { "node": ">= 14.18.0" }, @@ -3863,6 +4526,7 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "license": "MIT", "bin": { "uuid": "dist/esm/bin/uuid" } @@ -3871,6 +4535,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-2.0.6.tgz", "integrity": "sha512-84ze+CPfp1OWdpRi1/lOu59hOhTz38eVzJvRKrg9ykRFwDz+XleKfMsG0gUqNZYFa6v53XYzeD+xItt8uDW7NQ==", + "license": "MIT", "peerDependencies": { "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0", "class-transformer": "^0.4.0 || ^0.5.0", @@ -3890,6 +4555,7 @@ "version": "10.2.4", "resolved": "https://registry.npmjs.org/@nestjs/microservices/-/microservices-10.2.4.tgz", "integrity": "sha512-GytBFj4onLveWDUm+aj7Ft4518yiRx3dfHwqBzYfekPFWIfzVHNGWQCZUSNpS/jMbTfbM2PAknkuhWFjV1811A==", + "license": "MIT", "dependencies": { "iterare": "1.2.1", "tslib": "2.6.2" @@ -3946,18 +4612,20 @@ "node_modules/@nestjs/microservices/node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "license": "0BSD" }, "node_modules/@nestjs/platform-express": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.2.4.tgz", - "integrity": "sha512-E9F6WYo6bNwvTT0saJpkr8t4BJLbZRwrX5EKbtBRQqyRcw6NAvlKdacKzoo+Sompdre0IbF8AvNRFk4uLZTWqA==", + "version": "10.4.19", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.4.19.tgz", + "integrity": "sha512-IeQkBZUtPeJoO4E0QqSLwkB+60KcThw8/s4gGvAwIRJ5ViuXoxnwU59eBDy84PUuVbNe4VdKjfAF9fuQOEh11Q==", + "license": "MIT", "dependencies": { - "body-parser": "1.20.2", + "body-parser": "1.20.3", "cors": "2.8.5", - "express": "4.18.2", - "multer": "1.4.4-lts.1", - "tslib": "2.6.2" + "express": "4.21.2", + "multer": "2.0.1", + "tslib": "2.8.1" }, "funding": { "type": "opencollective", @@ -3968,208 +4636,14 @@ "@nestjs/core": "^10.0.0" } }, - "node_modules/@nestjs/platform-express/node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/@nestjs/platform-express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/@nestjs/platform-express/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/@nestjs/platform-express/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/@nestjs/platform-express/node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/@nestjs/platform-express/node_modules/express/node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/@nestjs/platform-express/node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/@nestjs/platform-express/node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, - "node_modules/@nestjs/platform-express/node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, - "node_modules/@nestjs/platform-express/node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/@nestjs/platform-express/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/@nestjs/platform-express/node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/@nestjs/platform-express/node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/@nestjs/platform-express/node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, "node_modules/@nestjs/platform-socket.io": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/@nestjs/platform-socket.io/-/platform-socket.io-10.2.4.tgz", - "integrity": "sha512-cHgMDKi4a73uPZ0G+hoYF7horywcebfvDlJJGsvOHaMDxJrARINZzyQECf9Jkmar2c39bIH8zbVs/Sb8Jk7i2Q==", + "version": "10.4.19", + "resolved": "https://registry.npmjs.org/@nestjs/platform-socket.io/-/platform-socket.io-10.4.19.tgz", + "integrity": "sha512-Pfz9dBcXaoUFdVpA/I96NoOTiTQ7eYfDNhQ2sZdQzne3oISEvts5G2SWyQNouoyjqkUPt6X5r/CQ++M4AzSlEQ==", + "license": "MIT", "dependencies": { - "socket.io": "4.7.2", - "tslib": "2.6.2" + "socket.io": "4.8.1", + "tslib": "2.8.1" }, "funding": { "type": "opencollective", @@ -4181,15 +4655,11 @@ "rxjs": "^7.1.0" } }, - "node_modules/@nestjs/platform-socket.io/node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, "node_modules/@nestjs/schedule": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@nestjs/schedule/-/schedule-3.0.3.tgz", "integrity": "sha512-xsMA4dmP3LcW3rt2iMPfm88bDbCj/hLuDsLrKmJQlbnxyCYtBwLtmu/4cSfZELLM7pTDT+E8QDAqGwhYyUUjxg==", + "license": "MIT", "dependencies": { "cron": "2.4.1", "uuid": "9.0.0" @@ -4204,6 +4674,7 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } @@ -4213,6 +4684,7 @@ "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-10.0.2.tgz", "integrity": "sha512-DaZZjymYoIfRqC5W62lnYXIIods1PDY6CGc8+IpRwyinzffjKxZ3DF3exu+mdyvllzkXo9DTXkoX4zOPSJHCkw==", "dev": true, + "license": "MIT", "dependencies": { "@angular-devkit/core": "16.1.8", "@angular-devkit/schematics": "16.1.8", @@ -4229,6 +4701,7 @@ "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.1.8.tgz", "integrity": "sha512-dSRD/+bGanArIXkj+kaU1kDFleZeQMzmBiOXX+pK0Ah9/0Yn1VmY3RZh1zcX9vgIQXV+t7UPrTpOjaERMUtVGw==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "8.12.0", "ajv-formats": "2.1.1", @@ -4255,6 +4728,7 @@ "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.1.8.tgz", "integrity": "sha512-6LyzMdFJs337RTxxkI2U1Ndw0CW5mMX/aXWl8d7cW2odiSrAg8IdlMqpc+AM8+CPfsB0FtS1aWkEZqJLT0jHOg==", "dev": true, + "license": "MIT", "dependencies": { "@angular-devkit/core": "16.1.8", "jsonc-parser": "3.2.0", @@ -4268,11 +4742,19 @@ "yarn": ">= 1.13.0" } }, + "node_modules/@nestjs/schematics/node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true, + "license": "MIT" + }, "node_modules/@nestjs/schematics/node_modules/magic-string": { "version": "0.30.0", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz", "integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.13" }, @@ -4285,28 +4767,31 @@ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/@nestjs/swagger": { - "version": "7.1.16", - "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-7.1.16.tgz", - "integrity": "sha512-f9KBk/BX9MUKPTj7tQNYJ124wV/jP5W2lwWHLGwe/4qQXixuDOo39zP55HIJ44LE7S04B7BOeUOo9GBJD/vRcw==", + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-7.4.2.tgz", + "integrity": "sha512-Mu6TEn1M/owIvAx2B4DUQObQXqo2028R2s9rSZ/hJEgBK95+doTwS0DjmVA2wTeZTyVtXOoN7CsoM5pONBzvKQ==", + "license": "MIT", "dependencies": { - "@nestjs/mapped-types": "2.0.3", + "@microsoft/tsdoc": "^0.15.0", + "@nestjs/mapped-types": "2.0.5", "js-yaml": "4.1.0", "lodash": "4.17.21", - "path-to-regexp": "3.2.0", - "swagger-ui-dist": "5.9.1" + "path-to-regexp": "3.3.0", + "swagger-ui-dist": "5.17.14" }, "peerDependencies": { - "@fastify/static": "^6.0.0", + "@fastify/static": "^6.0.0 || ^7.0.0", "@nestjs/common": "^9.0.0 || ^10.0.0", "@nestjs/core": "^9.0.0 || ^10.0.0", "class-transformer": "*", "class-validator": "*", - "reflect-metadata": "^0.1.12" + "reflect-metadata": "^0.1.12 || ^0.2.0" }, "peerDependenciesMeta": { "@fastify/static": { @@ -4321,14 +4806,15 @@ } }, "node_modules/@nestjs/swagger/node_modules/@nestjs/mapped-types": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-2.0.3.tgz", - "integrity": "sha512-40Zdqg98lqoF0+7ThWIZFStxgzisK6GG22+1ABO4kZiGF/Tu2FE+DYLw+Q9D94vcFWizJ+MSjNN4ns9r6hIGxw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-2.0.5.tgz", + "integrity": "sha512-bSJv4pd6EY99NX9CjBIyn4TVDoSit82DUZlL4I3bqNfy5Gt+gXTa86i3I/i0iIV9P4hntcGM5GyO+FhZAhxtyg==", + "license": "MIT", "peerDependencies": { "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0", "class-transformer": "^0.4.0 || ^0.5.0", "class-validator": "^0.13.0 || ^0.14.0", - "reflect-metadata": "^0.1.12" + "reflect-metadata": "^0.1.12 || ^0.2.0" }, "peerDependenciesMeta": { "class-transformer": { @@ -4344,6 +4830,7 @@ "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.2.4.tgz", "integrity": "sha512-2qqymiuPbC41yCXXhtt4cL8AOcVNu13gBCT13A8roUUdcs4lmtg+H3oXKF/Gc/vlLv2RkSTNO+JuzxP1hydLPg==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "2.6.2" }, @@ -4370,12 +4857,14 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/@nestjs/typeorm": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/@nestjs/typeorm/-/typeorm-10.0.0.tgz", "integrity": "sha512-WQU4HCDTz4UavsFzvGUKDHqi0MO5K47yFoPXdmh+Z/hCNO7SHCMmV9jLiLukM8n5nKUqJ3jDqiljkWBcZPdCtA==", + "license": "MIT", "dependencies": { "uuid": "9.0.0" }, @@ -4391,14 +4880,16 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/@nestjs/websockets": { - "version": "10.4.15", - "resolved": "https://registry.npmjs.org/@nestjs/websockets/-/websockets-10.4.15.tgz", - "integrity": "sha512-OmCUJwvtagzXfMVko595O98UI3M9zg+URL+/HV7vd3QPMCZ3uGCKSq15YYJ99LHJn9NyK4e4Szm2KnHtUg2QzA==", + "version": "10.4.19", + "resolved": "https://registry.npmjs.org/@nestjs/websockets/-/websockets-10.4.19.tgz", + "integrity": "sha512-3HhNZU40/ozB64ZZJ1W1bOOYSbxGuJwmM5Ui8y1uPwbzpL1Uov3wOG3eRp1IflSBK4Ia0wb8Iv3ChpFSTzrNiA==", + "license": "MIT", "dependencies": { "iterare": "1.2.1", "object-hash": "3.0.0", @@ -4426,7 +4917,8 @@ "type": "individual", "url": "https://paulmillr.com/funding/" } - ] + ], + "license": "MIT" }, "node_modules/@noble/hashes": { "version": "1.3.0", @@ -4437,12 +4929,14 @@ "type": "individual", "url": "https://paulmillr.com/funding/" } - ] + ], + "license": "MIT" }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -4455,6 +4949,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "license": "MIT", "engines": { "node": ">= 8" } @@ -4463,6 +4958,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -4475,6 +4971,7 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/@nuxtjs/opencollective/-/opencollective-0.3.2.tgz", "integrity": "sha512-um0xL3fO7Mf4fDxcqx9KryrB7zgRM5JSlvGN5AGkP6JLM5XEKyjeAiPbNxdXVXQ16isuAhYpvP88NgL2BGd6aA==", + "license": "MIT", "dependencies": { "chalk": "^4.1.0", "consola": "^2.15.0", @@ -4488,30 +4985,88 @@ "npm": ">=5.0.0" } }, + "node_modules/@opentelemetry/api": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", + "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/core": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", + "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@paralleldrive/cuid2": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.2.2.tgz", + "integrity": "sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "^1.1.5" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/base64": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/codegen": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/fetch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", "dependencies": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -4520,82 +5075,84 @@ "node_modules/@protobufjs/float": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" }, "node_modules/@sendgrid/client": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-7.7.0.tgz", - "integrity": "sha512-SxH+y8jeAQSnDavrTD0uGDXYIIkFylCo+eDofVmZLQ0f862nnqbC3Vd1ej6b7Le7lboyzQF6F7Fodv02rYspuA==", + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-8.1.5.tgz", + "integrity": "sha512-Jqt8aAuGIpWGa15ZorTWI46q9gbaIdQFA21HIPQQl60rCjzAko75l3D1z7EyjFrNr4MfQ0StusivWh8Rjh10Cg==", + "license": "MIT", "dependencies": { - "@sendgrid/helpers": "^7.7.0", - "axios": "^0.26.0" + "@sendgrid/helpers": "^8.0.0", + "axios": "^1.8.2" }, "engines": { - "node": "6.* || 8.* || >=10.*" - } - }, - "node_modules/@sendgrid/client/node_modules/axios": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", - "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", - "dependencies": { - "follow-redirects": "^1.14.8" + "node": ">=12.*" } }, "node_modules/@sendgrid/helpers": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@sendgrid/helpers/-/helpers-7.7.0.tgz", - "integrity": "sha512-3AsAxfN3GDBcXoZ/y1mzAAbKzTtUZ5+ZrHOmWQ279AuaFXUNCh9bPnRpN504bgveTqoW+11IzPg3I0WVgDINpw==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@sendgrid/helpers/-/helpers-8.0.0.tgz", + "integrity": "sha512-Ze7WuW2Xzy5GT5WRx+yEv89fsg/pgy3T1E3FS0QEx0/VvRmigMZ5qyVGhJz4SxomegDkzXv/i0aFPpHKN8qdAA==", + "license": "MIT", "dependencies": { "deepmerge": "^4.2.2" }, "engines": { - "node": ">= 6.0.0" + "node": ">= 12.0.0" } }, "node_modules/@sendgrid/mail": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@sendgrid/mail/-/mail-7.7.0.tgz", - "integrity": "sha512-5+nApPE9wINBvHSUxwOxkkQqM/IAAaBYoP9hw7WwgDNQPxraruVqHizeTitVtKGiqWCKm2mnjh4XGN3fvFLqaw==", + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@sendgrid/mail/-/mail-8.1.5.tgz", + "integrity": "sha512-W+YuMnkVs4+HA/bgfto4VHKcPKLc7NiZ50/NH2pzO6UHCCFuq8/GNB98YJlLEr/ESDyzAaDr7lVE7hoBwFTT3Q==", + "license": "MIT", "dependencies": { - "@sendgrid/client": "^7.7.0", - "@sendgrid/helpers": "^7.7.0" + "@sendgrid/client": "^8.1.5", + "@sendgrid/helpers": "^8.0.0" }, "engines": { - "node": "6.* || 8.* || >=10.*" + "node": ">=12.*" } }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@sinonjs/commons": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" } @@ -4605,16 +5162,18 @@ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.0" } }, "node_modules/@smithy/abort-controller": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.0.2.tgz", - "integrity": "sha512-Sl/78VDtgqKxN2+1qduaVE140XF+Xg+TafkncspwM4jFP/LHr76ZHmIY/y3V1M0mMLNk+Je6IGbzxy23RSToMw==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.0.4.tgz", + "integrity": "sha512-gJnEjZMvigPDQWHrW3oPrFhQtkrgqBkyjj3pCIdF3A5M6vsZODG93KNlfJprv6bp4245bdT32fsHK4kkH3KYDA==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -4625,6 +5184,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-5.0.0.tgz", "integrity": "sha512-+sKqDBQqb036hh4NPaUiEkYFkTUGYzRsn3EuFhyfQfMy6oGHEUJDurLP9Ufb5dasr/XiAmPNMr6wa9afjQB+Gw==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -4636,6 +5196,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-4.0.0.tgz", "integrity": "sha512-R9wM2yPmfEMsUmlMlIgSzOyICs0x9uu7UTHoccMyt7BWw8shcGM8HqB355+BZCPBcySvbTYMs62EgEQkNxz2ig==", + "license": "Apache-2.0", "dependencies": { "@smithy/util-base64": "^4.0.0", "tslib": "^2.6.2" @@ -4645,14 +5206,15 @@ } }, "node_modules/@smithy/config-resolver": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.1.0.tgz", - "integrity": "sha512-8smPlwhga22pwl23fM5ew4T9vfLUCeFXlcqNOCD5M5h8VmNPNUE9j6bQSuRXpDSV11L/E/SwEBQuW8hr6+nS1A==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.1.4.tgz", + "integrity": "sha512-prmU+rDddxHOH0oNcwemL+SwnzcG65sBF2yXRO7aeXIn/xTlq2pX7JLVbkBnVLowHLg4/OL4+jBmv9hVrVGS+w==", + "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/node-config-provider": "^4.1.3", + "@smithy/types": "^4.3.1", "@smithy/util-config-provider": "^4.0.0", - "@smithy/util-middleware": "^4.0.2", + "@smithy/util-middleware": "^4.0.4", "tslib": "^2.6.2" }, "engines": { @@ -4660,16 +5222,18 @@ } }, "node_modules/@smithy/core": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.2.0.tgz", - "integrity": "sha512-k17bgQhVZ7YmUvA8at4af1TDpl0NDMBuBKJl8Yg0nrefwmValU+CnA5l/AriVdQNthU/33H3nK71HrLgqOPr1Q==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.6.0.tgz", + "integrity": "sha512-Pgvfb+TQ4wUNLyHzvgCP4aYZMh16y7GcfF59oirRHcgGgkH1e/s9C0nv/v3WP+Quymyr5je71HeFQCwh+44XLg==", + "license": "Apache-2.0", "dependencies": { - "@smithy/middleware-serde": "^4.0.3", - "@smithy/protocol-http": "^5.1.0", - "@smithy/types": "^4.2.0", + "@smithy/middleware-serde": "^4.0.8", + "@smithy/protocol-http": "^5.1.2", + "@smithy/types": "^4.3.1", + "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", - "@smithy/util-middleware": "^4.0.2", - "@smithy/util-stream": "^4.2.0", + "@smithy/util-middleware": "^4.0.4", + "@smithy/util-stream": "^4.2.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" }, @@ -4678,14 +5242,15 @@ } }, "node_modules/@smithy/credential-provider-imds": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.0.2.tgz", - "integrity": "sha512-32lVig6jCaWBHnY+OEQ6e6Vnt5vDHaLiydGrwYMW9tPqO688hPGTYRamYJ1EptxEC2rAwJrHWmPoKRBl4iTa8w==", - "dependencies": { - "@smithy/node-config-provider": "^4.0.2", - "@smithy/property-provider": "^4.0.2", - "@smithy/types": "^4.2.0", - "@smithy/url-parser": "^4.0.2", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.0.6.tgz", + "integrity": "sha512-hKMWcANhUiNbCJouYkZ9V3+/Qf9pteR1dnwgdyzR09R4ODEYx8BbUysHwRSyex4rZ9zapddZhLFTnT4ZijR4pw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.1.3", + "@smithy/property-provider": "^4.0.4", + "@smithy/types": "^4.3.1", + "@smithy/url-parser": "^4.0.4", "tslib": "^2.6.2" }, "engines": { @@ -4693,12 +5258,13 @@ } }, "node_modules/@smithy/eventstream-codec": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.0.2.tgz", - "integrity": "sha512-p+f2kLSK7ZrXVfskU/f5dzksKTewZk8pJLPvER3aFHPt76C2MxD9vNatSfLzzQSQB4FNO96RK4PSXfhD1TTeMQ==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.0.4.tgz", + "integrity": "sha512-7XoWfZqWb/QoR/rAU4VSi0mWnO2vu9/ltS6JZ5ZSZv0eovLVfDfu0/AX4ub33RsJTOth3TiFWSHS5YdztvFnig==", + "license": "Apache-2.0", "dependencies": { "@aws-crypto/crc32": "5.2.0", - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.3.1", "@smithy/util-hex-encoding": "^4.0.0", "tslib": "^2.6.2" }, @@ -4707,12 +5273,13 @@ } }, "node_modules/@smithy/eventstream-serde-browser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.0.2.tgz", - "integrity": "sha512-CepZCDs2xgVUtH7ZZ7oDdZFH8e6Y2zOv8iiX6RhndH69nlojCALSKK+OXwZUgOtUZEUaZ5e1hULVCHYbCn7pug==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.0.4.tgz", + "integrity": "sha512-3fb/9SYaYqbpy/z/H3yIi0bYKyAa89y6xPmIqwr2vQiUT2St+avRt8UKwsWt9fEdEasc5d/V+QjrviRaX1JRFA==", + "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-serde-universal": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/eventstream-serde-universal": "^4.0.4", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -4720,11 +5287,12 @@ } }, "node_modules/@smithy/eventstream-serde-config-resolver": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.1.0.tgz", - "integrity": "sha512-1PI+WPZ5TWXrfj3CIoKyUycYynYJgZjuQo8U+sphneOtjsgrttYybdqESFReQrdWJ+LKt6NEdbYzmmfDBmjX2A==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.1.2.tgz", + "integrity": "sha512-JGtambizrWP50xHgbzZI04IWU7LdI0nh/wGbqH3sJesYToMi2j/DcoElqyOcqEIG/D4tNyxgRuaqBXWE3zOFhQ==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -4732,12 +5300,13 @@ } }, "node_modules/@smithy/eventstream-serde-node": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.0.2.tgz", - "integrity": "sha512-C5bJ/C6x9ENPMx2cFOirspnF9ZsBVnBMtP6BdPl/qYSuUawdGQ34Lq0dMcf42QTjUZgWGbUIZnz6+zLxJlb9aw==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.0.4.tgz", + "integrity": "sha512-RD6UwNZ5zISpOWPuhVgRz60GkSIp0dy1fuZmj4RYmqLVRtejFqQ16WmfYDdoSoAjlp1LX+FnZo+/hkdmyyGZ1w==", + "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-serde-universal": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/eventstream-serde-universal": "^4.0.4", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -4745,12 +5314,13 @@ } }, "node_modules/@smithy/eventstream-serde-universal": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.0.2.tgz", - "integrity": "sha512-St8h9JqzvnbB52FtckiHPN4U/cnXcarMniXRXTKn0r4b4XesZOGiAyUdj1aXbqqn1icSqBlzzUsCl6nPB018ng==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.0.4.tgz", + "integrity": "sha512-UeJpOmLGhq1SLox79QWw/0n2PFX+oPRE1ZyRMxPIaFEfCqWaqpB7BU9C8kpPOGEhLF7AwEqfFbtwNxGy4ReENA==", + "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-codec": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/eventstream-codec": "^4.0.4", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -4758,13 +5328,14 @@ } }, "node_modules/@smithy/fetch-http-handler": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.0.2.tgz", - "integrity": "sha512-+9Dz8sakS9pe7f2cBocpJXdeVjMopUDLgZs1yWeu7h++WqSbjUYv/JAJwKwXw1HV6gq1jyWjxuyn24E2GhoEcQ==", - "dependencies": { - "@smithy/protocol-http": "^5.1.0", - "@smithy/querystring-builder": "^4.0.2", - "@smithy/types": "^4.2.0", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.0.4.tgz", + "integrity": "sha512-AMtBR5pHppYMVD7z7G+OlHHAcgAN7v0kVKEpHuTO4Gb199Gowh0taYi9oDStFeUhetkeP55JLSVlTW1n9rFtUw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.1.2", + "@smithy/querystring-builder": "^4.0.4", + "@smithy/types": "^4.3.1", "@smithy/util-base64": "^4.0.0", "tslib": "^2.6.2" }, @@ -4773,13 +5344,14 @@ } }, "node_modules/@smithy/hash-blob-browser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-4.0.2.tgz", - "integrity": "sha512-3g188Z3DyhtzfBRxpZjU8R9PpOQuYsbNnyStc/ZVS+9nVX1f6XeNOa9IrAh35HwwIZg+XWk8bFVtNINVscBP+g==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-4.0.4.tgz", + "integrity": "sha512-WszRiACJiQV3QG6XMV44i5YWlkrlsM5Yxgz4jvsksuu7LDXA6wAtypfPajtNTadzpJy3KyJPoWehYpmZGKUFIQ==", + "license": "Apache-2.0", "dependencies": { "@smithy/chunked-blob-reader": "^5.0.0", "@smithy/chunked-blob-reader-native": "^4.0.0", - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -4787,11 +5359,12 @@ } }, "node_modules/@smithy/hash-node": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.0.2.tgz", - "integrity": "sha512-VnTpYPnRUE7yVhWozFdlxcYknv9UN7CeOqSrMH+V877v4oqtVYuoqhIhtSjmGPvYrYnAkaM61sLMKHvxL138yg==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.0.4.tgz", + "integrity": "sha512-qnbTPUhCVnCgBp4z4BUJUhOEkVwxiEi1cyFM+Zj6o+aY8OFGxUQleKWq8ltgp3dujuhXojIvJWdoqpm6dVO3lQ==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.3.1", "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" @@ -4801,11 +5374,12 @@ } }, "node_modules/@smithy/hash-stream-node": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-4.0.2.tgz", - "integrity": "sha512-POWDuTznzbIwlEXEvvXoPMS10y0WKXK790soe57tFRfvf4zBHyzE529HpZMqmDdwG9MfFflnyzndUQ8j78ZdSg==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-4.0.4.tgz", + "integrity": "sha512-wHo0d8GXyVmpmMh/qOR0R7Y46/G1y6OR8U+bSTB4ppEzRxd1xVAQ9xOE9hOc0bSjhz0ujCPAbfNLkLrpa6cevg==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.3.1", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" }, @@ -4814,11 +5388,12 @@ } }, "node_modules/@smithy/invalid-dependency": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.0.2.tgz", - "integrity": "sha512-GatB4+2DTpgWPday+mnUkoumP54u/MDM/5u44KF9hIu8jF0uafZtQLcdfIKkIcUNuF/fBojpLEHZS/56JqPeXQ==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.0.4.tgz", + "integrity": "sha512-bNYMi7WKTJHu0gn26wg8OscncTt1t2b8KcsZxvOv56XA6cyXtOAAAaNP7+m45xfppXfOatXF3Sb1MNsLUgVLTw==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -4829,6 +5404,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.0.0.tgz", "integrity": "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -4837,11 +5413,12 @@ } }, "node_modules/@smithy/md5-js": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.0.2.tgz", - "integrity": "sha512-Hc0R8EiuVunUewCse2syVgA2AfSRco3LyAv07B/zCOMa+jpXI9ll+Q21Nc6FAlYPcpNcAXqBzMhNs1CD/pP2bA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.0.4.tgz", + "integrity": "sha512-uGLBVqcOwrLvGh/v/jw423yWHq/ofUGK1W31M2TNspLQbUV1Va0F5kTxtirkoHawODAZcjXTSGi7JwbnPcDPJg==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.3.1", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" }, @@ -4850,12 +5427,13 @@ } }, "node_modules/@smithy/middleware-content-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.0.2.tgz", - "integrity": "sha512-hAfEXm1zU+ELvucxqQ7I8SszwQ4znWMbNv6PLMndN83JJN41EPuS93AIyh2N+gJ6x8QFhzSO6b7q2e6oClDI8A==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.0.4.tgz", + "integrity": "sha512-F7gDyfI2BB1Kc+4M6rpuOLne5LOcEknH1n6UQB69qv+HucXBR1rkzXBnQTB2q46sFy1PM/zuSJOB532yc8bg3w==", + "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.1.0", - "@smithy/types": "^4.2.0", + "@smithy/protocol-http": "^5.1.2", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -4863,17 +5441,18 @@ } }, "node_modules/@smithy/middleware-endpoint": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.1.0.tgz", - "integrity": "sha512-xhLimgNCbCzsUppRTGXWkZywksuTThxaIB0HwbpsVLY5sceac4e1TZ/WKYqufQLaUy+gUSJGNdwD2jo3cXL0iA==", - "dependencies": { - "@smithy/core": "^3.2.0", - "@smithy/middleware-serde": "^4.0.3", - "@smithy/node-config-provider": "^4.0.2", - "@smithy/shared-ini-file-loader": "^4.0.2", - "@smithy/types": "^4.2.0", - "@smithy/url-parser": "^4.0.2", - "@smithy/util-middleware": "^4.0.2", + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.1.13.tgz", + "integrity": "sha512-xg3EHV/Q5ZdAO5b0UiIMj3RIOCobuS40pBBODguUDVdko6YK6QIzCVRrHTogVuEKglBWqWenRnZ71iZnLL3ZAQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.6.0", + "@smithy/middleware-serde": "^4.0.8", + "@smithy/node-config-provider": "^4.1.3", + "@smithy/shared-ini-file-loader": "^4.0.4", + "@smithy/types": "^4.3.1", + "@smithy/url-parser": "^4.0.4", + "@smithy/util-middleware": "^4.0.4", "tslib": "^2.6.2" }, "engines": { @@ -4881,17 +5460,18 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.1.0.tgz", - "integrity": "sha512-2zAagd1s6hAaI/ap6SXi5T3dDwBOczOMCSkkYzktqN1+tzbk1GAsHNAdo/1uzxz3Ky02jvZQwbi/vmDA6z4Oyg==", - "dependencies": { - "@smithy/node-config-provider": "^4.0.2", - "@smithy/protocol-http": "^5.1.0", - "@smithy/service-error-classification": "^4.0.2", - "@smithy/smithy-client": "^4.2.0", - "@smithy/types": "^4.2.0", - "@smithy/util-middleware": "^4.0.2", - "@smithy/util-retry": "^4.0.2", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.1.14.tgz", + "integrity": "sha512-eoXaLlDGpKvdmvt+YBfRXE7HmIEtFF+DJCbTPwuLunP0YUnrydl+C4tS+vEM0+nyxXrX3PSUFqC+lP1+EHB1Tw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.1.3", + "@smithy/protocol-http": "^5.1.2", + "@smithy/service-error-classification": "^4.0.6", + "@smithy/smithy-client": "^4.4.5", + "@smithy/types": "^4.3.1", + "@smithy/util-middleware": "^4.0.4", + "@smithy/util-retry": "^4.0.6", "tslib": "^2.6.2", "uuid": "^9.0.1" }, @@ -4900,11 +5480,13 @@ } }, "node_modules/@smithy/middleware-serde": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.0.3.tgz", - "integrity": "sha512-rfgDVrgLEVMmMn0BI8O+8OVr6vXzjV7HZj57l0QxslhzbvVfikZbVfBVthjLHqib4BW44QhcIgJpvebHlRaC9A==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.0.8.tgz", + "integrity": "sha512-iSSl7HJoJaGyMIoNn2B7czghOVwJ9nD7TMvLhMWeSB5vt0TnEYyRRqPJu/TqW76WScaNvYYB8nRoiBHR9S1Ddw==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/protocol-http": "^5.1.2", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -4912,11 +5494,12 @@ } }, "node_modules/@smithy/middleware-stack": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.0.2.tgz", - "integrity": "sha512-eSPVcuJJGVYrFYu2hEq8g8WWdJav3sdrI4o2c6z/rjnYDd3xH9j9E7deZQCzFn4QvGPouLngH3dQ+QVTxv5bOQ==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.0.4.tgz", + "integrity": "sha512-kagK5ggDrBUCCzI93ft6DjteNSfY8Ulr83UtySog/h09lTIOAJ/xUSObutanlPT0nhoHAkpmW9V5K8oPyLh+QA==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -4924,13 +5507,14 @@ } }, "node_modules/@smithy/node-config-provider": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.0.2.tgz", - "integrity": "sha512-WgCkILRZfJwJ4Da92a6t3ozN/zcvYyJGUTmfGbgS/FkCcoCjl7G4FJaCDN1ySdvLvemnQeo25FdkyMSTSwulsw==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.1.3.tgz", + "integrity": "sha512-HGHQr2s59qaU1lrVH6MbLlmOBxadtzTsoO4c+bF5asdgVik3I8o7JIOzoeqWc5MjVa+vD36/LWE0iXKpNqooRw==", + "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^4.0.2", - "@smithy/shared-ini-file-loader": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/property-provider": "^4.0.4", + "@smithy/shared-ini-file-loader": "^4.0.4", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -4938,14 +5522,15 @@ } }, "node_modules/@smithy/node-http-handler": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.0.4.tgz", - "integrity": "sha512-/mdqabuAT3o/ihBGjL94PUbTSPSRJ0eeVTdgADzow0wRJ0rN4A27EOrtlK56MYiO1fDvlO3jVTCxQtQmK9dZ1g==", - "dependencies": { - "@smithy/abort-controller": "^4.0.2", - "@smithy/protocol-http": "^5.1.0", - "@smithy/querystring-builder": "^4.0.2", - "@smithy/types": "^4.2.0", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.0.6.tgz", + "integrity": "sha512-NqbmSz7AW2rvw4kXhKGrYTiJVDHnMsFnX4i+/FzcZAfbOBauPYs2ekuECkSbtqaxETLLTu9Rl/ex6+I2BKErPA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/abort-controller": "^4.0.4", + "@smithy/protocol-http": "^5.1.2", + "@smithy/querystring-builder": "^4.0.4", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -4953,11 +5538,12 @@ } }, "node_modules/@smithy/property-provider": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.0.2.tgz", - "integrity": "sha512-wNRoQC1uISOuNc2s4hkOYwYllmiyrvVXWMtq+TysNRVQaHm4yoafYQyjN/goYZS+QbYlPIbb/QRjaUZMuzwQ7A==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.0.4.tgz", + "integrity": "sha512-qHJ2sSgu4FqF4U/5UUp4DhXNmdTrgmoAai6oQiM+c5RZ/sbDwJ12qxB1M6FnP+Tn/ggkPZf9ccn4jqKSINaquw==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -4965,11 +5551,12 @@ } }, "node_modules/@smithy/protocol-http": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.1.0.tgz", - "integrity": "sha512-KxAOL1nUNw2JTYrtviRRjEnykIDhxc84qMBzxvu1MUfQfHTuBlCG7PA6EdVwqpJjH7glw7FqQoFxUJSyBQgu7g==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.1.2.tgz", + "integrity": "sha512-rOG5cNLBXovxIrICSBm95dLqzfvxjEmuZx4KK3hWwPFHGdW3lxY0fZNXfv2zebfRO7sJZ5pKJYHScsqopeIWtQ==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -4977,11 +5564,12 @@ } }, "node_modules/@smithy/querystring-builder": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.0.2.tgz", - "integrity": "sha512-NTOs0FwHw1vimmQM4ebh+wFQvOwkEf/kQL6bSM1Lock+Bv4I89B3hGYoUEPkmvYPkDKyp5UdXJYu+PoTQ3T31Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.0.4.tgz", + "integrity": "sha512-SwREZcDnEYoh9tLNgMbpop+UTGq44Hl9tdj3rf+yeLcfH7+J8OXEBaMc2kDxtyRHu8BhSg9ADEx0gFHvpJgU8w==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.3.1", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" }, @@ -4990,11 +5578,12 @@ } }, "node_modules/@smithy/querystring-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.0.2.tgz", - "integrity": "sha512-v6w8wnmZcVXjfVLjxw8qF7OwESD9wnpjp0Dqry/Pod0/5vcEA3qxCr+BhbOHlxS8O+29eLpT3aagxXGwIoEk7Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.0.4.tgz", + "integrity": "sha512-6yZf53i/qB8gRHH/l2ZwUG5xgkPgQF15/KxH0DdXMDHjesA9MeZje/853ifkSY0x4m5S+dfDZ+c4x439PF0M2w==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -5002,22 +5591,24 @@ } }, "node_modules/@smithy/service-error-classification": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.0.2.tgz", - "integrity": "sha512-LA86xeFpTKn270Hbkixqs5n73S+LVM0/VZco8dqd+JT75Dyx3Lcw/MraL7ybjmz786+160K8rPOmhsq0SocoJQ==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.0.6.tgz", + "integrity": "sha512-RRoTDL//7xi4tn5FrN2NzH17jbgmnKidUqd4KvquT0954/i6CXXkh1884jBiunq24g9cGtPBEXlU40W6EpNOOg==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0" + "@smithy/types": "^4.3.1" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@smithy/shared-ini-file-loader": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.0.2.tgz", - "integrity": "sha512-J9/gTWBGVuFZ01oVA6vdb4DAjf1XbDhK6sLsu3OS9qmLrS6KB5ygpeHiM3miIbj1qgSJ96GYszXFWv6ErJ8QEw==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.0.4.tgz", + "integrity": "sha512-63X0260LoFBjrHifPDs+nM9tV0VMkOTl4JRMYNuKh/f5PauSjowTfvF3LogfkWdcPoxsA9UjqEOgjeYIbhb7Nw==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -5025,15 +5616,16 @@ } }, "node_modules/@smithy/signature-v4": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.0.2.tgz", - "integrity": "sha512-Mz+mc7okA73Lyz8zQKJNyr7lIcHLiPYp0+oiqiMNc/t7/Kf2BENs5d63pEj7oPqdjaum6g0Fc8wC78dY1TgtXw==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.1.2.tgz", + "integrity": "sha512-d3+U/VpX7a60seHziWnVZOHuEgJlclufjkS6zhXvxcJgkJq4UWdH5eOBLzHRMx6gXjsdT9h6lfpmLzbrdupHgQ==", + "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^4.0.0", - "@smithy/protocol-http": "^5.1.0", - "@smithy/types": "^4.2.0", + "@smithy/protocol-http": "^5.1.2", + "@smithy/types": "^4.3.1", "@smithy/util-hex-encoding": "^4.0.0", - "@smithy/util-middleware": "^4.0.2", + "@smithy/util-middleware": "^4.0.4", "@smithy/util-uri-escape": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" @@ -5043,16 +5635,17 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.2.0.tgz", - "integrity": "sha512-Qs65/w30pWV7LSFAez9DKy0Koaoh3iHhpcpCCJ4waj/iqwsuSzJna2+vYwq46yBaqO5ZbP9TjUsATUNxrKeBdw==", - "dependencies": { - "@smithy/core": "^3.2.0", - "@smithy/middleware-endpoint": "^4.1.0", - "@smithy/middleware-stack": "^4.0.2", - "@smithy/protocol-http": "^5.1.0", - "@smithy/types": "^4.2.0", - "@smithy/util-stream": "^4.2.0", + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.4.5.tgz", + "integrity": "sha512-+lynZjGuUFJaMdDYSTMnP/uPBBXXukVfrJlP+1U/Dp5SFTEI++w6NMga8DjOENxecOF71V9Z2DllaVDYRnGlkg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.6.0", + "@smithy/middleware-endpoint": "^4.1.13", + "@smithy/middleware-stack": "^4.0.4", + "@smithy/protocol-http": "^5.1.2", + "@smithy/types": "^4.3.1", + "@smithy/util-stream": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -5060,9 +5653,10 @@ } }, "node_modules/@smithy/types": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.2.0.tgz", - "integrity": "sha512-7eMk09zQKCO+E/ivsjQv+fDlOupcFUCSC/L2YUPgwhvowVGWbPQHjEFcmjt7QQ4ra5lyowS92SV53Zc6XD4+fg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.3.1.tgz", + "integrity": "sha512-UqKOQBL2x6+HWl3P+3QqFD4ncKq0I8Nuz9QItGv5WuKuMHuuwlhvqcZCoXGfc+P1QmfJE7VieykoYYmrOoFJxA==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -5071,12 +5665,13 @@ } }, "node_modules/@smithy/url-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.0.2.tgz", - "integrity": "sha512-Bm8n3j2ScqnT+kJaClSVCMeiSenK6jVAzZCNewsYWuZtnBehEz4r2qP0riZySZVfzB+03XZHJeqfmJDkeeSLiQ==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.0.4.tgz", + "integrity": "sha512-eMkc144MuN7B0TDA4U2fKs+BqczVbk3W+qIvcoCY6D1JY3hnAdCuhCZODC+GAeaxj0p6Jroz4+XMUn3PCxQQeQ==", + "license": "Apache-2.0", "dependencies": { - "@smithy/querystring-parser": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/querystring-parser": "^4.0.4", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -5087,6 +5682,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.0.0.tgz", "integrity": "sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg==", + "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-utf8": "^4.0.0", @@ -5100,6 +5696,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.0.0.tgz", "integrity": "sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -5111,6 +5708,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.0.0.tgz", "integrity": "sha512-q0iDP3VsZzqJyje8xJWEJCNIu3lktUGVoSy1KB0UWym2CL1siV3artm+u1DFYTLejpsrdGyCSWBdGNjJzfDPjg==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -5122,6 +5720,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.0.0.tgz", "integrity": "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug==", + "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^4.0.0", "tslib": "^2.6.2" @@ -5134,6 +5733,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.0.0.tgz", "integrity": "sha512-L1RBVzLyfE8OXH+1hsJ8p+acNUSirQnWQ6/EgpchV88G6zGBTDPdXiiExei6Z1wR2RxYvxY/XLw6AMNCCt8H3w==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -5142,13 +5742,14 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.8.tgz", - "integrity": "sha512-ZTypzBra+lI/LfTYZeop9UjoJhhGRTg3pxrNpfSTQLd3AJ37r2z4AXTKpq1rFXiiUIJsYyFgNJdjWRGP/cbBaQ==", - "dependencies": { - "@smithy/property-provider": "^4.0.2", - "@smithy/smithy-client": "^4.2.0", - "@smithy/types": "^4.2.0", + "version": "4.0.21", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.21.tgz", + "integrity": "sha512-wM0jhTytgXu3wzJoIqpbBAG5U6BwiubZ6QKzSbP7/VbmF1v96xlAbX2Am/mz0Zep0NLvLh84JT0tuZnk3wmYQA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/property-provider": "^4.0.4", + "@smithy/smithy-client": "^4.4.5", + "@smithy/types": "^4.3.1", "bowser": "^2.11.0", "tslib": "^2.6.2" }, @@ -5157,16 +5758,17 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.8.tgz", - "integrity": "sha512-Rgk0Jc/UDfRTzVthye/k2dDsz5Xxs9LZaKCNPgJTRyoyBoeiNCnHsYGOyu1PKN+sDyPnJzMOz22JbwxzBp9NNA==", - "dependencies": { - "@smithy/config-resolver": "^4.1.0", - "@smithy/credential-provider-imds": "^4.0.2", - "@smithy/node-config-provider": "^4.0.2", - "@smithy/property-provider": "^4.0.2", - "@smithy/smithy-client": "^4.2.0", - "@smithy/types": "^4.2.0", + "version": "4.0.21", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.21.tgz", + "integrity": "sha512-/F34zkoU0GzpUgLJydHY8Rxu9lBn8xQC/s/0M0U9lLBkYbA1htaAFjWYJzpzsbXPuri5D1H8gjp2jBum05qBrA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/config-resolver": "^4.1.4", + "@smithy/credential-provider-imds": "^4.0.6", + "@smithy/node-config-provider": "^4.1.3", + "@smithy/property-provider": "^4.0.4", + "@smithy/smithy-client": "^4.4.5", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -5174,12 +5776,13 @@ } }, "node_modules/@smithy/util-endpoints": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.0.2.tgz", - "integrity": "sha512-6QSutU5ZyrpNbnd51zRTL7goojlcnuOB55+F9VBD+j8JpRY50IGamsjlycrmpn8PQkmJucFW8A0LSfXj7jjtLQ==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.0.6.tgz", + "integrity": "sha512-YARl3tFL3WgPuLzljRUnrS2ngLiUtkwhQtj8PAL13XZSyUiNLQxwG3fBBq3QXFqGFUXepIN73pINp3y8c2nBmA==", + "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/node-config-provider": "^4.1.3", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -5190,6 +5793,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.0.0.tgz", "integrity": "sha512-Yk5mLhHtfIgW2W2WQZWSg5kuMZCVbvhFmC7rV4IO2QqnZdbEFPmQnCcGMAX2z/8Qj3B9hYYNjZOhWym+RwhePw==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -5198,11 +5802,12 @@ } }, "node_modules/@smithy/util-middleware": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.0.2.tgz", - "integrity": "sha512-6GDamTGLuBQVAEuQ4yDQ+ti/YINf/MEmIegrEeg7DdB/sld8BX1lqt9RRuIcABOhAGTA50bRbPzErez7SlDtDQ==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.0.4.tgz", + "integrity": "sha512-9MLKmkBmf4PRb0ONJikCbCwORACcil6gUWojwARCClT7RmLzF04hUR4WdRprIXal7XVyrddadYNfp2eF3nrvtQ==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -5210,12 +5815,13 @@ } }, "node_modules/@smithy/util-retry": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.0.2.tgz", - "integrity": "sha512-Qryc+QG+7BCpvjloFLQrmlSd0RsVRHejRXd78jNO3+oREueCjwG1CCEH1vduw/ZkM1U9TztwIKVIi3+8MJScGg==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.0.6.tgz", + "integrity": "sha512-+YekoF2CaSMv6zKrA6iI/N9yva3Gzn4L6n35Luydweu5MMPYpiGZlWqehPHDHyNbnyaYlz/WJyYAZnC+loBDZg==", + "license": "Apache-2.0", "dependencies": { - "@smithy/service-error-classification": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/service-error-classification": "^4.0.6", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -5223,13 +5829,14 @@ } }, "node_modules/@smithy/util-stream": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.2.0.tgz", - "integrity": "sha512-Vj1TtwWnuWqdgQI6YTUF5hQ/0jmFiOYsc51CSMgj7QfyO+RF4EnT2HNjoviNlOOmgzgvf3f5yno+EiC4vrnaWQ==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.2.2.tgz", + "integrity": "sha512-aI+GLi7MJoVxg24/3J1ipwLoYzgkB4kUfogZfnslcYlynj3xsQ0e7vk4TnTro9hhsS5PvX1mwmkRqqHQjwcU7w==", + "license": "Apache-2.0", "dependencies": { - "@smithy/fetch-http-handler": "^5.0.2", - "@smithy/node-http-handler": "^4.0.4", - "@smithy/types": "^4.2.0", + "@smithy/fetch-http-handler": "^5.0.4", + "@smithy/node-http-handler": "^4.0.6", + "@smithy/types": "^4.3.1", "@smithy/util-base64": "^4.0.0", "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-hex-encoding": "^4.0.0", @@ -5244,6 +5851,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.0.0.tgz", "integrity": "sha512-77yfbCbQMtgtTylO9itEAdpPXSog3ZxMe09AEhm0dU0NLTalV70ghDZFR+Nfi1C60jnJoh/Re4090/DuZh2Omg==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -5255,6 +5863,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.0.0.tgz", "integrity": "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow==", + "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^4.0.0", "tslib": "^2.6.2" @@ -5264,12 +5873,13 @@ } }, "node_modules/@smithy/util-waiter": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.0.3.tgz", - "integrity": "sha512-JtaY3FxmD+te+KSI2FJuEcfNC9T/DGGVf551babM7fAaXhjJUt7oSYurH1Devxd2+BOSUACCgt3buinx4UnmEA==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.0.6.tgz", + "integrity": "sha512-slcr1wdRbX7NFphXZOxtxRNA7hXAAtJAXJDE/wdoMAos27SIquVCKiSqfB6/28YzQ8FCsB5NKkhdM5gMADbqxg==", + "license": "Apache-2.0", "dependencies": { - "@smithy/abort-controller": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/abort-controller": "^4.0.4", + "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, "engines": { @@ -5279,18 +5889,21 @@ "node_modules/@socket.io/component-emitter": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", - "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==" + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "license": "MIT" }, "node_modules/@sqltools/formatter": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.5.tgz", - "integrity": "sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==" + "integrity": "sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==", + "license": "MIT" }, "node_modules/@testing-library/jest-dom": { "version": "6.1.4", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.1.4.tgz", "integrity": "sha512-wpoYrCYwSZ5/AxcrjLxJmCU6I5QAJXslEeSiMQqaWmP2Kzpd1LvF/qxmAIW2qposULGWq2gw30GgVNFLSc2Jnw==", "dev": true, + "license": "MIT", "dependencies": { "@adobe/css-tools": "^4.3.1", "@babel/runtime": "^7.9.2", @@ -5332,6 +5945,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -5340,34 +5954,63 @@ "node": ">=8" } }, + "node_modules/@tokenizer/inflate": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.2.7.tgz", + "integrity": "sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "fflate": "^0.8.2", + "token-types": "^6.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "license": "MIT" + }, "node_modules/@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/@types/accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.7.tgz", "integrity": "sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==", + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -5377,6 +6020,7 @@ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", @@ -5386,10 +6030,11 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.0.0" } @@ -5399,6 +6044,7 @@ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, + "license": "MIT", "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" @@ -5409,48 +6055,60 @@ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz", "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.20.7" } }, "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "license": "MIT", "dependencies": { "@types/connect": "*", "@types/node": "*" } }, + "node_modules/@types/compression": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@types/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-kCFuWS0ebDbmxs0AXYn6e2r2nrGAb5KwQhknjSPSPgJcGd8+HVSILlUyFhGqML2gk39HcG7D1ydW9/qpYkN00Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "*", + "@types/node": "*" + } + }, "node_modules/@types/connect": { "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, - "node_modules/@types/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" - }, "node_modules/@types/cookiejar": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.5.tgz", "integrity": "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/cors": { "version": "2.8.12", "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", - "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==" + "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", + "license": "MIT" }, "node_modules/@types/cron": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/@types/cron/-/cron-1.7.3.tgz", "integrity": "sha512-iPmUXyIJG1Js+ldPYhOQcYU3kCAQ2FWrSkm1FJPoii2eYSn6wEW6onPukNTT0bfiflexNSRPl6KWmAIqS+36YA==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "moment": ">=2.14.0" @@ -5460,13 +6118,15 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.2.2.tgz", "integrity": "sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/eslint": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -5477,21 +6137,24 @@ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "dev": true, + "license": "MIT", "dependencies": { "@types/eslint": "*", "@types/estree": "*" } }, "node_modules/@types/estree": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", - "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", - "dev": true + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" }, "node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz", + "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==", + "license": "MIT", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -5503,6 +6166,7 @@ "version": "4.19.6", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "license": "MIT", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -5515,6 +6179,7 @@ "resolved": "https://registry.npmjs.org/@types/fluent-ffmpeg/-/fluent-ffmpeg-2.1.27.tgz", "integrity": "sha512-QiDWjihpUhriISNoBi2hJBRUUmoj/BMTYcfz+F+ZM9hHWBYABFAE6hjP/TbCZC0GWwlpa3FzvHH9RzFeRusZ7A==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -5524,26 +6189,30 @@ "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "license": "MIT" }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/istanbul-lib-report": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, + "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "*" } @@ -5553,6 +6222,7 @@ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/istanbul-lib-report": "*" } @@ -5562,6 +6232,7 @@ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==", "dev": true, + "license": "MIT", "dependencies": { "expect": "^29.0.0", "pretty-format": "^29.0.0" @@ -5571,86 +6242,93 @@ "version": "4.0.9", "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/json-diff": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/@types/json-diff/-/json-diff-0.7.0.tgz", "integrity": "sha512-20IJqupGHywtIaE6fS30iygh3dVqVdzmsnrYn/VFuRaQKxLx/RGH5K9hhCfctVxgN7KzJlnD7gYFAOrNwiCgtA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/jsonwebtoken": { "version": "8.5.9", "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.9.tgz", "integrity": "sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/lodash": { - "version": "4.17.16", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.16.tgz", - "integrity": "sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==" + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-NYqRyg/hIQrYPT9lbOeYc3kIRabJDn/k4qQHIXUpx88CBDww2fD15Sg5kbXlW86zm2XEW4g0QxkTI3/Kfkc7xQ==", + "license": "MIT" }, "node_modules/@types/long": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "license": "MIT" }, "node_modules/@types/methods": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz", "integrity": "sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "license": "MIT" }, "node_modules/@types/node": { "version": "17.0.45", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", - "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", + "license": "MIT" }, "node_modules/@types/node-fetch": { "version": "2.6.12", "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", + "license": "MIT", "peer": true, "dependencies": { "@types/node": "*", "form-data": "^4.0.0" } }, - "node_modules/@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", - "dev": true - }, "node_modules/@types/qs": { - "version": "6.9.18", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.18.tgz", - "integrity": "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==" + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", + "license": "MIT" }, "node_modules/@types/range-parser": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "license": "MIT" }, "node_modules/@types/redis": { "version": "2.8.32", "resolved": "https://registry.npmjs.org/@types/redis/-/redis-2.8.32.tgz", "integrity": "sha512-7jkMKxcGq9p242exlbsVzuJb57KqHRhNl4dHoQu2Y5v9bCAbtIXXH0R3HleSQW4CTOqpHIYUW3t6tpUj4BVQ+w==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -5660,6 +6338,7 @@ "resolved": "https://registry.npmjs.org/@types/request-ip/-/request-ip-0.0.37.tgz", "integrity": "sha512-uw6/i3rQnpznxD7LtLaeuZytLhKZK6bRoTS6XVJlwxIOoOpEBU7bgKoVXDNtOg4Xl6riUKHa9bjMVrL6ESqYlQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -5668,21 +6347,24 @@ "version": "7.7.0", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.0.tgz", "integrity": "sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "version": "0.17.5", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", + "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", + "license": "MIT", "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "node_modules/@types/serve-static": { - "version": "1.15.7", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", - "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", + "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", + "license": "MIT", "dependencies": { "@types/http-errors": "*", "@types/node": "*", @@ -5694,6 +6376,7 @@ "resolved": "https://registry.npmjs.org/@types/sharp/-/sharp-0.28.6.tgz", "integrity": "sha512-AjKjo5vk5mkcTrWL0U1zFUdCp/uqLebvbe7ezAJx0tgp6ST9JmfsYK1q1lpjfPM5S1YQ1wr5uboPSu2S8UO9yw==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -5702,13 +6385,15 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/superagent": { "version": "8.1.9", "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.9.tgz", "integrity": "sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/cookiejar": "^2.1.5", "@types/methods": "^1.1.4", @@ -5721,6 +6406,7 @@ "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-2.0.16.tgz", "integrity": "sha512-6c2ogktZ06tr2ENoZivgm7YnprnhYE4ZoXGMY+oA7IuAf17M8FWvujXZGmxLv8y0PTyts4x5A+erSwVUFA8XSg==", "dev": true, + "license": "MIT", "dependencies": { "@types/superagent": "*" } @@ -5729,18 +6415,42 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/tiny-async-pool/-/tiny-async-pool-1.0.5.tgz", "integrity": "sha512-8hqr+s4rBthBtb+k02NXejl7BGVbj7CD/ZB2rMSvoSjXO52aXbtm9q/JEey5uDjzADs/zXEo7bU9iX+M6glAUA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/triple-beam": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", - "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" + "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==", + "license": "MIT" + }, + "node_modules/@types/uuid": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", + "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", + "license": "MIT" + }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", + "license": "MIT" + }, + "node_modules/@types/whatwg-url": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz", + "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==", + "license": "MIT", + "dependencies": { + "@types/webidl-conversions": "*" + } }, "node_modules/@types/yargs": { "version": "17.0.33", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", "dev": true, + "license": "MIT", "dependencies": { "@types/yargs-parser": "*" } @@ -5749,13 +6459,15 @@ "version": "21.0.3", "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "5.62.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.4.0", "@typescript-eslint/scope-manager": "5.62.0", @@ -5790,6 +6502,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/scope-manager": "5.62.0", "@typescript-eslint/types": "5.62.0", @@ -5817,6 +6530,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "5.62.0", "@typescript-eslint/visitor-keys": "5.62.0" @@ -5834,6 +6548,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/typescript-estree": "5.62.0", "@typescript-eslint/utils": "5.62.0", @@ -5861,6 +6576,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -5874,6 +6590,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/types": "5.62.0", "@typescript-eslint/visitor-keys": "5.62.0", @@ -5901,6 +6618,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", @@ -5927,6 +6645,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "5.62.0", "eslint-visitor-keys": "^3.3.0" @@ -5943,13 +6662,15 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/@webassemblyjs/ast": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/helper-numbers": "1.13.2", "@webassemblyjs/helper-wasm-bytecode": "1.13.2" @@ -5959,25 +6680,29 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-api-error": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-buffer": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.13.2", "@webassemblyjs/helper-api-error": "1.13.2", @@ -5988,13 +6713,15 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-buffer": "1.14.1", @@ -6007,6 +6734,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "dev": true, + "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" } @@ -6016,6 +6744,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" } @@ -6024,13 +6753,15 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-buffer": "1.14.1", @@ -6047,6 +6778,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-wasm-bytecode": "1.13.2", @@ -6060,6 +6792,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-buffer": "1.14.1", @@ -6072,6 +6805,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-api-error": "1.13.2", @@ -6086,6 +6820,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" @@ -6095,18 +6830,21 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@xtuc/long": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -6119,14 +6857,16 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/acorn": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", - "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -6134,20 +6874,11 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "deprecated": "package has been renamed to acorn-import-attributes", - "dev": true, - "peerDependencies": { - "acorn": "^8" - } - }, "node_modules/acorn-import-attributes": { "version": "1.9.5", "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "license": "MIT", "peerDependencies": { "acorn": "^8" } @@ -6157,6 +6888,7 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -6166,6 +6898,7 @@ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", "devOptional": true, + "license": "MIT", "dependencies": { "acorn": "^8.11.0" }, @@ -6177,6 +6910,7 @@ "version": "4.6.0", "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", + "license": "MIT", "dependencies": { "humanize-ms": "^1.2.1" }, @@ -6189,6 +6923,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -6205,6 +6940,7 @@ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^8.0.0" }, @@ -6222,6 +6958,7 @@ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3" }, @@ -6233,6 +6970,7 @@ "version": "4.1.14", "resolved": "https://registry.npmjs.org/amqp-connection-manager/-/amqp-connection-manager-4.1.14.tgz", "integrity": "sha512-1km47dIvEr0HhMUazqovSvNwIlSvDX2APdUpULaINtHpiki1O+cLRaTeXb/jav4OLtH+k6GBXx5gsKOT9kcGKQ==", + "license": "MIT", "dependencies": { "promise-breaker": "^6.0.0" }, @@ -6245,11 +6983,11 @@ } }, "node_modules/amqplib": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.10.5.tgz", - "integrity": "sha512-Dx5zmy0Ur+Q7LPPdhz+jx5IzmJBoHd15tOeAfQ8SuvEtyPJ20hBemhOBA4b1WeORCRa0ENM/kHCzmem1w/zHvQ==", + "version": "0.10.8", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.10.8.tgz", + "integrity": "sha512-Tfn1O9sFgAP8DqeMEpt2IacsVTENBpblB3SqLdn0jK2AeX8iyCvbptBc8lyATT9bQ31MsjVwUSQ1g8f4jHOUfw==", + "license": "MIT", "dependencies": { - "@acuminous/bitsyntax": "^0.1.2", "buffer-more-ints": "~1.0.0", "url-parse": "~1.5.10" }, @@ -6258,15 +6996,17 @@ } }, "node_modules/anchorme": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/anchorme/-/anchorme-2.1.2.tgz", - "integrity": "sha512-2iPY3kxDDZvtRzauqKDb4v7a5sTF4GZ+esQTY8nGYvmhAtGTeFPMn4cRnvyWS1qmtPTP0Mv8hyLOp9l3ZzWMKg==" + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/anchorme/-/anchorme-3.0.8.tgz", + "integrity": "sha512-K61vxP907NA0Pv4z5v7xbiwosAjhdjCVUFGOFm1TEDFbKmK9/dRLT1jirFIQUuE5ni78Mv4D3Yr4rnQT1PJl9w==", + "license": "MIT" }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -6276,6 +7016,7 @@ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.21.3" }, @@ -6291,6 +7032,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -6302,6 +7044,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", "engines": { "node": ">=8" } @@ -6310,6 +7053,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -6320,16 +7064,21 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + "node_modules/ansis": { + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-3.17.0.tgz", + "integrity": "sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==", + "license": "ISC", + "engines": { + "node": ">=14" + } }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -6338,11 +7087,25 @@ "node": ">= 8" } }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/apollo-datasource": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-3.3.2.tgz", "integrity": "sha512-L5TiS8E2Hn/Yz7SSnWIVbZw0ZfEIXZCa5VUiVxD9P53JvSrf4aStvsFDlGWPvpIdCR+aly2CfoB79B9/JjKFqg==", "deprecated": "The `apollo-datasource` package is part of Apollo Server v2 and v3, which are now end-of-life (as of October 22nd 2023 and October 22nd 2024, respectively). See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.", + "license": "MIT", "dependencies": { "@apollo/utils.keyvaluecache": "^1.0.1", "apollo-server-env": "^4.2.1" @@ -6355,6 +7118,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/@apollo/utils.keyvaluecache/-/utils.keyvaluecache-1.0.2.tgz", "integrity": "sha512-p7PVdLPMnPzmXSQVEsy27cYEjVON+SH/Wb7COyW3rQN8+wJgT1nv9jZouYtztWW8ZgTkii5T6tC9qfoDREd4mg==", + "license": "MIT", "dependencies": { "@apollo/utils.logger": "^1.0.0", "lru-cache": "7.10.1 - 7.13.1" @@ -6363,12 +7127,14 @@ "node_modules/apollo-datasource/node_modules/@apollo/utils.logger": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@apollo/utils.logger/-/utils.logger-1.0.1.tgz", - "integrity": "sha512-XdlzoY7fYNK4OIcvMD2G94RoFZbzTQaNP0jozmqqMudmaGo2I/2Jx71xlDJ801mWA/mbYRihyaw6KJii7k5RVA==" + "integrity": "sha512-XdlzoY7fYNK4OIcvMD2G94RoFZbzTQaNP0jozmqqMudmaGo2I/2Jx71xlDJ801mWA/mbYRihyaw6KJii7k5RVA==", + "license": "MIT" }, "node_modules/apollo-datasource/node_modules/lru-cache": { "version": "7.13.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.13.1.tgz", "integrity": "sha512-CHqbAq7NFlW3RSnoWXLJBxCWaZVBrfa9UEHId2M3AW8iEBurbqduNexEUCGc3SHc6iCYXNJCDi903LajSVAEPQ==", + "license": "ISC", "engines": { "node": ">=12" } @@ -6378,6 +7144,7 @@ "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-3.4.0.tgz", "integrity": "sha512-h0u3EbC/9RpihWOmcSsvTW2O6RXVaD/mPEjfrPkxRPTEPWqncsgOoRJw+wih4OqfH3PvTJvoEIf4LwKrUaqWog==", "deprecated": "The `apollo-reporting-protobuf` package is part of Apollo Server v2 and v3, which are now end-of-life (as of October 22nd 2023 and October 22nd 2024, respectively). This package's functionality is now found in the `@apollo/usage-reporting-protobuf` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.", + "license": "MIT", "dependencies": { "@apollo/protobufjs": "1.2.6" } @@ -6387,6 +7154,7 @@ "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.6.tgz", "integrity": "sha512-Wqo1oSHNUj/jxmsVp4iR3I480p6qdqHikn38lKrFhfzcDJ7lwd7Ck7cHRl4JE81tWNArl77xhnG/OkZhxKBYOw==", "hasInstallScript": true, + "license": "BSD-3-Clause", "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -6410,13 +7178,15 @@ "node_modules/apollo-reporting-protobuf/node_modules/@types/node": { "version": "10.17.60", "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", + "license": "MIT" }, "node_modules/apollo-server-core": { "version": "3.13.0", "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-3.13.0.tgz", "integrity": "sha512-v/g6DR6KuHn9DYSdtQijz8dLOkP78I5JSVJzPkARhDbhpH74QNwrQ2PP2URAPPEDJ2EeZNQDX8PvbYkAKqg+kg==", "deprecated": "The `apollo-server-core` package is part of Apollo Server v2 and v3, which are now end-of-life (as of October 22nd 2023 and October 22nd 2024, respectively). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.", + "license": "MIT", "dependencies": { "@apollo/utils.keyvaluecache": "^1.0.1", "@apollo/utils.logger": "^1.0.0", @@ -6453,6 +7223,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@apollo/utils.dropunuseddefinitions/-/utils.dropunuseddefinitions-1.1.0.tgz", "integrity": "sha512-jU1XjMr6ec9pPoL+BFWzEPW7VHHulVdGKMkPAMiCigpVIT11VmCbnij0bWob8uS3ODJ65tZLYKAh/55vLw2rbg==", + "license": "MIT", "engines": { "node": ">=12.13.0" }, @@ -6464,6 +7235,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/@apollo/utils.keyvaluecache/-/utils.keyvaluecache-1.0.2.tgz", "integrity": "sha512-p7PVdLPMnPzmXSQVEsy27cYEjVON+SH/Wb7COyW3rQN8+wJgT1nv9jZouYtztWW8ZgTkii5T6tC9qfoDREd4mg==", + "license": "MIT", "dependencies": { "@apollo/utils.logger": "^1.0.0", "lru-cache": "7.10.1 - 7.13.1" @@ -6473,6 +7245,7 @@ "version": "7.13.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.13.1.tgz", "integrity": "sha512-CHqbAq7NFlW3RSnoWXLJBxCWaZVBrfa9UEHId2M3AW8iEBurbqduNexEUCGc3SHc6iCYXNJCDi903LajSVAEPQ==", + "license": "ISC", "engines": { "node": ">=12" } @@ -6480,12 +7253,14 @@ "node_modules/apollo-server-core/node_modules/@apollo/utils.logger": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@apollo/utils.logger/-/utils.logger-1.0.1.tgz", - "integrity": "sha512-XdlzoY7fYNK4OIcvMD2G94RoFZbzTQaNP0jozmqqMudmaGo2I/2Jx71xlDJ801mWA/mbYRihyaw6KJii7k5RVA==" + "integrity": "sha512-XdlzoY7fYNK4OIcvMD2G94RoFZbzTQaNP0jozmqqMudmaGo2I/2Jx71xlDJ801mWA/mbYRihyaw6KJii7k5RVA==", + "license": "MIT" }, "node_modules/apollo-server-core/node_modules/@apollo/utils.printwithreducedwhitespace": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@apollo/utils.printwithreducedwhitespace/-/utils.printwithreducedwhitespace-1.1.0.tgz", "integrity": "sha512-GfFSkAv3n1toDZ4V6u2d7L4xMwLA+lv+6hqXicMN9KELSJ9yy9RzuEXaX73c/Ry+GzRsBy/fdSUGayGqdHfT2Q==", + "license": "MIT", "engines": { "node": ">=12.13.0" }, @@ -6497,6 +7272,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@apollo/utils.removealiases/-/utils.removealiases-1.0.0.tgz", "integrity": "sha512-6cM8sEOJW2LaGjL/0vHV0GtRaSekrPQR4DiywaApQlL9EdROASZU5PsQibe2MWeZCOhNrPRuHh4wDMwPsWTn8A==", + "license": "MIT", "engines": { "node": ">=12.13.0" }, @@ -6508,6 +7284,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@apollo/utils.sortast/-/utils.sortast-1.1.0.tgz", "integrity": "sha512-VPlTsmUnOwzPK5yGZENN069y6uUHgeiSlpEhRnLFYwYNoJHsuJq2vXVwIaSmts015WTPa2fpz1inkLYByeuRQA==", + "license": "MIT", "dependencies": { "lodash.sortby": "^4.7.0" }, @@ -6522,6 +7299,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@apollo/utils.stripsensitiveliterals/-/utils.stripsensitiveliterals-1.2.0.tgz", "integrity": "sha512-E41rDUzkz/cdikM5147d8nfCFVKovXxKBcjvLEQ7bjZm/cg9zEcXvS6vFY8ugTubI3fn6zoqo0CyU8zT+BGP9w==", + "license": "MIT", "engines": { "node": ">=12.13.0" }, @@ -6533,6 +7311,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@apollo/utils.usagereporting/-/utils.usagereporting-1.0.1.tgz", "integrity": "sha512-6dk+0hZlnDbahDBB2mP/PZ5ybrtCJdLMbeNJD+TJpKyZmSY6bA3SjI8Cr2EM9QA+AdziywuWg+SgbWUF3/zQqQ==", + "license": "MIT", "dependencies": { "@apollo/usage-reporting-protobuf": "^4.0.0", "@apollo/utils.dropunuseddefinitions": "^1.1.0", @@ -6552,6 +7331,7 @@ "version": "8.3.1", "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.3.1.tgz", "integrity": "sha512-BMm99mqdNZbEYeTPK3it9r9S6rsZsQKtlqJsSBknAclXq2pGEfOxjcIZi+kBSkHZKPKCRrYDd5vY0+rUmIHVLg==", + "license": "MIT", "dependencies": { "@graphql-tools/utils": "8.9.0", "tslib": "^2.4.0" @@ -6564,6 +7344,7 @@ "version": "8.5.1", "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-8.5.1.tgz", "integrity": "sha512-0Esilsh0P/qYcB5DKQpiKeQs/jevzIadNTaT0jeWklPMwNbT7yMX4EqZany7mbeRRlSRwMzNzL5olyFdffHBZg==", + "license": "MIT", "dependencies": { "@graphql-tools/merge": "8.3.1", "@graphql-tools/utils": "8.9.0", @@ -6578,6 +7359,7 @@ "version": "8.9.0", "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.9.0.tgz", "integrity": "sha512-pjJIWH0XOVnYGXCqej8g/u/tsfV4LvLlj0eATKQu5zwnxd/TiTHq7Cg313qUPTFFHZ3PP5wJ15chYVtLDwaymg==", + "license": "MIT", "dependencies": { "tslib": "^2.4.0" }, @@ -6589,6 +7371,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -6600,6 +7383,7 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/value-or-promise/-/value-or-promise-1.0.11.tgz", "integrity": "sha512-41BrgH+dIbCFXClcSapVs5M6GkENd3gQOJpEfPDNa71LsUGMXDL0jMWpI/Rh7WhX+Aalfz2TTS3Zt5pUsbnhLg==", + "license": "MIT", "engines": { "node": ">=12" } @@ -6607,13 +7391,15 @@ "node_modules/apollo-server-core/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" }, "node_modules/apollo-server-env": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-4.2.1.tgz", "integrity": "sha512-vm/7c7ld+zFMxibzqZ7SSa5tBENc4B0uye9LTfjJwGoQFY5xsUPH5FpO5j0bMUDZ8YYNbrF9SNtzc5Cngcr90g==", "deprecated": "The `apollo-server-env` package is part of Apollo Server v2 and v3, which are now end-of-life (as of October 22nd 2023 and October 22nd 2024, respectively). This package's functionality is now found in the `@apollo/utils.fetcher` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.", + "license": "MIT", "dependencies": { "node-fetch": "^2.6.7" }, @@ -6626,6 +7412,7 @@ "resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-3.3.1.tgz", "integrity": "sha512-xnZJ5QWs6FixHICXHxUfm+ZWqqxrNuPlQ+kj5m6RtEgIpekOPssH/SD9gf2B4HuWV0QozorrygwZnux8POvyPA==", "deprecated": "The `apollo-server-errors` package is part of Apollo Server v2 and v3, which are now end-of-life (as of October 22nd 2023 and October 22nd 2024, respectively). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.", + "license": "MIT", "engines": { "node": ">=12.0" }, @@ -6638,6 +7425,7 @@ "resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-3.13.0.tgz", "integrity": "sha512-iSxICNbDUyebOuM8EKb3xOrpIwOQgKxGbR2diSr4HP3IW8T3njKFOoMce50vr+moOCe1ev8BnLcw9SNbuUtf7g==", "deprecated": "The `apollo-server-express` package is part of Apollo Server v2 and v3, which are now end-of-life (as of October 22nd 2023 and October 22nd 2024, respectively). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.", + "license": "MIT", "dependencies": { "@types/accepts": "^1.3.5", "@types/body-parser": "1.19.2", @@ -6663,6 +7451,7 @@ "version": "1.19.2", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "license": "MIT", "dependencies": { "@types/connect": "*", "@types/node": "*" @@ -6672,6 +7461,7 @@ "version": "4.17.14", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz", "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==", + "license": "MIT", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.18", @@ -6683,6 +7473,7 @@ "version": "4.17.31", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz", "integrity": "sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==", + "license": "MIT", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -6694,6 +7485,7 @@ "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-3.7.2.tgz", "integrity": "sha512-wE8dwGDvBOGehSsPTRZ8P/33Jan6/PmL0y0aN/1Z5a5GcbFhDaaJCjK5cav6npbbGL2DPKK0r6MPXi3k3N45aw==", "deprecated": "The `apollo-server-plugin-base` package is part of Apollo Server v2 and v3, which are now end-of-life (as of October 22nd 2023 and October 22nd 2024, respectively). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.", + "license": "MIT", "dependencies": { "apollo-server-types": "^3.8.0" }, @@ -6709,6 +7501,7 @@ "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-3.8.0.tgz", "integrity": "sha512-ZI/8rTE4ww8BHktsVpb91Sdq7Cb71rdSkXELSwdSR0eXu600/sY+1UXhTWdiJvk+Eq5ljqoHLwLbY2+Clq2b9A==", "deprecated": "The `apollo-server-types` package is part of Apollo Server v2 and v3, which are now end-of-life (as of October 22nd 2023 and October 22nd 2024, respectively). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.", + "license": "MIT", "dependencies": { "@apollo/utils.keyvaluecache": "^1.0.1", "@apollo/utils.logger": "^1.0.0", @@ -6726,6 +7519,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/@apollo/utils.keyvaluecache/-/utils.keyvaluecache-1.0.2.tgz", "integrity": "sha512-p7PVdLPMnPzmXSQVEsy27cYEjVON+SH/Wb7COyW3rQN8+wJgT1nv9jZouYtztWW8ZgTkii5T6tC9qfoDREd4mg==", + "license": "MIT", "dependencies": { "@apollo/utils.logger": "^1.0.0", "lru-cache": "7.10.1 - 7.13.1" @@ -6734,12 +7528,14 @@ "node_modules/apollo-server-types/node_modules/@apollo/utils.logger": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@apollo/utils.logger/-/utils.logger-1.0.1.tgz", - "integrity": "sha512-XdlzoY7fYNK4OIcvMD2G94RoFZbzTQaNP0jozmqqMudmaGo2I/2Jx71xlDJ801mWA/mbYRihyaw6KJii7k5RVA==" + "integrity": "sha512-XdlzoY7fYNK4OIcvMD2G94RoFZbzTQaNP0jozmqqMudmaGo2I/2Jx71xlDJ801mWA/mbYRihyaw6KJii7k5RVA==", + "license": "MIT" }, "node_modules/apollo-server-types/node_modules/lru-cache": { "version": "7.13.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.13.1.tgz", "integrity": "sha512-CHqbAq7NFlW3RSnoWXLJBxCWaZVBrfa9UEHId2M3AW8iEBurbqduNexEUCGc3SHc6iCYXNJCDi903LajSVAEPQ==", + "license": "ISC", "engines": { "node": ">=12" } @@ -6748,6 +7544,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz", "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==", + "license": "MIT", "engines": { "node": ">= 6.0.0" } @@ -6755,24 +7552,28 @@ "node_modules/append-field": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", - "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==" + "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==", + "license": "MIT" }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" }, "node_modules/aria-query": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">= 0.4" } @@ -6780,19 +7581,22 @@ "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" }, "node_modules/array-timsort": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz", "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -6801,7 +7605,8 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/async": { "version": "0.2.10", @@ -6812,6 +7617,7 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "license": "MIT", "dependencies": { "retry": "0.13.1" } @@ -6819,39 +7625,50 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "bin": { - "atob": "bin/atob.js" + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/aws-ssl-profiles": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz", + "integrity": "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==", + "license": "MIT", "engines": { - "node": ">= 4.5.0" + "node": ">= 6.0.0" } }, "node_modules/axios": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", - "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz", + "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==", + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } }, - "node_modules/b4a": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", - "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==" - }, "node_modules/babel-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "dev": true, + "license": "MIT", "dependencies": { "@jest/transform": "^29.7.0", "@types/babel__core": "^7.1.14", @@ -6873,6 +7690,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", @@ -6889,6 +7707,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", @@ -6905,6 +7724,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -6914,6 +7734,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", @@ -6929,6 +7750,7 @@ "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", @@ -6955,6 +7777,7 @@ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", "dev": true, + "license": "MIT", "dependencies": { "babel-plugin-jest-hoist": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0" @@ -6969,7 +7792,8 @@ "node_modules/backo2": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==" + "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==", + "license": "MIT" }, "node_modules/backslash": { "version": "0.2.0", @@ -6979,74 +7803,8 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/bare-events": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.4.tgz", - "integrity": "sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==", - "optional": true - }, - "node_modules/bare-fs": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.0.2.tgz", - "integrity": "sha512-S5mmkMesiduMqnz51Bfh0Et9EX0aTCJxhsI4bvzFFLs8Z1AV8RDHadfY5CyLwdoLHgXbNBEN1gQcbEtGwuvixw==", - "optional": true, - "dependencies": { - "bare-events": "^2.5.4", - "bare-path": "^3.0.0", - "bare-stream": "^2.6.4" - }, - "engines": { - "bare": ">=1.16.0" - }, - "peerDependencies": { - "bare-buffer": "*" - }, - "peerDependenciesMeta": { - "bare-buffer": { - "optional": true - } - } - }, - "node_modules/bare-os": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.1.tgz", - "integrity": "sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==", - "optional": true, - "engines": { - "bare": ">=1.14.0" - } - }, - "node_modules/bare-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", - "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", - "optional": true, - "dependencies": { - "bare-os": "^3.0.1" - } - }, - "node_modules/bare-stream": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.6.5.tgz", - "integrity": "sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==", - "optional": true, - "dependencies": { - "streamx": "^2.21.0" - }, - "peerDependencies": { - "bare-buffer": "*", - "bare-events": "*" - }, - "peerDependenciesMeta": { - "bare-buffer": { - "optional": true - }, - "bare-events": { - "optional": true - } - } + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" }, "node_modules/base64-js": { "version": "1.5.1", @@ -7065,12 +7823,14 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/base64id": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "license": "MIT", "engines": { "node": "^4.5.0 || >= 5.9" } @@ -7078,12 +7838,14 @@ "node_modules/bech32": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", + "license": "MIT" }, "node_modules/bignumber.js": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", - "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.0.tgz", + "integrity": "sha512-EM7aMFTXbptt/wZdMlBv2t8IViwQL+h6SLHosp8Yf0dqJMTnY6iL32opnAB6kAdL0SZPuvcAzFr31o0c/R3/RA==", + "license": "MIT", "engines": { "node": "*" } @@ -7093,6 +7855,7 @@ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -7103,12 +7866,14 @@ "node_modules/bintrees": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.2.tgz", - "integrity": "sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==" + "integrity": "sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==", + "license": "MIT" }, "node_modules/bip39": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.1.0.tgz", "integrity": "sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==", + "license": "ISC", "optional": true, "dependencies": { "@noble/hashes": "^1.2.0" @@ -7118,6 +7883,7 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/bitsyntax/-/bitsyntax-0.1.0.tgz", "integrity": "sha512-ikAdCnrloKmFOugAfxWws89/fPc+nw0OOG1IzIE72uSOg/A3cYptKCjSUhDTuj7fhsJtzkzlv7l3b8PzRHLN0Q==", + "license": "MIT", "dependencies": { "buffer-more-ints": "~1.0.0", "debug": "~2.6.9", @@ -7131,6 +7897,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -7138,48 +7905,57 @@ "node_modules/bitsyntax/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/bl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", - "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", - "dependencies": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" - } + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, - "node_modules/bl/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + "node_modules/bitsyntax/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" }, - "node_modules/bl/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" } }, - "node_modules/bl/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "node_modules/bl/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", "dependencies": { - "safe-buffer": "~5.1.0" + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" } }, "node_modules/blake2b": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/blake2b/-/blake2b-2.1.3.tgz", "integrity": "sha512-pkDss4xFVbMb4270aCyGD3qLv92314Et+FsKzilCLxDz5DuZ2/1g3w4nmBbu6nKApPspnjG7JcwTjGZnduB1yg==", + "license": "ISC", "dependencies": { "blake2b-wasm": "^1.1.0", "nanoassert": "^1.0.0" @@ -7189,6 +7965,7 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/blake2b-wasm/-/blake2b-wasm-1.1.7.tgz", "integrity": "sha512-oFIHvXhlz/DUgF0kq5B1CqxIDjIJwh9iDeUUGQUcvgiGz7Wdw03McEO7CfLBy7QKGdsydcMCgO9jFNBAFCtFcA==", + "license": "MIT", "dependencies": { "nanoassert": "^1.0.0" } @@ -7196,12 +7973,14 @@ "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "license": "MIT" }, "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -7211,7 +7990,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.11.0", + "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -7225,6 +8004,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -7232,17 +8012,21 @@ "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/bowser": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", - "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==" + "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==", + "license": "MIT" }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -7252,6 +8036,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -7260,9 +8045,9 @@ } }, "node_modules/browserslist": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", - "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "version": "4.25.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", + "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", "dev": true, "funding": [ { @@ -7278,11 +8063,12 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001688", - "electron-to-chromium": "^1.5.73", + "caniuse-lite": "^1.0.30001726", + "electron-to-chromium": "^1.5.173", "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.1" + "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" @@ -7296,6 +8082,7 @@ "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", "dev": true, + "license": "MIT", "dependencies": { "fast-json-stable-stringify": "2.x" }, @@ -7308,16 +8095,18 @@ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "node-int64": "^0.4.0" } }, "node_modules/bson": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", - "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==", + "version": "6.10.4", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.4.tgz", + "integrity": "sha512-WIsKqkSC0ABoBJuT1LEX+2HEvNmNKKgnTAyd0fL8qzK4SH2i9NXg+t08YtdZp/V9IZ33cxe3iV4yM0qg8lMQng==", + "license": "Apache-2.0", "engines": { - "node": ">=0.6.19" + "node": ">=16.20.1" } }, "node_modules/buffer": { @@ -7338,6 +8127,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -7346,17 +8136,20 @@ "node_modules/buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" }, "node_modules/buffer-more-ints": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", - "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==" + "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==", + "license": "MIT" }, "node_modules/busboy": { "version": "1.6.0", @@ -7373,14 +8166,34 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" @@ -7393,6 +8206,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" @@ -7409,6 +8223,7 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -7418,14 +8233,15 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001707", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001707.tgz", - "integrity": "sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==", + "version": "1.0.30001726", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001726.tgz", + "integrity": "sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw==", "dev": true, "funding": [ { @@ -7440,12 +8256,14 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -7462,6 +8280,7 @@ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } @@ -7470,19 +8289,15 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -7495,20 +8310,19 @@ "engines": { "node": ">= 8.10.0" }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, "optionalDependencies": { "fsevents": "~2.3.2" } }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, "node_modules/chrome-trace-event": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0" } @@ -7524,6 +8338,7 @@ "url": "https://github.com/sponsors/sibiraj-s" } ], + "license": "MIT", "engines": { "node": ">=8" } @@ -7532,6 +8347,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.6.tgz", "integrity": "sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==", + "license": "MIT", "dependencies": { "inherits": "^2.0.4", "safe-buffer": "^5.2.1" @@ -7540,34 +8356,17 @@ "node": ">= 0.10" } }, - "node_modules/cipher-base/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/cjs-module-lexer": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", - "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==" + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "license": "MIT" }, "node_modules/cli-color": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.4.tgz", "integrity": "sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA==", + "license": "ISC", "dependencies": { "d": "^1.0.1", "es5-ext": "^0.10.64", @@ -7584,6 +8383,7 @@ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, + "license": "MIT", "dependencies": { "restore-cursor": "^3.1.0" }, @@ -7591,82 +8391,12 @@ "node": ">=8" } }, - "node_modules/cli-highlight": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", - "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", - "dependencies": { - "chalk": "^4.0.0", - "highlight.js": "^10.7.1", - "mz": "^2.4.0", - "parse5": "^5.1.1", - "parse5-htmlparser2-tree-adapter": "^6.0.0", - "yargs": "^16.0.0" - }, - "bin": { - "highlight": "bin/highlight" - }, - "engines": { - "node": ">=8.0.0", - "npm": ">=5.0.0" - } - }, - "node_modules/cli-highlight/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/cli-highlight/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/cli-highlight/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cli-highlight/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "engines": { - "node": ">=10" - } - }, "node_modules/cli-spinners": { "version": "2.9.2", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" }, @@ -7675,10 +8405,11 @@ } }, "node_modules/cli-table3": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", - "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", "dev": true, + "license": "MIT", "dependencies": { "string-width": "^4.2.0" }, @@ -7694,6 +8425,7 @@ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", "dev": true, + "license": "ISC", "engines": { "node": ">= 10" } @@ -7702,6 +8434,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -7715,6 +8448,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -7732,6 +8466,7 @@ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8" } @@ -7740,6 +8475,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", + "license": "Apache-2.0", "engines": { "node": ">=0.10.0" } @@ -7749,6 +8485,7 @@ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true, + "license": "MIT", "engines": { "iojs": ">= 1.0.0", "node": ">= 0.12.0" @@ -7758,12 +8495,14 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/color": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "license": "MIT", "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" @@ -7776,6 +8515,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -7786,12 +8526,14 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" }, "node_modules/color-string": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" @@ -7801,6 +8543,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", + "license": "MIT", "dependencies": { "color": "^3.1.3", "text-hex": "1.0.x" @@ -7810,6 +8553,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "license": "MIT", "dependencies": { "color-convert": "^1.9.3", "color-string": "^1.6.0" @@ -7819,6 +8563,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", "dependencies": { "color-name": "1.1.3" } @@ -7826,12 +8571,14 @@ "node_modules/colorspace/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -7844,6 +8591,7 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } @@ -7853,6 +8601,7 @@ "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.2.3.tgz", "integrity": "sha512-SsxdiOf064DWoZLH799Ata6u7iV658A11PlWtZATDlXPpKGJnbJZ5Z24ybixAi+LUUqJ/GKowAejtC5GFUG7Tw==", "dev": true, + "license": "MIT", "dependencies": { "array-timsort": "^1.0.3", "core-util-is": "^1.0.3", @@ -7869,65 +8618,89 @@ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.0.tgz", + "integrity": "sha512-k6WLKfunuqCYD3t6AsuPGvQWaKwuLLh2/xHNcX4qE+vIfDNXpSqnrhwA7O53R7WVQUnt8dVAIW+YHr7xTgOgGA==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.0.2", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" }, "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", "engines": [ - "node >= 0.8" + "node >= 6.0" ], + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", - "readable-stream": "^2.2.2", + "readable-stream": "^3.0.2", "typedarray": "^0.0.6" } }, - "node_modules/concat-stream/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "node_modules/concat-stream/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/concat-stream/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, "node_modules/consola": { "version": "2.15.3", "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", - "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==" + "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==", + "license": "MIT" }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" }, @@ -7935,29 +8708,11 @@ "node": ">= 0.6" } }, - "node_modules/content-disposition/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/content-type": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -7966,13 +8721,14 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cookie": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", - "peer": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -7980,23 +8736,27 @@ "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "license": "MIT" }, "node_modules/cookiejar": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" }, "node_modules/cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "license": "MIT", "dependencies": { "object-assign": "^4", "vary": "^1" @@ -8006,25 +8766,37 @@ } }, "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", "dev": true, + "license": "MIT", "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" }, "engines": { - "node": ">=10" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/create-hash": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "license": "MIT", "dependencies": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", @@ -8037,6 +8809,7 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "license": "MIT", "dependencies": { "cipher-base": "^1.0.3", "create-hash": "^1.1.0", @@ -8051,6 +8824,7 @@ "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "chalk": "^4.0.0", @@ -8071,12 +8845,14 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/cron": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/cron/-/cron-2.4.1.tgz", "integrity": "sha512-ty0hUSPuENwDtIShDFxUxWEIsqiu2vhoFtt6Vwrbg4lHGtJX2/cV2p0hH6/qaEM9Pj+i6mQoau48BO5wBpkP4w==", + "license": "MIT", "dependencies": { "luxon": "^3.2.1" } @@ -8085,6 +8861,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz", "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==", + "license": "MIT", "dependencies": { "node-fetch": "^2.7.0" } @@ -8093,6 +8870,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/cross-inspect/-/cross-inspect-1.0.1.tgz", "integrity": "sha512-Pcw1JTvZLSJH83iiGWt6fRcT+BjZlCDRVwYLbUcHzv/CRpB7r0MlSrGbIyQvVSNyGnbt7G4AXuyCiDR3POvZ1A==", + "license": "MIT", "dependencies": { "tslib": "^2.4.0" }, @@ -8104,7 +8882,7 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -8117,28 +8895,33 @@ "node_modules/crypto-js": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", - "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", + "license": "MIT" }, "node_modules/crypto-randomuuid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/crypto-randomuuid/-/crypto-randomuuid-1.0.0.tgz", - "integrity": "sha512-/RC5F4l1SCqD/jazwUF6+t34Cd8zTSAGZ7rvvZu1whZUhD2a5MOGKjSGowoGcpj/cbVZk1ZODIooJEQQq3nNAA==" + "integrity": "sha512-/RC5F4l1SCqD/jazwUF6+t34Cd8zTSAGZ7rvvZu1whZUhD2a5MOGKjSGowoGcpj/cbVZk1ZODIooJEQQq3nNAA==", + "license": "MIT" }, "node_modules/css.escape": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cssfilter": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz", - "integrity": "sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==" + "integrity": "sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==", + "license": "MIT" }, "node_modules/d": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", + "license": "ISC", "dependencies": { "es5-ext": "^0.10.64", "type": "^2.7.2" @@ -8150,183 +8933,97 @@ "node_modules/dataloader": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-2.2.3.tgz", - "integrity": "sha512-y2krtASINtPFS1rSDjacrFgn1dcUuoREVabwlOGOe4SdxenREqwjwjElAdwvbGM7kgZz9a3KVicWR7vcz8rnzA==" + "integrity": "sha512-y2krtASINtPFS1rSDjacrFgn1dcUuoREVabwlOGOe4SdxenREqwjwjElAdwvbGM7kgZz9a3KVicWR7vcz8rnzA==", + "license": "MIT" }, - "node_modules/date-fns": { - "version": "2.30.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", - "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", - "dependencies": { - "@babel/runtime": "^7.21.0" - }, + "node_modules/dayjs": { + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", + "license": "MIT" + }, + "node_modules/dc-polyfill": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/dc-polyfill/-/dc-polyfill-0.1.9.tgz", + "integrity": "sha512-D5mJThEEk9hf+CJPwTf9JFsrWdlWp8Pccjxkhf7uUT/E/cU9Mx3ebWe2Bz2OawRmJ6WS9eaDPBkeBE4uOKq9uw==", + "license": "MIT", "engines": { - "node": ">=0.11" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/date-fns" + "node": ">=12.17" } }, "node_modules/dd-trace": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-1.7.1.tgz", - "integrity": "sha512-hRrgJgjP3xF/s4EKxSGzOG+ARkWyRz33dwIwi1gJych7zSE7qnt5VL6LcK1Jou4mfyn+kHUbbb0d7t19YpmZsg==", - "deprecated": "The v1.x release line of dd-trace has reached End of Life! Please upgrade to the latest version of dd-trace to continue receiving updates.", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.56.0.tgz", + "integrity": "sha512-1GiAh1UATmn8uZxk+nqZAdfJppiOq4kxJKiozMNvupffbcbAuDj5qnfYF9Hz3oqsk+Jtt2oheQeR05c4JRshXw==", "hasInstallScript": true, - "dependencies": { - "@datadog/native-metrics": "^1.1.0", - "@datadog/pprof": "^0.3.0", - "@datadog/sketches-js": "^1.0.4", - "@types/node": ">=12", + "license": "(Apache-2.0 OR BSD-3-Clause)", + "dependencies": { + "@datadog/libdatadog": "^0.6.0", + "@datadog/native-appsec": "8.5.2", + "@datadog/native-iast-taint-tracking": "4.0.0", + "@datadog/native-metrics": "^3.1.1", + "@datadog/pprof": "5.8.2", + "@datadog/sketches-js": "^2.1.1", + "@datadog/wasm-js-rewriter": "4.0.1", + "@isaacs/ttlcache": "^1.4.1", + "@opentelemetry/api": ">=1.0.0 <1.9.0", + "@opentelemetry/core": "^1.14.0", "crypto-randomuuid": "^1.0.0", - "form-data": "^3.0.0", - "import-in-the-middle": "^1.1.2", + "dc-polyfill": "0.1.9", + "ignore": "^5.2.4", + "import-in-the-middle": "1.14.0", + "istanbul-lib-coverage": "3.2.2", + "jest-docblock": "^29.7.0", "koalas": "^1.0.2", - "limiter": "^1.1.4", - "lodash.kebabcase": "^4.1.1", - "lodash.pick": "^4.4.0", + "limiter": "1.1.5", "lodash.sortby": "^4.7.0", - "lodash.uniq": "^4.5.0", - "methods": "^1.1.2", - "module-details-from-path": "^1.0.3", - "multer": "^1.4.2", + "lru-cache": "^7.18.3", + "module-details-from-path": "^1.0.4", + "mutexify": "^1.4.0", "opentracing": ">=0.12.1", - "path-to-regexp": "^0.1.2", - "performance-now": "^2.1.0", - "retry": "^0.10.1", - "semver": "^5.5.0", - "source-map": "^0.7.3", - "source-map-resolve": "^0.6.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/dd-trace/node_modules/busboy": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", - "integrity": "sha512-InWFDomvlkEj+xWLBfU3AvnbVYqeTWmQopiW0tWWEy5yehYm2YkGEc59sUmw/4ty5Zj/b0WHGs1LgecuBSBGrg==", - "dependencies": { - "dicer": "0.2.5", - "readable-stream": "1.1.x" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/dd-trace/node_modules/form-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.3.tgz", - "integrity": "sha512-q5YBMeWy6E2Un0nMGWMgI65MAKtaylxfNJGJxpGh45YDciZB4epbWpaAfImil6CPAPTYB4sh0URQNDRIZG5F2w==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "mime-types": "^2.1.35" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/dd-trace/node_modules/multer": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.4.tgz", - "integrity": "sha512-2wY2+xD4udX612aMqMcB8Ws2Voq6NIUPEtD1be6m411T4uDH/VtL9i//xvcyFlTVfRdaBsk7hV5tgrGQqhuBiw==", - "deprecated": "Multer 1.x is affected by CVE-2022-24434. This is fixed in v1.4.4-lts.1 which drops support for versions of Node.js before 6. Please upgrade to at least Node.js 6 and version 1.4.4-lts.1 of Multer. If you need support for older versions of Node.js, we are open to accepting patches that would fix the CVE on the main 1.x release line, whilst maintaining compatibility with Node.js 0.10.", - "dependencies": { - "append-field": "^1.0.0", - "busboy": "^0.2.11", - "concat-stream": "^1.5.2", - "mkdirp": "^0.5.4", - "object-assign": "^4.1.1", - "on-finished": "^2.3.0", - "type-is": "^1.6.4", - "xtend": "^4.0.0" + "path-to-regexp": "^0.1.12", + "pprof-format": "^2.1.0", + "protobufjs": "^7.5.3", + "retry": "^0.13.1", + "rfdc": "^1.4.1", + "semifies": "^1.0.0", + "shell-quote": "^1.8.2", + "source-map": "^0.7.4", + "tlhunter-sorted-set": "^0.1.0", + "ttl-set": "^1.0.0" }, "engines": { - "node": ">= 0.10.0" + "node": ">=18" } }, "node_modules/dd-trace/node_modules/path-to-regexp": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==" - }, - "node_modules/dd-trace/node_modules/readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/dd-trace/node_modules/retry": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", - "integrity": "sha512-ZXUSQYTHdl3uS7IuCehYfMzKyIDBNoAuUblvy5oGO5UJSUTmStUUVPXbA9Qxd173Bgre53yCQczQuHgRWAdvJQ==", - "engines": { - "node": "*" - } - }, - "node_modules/dd-trace/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/dd-trace/node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "license": "MIT" }, "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "license": "MIT", "dependencies": { - "mimic-response": "^3.1.0" + "ms": "^2.1.3" }, "engines": { - "node": ">=10" + "node": ">=6.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/dedent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", - "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", - "dev": true, + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.6.0.tgz", + "integrity": "sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA==", + "license": "MIT", "peerDependencies": { "babel-plugin-macros": "^3.1.0" }, @@ -8336,24 +9033,18 @@ } } }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8363,6 +9054,7 @@ "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", "dev": true, + "license": "MIT", "dependencies": { "clone": "^1.0.2" }, @@ -8370,10 +9062,28 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/delay": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -8385,6 +9095,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -8393,6 +9104,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "license": "Apache-2.0", "engines": { "node": ">=0.10" } @@ -8401,6 +9113,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -8409,15 +9122,17 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" } }, "node_modules/detect-libc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "license": "Apache-2.0", "engines": { "node": ">=8" } @@ -8426,7 +9141,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -8436,52 +9151,18 @@ "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", "dev": true, + "license": "ISC", "dependencies": { "asap": "^2.0.0", "wrappy": "1" } }, - "node_modules/dicer": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", - "integrity": "sha512-FDvbtnq7dzlPz0wyYlOExifDEZcu8h+rErEXgfxqmLfRfC/kJidEFh4+effJRO3P0xmfqyPbSMG0LveNRfTKVg==", - "dependencies": { - "readable-stream": "1.1.x", - "streamsearch": "0.1.2" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/dicer/node_modules/readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/dicer/node_modules/streamsearch": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", - "integrity": "sha512-jos8u++JKm0ARcSUTAZXOVC0mSox7Bhn6sBgty73P1f3JGf7yG2clTbBNHUdde/kdvP2FESam+vM6l8jBrNxHA==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/dicer/node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" - }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "devOptional": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } @@ -8491,6 +9172,7 @@ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } @@ -8511,6 +9193,7 @@ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -8523,6 +9206,7 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -8534,12 +9218,14 @@ "version": "0.5.16", "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/dotenv": { "version": "16.3.1", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", + "license": "BSD-2-Clause", "engines": { "node": ">=12" }, @@ -8551,6 +9237,7 @@ "version": "10.0.0", "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz", "integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==", + "license": "BSD-2-Clause", "engines": { "node": ">=12" } @@ -8570,6 +9257,7 @@ "version": "3.1.4", "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.4.tgz", "integrity": "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==", + "license": "MIT", "engines": { "node": ">=4" } @@ -8578,6 +9266,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", @@ -8587,10 +9276,17 @@ "node": ">= 0.4" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", "dependencies": { "safe-buffer": "^5.0.1" } @@ -8599,6 +9295,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/ed25519-hd-key/-/ed25519-hd-key-1.1.2.tgz", "integrity": "sha512-/0y9y6N7vM6Kj5ASr9J9wcMVDTtygxSOvYX+PJiMD7VcxCx2G03V5bLRl8Dug9EgkLFsLhGqBtQWQRcElEeWTA==", + "license": "MIT", "dependencies": { "bip39": "3.0.2", "create-hmac": "1.1.7", @@ -8608,12 +9305,14 @@ "node_modules/ed25519-hd-key/node_modules/@types/node": { "version": "11.11.6", "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz", - "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==" + "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==", + "license": "MIT" }, "node_modules/ed25519-hd-key/node_modules/bip39": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.2.tgz", "integrity": "sha512-J4E1r2N0tUylTKt07ibXvhpT2c5pyAFgvuA5q1H9uDy6dEGpjV8jmymh3MTYJDLCNbIVClSB9FbND49I6N24MQ==", + "license": "ISC", "dependencies": { "@types/node": "11.11.6", "create-hash": "^1.1.0", @@ -8625,6 +9324,7 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/ed2curve/-/ed2curve-0.3.0.tgz", "integrity": "sha512-8w2fmmq3hv9rCrcI7g9hms2pMunQr1JINfcjwR9tAyZqhtyaMN991lF/ZfHfr5tzZQ8c7y7aBgZbjfbd0fjFwQ==", + "license": "Unlicense", "dependencies": { "tweetnacl": "1.x.x" } @@ -8632,13 +9332,15 @@ "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" }, "node_modules/ejs": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "jake": "^10.8.5" }, @@ -8650,16 +9352,18 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.124", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.124.tgz", - "integrity": "sha512-riELkpDUqBi00gqreV3RIGoowxGrfueEKBd6zPdOk/I8lvuFpBGNkYoHof3zUHbiTBsIU8oxdIIL/WNrAG1/7A==", - "dev": true + "version": "1.5.178", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.178.tgz", + "integrity": "sha512-wObbz/ar3Bc6e4X5vf0iO8xTN8YAjN/tgiAOJLr7yjYFtP9wAjq8Mb5h0yn6kResir+VYx2DXBj9NNobs0ETSA==", + "dev": true, + "license": "ISC" }, "node_modules/emittery": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -8670,41 +9374,35 @@ "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" }, "node_modules/enabled": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==", + "license": "MIT" }, "node_modules/encodeurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "peer": true, + "license": "MIT", "engines": { "node": ">= 0.8" } }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dependencies": { - "once": "^1.4.0" - } - }, "node_modules/engine.io": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", - "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz", + "integrity": "sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==", + "license": "MIT", "dependencies": { - "@types/cookie": "^0.4.1", "@types/cors": "^2.8.12", "@types/node": ">=10.0.0", "accepts": "~1.3.4", "base64id": "2.0.0", - "cookie": "~0.4.1", + "cookie": "~0.7.2", "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~5.2.1", @@ -8718,14 +9416,16 @@ "version": "5.2.3", "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "license": "MIT", "engines": { "node": ">=10.0.0" } }, "node_modules/engine.io/node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -8734,6 +9434,7 @@ "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", "dependencies": { "ms": "^2.1.3" }, @@ -8750,6 +9451,7 @@ "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -8767,10 +9469,11 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.18.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", - "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", + "version": "5.18.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", + "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -8784,6 +9487,7 @@ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, + "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } @@ -8792,6 +9496,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -8800,20 +9505,23 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/es-module-lexer": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", - "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", - "dev": true + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" }, "node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0" }, @@ -8825,6 +9533,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", @@ -8840,6 +9549,7 @@ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", "hasInstallScript": true, + "license": "ISC", "dependencies": { "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.3", @@ -8854,6 +9564,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "license": "MIT", "dependencies": { "d": "1", "es5-ext": "^0.10.35", @@ -8864,6 +9575,7 @@ "version": "3.1.4", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", + "license": "ISC", "dependencies": { "d": "^1.0.2", "ext": "^1.7.0" @@ -8876,6 +9588,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "license": "ISC", "dependencies": { "d": "1", "es5-ext": "^0.10.46", @@ -8887,6 +9600,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", "engines": { "node": ">=6" } @@ -8894,13 +9608,15 @@ "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -8914,6 +9630,7 @@ "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -8969,6 +9686,7 @@ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", "dev": true, + "license": "MIT", "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -8981,6 +9699,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", "dev": true, + "license": "MIT", "dependencies": { "prettier-linter-helpers": "^1.0.0" }, @@ -9002,6 +9721,7 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -9015,6 +9735,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -9027,6 +9748,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -9043,6 +9765,7 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -9059,6 +9782,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -9068,6 +9792,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -9079,12 +9804,14 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/esniff": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "license": "ISC", "dependencies": { "d": "^1.0.1", "es5-ext": "^0.10.62", @@ -9100,6 +9827,7 @@ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -9117,6 +9845,7 @@ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, + "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -9130,6 +9859,7 @@ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -9142,6 +9872,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -9151,6 +9882,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -9163,6 +9895,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -9172,6 +9905,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -9181,6 +9915,7 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -9189,6 +9924,7 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -9197,6 +9933,7 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "license": "MIT", "dependencies": { "d": "1", "es5-ext": "~0.10.14" @@ -9205,18 +9942,21 @@ "node_modules/eventemitter2": { "version": "6.4.9", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", - "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==" + "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==", + "license": "MIT" }, "node_modules/eventemitter3": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "license": "MIT" }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.x" } @@ -9226,6 +9966,7 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -9244,6 +9985,13 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/execa/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -9253,19 +10001,12 @@ "node": ">= 0.8.0" } }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "engines": { - "node": ">=6" - } - }, "node_modules/expect": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/expect-utils": "^29.7.0", "jest-get-type": "^29.6.3", @@ -9281,7 +10022,7 @@ "version": "4.21.2", "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", - "peer": true, + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -9323,35 +10064,11 @@ "url": "https://opencollective.com/express" } }, - "node_modules/express/node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", - "peer": true, - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, "node_modules/express/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "peer": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -9360,53 +10077,19 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "peer": true + "license": "MIT" }, "node_modules/express/node_modules/path-to-regexp": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", - "peer": true - }, - "node_modules/express/node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "peer": true, - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/express/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "peer": true + "license": "MIT" }, "node_modules/ext": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "license": "ISC", "dependencies": { "type": "^2.7.2" } @@ -9416,6 +10099,7 @@ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dev": true, + "license": "MIT", "dependencies": { "chardet": "^0.7.0", "iconv-lite": "^0.4.24", @@ -9429,6 +10113,7 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/extract-files/-/extract-files-9.0.0.tgz", "integrity": "sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ==", + "license": "MIT", "engines": { "node": "^10.17.0 || ^12.0.0 || >= 13.7.0" }, @@ -9440,23 +10125,27 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-diff": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/fast-fifo": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -9471,18 +10160,21 @@ "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-safe-stringify": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "license": "MIT" }, "node_modules/fast-xml-parser": { "version": "4.4.1", @@ -9498,6 +10190,7 @@ "url": "https://paypal.me/naturalintelligence" } ], + "license": "MIT", "dependencies": { "strnum": "^1.0.5" }, @@ -9509,6 +10202,7 @@ "version": "1.19.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } @@ -9518,6 +10212,7 @@ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "bser": "2.1.1" } @@ -9525,13 +10220,21 @@ "node_modules/fecha": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", - "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==", + "license": "MIT" + }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "license": "MIT" }, "node_modules/figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dev": true, + "license": "MIT", "dependencies": { "escape-string-regexp": "^1.0.5" }, @@ -9547,6 +10250,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -9556,6 +10260,7 @@ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, + "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" }, @@ -9567,24 +10272,45 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.6.1.tgz", "integrity": "sha512-u+dBid4PvZw17PmDeRcNOtCP9CCK/9lRN2w+r1xIS7yOL9JFrIBKTvrYsxT4P0pGtThYTn++QS5ChHaUov3+zQ==", + "license": "MIT", "dependencies": { "moment": "^2.29.1" } }, + "node_modules/file-type": { + "version": "20.4.1", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-20.4.1.tgz", + "integrity": "sha512-hw9gNZXUfZ02Jo0uafWLaFVPter5/k2rfcrjFJJHX/77xtSDOfJuEFb6oKlFV86FLP1SuyHMW1PSk0U9M5tKkQ==", + "license": "MIT", + "dependencies": { + "@tokenizer/inflate": "^0.2.6", + "strtok3": "^10.2.0", + "token-types": "^6.0.0", + "uint8array-extras": "^1.4.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, "node_modules/filelist": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", "dev": true, + "license": "Apache-2.0", "dependencies": { "minimatch": "^5.0.1" } }, "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -9594,6 +10320,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -9605,6 +10332,7 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -9616,7 +10344,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", - "peer": true, + "license": "MIT", "dependencies": { "debug": "2.6.9", "encodeurl": "~2.0.0", @@ -9634,7 +10362,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "peer": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -9643,13 +10371,14 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "peer": true + "license": "MIT" }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -9661,19 +10390,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/findit2": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz", - "integrity": "sha512-lg/Moejf4qXovVutL0Lz4IsaPoNYMuxt4PA0nGqFxnJ1CTTGGlEO2wKgoDpwknhvZ8k4Q2F+eesgkLbG2Mxfog==", - "engines": { - "node": ">=0.8.22" - } - }, "node_modules/flat-cache": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, + "license": "MIT", "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", @@ -9683,16 +10405,58 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/flat-cache/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/flatted": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/fluent-ffmpeg": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.3.tgz", "integrity": "sha512-Be3narBNt2s6bsaqP6Jzq91heDgOEaDCJAXcE3qcma/EJBSy5FB4cvO31XBInuAuKBx8Kptf8dkhjK0IOru39Q==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "license": "MIT", "dependencies": { "async": "^0.2.9", "which": "^1.1.1" @@ -9705,6 +10469,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -9715,7 +10480,8 @@ "node_modules/fn.name": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==", + "license": "MIT" }, "node_modules/follow-redirects": { "version": "1.15.9", @@ -9727,6 +10493,7 @@ "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -9736,16 +10503,48 @@ } } }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/fork-ts-checker-webpack-plugin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-8.0.0.tgz", - "integrity": "sha512-mX3qW3idpueT2klaQXBzrIM/pHw+T0B/V9KHEvNrqijTq9NFnMZU6oreVxDYcf33P8a5cW+67PjodNHthGnNVg==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-9.0.2.tgz", + "integrity": "sha512-Uochze2R8peoN1XqlSi/rGUkDQpRogtLFocP9+PGu68zk1BDAKXfdeCdyVZpgTk8V8WFVQXdEz426VKjXLO1Gg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.16.7", "chalk": "^4.1.2", "chokidar": "^3.5.3", - "cosmiconfig": "^7.0.1", + "cosmiconfig": "^8.2.0", "deepmerge": "^4.2.2", "fs-extra": "^10.0.0", "memfs": "^3.4.1", @@ -9765,13 +10564,15 @@ } }, "node_modules/form-data": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", - "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", + "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "engines": { @@ -9779,13 +10580,14 @@ } }, "node_modules/formidable": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz", - "integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.5.tgz", + "integrity": "sha512-Oz5Hwvwak/DCaXVVUtPn4oLMLLy1CdclLKO1LFgU7XzDpVMUU5UjlSLpGMocyQNNk8F6IJW9M/YdooSn2MRI+Q==", "dev": true, + "license": "MIT", "dependencies": { + "@paralleldrive/cuid2": "^2.2.2", "dezalgo": "^1.0.4", - "hexoid": "^1.0.0", "once": "^1.4.0", "qs": "^6.11.0" }, @@ -9797,6 +10599,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -9805,20 +10608,17 @@ "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, "node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -9832,12 +10632,15 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==", - "dev": true + "dev": true, + "license": "Unlicense" }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" }, "node_modules/fsevents": { "version": "2.3.3", @@ -9845,6 +10648,7 @@ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -9857,6 +10661,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -9865,6 +10670,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "license": "MIT", "dependencies": { "is-property": "^1.0.2" } @@ -9874,6 +10680,7 @@ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -9882,6 +10689,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -9890,6 +10698,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", @@ -9914,6 +10723,7 @@ "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.0.0" } @@ -9922,6 +10732,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" @@ -9935,6 +10746,7 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -9942,26 +10754,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" - }, "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, - "engines": { - "node": "*" + "bin": { + "glob": "dist/esm/bin.mjs" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -9971,6 +10778,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -9982,13 +10790,39 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, "node_modules/globals": { "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -10004,6 +10838,7 @@ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -10023,6 +10858,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -10034,18 +10870,21 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/graphql": { - "version": "16.10.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.10.0.tgz", - "integrity": "sha512-AjqGKbDGUFRKIRCP9tCKiIGHyriz2oHEbPIbEtcSLSs4YjReZOIPQQWek4+6hjw62H9QShXHyaGivGiYVLeYFQ==", + "version": "16.11.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.11.0.tgz", + "integrity": "sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==", + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } @@ -10053,12 +10892,14 @@ "node_modules/graphql-fields-list": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/graphql-fields-list/-/graphql-fields-list-2.3.0.tgz", - "integrity": "sha512-psnXCYTjZH46FAvIw0MelMwQg1IFI2uEl8rYAGXxTjFPLxd1UW0W5eaQb4kuNBh7Hh4FzQQ+I/TYtjLIPtXI1A==" + "integrity": "sha512-psnXCYTjZH46FAvIw0MelMwQg1IFI2uEl8rYAGXxTjFPLxd1UW0W5eaQb4kuNBh7Hh4FzQQ+I/TYtjLIPtXI1A==", + "license": "ISC" }, "node_modules/graphql-request": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-4.3.0.tgz", "integrity": "sha512-2v6hQViJvSsifK606AliqiNiijb1uwWp6Re7o0RTyH+uRTv/u7Uqm2g4Fjq/LgZIzARB38RZEvVBFOQOVdlBow==", + "license": "MIT", "dependencies": { "cross-fetch": "^3.1.5", "extract-files": "^9.0.0", @@ -10072,6 +10913,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.3.tgz", "integrity": "sha512-q5YBMeWy6E2Un0nMGWMgI65MAKtaylxfNJGJxpGh45YDciZB4epbWpaAfImil6CPAPTYB4sh0URQNDRIZG5F2w==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -10086,6 +10928,7 @@ "version": "2.12.6", "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", + "license": "MIT", "dependencies": { "tslib": "^2.1.0" }, @@ -10100,6 +10943,7 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/graphql-type-json/-/graphql-type-json-0.3.2.tgz", "integrity": "sha512-J+vjof74oMlCWXSvt0DOf2APEdZOCdubEvGDUAlqH//VBYcOYsGgRW7Xzorr44LvkjiuvecWc8fChxuZZbChtg==", + "license": "MIT", "peerDependencies": { "graphql": ">=0.8.0" } @@ -10108,6 +10952,7 @@ "version": "5.16.0", "resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.16.0.tgz", "integrity": "sha512-Ju2RCU2dQMgSKtArPbEtsK5gNLnsQyTNIo/T7cZNp96niC1x0KdJNZV0TIoilceBPQwfb5itrGl8pkFeOUMl4A==", + "license": "MIT", "workspaces": [ "website" ], @@ -10122,6 +10967,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", "engines": { "node": ">=8" } @@ -10131,14 +10977,28 @@ "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -10150,6 +11010,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" }, @@ -10164,6 +11025,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.4", "readable-stream": "^3.6.0", @@ -10173,29 +11035,11 @@ "node": ">=4" } }, - "node_modules/hash-base/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -10206,35 +11050,21 @@ "node_modules/heap": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", - "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==" - }, - "node_modules/hexoid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", - "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", - "engines": { - "node": "*" - } + "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==", + "license": "MIT" }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -10251,6 +11081,7 @@ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=10.17.0" } @@ -10259,6 +11090,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "license": "MIT", "dependencies": { "ms": "^2.0.0" } @@ -10267,6 +11099,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -10291,13 +11124,14 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "BSD-3-Clause" }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -10307,6 +11141,7 @@ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -10319,9 +11154,10 @@ } }, "node_modules/import-in-the-middle": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.13.1.tgz", - "integrity": "sha512-k2V9wNm9B+ysuelDTHjI9d5KPc4l8zAZTGqj+pcynvWkypZd857ryzN8jNC7Pg2YZXNMJcHRPpaDyCBbNyVRpA==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.14.0.tgz", + "integrity": "sha512-g5zLT0HaztRJWysayWYiUq/7E5H825QIiecMD2pI5QO7Wzr847l6GDvPvmZaDIdrDtS2w7qRczywxiK6SL5vRw==", + "license": "Apache-2.0", "dependencies": { "acorn": "^8.14.0", "acorn-import-attributes": "^1.9.5", @@ -10334,6 +11170,7 @@ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "dev": true, + "license": "MIT", "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" @@ -10353,6 +11190,7 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } @@ -10362,6 +11200,7 @@ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -10371,6 +11210,8 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -10379,18 +11220,15 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" }, "node_modules/inquirer": { "version": "8.2.6", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz", "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==", "dev": true, + "license": "MIT", "dependencies": { "ansi-escapes": "^4.2.1", "chalk": "^4.1.1", @@ -10412,19 +11250,11 @@ "node": ">=12.0.0" } }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/ioredis": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.6.0.tgz", - "integrity": "sha512-tBZlIIWbndeWBWCXWZiqtOF/yxf6yZX3tAlTJ7nfo5jhd6dctNxF7QnYlZLZ1a0o0pDoen7CgZqO+zjNaFbJAg==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.6.1.tgz", + "integrity": "sha512-UxC0Yv1Y4WRJiGQxQkP0hfdL0/5/6YvdfOOClRgJ0qppSarkhneSa6UvkMkms0AkdGimSH3Ikqm+6mkMmX7vGA==", + "license": "MIT", "dependencies": { "@ioredis/commands": "^1.1.1", "cluster-key-slot": "^1.1.0", @@ -10448,26 +11278,24 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", "engines": { "node": ">= 0.10" } }, - "node_modules/is_js": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/is_js/-/is_js-0.9.0.tgz", - "integrity": "sha512-8Y5EHSH+TonfUHX2g3pMJljdbGavg55q4jmHzghJCdqYDbdNROC8uw/YFQwIRCRqRJT1EY3pJefz+kglw+o7sg==" - }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, + "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -10475,11 +11303,24 @@ "node": ">=8" } }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-core-module": { "version": "2.16.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, + "license": "MIT", "dependencies": { "hasown": "^2.0.2" }, @@ -10494,6 +11335,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -10502,6 +11344,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", "engines": { "node": ">=8" } @@ -10511,6 +11354,7 @@ "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -10519,6 +11363,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -10531,6 +11376,7 @@ "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -10539,6 +11385,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -10548,6 +11395,7 @@ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -10555,17 +11403,20 @@ "node_modules/is-promise": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "license": "MIT" }, "node_modules/is-property": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==", + "license": "MIT" }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", "engines": { "node": ">=8" }, @@ -10573,11 +11424,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -10588,18 +11455,20 @@ "node_modules/isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=8" } @@ -10609,6 +11478,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.23.9", "@babel/parser": "^7.23.9", @@ -10625,6 +11495,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", @@ -10639,6 +11510,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", @@ -10653,6 +11525,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -10662,6 +11535,7 @@ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -10673,21 +11547,39 @@ "node_modules/iterall": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz", - "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==" + "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==", + "license": "MIT" }, "node_modules/iterare": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/iterare/-/iterare-1.2.1.tgz", "integrity": "sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==", + "license": "ISC", "engines": { "node": ">=6" } }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/jake": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "async": "^3.2.3", "chalk": "^4.0.2", @@ -10705,13 +11597,15 @@ "version": "3.2.6", "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/jest": { "version": "29.5.0", "resolved": "https://registry.npmjs.org/jest/-/jest-29.5.0.tgz", "integrity": "sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/core": "^29.5.0", "@jest/types": "^29.5.0", @@ -10738,6 +11632,7 @@ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", "dev": true, + "license": "MIT", "dependencies": { "execa": "^5.0.0", "jest-util": "^29.7.0", @@ -10752,6 +11647,7 @@ "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", "@jest/expect": "^29.7.0", @@ -10783,6 +11679,7 @@ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", "dev": true, + "license": "MIT", "dependencies": { "@jest/core": "^29.7.0", "@jest/test-result": "^29.7.0", @@ -10816,6 +11713,7 @@ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", "@jest/test-sequencer": "^29.7.0", @@ -10856,11 +11754,34 @@ } } }, + "node_modules/jest-config/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/jest-diff": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "diff-sequences": "^29.6.3", @@ -10875,7 +11796,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", - "dev": true, + "license": "MIT", "dependencies": { "detect-newline": "^3.0.0" }, @@ -10888,6 +11809,7 @@ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "chalk": "^4.0.0", @@ -10904,6 +11826,7 @@ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", "@jest/fake-timers": "^29.7.0", @@ -10921,6 +11844,7 @@ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } @@ -10930,6 +11854,7 @@ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@types/graceful-fs": "^4.1.3", @@ -10955,6 +11880,7 @@ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", "dev": true, + "license": "MIT", "dependencies": { "jest-get-type": "^29.6.3", "pretty-format": "^29.7.0" @@ -10968,6 +11894,7 @@ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "jest-diff": "^29.7.0", @@ -10983,6 +11910,7 @@ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.13", "@jest/types": "^29.6.3", @@ -11003,6 +11931,7 @@ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", @@ -11017,6 +11946,7 @@ "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" }, @@ -11034,6 +11964,7 @@ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } @@ -11043,6 +11974,7 @@ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", @@ -11063,6 +11995,7 @@ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", "dev": true, + "license": "MIT", "dependencies": { "jest-regex-util": "^29.6.3", "jest-snapshot": "^29.7.0" @@ -11076,6 +12009,7 @@ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", "@jest/environment": "^29.7.0", @@ -11103,30 +12037,12 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-runner/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jest-runner/node_modules/source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, "node_modules/jest-runtime": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", "@jest/fake-timers": "^29.7.0", @@ -11155,11 +12071,34 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-runtime/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/jest-snapshot": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", "@babel/generator": "^7.7.2", @@ -11191,6 +12130,7 @@ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", @@ -11203,11 +12143,25 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-util/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/jest-validate": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "camelcase": "^6.2.0", @@ -11225,6 +12179,7 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -11237,6 +12192,7 @@ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", "dev": true, + "license": "MIT", "dependencies": { "@jest/test-result": "^29.7.0", "@jest/types": "^29.6.3", @@ -11256,6 +12212,7 @@ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "jest-util": "^29.7.0", @@ -11271,6 +12228,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -11285,12 +12243,14 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -11303,6 +12263,7 @@ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, @@ -11314,6 +12275,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", "dependencies": { "bignumber.js": "^9.0.0" } @@ -11322,12 +12284,14 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-diff": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/json-diff/-/json-diff-0.7.4.tgz", "integrity": "sha512-FJ2P+ShDbzu9epF+kCKgoSUhPIUW7Ta7A4XlIT0L5LzgaR/z1TBF1mm0XhRGj8RlA3Xm0j+c/FsWOHDtuoYejA==", + "license": "MIT", "dependencies": { "cli-color": "^2.0.0", "difflib": "~0.2.1", @@ -11352,25 +12316,29 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, + "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -11379,16 +12347,18 @@ } }, "node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", - "dev": true + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", + "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", + "dev": true, + "license": "MIT" }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, + "license": "MIT", "dependencies": { "universalify": "^2.0.0" }, @@ -11397,9 +12367,10 @@ } }, "node_modules/jsonwebtoken": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", - "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "license": "MIT", "dependencies": { "jws": "^3.2.2", "lodash.includes": "^4.3.0", @@ -11410,27 +12381,20 @@ "lodash.isstring": "^4.0.1", "lodash.once": "^4.0.0", "ms": "^2.1.1", - "semver": "^5.6.0" + "semver": "^7.5.4" }, "engines": { - "node": ">=4", - "npm": ">=1.4.28" - } - }, - "node_modules/jsonwebtoken/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "bin": { - "semver": "bin/semver" + "node": ">=12", + "npm": ">=6" } }, "node_modules/jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", + "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", + "license": "MIT", "dependencies": { - "buffer-equal-constant-time": "1.0.1", + "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } @@ -11439,6 +12403,7 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "license": "MIT", "dependencies": { "jwa": "^1.4.1", "safe-buffer": "^5.0.1" @@ -11449,6 +12414,7 @@ "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", "hasInstallScript": true, + "license": "MIT", "dependencies": { "node-addon-api": "^2.0.0", "node-gyp-build": "^4.2.0", @@ -11458,10 +12424,17 @@ "node": ">=10.0.0" } }, + "node_modules/keccak/node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", + "license": "MIT" + }, "node_modules/keccak/node_modules/node-gyp-build": { "version": "4.8.4", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", @@ -11473,6 +12446,7 @@ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, + "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } @@ -11482,6 +12456,7 @@ "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -11490,6 +12465,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/koalas/-/koalas-1.0.2.tgz", "integrity": "sha512-RYhBbYaTTTHId3l6fnMZc3eGQNW6FVCqMG6AMwA5I1Mafr6AflaXeoi6x3xQuATRotGYRLk6+1ELZH4dstFNOA==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -11497,13 +12473,15 @@ "node_modules/kuler": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==", + "license": "MIT" }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -11513,6 +12491,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -11530,13 +12509,15 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.11.5" } @@ -11546,6 +12527,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -11559,109 +12541,110 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" }, "node_modules/lodash-es": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" }, "node_modules/lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==" + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", + "license": "MIT" }, "node_modules/lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT" }, "node_modules/lodash.isarguments": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==" + "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==", + "license": "MIT" }, "node_modules/lodash.isboolean": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" }, "node_modules/lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.isinteger": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT" }, "node_modules/lodash.isnumber": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "license": "MIT" }, "node_modules/lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" }, "node_modules/lodash.isstring": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" - }, - "node_modules/lodash.kebabcase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", - "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==" + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.omit": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", "integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==", - "deprecated": "This package is deprecated. Use destructuring assignment syntax instead." + "deprecated": "This package is deprecated. Use destructuring assignment syntax instead.", + "license": "MIT" }, "node_modules/lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" - }, - "node_modules/lodash.pick": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", - "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==", - "deprecated": "This package is deprecated. Use destructuring assignment syntax instead." + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" }, "node_modules/lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" - }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "license": "MIT" }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -11677,6 +12660,7 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz", "integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==", + "license": "MIT", "dependencies": { "@colors/colors": "1.6.0", "@types/triple-beam": "^1.3.2", @@ -11693,6 +12677,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", + "license": "MIT", "engines": { "node": ">=0.1.90" } @@ -11701,6 +12686,7 @@ "version": "1.9.2", "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz", "integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==", + "license": "MIT", "engines": { "node": ">= 0.6.0" }, @@ -11712,12 +12698,14 @@ "node_modules/long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "license": "Apache-2.0" }, "node_modules/lru-cache": { "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "license": "ISC", "engines": { "node": ">=12" } @@ -11726,35 +12714,41 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", + "license": "MIT", "dependencies": { "es5-ext": "~0.10.2" } }, - "node_modules/luxon": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.6.0.tgz", - "integrity": "sha512-WE7p0p7W1xji9qxkLYsvcIxZyfP48GuFrWIBQZIsbjCyf65dG1rv4n83HcOyEyhvzxJCrUoObCRNFgRNIQ5KNA==", + "node_modules/lru.min": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/lru.min/-/lru.min-1.1.2.tgz", + "integrity": "sha512-Nv9KddBcQSlQopmBHXSsZVY5xsdlZkdH/Iey0BlcBYggMd4two7cZnKOK9vmy3nY0O5RGH99z1PCeTpPqszUYg==", + "license": "MIT", "engines": { - "node": ">=12" + "bun": ">=1.0.0", + "deno": ">=1.30.0", + "node": ">=8.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wellwelwel" } }, - "node_modules/macos-release": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.5.1.tgz", - "integrity": "sha512-DXqXhEM7gW59OjZO8NIjBCz9AQ1BEMrfiOAl4AYByHCtVHRF4KoGNO8mqQeM8lRCtQe/UnJ4imO/d2HdkKsd+A==", - "dev": true, + "node_modules/luxon": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.6.1.tgz", + "integrity": "sha512-tJLxrKJhO2ukZ5z0gyjY1zPh3Rh88Ej9P7jNrZiHMUXHae1yvI2imgOZtL1TO8TW6biMMKfTtAOoEJANgtWBMQ==", + "license": "MIT", "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, "node_modules/magic-string": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.1.tgz", - "integrity": "sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==", + "version": "0.30.8", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", + "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" }, @@ -11767,6 +12761,7 @@ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, + "license": "MIT", "dependencies": { "semver": "^7.5.3" }, @@ -11781,13 +12776,15 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "devOptional": true + "devOptional": true, + "license": "ISC" }, "node_modules/makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "tmpl": "1.0.5" } @@ -11796,6 +12793,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -11804,6 +12802,7 @@ "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "license": "MIT", "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1", @@ -11814,6 +12813,7 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -11823,6 +12823,7 @@ "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", "dev": true, + "license": "Unlicense", "dependencies": { "fs-monkey": "^1.0.4" }, @@ -11834,6 +12835,7 @@ "version": "0.4.17", "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.17.tgz", "integrity": "sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==", + "license": "ISC", "dependencies": { "d": "^1.0.2", "es5-ext": "^0.10.64", @@ -11852,13 +12854,13 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", - "optional": true + "license": "MIT" }, "node_modules/merge-descriptors": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "peer": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/sindresorhus" } @@ -11867,12 +12869,14 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", "engines": { "node": ">= 8" } @@ -11881,6 +12885,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -11889,6 +12894,7 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -11897,10 +12903,23 @@ "node": ">=8.6" } }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", "bin": { "mime": "cli.js" }, @@ -11909,9 +12928,10 @@ } }, "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -11920,6 +12940,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -11927,31 +12948,31 @@ "node": ">= 0.6" } }, + "node_modules/mime-types/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -11960,6 +12981,8 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -11971,23 +12994,25 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/minipass": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", - "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", - "dev": true, + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" } }, "node_modules/mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "license": "MIT", "dependencies": { "minimist": "^1.2.6" }, @@ -11995,46 +13020,51 @@ "mkdirp": "bin/cmd.js" } }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" - }, "node_modules/module-details-from-path": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz", + "integrity": "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==", + "license": "MIT" }, "node_modules/moment": { "version": "2.30.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "license": "MIT", "engines": { "node": "*" } }, "node_modules/mongodb": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.7.4.tgz", - "integrity": "sha512-K5q8aBqEXMwWdVNh94UQTwZ6BejVbFhh1uB6c5FKtPE9eUMZPUO3sRZdgIEcHSrAWmxzpG/FeODDKL388sqRmw==", - "dependencies": { - "bl": "^2.2.1", - "bson": "^1.1.4", - "denque": "^1.4.1", - "optional-require": "^1.1.8", - "safe-buffer": "^5.1.2" + "version": "6.17.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.17.0.tgz", + "integrity": "sha512-neerUzg/8U26cgruLysKEjJvoNSXhyID3RvzvdcpsIi2COYM3FS3o9nlH7fxFtefTb942dX3W9i37oPfCVj4wA==", + "license": "Apache-2.0", + "dependencies": { + "@mongodb-js/saslprep": "^1.1.9", + "bson": "^6.10.4", + "mongodb-connection-string-url": "^3.0.0" }, "engines": { - "node": ">=4" + "node": ">=16.20.1" }, - "optionalDependencies": { - "saslprep": "^1.0.0" + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.188.0", + "@mongodb-js/zstd": "^1.1.0 || ^2.0.0", + "gcp-metadata": "^5.2.0", + "kerberos": "^2.0.1", + "mongodb-client-encryption": ">=6.0.0 <7", + "snappy": "^7.2.2", + "socks": "^2.7.1" }, "peerDependenciesMeta": { - "aws4": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { "optional": true }, - "bson-ext": { + "gcp-metadata": { "optional": true }, "kerberos": { @@ -12043,61 +13073,77 @@ "mongodb-client-encryption": { "optional": true }, - "mongodb-extjson": { + "snappy": { "optional": true }, - "snappy": { + "socks": { "optional": true } } - }, - "node_modules/mongodb/node_modules/denque": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", - "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==", - "engines": { - "node": ">=0.10" + }, + "node_modules/mongodb-connection-string-url": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.2.tgz", + "integrity": "sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA==", + "license": "Apache-2.0", + "dependencies": { + "@types/whatwg-url": "^11.0.2", + "whatwg-url": "^14.1.0 || ^13.0.0" } }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, "node_modules/multer": { - "version": "1.4.4-lts.1", - "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.4-lts.1.tgz", - "integrity": "sha512-WeSGziVj6+Z2/MwQo3GvqzgR+9Uc+qt8SwHKh3gvNPiISKfsMfG4SvCOFYlxxgkXt7yIV2i1yczehm0EOKIxIg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/multer/-/multer-2.0.1.tgz", + "integrity": "sha512-Ug8bXeTIUlxurg8xLTEskKShvcKDZALo1THEX5E41pYCD2sCVub5/kIRIGqWNoqV6szyLyQKV6mD4QUrWE5GCQ==", + "license": "MIT", "dependencies": { "append-field": "^1.0.0", - "busboy": "^1.0.0", - "concat-stream": "^1.5.2", - "mkdirp": "^0.5.4", + "busboy": "^1.6.0", + "concat-stream": "^2.0.0", + "mkdirp": "^0.5.6", "object-assign": "^4.1.1", - "type-is": "^1.6.4", - "xtend": "^4.0.0" + "type-is": "^1.6.18", + "xtend": "^4.0.2" }, "engines": { - "node": ">= 6.0.0" + "node": ">= 10.16.0" } }, "node_modules/mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true + "dev": true, + "license": "ISC" + }, + "node_modules/mutexify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/mutexify/-/mutexify-1.4.0.tgz", + "integrity": "sha512-pbYSsOrSB/AKN5h/WzzLRMFgZhClWccf2XIB4RSMC8JbquiB0e0/SH5AIfdQMdyHmYtv4seU7yV/TvAwPLJ1Yg==", + "license": "MIT", + "dependencies": { + "queue-tick": "^1.0.0" + } }, "node_modules/mysql2": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.3.3.tgz", - "integrity": "sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.14.1.tgz", + "integrity": "sha512-7ytuPQJjQB8TNAYX/H2yhL+iQOnIBjAMam361R7UAL0lOVXWjtdrmoL9HYKqKoLp/8UUTRcvo1QPvK9KL7wA8w==", + "license": "MIT", "dependencies": { - "denque": "^2.0.1", + "aws-ssl-profiles": "^1.1.1", + "denque": "^2.1.0", "generate-function": "^2.3.1", "iconv-lite": "^0.6.3", - "long": "^4.0.0", - "lru-cache": "^6.0.0", - "named-placeholders": "^1.1.2", + "long": "^5.2.1", + "lru.min": "^1.0.0", + "named-placeholders": "^1.1.3", "seq-queue": "^0.0.5", "sqlstring": "^2.3.2" }, @@ -12109,6 +13155,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -12116,36 +13163,17 @@ "node": ">=0.10.0" } }, - "node_modules/mysql2/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mysql2/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } + "node_modules/mysql2/node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" }, "node_modules/named-placeholders": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz", "integrity": "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==", + "license": "MIT", "dependencies": { "lru-cache": "^7.14.1" }, @@ -12153,43 +13181,37 @@ "node": ">=12.0.0" } }, - "node_modules/nan": { - "version": "2.22.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.2.tgz", - "integrity": "sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==" - }, "node_modules/nanoassert": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-1.1.0.tgz", - "integrity": "sha512-C40jQ3NzfkP53NsO8kEOFd79p4b9kDXQMwgiY1z8ZwrDZgUyom0AHwGegF4Dm99L+YoYhuaB0ceerUcXmqr1rQ==" + "integrity": "sha512-C40jQ3NzfkP53NsO8kEOFd79p4b9kDXQMwgiY1z8ZwrDZgUyom0AHwGegF4Dm99L+YoYhuaB0ceerUcXmqr1rQ==", + "license": "ISC" }, "node_modules/nanoclone": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz", - "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==" - }, - "node_modules/napi-build-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", - "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==" + "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==", + "license": "MIT" }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/natural-compare-lite": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/negotiator": { "version": "0.6.4", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", - "peer": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -12198,12 +13220,14 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/nest-winston": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/nest-winston/-/nest-winston-1.10.2.tgz", "integrity": "sha512-Z9IzL/nekBOF/TEwBHUJDiDPMaXUcFquUQOFavIRet6xF0EbuWnOzslyN/ksgzG+fITNgXhMdrL/POp9SdaFxA==", + "license": "MIT", "dependencies": { "fast-safe-stringify": "^2.1.1" }, @@ -12215,34 +13239,27 @@ "node_modules/next-tick": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" - }, - "node_modules/node-abi": { - "version": "3.74.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.74.0.tgz", - "integrity": "sha512-c5XK0MjkGBrQPGYG24GBADZud0NCbznxNx0ZkS+ebUTrmV1qTDxPxSL8zEAPURXSbLRWVexxmP4986BziahL5w==", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "license": "ISC" }, "node_modules/node-abort-controller": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", - "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==" + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", + "license": "MIT" }, "node_modules/node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "license": "MIT" }, "node_modules/node-emoji": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", "dev": true, + "license": "MIT", "dependencies": { "lodash": "^4.17.21" } @@ -12251,6 +13268,7 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -12266,10 +13284,33 @@ } } }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/node-gyp-build": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.9.0.tgz", "integrity": "sha512-zLcTg6P4AbcHPq465ZMFNXx7XpKKJh+7kkN699NiQWisR2uWYOWNWqRHAmbnmKiL4e9aLSlmy5U7rEMUXV59+A==", + "license": "MIT", "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", @@ -12280,12 +13321,14 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-object-hash": { "version": "2.3.10", "resolved": "https://registry.npmjs.org/node-object-hash/-/node-object-hash-2.3.10.tgz", "integrity": "sha512-jY5dPJzw6NHd/KPSfPKJ+IHoFS81/tJ43r34ZeNMXGzCOM8jwQDCD12HYayKIB6MuznrnqIYy2e891NA2g0ibA==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -12294,12 +13337,14 @@ "version": "2.0.19", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -12309,6 +13354,7 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.0.0" }, @@ -12320,6 +13366,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -12328,6 +13375,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "license": "MIT", "engines": { "node": ">= 6" } @@ -12336,6 +13384,7 @@ "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -12347,6 +13396,7 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, @@ -12354,10 +13404,21 @@ "node": ">= 0.8" } }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", "dependencies": { "wrappy": "1" } @@ -12366,6 +13427,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "license": "MIT", "dependencies": { "fn.name": "1.x.x" } @@ -12375,6 +13437,7 @@ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -12389,26 +13452,17 @@ "version": "0.14.7", "resolved": "https://registry.npmjs.org/opentracing/-/opentracing-0.14.7.tgz", "integrity": "sha512-vz9iS7MJ5+Bp1URw8Khvdyw1H/hGvzHWlKQ7eRrQojSCDL1/SrWfrY9QebLw97n2deyRtzHRC3MkQfVNUCo91Q==", + "license": "Apache-2.0", "engines": { "node": ">=0.10" } }, - "node_modules/optional-require": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.1.8.tgz", - "integrity": "sha512-jq83qaUb0wNg9Krv1c5OQ+58EK+vHde6aBPzLvPPqJm89UQWsvSuFy9X/OSNJnFeSOKo7btE0n8Nl2+nE+z5nA==", - "dependencies": { - "require-at": "^1.0.6" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -12426,6 +13480,7 @@ "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", "dev": true, + "license": "MIT", "dependencies": { "bl": "^4.1.0", "chalk": "^4.1.0", @@ -12444,62 +13499,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ora/node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/ora/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/os-name": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-4.0.1.tgz", - "integrity": "sha512-xl9MAoU97MH1Xt5K9ERft2YfCAoaO6msy1OBA0ozxEC0x0TmIoE6K3QvgJMMZA9yKGLmHXNY/YZoDbiGDj4zYw==", - "dev": true, - "dependencies": { - "macos-release": "^2.5.0", - "windows-release": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -12508,6 +13513,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -12523,6 +13529,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -12538,15 +13545,23 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "license": "BlueOak-1.0.0" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -12559,6 +13574,7 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -12572,28 +13588,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/parse5": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", - "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==" - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", - "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", - "dependencies": { - "parse5": "^6.0.1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" - }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -12603,6 +13602,7 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -12611,6 +13611,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -12619,7 +13621,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -12628,13 +13630,14 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -12650,67 +13653,89 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true - }, - "node_modules/path-scurry/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } + "license": "ISC" }, "node_modules/path-to-regexp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.2.0.tgz", - "integrity": "sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA==" + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", + "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==", + "license": "MIT" }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.3.tgz", + "integrity": "sha512-wfRLBZ0feWRhCIkoMB6ete7czJcnNnqRpcoWQBLqatqXXmelSRqfdDK4F3u9T2s2cXas/hQJcryI/4lAL+XTlA==", + "license": "MIT", + "dependencies": { + "create-hash": "~1.1.3", + "create-hmac": "^1.1.7", + "ripemd160": "=2.0.1", + "safe-buffer": "^5.2.1", + "sha.js": "^2.4.11", + "to-buffer": "^1.2.0" }, "engines": { "node": ">=0.12" } }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + "node_modules/pbkdf2/node_modules/create-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", + "integrity": "sha512-snRpch/kwQhcdlnZKYanNF1m0RDlrCdSKQaH87w1FCFPVPNCQ/Il9QJKAX2jVBZddRdaHBMC+zXa9Gw9tmkNUA==", + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "sha.js": "^2.4.0" + } + }, + "node_modules/pbkdf2/node_modules/hash-base": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", + "integrity": "sha512-0TROgQ1/SxE6KmxWSvXHvRj90/Xo1JvZShofnYF+f6ZsGtR4eES7WfrQzPalmyagfKZCXpVnitiRebZulWsbiw==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1" + } + }, + "node_modules/pbkdf2/node_modules/ripemd160": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", + "integrity": "sha512-J7f4wutN8mdbV08MJnXibYpCOPHR+yzy+iQ/AsjMv2j8cLavQ8VGagDFUwwTAdF8FmRKVeNpbTTEwNHCW1g94w==", + "license": "MIT", + "dependencies": { + "hash-base": "^2.0.0", + "inherits": "^2.0.1" + } }, "node_modules/pg": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.14.1.tgz", - "integrity": "sha512-0TdbqfjwIun9Fm/r89oB7RFQ0bLgduAhiIqIXOsyKoiC/L54DbuAAzIEN/9Op0f1Po9X7iCPXGoa/Ah+2aI8Xw==", + "version": "8.16.3", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.16.3.tgz", + "integrity": "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==", + "license": "MIT", "dependencies": { - "pg-connection-string": "^2.7.0", - "pg-pool": "^3.8.0", - "pg-protocol": "^1.8.0", - "pg-types": "^2.1.0", - "pgpass": "1.x" + "pg-connection-string": "^2.9.1", + "pg-pool": "^3.10.1", + "pg-protocol": "^1.10.3", + "pg-types": "2.2.0", + "pgpass": "1.0.5" }, "engines": { - "node": ">= 8.0.0" + "node": ">= 16.0.0" }, "optionalDependencies": { - "pg-cloudflare": "^1.1.1" + "pg-cloudflare": "^1.2.7" }, "peerDependencies": { "pg-native": ">=3.0.1" @@ -12722,41 +13747,47 @@ } }, "node_modules/pg-cloudflare": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", - "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.2.7.tgz", + "integrity": "sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==", + "license": "MIT", "optional": true }, "node_modules/pg-connection-string": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.7.0.tgz", - "integrity": "sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA==" + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.9.1.tgz", + "integrity": "sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==", + "license": "MIT" }, "node_modules/pg-int8": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", "engines": { "node": ">=4.0.0" } }, "node_modules/pg-pool": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.8.0.tgz", - "integrity": "sha512-VBw3jiVm6ZOdLBTIcXLNdSotb6Iy3uOCwDGFAksZCXmi10nyRvnP2v3jl4d+IsLYRyXf6o9hIm/ZtUzlByNUdw==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.10.1.tgz", + "integrity": "sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==", + "license": "MIT", "peerDependencies": { "pg": ">=8.0" } }, "node_modules/pg-protocol": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.8.0.tgz", - "integrity": "sha512-jvuYlEkL03NRvOoyoRktBK7+qU5kOvlAwvmrH8sr3wbLrOdVWsRxQfz8mMy9sZFsqJ1hEWNfdWKI4SAmoL+j7g==" + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz", + "integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==", + "license": "MIT" }, "node_modules/pg-types": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", "dependencies": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", @@ -12772,6 +13803,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "license": "MIT", "dependencies": { "split2": "^4.1.0" } @@ -12780,35 +13812,28 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.1.tgz", + "integrity": "sha512-xUXwsxNjwTQ8K3GnT4pCJm+xq3RUPQbmkYJTP5aFIfNIvbcc/4MUxgBaaRSZJ6yGJZiGSyYlM6MzwTsRk8SYCg==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=8.6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", - "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } @@ -12818,6 +13843,7 @@ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, + "license": "MIT", "dependencies": { "find-up": "^4.0.0" }, @@ -12830,6 +13856,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -12843,6 +13870,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -12855,6 +13883,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -12870,6 +13899,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -12882,14 +13912,25 @@ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/postgres-array": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", "engines": { "node": ">=4" } @@ -12898,118 +13939,44 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/postgres-date": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", - "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postgres-interval": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", - "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", - "dependencies": { - "xtend": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/prebuild-install": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", - "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^2.0.0", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/prebuild-install/node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/prebuild-install/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/prebuild-install/node_modules/tar-fs": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz", - "integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==", - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/prebuild-install/node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" + "xtend": "^4.0.0" }, "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, + "node_modules/pprof-format": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pprof-format/-/pprof-format-2.1.0.tgz", + "integrity": "sha512-0+G5bHH0RNr8E5hoZo/zJYsL92MhkZjwrHp3O2IxmY8RJL9ooKeuZ8Tm0ZNBw5sGZ9TiM71sthTjWoR2Vf5/xw==", + "license": "MIT" + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } @@ -13018,6 +13985,7 @@ "version": "2.8.8", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "license": "MIT", "bin": { "prettier": "bin-prettier.js" }, @@ -13033,6 +14001,7 @@ "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, + "license": "MIT", "dependencies": { "fast-diff": "^1.1.2" }, @@ -13045,6 +14014,7 @@ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -13059,6 +14029,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -13066,15 +14037,11 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, "node_modules/prom-client": { "version": "14.2.0", "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-14.2.0.tgz", "integrity": "sha512-sF308EhTenb/pDRPakm+WgiN+VdM/T1RaHj1x+MvAuT8UiQP8JmOEbxVqtkbfR4LrvOg5n7ic01kRBDGXjYikA==", + "license": "Apache-2.0", "dependencies": { "tdigest": "^0.1.1" }, @@ -13085,13 +14052,15 @@ "node_modules/promise-breaker": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/promise-breaker/-/promise-breaker-6.0.0.tgz", - "integrity": "sha512-BthzO9yTPswGf7etOBiHCVuugs2N01/Q/94dIPls48z2zCmrnDptUUZzfIb+41xq0MnYZ/BzmOd6ikDR4ibNZA==" + "integrity": "sha512-BthzO9yTPswGf7etOBiHCVuugs2N01/Q/94dIPls48z2zCmrnDptUUZzfIb+41xq0MnYZ/BzmOd6ikDR4ibNZA==", + "license": "MIT" }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, + "license": "MIT", "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" @@ -13103,14 +14072,15 @@ "node_modules/property-expr": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz", - "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==" + "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==", + "license": "MIT" }, "node_modules/protobufjs": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", - "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.3.tgz", + "integrity": "sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==", "hasInstallScript": true, - "peer": true, + "license": "BSD-3-Clause", "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -13130,15 +14100,16 @@ } }, "node_modules/protobufjs/node_modules/long": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/long/-/long-5.3.1.tgz", - "integrity": "sha512-ka87Jz3gcx/I7Hal94xaN2tZEOPoUOEVftkQqZx2EeQRN7LGdfLlI3FvZ+7WDplm+vK2Urx9ULrvSowtdCieng==", - "peer": true + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -13150,22 +14121,14 @@ "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "node_modules/pump": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", - "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -13184,14 +14147,16 @@ "type": "opencollective", "url": "https://opencollective.com/fast-check" } - ] + ], + "license": "MIT" }, "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.0.4" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -13203,7 +14168,8 @@ "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "license": "MIT" }, "node_modules/queue-microtask": { "version": "1.2.3", @@ -13222,12 +14188,20 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" + }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "license": "MIT" }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } @@ -13236,6 +14210,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -13244,6 +14219,7 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -13254,38 +14230,18 @@ "node": ">= 0.8" } }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -13300,6 +14256,7 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, + "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -13307,16 +14264,17 @@ "node": ">=8.10.0" } }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, - "dependencies": { - "resolve": "^1.1.6" - }, + "license": "MIT", "engines": { - "node": ">= 0.10" + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/redent": { @@ -13324,6 +14282,7 @@ "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, + "license": "MIT", "dependencies": { "indent-string": "^4.0.0", "strip-indent": "^3.0.0" @@ -13336,6 +14295,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/redis/-/redis-3.1.2.tgz", "integrity": "sha512-grn5KoZLr/qrRQVwoSkmzdbw6pwF+/rwODtrOr6vuBRiR/f3rjSTGupbF90Zpqm2oenix8Do6RV7pYEkGwlKkw==", + "license": "MIT", "dependencies": { "denque": "^1.5.0", "redis-commands": "^1.7.0", @@ -13353,12 +14313,14 @@ "node_modules/redis-commands": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz", - "integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==" + "integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==", + "license": "MIT" }, "node_modules/redis-errors": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", + "license": "MIT", "engines": { "node": ">=4" } @@ -13367,6 +14329,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", + "license": "MIT", "dependencies": { "redis-errors": "^1.0.0" }, @@ -13378,6 +14341,7 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==", + "license": "Apache-2.0", "engines": { "node": ">=0.10" } @@ -13385,42 +14349,30 @@ "node_modules/reflect-metadata": { "version": "0.1.14", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz", - "integrity": "sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==" - }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + "integrity": "sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==", + "license": "Apache-2.0" }, "node_modules/repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10" } }, "node_modules/request-ip": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/request-ip/-/request-ip-2.2.0.tgz", - "integrity": "sha512-Hn4zUAr+XHbUs2RrfHur62t7+UhvtevqK32ordFewguEfNHUkhSdYgbG7PDGmXZEzqEXll9bei0+VMe6gkmuUQ==", - "dependencies": { - "is_js": "^0.9.0" - } - }, - "node_modules/require-at": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/require-at/-/require-at-1.0.6.tgz", - "integrity": "sha512-7i1auJbMUrXEAZCOQ0VNJgmcT2VOKPRl2YGJwgpHpC9CE91Mv4/4UYIUm4chGJaI381ZDq1JUicFii64Hapd8g==", - "engines": { - "node": ">=4" - } + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/request-ip/-/request-ip-3.3.0.tgz", + "integrity": "sha512-cA6Xh6e0fDBBBwH77SLJaJPBmD3nWVAcF9/XAcsrIHdjhFzFiB5aNQFytdjCGPezU3ROwrR11IddKAM08vohxA==", + "license": "MIT" }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -13430,6 +14382,7 @@ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -13437,13 +14390,15 @@ "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "license": "MIT" }, "node_modules/resolve": { "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "dev": true, + "license": "MIT", "dependencies": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", @@ -13464,6 +14419,7 @@ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, + "license": "MIT", "dependencies": { "resolve-from": "^5.0.0" }, @@ -13476,6 +14432,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -13485,6 +14442,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -13494,6 +14452,7 @@ "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } @@ -13503,6 +14462,7 @@ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dev": true, + "license": "MIT", "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" @@ -13511,10 +14471,18 @@ "node": ">=8" } }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, "node_modules/retry": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", "engines": { "node": ">= 4" } @@ -13523,21 +14491,28 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "license": "MIT" + }, "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "license": "ISC", "dependencies": { - "glob": "^7.1.3" + "glob": "^10.3.7" }, "bin": { - "rimraf": "bin.js" + "rimraf": "dist/esm/bin.mjs" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -13547,6 +14522,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "license": "MIT", "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1" @@ -13557,6 +14533,7 @@ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -13579,6 +14556,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } @@ -13588,6 +14566,7 @@ "resolved": "https://registry.npmjs.org/run-script-os/-/run-script-os-1.1.6.tgz", "integrity": "sha512-ql6P2LzhBTTDfzKts+Qo4H94VUKpxKDFz6QxxwaUZN0mwvi7L3lpOI7BqPCq7lgDh3XLl0dpeXwfcVIitlrYrw==", "dev": true, + "license": "MIT", "bin": { "run-os": "index.js", "run-script-os": "index.js" @@ -13597,19 +14576,36 @@ "version": "7.8.2", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" }, "node_modules/safe-stable-stringify": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "license": "MIT", "engines": { "node": ">=10" } @@ -13617,30 +14613,15 @@ "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/saslprep": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", - "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", - "optional": true, - "dependencies": { - "sparse-bitfield": "^3.0.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/sax": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", - "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" }, "node_modules/schema-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -13659,6 +14640,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -13675,6 +14657,7 @@ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, + "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" } @@ -13683,17 +14666,26 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/scryptsy": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-2.1.0.tgz", - "integrity": "sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w==" + "integrity": "sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w==", + "license": "MIT" + }, + "node_modules/semifies": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semifies/-/semifies-1.0.0.tgz", + "integrity": "sha512-xXR3KGeoxTNWPD4aBvL5NUpMTT7WMANr3EWnaS190QVkY52lqqcVRD7Q05UVbBhiWDGWMlJEUam9m7uFFGVScw==", + "license": "Apache-2.0" }, "node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -13705,7 +14697,7 @@ "version": "0.19.0", "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", - "peer": true, + "license": "MIT", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -13729,7 +14721,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "peer": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -13738,13 +14730,13 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "peer": true + "license": "MIT" }, "node_modules/send/node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "peer": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -13759,6 +14751,7 @@ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } @@ -13767,7 +14760,7 @@ "version": "1.16.2", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", - "peer": true, + "license": "MIT", "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", @@ -13778,15 +14771,34 @@ "node": ">= 0.8.0" } }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" }, "node_modules/sha.js": { "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "license": "(MIT AND BSD-3-Clause)", "dependencies": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -13796,37 +14808,51 @@ } }, "node_modules/sharp": { - "version": "0.32.6", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz", - "integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==", + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.2.tgz", + "integrity": "sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==", "hasInstallScript": true, + "license": "Apache-2.0", "dependencies": { "color": "^4.2.3", - "detect-libc": "^2.0.2", - "node-addon-api": "^6.1.0", - "prebuild-install": "^7.1.1", - "semver": "^7.5.4", - "simple-get": "^4.0.1", - "tar-fs": "^3.0.4", - "tunnel-agent": "^0.6.0" + "detect-libc": "^2.0.4", + "semver": "^7.7.2" }, "engines": { - "node": ">=14.15.0" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.2", + "@img/sharp-darwin-x64": "0.34.2", + "@img/sharp-libvips-darwin-arm64": "1.1.0", + "@img/sharp-libvips-darwin-x64": "1.1.0", + "@img/sharp-libvips-linux-arm": "1.1.0", + "@img/sharp-libvips-linux-arm64": "1.1.0", + "@img/sharp-libvips-linux-ppc64": "1.1.0", + "@img/sharp-libvips-linux-s390x": "1.1.0", + "@img/sharp-libvips-linux-x64": "1.1.0", + "@img/sharp-libvips-linuxmusl-arm64": "1.1.0", + "@img/sharp-libvips-linuxmusl-x64": "1.1.0", + "@img/sharp-linux-arm": "0.34.2", + "@img/sharp-linux-arm64": "0.34.2", + "@img/sharp-linux-s390x": "0.34.2", + "@img/sharp-linux-x64": "0.34.2", + "@img/sharp-linuxmusl-arm64": "0.34.2", + "@img/sharp-linuxmusl-x64": "0.34.2", + "@img/sharp-wasm32": "0.34.2", + "@img/sharp-win32-arm64": "0.34.2", + "@img/sharp-win32-ia32": "0.34.2", + "@img/sharp-win32-x64": "0.34.2" } }, - "node_modules/sharp/node_modules/node-addon-api": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", - "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==" - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -13838,32 +14864,28 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "dev": true, - "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" - }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "license": "MIT", "engines": { - "node": ">=4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/side-channel": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", @@ -13882,6 +14904,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" @@ -13897,6 +14920,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -13914,6 +14938,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -13929,62 +14954,26 @@ } }, "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/simple-git": { - "version": "3.27.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.27.0.tgz", - "integrity": "sha512-ivHoFS9Yi9GY49ogc6/YAi3Fl9ROnF4VyubNylgCkA+RVqLaKWnDSzXOVzya8csELIaWaYNutsEuAhZrtOjozA==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.28.0.tgz", + "integrity": "sha512-Rs/vQRwsn1ILH1oBUy8NucJlXmnnLeLCfcvbSehkPzbv3wwoFWIdtfd6Ndo6ZPhlPsCZ60CPI4rxurnwAa+a2w==", + "license": "MIT", "dependencies": { "@kwsites/file-exists": "^1.1.1", "@kwsites/promise-deferred": "^1.1.1", - "debug": "^4.3.5" + "debug": "^4.4.0" }, "funding": { "type": "github", @@ -13995,6 +14984,7 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "license": "MIT", "dependencies": { "is-arrayish": "^0.3.1" } @@ -14002,33 +14992,37 @@ "node_modules/simple-swizzle/node_modules/is-arrayish": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "license": "MIT" }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/socket.io": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.2.tgz", - "integrity": "sha512-bvKVS29/I5fl2FGLNHuXlQaUH/BlzX1IN6S+NKLNZpBsPZIDH+90eQmCs2Railn4YUiww4SzUedJ6+uzwFnKLw==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", + "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==", + "license": "MIT", "dependencies": { "accepts": "~1.3.4", "base64id": "~2.0.0", "cors": "~2.8.5", "debug": "~4.3.2", - "engine.io": "~6.5.2", + "engine.io": "~6.6.0", "socket.io-adapter": "~2.5.2", "socket.io-parser": "~4.2.4" }, @@ -14040,6 +15034,7 @@ "version": "2.5.5", "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", + "license": "MIT", "dependencies": { "debug": "~4.3.4", "ws": "~8.17.1" @@ -14049,6 +15044,7 @@ "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", "dependencies": { "ms": "^2.1.3" }, @@ -14065,6 +15061,7 @@ "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -14085,6 +15082,7 @@ "version": "4.2.4", "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "license": "MIT", "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.1" @@ -14097,6 +15095,7 @@ "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", "dependencies": { "ms": "^2.1.3" }, @@ -14113,6 +15112,7 @@ "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", "dependencies": { "ms": "^2.1.3" }, @@ -14129,25 +15129,17 @@ "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "license": "BSD-3-Clause", "engines": { "node": ">= 8" } }, - "node_modules/source-map-resolve": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", - "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", - "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0" - } - }, "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -14158,6 +15150,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -14166,26 +15159,16 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", - "optional": true, + "license": "MIT", "dependencies": { "memory-pager": "^1.0.2" } }, - "node_modules/split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "dependencies": { - "through": "2" - }, - "engines": { - "node": "*" - } - }, "node_modules/split2": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", "engines": { "node": ">= 10.x" } @@ -14194,12 +15177,30 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/sql-highlight": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sql-highlight/-/sql-highlight-6.1.0.tgz", + "integrity": "sha512-ed7OK4e9ywpE7pgRMkMQmZDPKSVdm0oX5IEtZiKnFucSF0zu6c80GZBe38UqHuVhTWJ9xsKgSMjCG2bml86KvA==", + "funding": [ + "https://github.com/scriptcoded/sql-highlight?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/scriptcoded" + } + ], + "license": "MIT", + "engines": { + "node": ">=14" + } }, "node_modules/sqlstring": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -14208,6 +15209,7 @@ "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "license": "MIT", "engines": { "node": "*" } @@ -14217,6 +15219,7 @@ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, + "license": "MIT", "dependencies": { "escape-string-regexp": "^2.0.0" }, @@ -14229,6 +15232,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -14236,12 +15240,14 @@ "node_modules/standard-as-callback": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", - "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==" + "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==", + "license": "MIT" }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -14254,50 +15260,21 @@ "node": ">=10.0.0" } }, - "node_modules/streamx": { - "version": "2.22.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.0.tgz", - "integrity": "sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==", - "dependencies": { - "fast-fifo": "^1.3.2", - "text-decoder": "^1.1.0" - }, - "optionalDependencies": { - "bare-events": "^2.2.0" - } - }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, + "license": "MIT", "dependencies": { "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" @@ -14310,6 +15287,22 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -14319,10 +15312,24 @@ "node": ">=8" } }, - "node_modules/strip-ansi": { + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -14335,6 +15342,7 @@ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -14344,6 +15352,7 @@ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -14353,6 +15362,7 @@ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, + "license": "MIT", "dependencies": { "min-indent": "^1.0.0" }, @@ -14365,6 +15375,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -14381,13 +15392,31 @@ "type": "github", "url": "https://github.com/sponsors/NaturalIntelligence" } - ] + ], + "license": "MIT" + }, + "node_modules/strtok3": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.1.tgz", + "integrity": "sha512-3JWEZM6mfix/GCJBBUrkA8p2Id2pBkyTkVCJKto55w080QBKZ+8R171fGrbiSp+yMO/u6F8/yUh7K4V9K+YCnw==", + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } }, "node_modules/subscriptions-transport-ws": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.11.0.tgz", "integrity": "sha512-8D4C6DIH5tGiAIpp5I0wD/xRlNiZAPGHygzCe7VzyzUoxHtawzjNAY9SUTXU05/EY2NMY9/9GF0ycizkXr1CWQ==", "deprecated": "The `subscriptions-transport-ws` package is no longer maintained. We recommend you use `graphql-ws` instead. For help migrating Apollo software to `graphql-ws`, see https://www.apollographql.com/docs/apollo-server/data/subscriptions/#switching-from-subscriptions-transport-ws For general help using `graphql-ws`, see https://github.com/enisdenjo/graphql-ws/blob/master/README.md", + "license": "MIT", "dependencies": { "backo2": "^1.0.2", "eventemitter3": "^3.1.0", @@ -14403,6 +15432,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -14411,6 +15441,7 @@ "version": "7.5.10", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "license": "MIT", "engines": { "node": ">=8.3.0" }, @@ -14433,6 +15464,7 @@ "integrity": "sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==", "deprecated": "Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net", "dev": true, + "license": "MIT", "dependencies": { "component-emitter": "^1.3.0", "cookiejar": "^2.1.4", @@ -14454,6 +15486,7 @@ "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", "dev": true, + "license": "MIT", "bin": { "mime": "cli.js" }, @@ -14466,6 +15499,7 @@ "resolved": "https://registry.npmjs.org/supertest/-/supertest-6.3.4.tgz", "integrity": "sha512-erY3HFDG0dPnhw4U+udPfrzXa4xhSG+n4rxfRuZWCUvjFWwKl+OxWf/7zk50s84/fAAs7vf5QAb9uRa0cCykxw==", "dev": true, + "license": "MIT", "dependencies": { "methods": "^1.1.2", "superagent": "^8.1.2" @@ -14478,6 +15512,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -14490,6 +15525,7 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -14498,14 +15534,16 @@ } }, "node_modules/swagger-ui-dist": { - "version": "5.9.1", - "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.9.1.tgz", - "integrity": "sha512-5zAx+hUwJb9T3EAntc7TqYkV716CMqG6sZpNlAAMOMWkNXRYxGkN8ADIvD55dQZ10LxN90ZM/TQmN7y1gpICnw==" + "version": "5.17.14", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.17.14.tgz", + "integrity": "sha512-CVbSfaLpstV65OnSjbXfVd6Sta3q3F7Cj/yYuvHMp1P90LztOLs6PfUnKEVAeiIVQt9u2SaPwv0LiH/OyMjHRw==", + "license": "Apache-2.0" }, "node_modules/swagger-ui-express": { "version": "4.6.3", "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-4.6.3.tgz", "integrity": "sha512-CDje4PndhTD2HkgyKH3pab+LKspDeB/NhPN2OF1j+piYIamQqBYwAXWESOT1Yju2xFg51bRW9sUng2WxDjzArw==", + "license": "MIT", "dependencies": { "swagger-ui-dist": ">=4.11.0" }, @@ -14521,58 +15559,39 @@ "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10" } }, "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", + "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/tar-fs": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.8.tgz", - "integrity": "sha512-ZoROL70jptorGAlgAYiLoBLItEKw/fUxg9BSYK/dF/GAGYFJOJJJMvjPAKDJraCXFwadD456FCuvLWgfhMsPwg==", - "dependencies": { - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - }, - "optionalDependencies": { - "bare-fs": "^4.0.1", - "bare-path": "^3.0.0" - } - }, - "node_modules/tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, "node_modules/tdigest": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.2.tgz", "integrity": "sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA==", + "license": "MIT", "dependencies": { "bintrees": "1.0.2" } }, "node_modules/terser": { - "version": "5.39.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz", - "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==", + "version": "5.43.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz", + "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", + "acorn": "^8.14.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -14588,6 +15607,7 @@ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", @@ -14622,6 +15642,7 @@ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -14632,10 +15653,11 @@ } }, "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", - "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -14655,6 +15677,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -14669,13 +15692,36 @@ "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/terser/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/terser/node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, + "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", @@ -14685,53 +15731,53 @@ "node": ">=8" } }, - "node_modules/text-decoder": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", - "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", "dependencies": { - "b4a": "^1.6.4" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/text-hex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==", + "license": "MIT" }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } + "dev": true, + "license": "MIT" }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true, + "license": "MIT" }, "node_modules/timers-ext": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.8.tgz", "integrity": "sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==", + "license": "ISC", "dependencies": { "es5-ext": "^0.10.64", "next-tick": "^1.1.0" @@ -14744,6 +15790,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/tiny-async-pool/-/tiny-async-pool-1.3.0.tgz", "integrity": "sha512-01EAw5EDrcVrdgyCLgoSPvqznC0sVxDSVeiOz09FUpjh71G79VCqneOr+xvt7T1r76CF6ZZfPjHorN2+d+3mqA==", + "license": "MIT", "dependencies": { "semver": "^5.5.0" } @@ -14752,15 +15799,23 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "license": "ISC", "bin": { "semver": "bin/semver" } }, + "node_modules/tlhunter-sorted-set": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/tlhunter-sorted-set/-/tlhunter-sorted-set-0.1.0.tgz", + "integrity": "sha512-eGYW4bjf1DtrHzUYxYfAcSytpOkA44zsr7G2n3PV7yOUR23vmkGe3LL4R+1jL9OsXtbsFOwe8XtbCrabeaEFnw==", + "license": "MIT" + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, + "license": "MIT", "dependencies": { "os-tmpdir": "~1.0.2" }, @@ -14772,12 +15827,34 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/to-buffer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.1.tgz", + "integrity": "sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==", + "license": "MIT", + "dependencies": { + "isarray": "^2.0.5", + "safe-buffer": "^5.2.1", + "typed-array-buffer": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/to-buffer/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "license": "MIT" }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -14789,25 +15866,52 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", "engines": { "node": ">=0.6" } }, + "node_modules/token-types": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.0.3.tgz", + "integrity": "sha512-IKJ6EzuPPWtKtEIEPpIdXv9j5j2LGJEYk0CKY2efgKoYKLBiZdh6iQkLVBow/CB3phyWAWCyk+bZeaimJn6uRQ==", + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/toposort": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", - "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==" + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==", + "license": "MIT" }, "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } }, "node_modules/tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "dev": true, + "license": "MIT", "bin": { "tree-kill": "cli.js" } @@ -14816,25 +15920,26 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", + "license": "MIT", "engines": { "node": ">= 14.0.0" } }, "node_modules/ts-jest": { - "version": "29.3.0", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.3.0.tgz", - "integrity": "sha512-4bfGBX7Gd1Aqz3SyeDS9O276wEU/BInZxskPrbhZLyv+c1wskDCqDFMJQJLWrIr/fKoAH4GE5dKUlrdyvo+39A==", + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.0.tgz", + "integrity": "sha512-d423TJMnJGu80/eSgfQ5w/R+0zFJvdtTxwtF9KzFFunOpSeD+79lHJQIiAhluJoyGRbvj9NZJsl9WjCUo0ND7Q==", "dev": true, + "license": "MIT", "dependencies": { "bs-logger": "^0.2.6", "ejs": "^3.1.10", "fast-json-stable-stringify": "^2.1.0", - "jest-util": "^29.0.0", "json5": "^2.2.3", "lodash.memoize": "^4.1.2", "make-error": "^1.3.6", - "semver": "^7.7.1", - "type-fest": "^4.37.0", + "semver": "^7.7.2", + "type-fest": "^4.41.0", "yargs-parser": "^21.1.1" }, "bin": { @@ -14845,10 +15950,11 @@ }, "peerDependencies": { "@babel/core": ">=7.0.0-beta.0 <8", - "@jest/transform": "^29.0.0", - "@jest/types": "^29.0.0", - "babel-jest": "^29.0.0", - "jest": "^29.0.0", + "@jest/transform": "^29.0.0 || ^30.0.0", + "@jest/types": "^29.0.0 || ^30.0.0", + "babel-jest": "^29.0.0 || ^30.0.0", + "jest": "^29.0.0 || ^30.0.0", + "jest-util": "^29.0.0 || ^30.0.0", "typescript": ">=4.3 <6" }, "peerDependenciesMeta": { @@ -14866,14 +15972,18 @@ }, "esbuild": { "optional": true + }, + "jest-util": { + "optional": true } } }, "node_modules/ts-jest/node_modules/type-fest": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.38.0.tgz", - "integrity": "sha512-2dBz5D5ycHIoliLYLi0Q2V7KRaDlH0uWIvmk7TYlAg5slqwiPv1ezJdZm1QEM0xgk29oYWMCbIG7E6gHpvChlg==", + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=16" }, @@ -14886,6 +15996,7 @@ "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.2.tgz", "integrity": "sha512-OmlC4WVmFv5I0PpaxYb+qGeGOdm5giHU7HwDDUjw59emP2UYMHy9fFSDcYgSNoH8sXcj4hGCSEhlDZ9ULeDraA==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.1.0", "enhanced-resolve": "^5.0.0", @@ -14905,6 +16016,7 @@ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", "devOptional": true, + "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "0.7.0", "@tsconfig/node10": "^1.0.7", @@ -14948,6 +16060,7 @@ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", "dev": true, + "license": "MIT", "dependencies": { "json5": "^2.2.2", "minimist": "^1.2.6", @@ -14958,13 +16071,15 @@ } }, "node_modules/tsconfig-paths-webpack-plugin": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.1.0.tgz", - "integrity": "sha512-xWFISjviPydmtmgeUAuXp4N1fky+VCtfhOkDUFIv5ea7p4wuTomI4QTrXvFBX2S4jZsmyTSrStQl+E+4w+RzxA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.2.0.tgz", + "integrity": "sha512-zbem3rfRS8BgeNK50Zz5SIQgXzLafiHjOwUAvk/38/o1jHn/V5QAgVUcz884or7WYcPaH3N2CIfUc2u0ul7UcA==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.1.0", "enhanced-resolve": "^5.7.0", + "tapable": "^2.2.1", "tsconfig-paths": "^4.1.2" }, "engines": { @@ -14976,6 +16091,7 @@ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -14983,13 +16099,15 @@ "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, "node_modules/tsutils": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^1.8.1" }, @@ -15004,34 +16122,36 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "dev": true, + "license": "0BSD" }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "node_modules/ttl-set": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ttl-set/-/ttl-set-1.0.0.tgz", + "integrity": "sha512-2fuHn/UR+8Z9HK49r97+p2Ru1b5Eewg2QqPrU14BVCQ9QoyU3+vLLZk2WEiyZ9sgJh6W8G1cZr9I2NBLywAHrA==", + "license": "MIT", "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" + "fast-fifo": "^1.3.2" } }, "node_modules/tweetnacl": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "license": "Unlicense" }, "node_modules/type": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", - "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==" + "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==", + "license": "ISC" }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -15044,6 +16164,7 @@ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -15053,6 +16174,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -15064,6 +16186,7 @@ "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -15072,33 +16195,46 @@ "node": ">= 0.6" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "license": "MIT" }, "node_modules/typeorm": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.10.tgz", - "integrity": "sha512-VMKiM84EpJQ+Mz9xDIPqnfplWhyUy1d8ccaKdMY9obifxJOTFnv8GYVyPsGwG8Lk7Nb8MlttHyHWENGAhBA3WA==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.25.tgz", + "integrity": "sha512-fTKDFzWXKwAaBdEMU4k661seZewbNYET4r1J/z3Jwf+eAvlzMVpTLKAVcAzg75WwQk7GDmtsmkZ5MfkmXCiFWg==", + "license": "MIT", "dependencies": { - "@sqltools/formatter": "^1.2.2", - "app-root-path": "^3.0.0", + "@sqltools/formatter": "^1.2.5", + "ansis": "^3.17.0", + "app-root-path": "^3.1.0", "buffer": "^6.0.3", - "chalk": "^4.1.0", - "cli-highlight": "^2.1.11", - "date-fns": "^2.28.0", - "debug": "^4.3.3", - "dotenv": "^16.0.0", - "glob": "^7.2.0", - "js-yaml": "^4.1.0", - "mkdirp": "^1.0.4", - "reflect-metadata": "^0.1.13", + "dayjs": "^1.11.13", + "debug": "^4.4.0", + "dedent": "^1.6.0", + "dotenv": "^16.4.7", + "glob": "^10.4.5", "sha.js": "^2.4.11", - "tslib": "^2.3.1", - "uuid": "^8.3.2", - "xml2js": "^0.4.23", - "yargs": "^17.3.1" + "sql-highlight": "^6.0.0", + "tslib": "^2.8.1", + "uuid": "^11.1.0", + "yargs": "^17.7.2" }, "bin": { "typeorm": "cli.js", @@ -15106,29 +16242,30 @@ "typeorm-ts-node-esm": "cli-ts-node-esm.js" }, "engines": { - "node": ">= 12.9.0" + "node": ">=16.13.0" }, "funding": { "url": "https://opencollective.com/typeorm" }, "peerDependencies": { - "@google-cloud/spanner": "^5.18.0", + "@google-cloud/spanner": "^5.18.0 || ^6.0.0 || ^7.0.0", "@sap/hana-client": "^2.12.25", - "better-sqlite3": "^7.1.2", + "better-sqlite3": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0", "hdb-pool": "^0.1.6", "ioredis": "^5.0.4", - "mongodb": "^3.6.0", - "mssql": "^7.3.0", - "mysql2": "^2.2.5", - "oracledb": "^5.1.0", + "mongodb": "^5.8.0 || ^6.0.0", + "mssql": "^9.1.1 || ^10.0.1 || ^11.0.1", + "mysql2": "^2.2.5 || ^3.0.1", + "oracledb": "^6.3.0", "pg": "^8.5.1", "pg-native": "^3.0.0", "pg-query-stream": "^4.0.0", "redis": "^3.1.1 || ^4.0.0", + "reflect-metadata": "^0.1.14 || ^0.2.0", "sql.js": "^1.4.0", "sqlite3": "^5.0.3", "ts-node": "^10.7.0", - "typeorm-aurora-data-api-driver": "^2.0.0" + "typeorm-aurora-data-api-driver": "^2.0.0 || ^3.0.0" }, "peerDependenciesMeta": { "@google-cloud/spanner": { @@ -15184,23 +16321,29 @@ } } }, - "node_modules/typeorm/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, + "node_modules/typeorm/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", "engines": { - "node": ">=10" + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" } }, "node_modules/typeorm/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", "bin": { - "uuid": "dist/bin/uuid" + "uuid": "dist/esm/bin/uuid" } }, "node_modules/typescript": { @@ -15208,6 +16351,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "devOptional": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -15220,6 +16364,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/uid/-/uid-2.0.2.tgz", "integrity": "sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==", + "license": "MIT", "dependencies": { "@lukeed/csprng": "^1.0.0" }, @@ -15227,11 +16372,24 @@ "node": ">=8" } }, + "node_modules/uint8array-extras": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.4.0.tgz", + "integrity": "sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/universalify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.0.0" } @@ -15240,6 +16398,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -15263,6 +16422,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" @@ -15279,6 +16439,7 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -15287,6 +16448,7 @@ "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "license": "MIT", "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -15295,12 +16457,14 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", "engines": { "node": ">= 0.4.0" } @@ -15313,6 +16477,7 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } @@ -15321,13 +16486,15 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/v8-to-istanbul": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", "dev": true, + "license": "ISC", "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", @@ -15341,6 +16508,7 @@ "version": "1.0.12", "resolved": "https://registry.npmjs.org/value-or-promise/-/value-or-promise-1.0.12.tgz", "integrity": "sha512-Z6Uz+TYwEqE7ZN50gwn+1LCVo9ZVrpxRPOhOLnncYkY1ZzOYtrX8Fwf/rFktZ8R5mJms6EZf5TqNOMeZmnPq9Q==", + "license": "MIT", "engines": { "node": ">=12" } @@ -15349,6 +16517,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -15358,15 +16527,17 @@ "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "makeerror": "1.0.12" } }, "node_modules/watchpack": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", - "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", + "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", "dev": true, + "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -15380,23 +16551,30 @@ "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", "dev": true, + "license": "MIT", "dependencies": { "defaults": "^1.0.3" } }, "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } }, "node_modules/webpack": { - "version": "5.98.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.98.0.tgz", - "integrity": "sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==", + "version": "5.99.9", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.9.tgz", + "integrity": "sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==", "dev": true, + "license": "MIT", "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", @@ -15413,7 +16591,7 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^4.3.0", + "schema-utils": "^4.3.2", "tapable": "^2.1.1", "terser-webpack-plugin": "^5.3.11", "watchpack": "^2.4.1", @@ -15440,24 +16618,27 @@ "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-3.0.0.tgz", "integrity": "sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.13.0" } }, "node_modules/webpack/node_modules/schema-utils": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", - "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -15476,24 +16657,29 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "license": "MIT", "engines": { "node": ">=12" } }, "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "license": "MIT", "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" } }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -15504,72 +16690,32 @@ "node": ">= 8" } }, - "node_modules/windows-release": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-4.0.0.tgz", - "integrity": "sha512-OxmV4wzDKB1x7AZaZgXMVsdJ1qER1ed83ZrTYd5Bwq2HfJVg3DJS8nqlAG4sMoJ7mu8cuRmLEYyU13BKwctRAg==", - "dev": true, - "dependencies": { - "execa": "^4.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/windows-release/node_modules/execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/windows-release/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "license": "MIT", "dependencies": { - "pump": "^3.0.0" + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/windows-release/node_modules/human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "dev": true, - "engines": { - "node": ">=8.12.0" + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/winston": { "version": "3.17.0", "resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz", "integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==", + "license": "MIT", "dependencies": { "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.2", @@ -15591,6 +16737,7 @@ "version": "4.7.1", "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-4.7.1.tgz", "integrity": "sha512-7LGPiYGBPNyGHLn9z33i96zx/bd71pjBn9tqQzO3I4Tayv94WPmBNwKC7CO1wPHdP9uvu+Md/1nr6VSH9h0iaA==", + "license": "MIT", "dependencies": { "file-stream-rotator": "^0.6.1", "object-hash": "^2.0.1", @@ -15608,6 +16755,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", + "license": "MIT", "engines": { "node": ">= 6" } @@ -15616,6 +16764,7 @@ "version": "4.9.0", "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.9.0.tgz", "integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==", + "license": "MIT", "dependencies": { "logform": "^2.7.0", "readable-stream": "^3.6.2", @@ -15629,6 +16778,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", + "license": "MIT", "engines": { "node": ">=0.1.90" } @@ -15636,13 +16786,15 @@ "node_modules/winston/node_modules/async": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==" + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -15650,13 +16802,15 @@ "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "license": "MIT" }, "node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -15666,16 +16820,37 @@ "node": ">=8" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" }, "node_modules/write-file-atomic": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, + "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^3.0.7" @@ -15684,10 +16859,18 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/write-file-atomic/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, "node_modules/ws": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -15704,30 +16887,11 @@ } } }, - "node_modules/xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "engines": { - "node": ">=4.0" - } - }, "node_modules/xss": { "version": "1.0.15", "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.15.tgz", "integrity": "sha512-FVdlVVC67WOIPvfOwhoMETV72f6GbW7aOabBC3WxN/oUdoEMDyLz4OgRv5/gck2ZeNqEQu+Tb0kloovXOfpYVg==", + "license": "MIT", "dependencies": { "commander": "^2.20.3", "cssfilter": "0.0.10" @@ -15742,12 +16906,14 @@ "node_modules/xss/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", "engines": { "node": ">=0.4" } @@ -15756,6 +16922,7 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", "engines": { "node": ">=10" } @@ -15764,21 +16931,14 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true, - "engines": { - "node": ">= 6" - } + "license": "ISC" }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -15796,6 +16956,7 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", "engines": { "node": ">=12" } @@ -15805,6 +16966,7 @@ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -15813,6 +16975,7 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -15824,6 +16987,7 @@ "version": "0.32.11", "resolved": "https://registry.npmjs.org/yup/-/yup-0.32.11.tgz", "integrity": "sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.15.4", "@types/lodash": "^4.14.175", diff --git a/package.json b/package.json index d1d3dbaa2..66a869e19 100644 --- a/package.json +++ b/package.json @@ -89,39 +89,40 @@ "@multiversx/sdk-core": "^13.2.2", "@multiversx/sdk-data-api-client": "^0.7.0", "@multiversx/sdk-exchange": "^0.2.21", - "@multiversx/sdk-nestjs-auth": "5.0.2-beta.0", - "@multiversx/sdk-nestjs-cache": "5.0.2-beta.0", - "@multiversx/sdk-nestjs-common": "5.0.2-beta.0", - "@multiversx/sdk-nestjs-elastic": "5.0.2-beta.0", - "@multiversx/sdk-nestjs-http": "5.0.2-beta.0", - "@multiversx/sdk-nestjs-monitoring": "5.0.2-beta.0", - "@multiversx/sdk-nestjs-rabbitmq": "5.0.2-beta.0", - "@multiversx/sdk-nestjs-redis": "5.0.2-beta.0", + "@multiversx/sdk-nestjs-auth": "6.0.1-beta.0", + "@multiversx/sdk-nestjs-cache": "6.0.1-beta.0", + "@multiversx/sdk-nestjs-common": "6.0.1-beta.0", + "@multiversx/sdk-nestjs-elastic": "6.0.1-beta.0", + "@multiversx/sdk-nestjs-http": "6.0.1-beta.0", + "@multiversx/sdk-nestjs-monitoring": "6.0.1-beta.0", + "@multiversx/sdk-nestjs-rabbitmq": "6.0.1-beta.0", + "@multiversx/sdk-nestjs-redis": "6.0.1-beta.0", "@multiversx/sdk-transaction-processor": "^0.1.35", "@nestjs/apollo": "12.0.11", - "@nestjs/common": "10.2.0", + "@nestjs/common": "^10.2.0", "@nestjs/config": "3.0.1", - "@nestjs/core": "10.2.4", + "@nestjs/core": "10.4.2", "@nestjs/event-emitter": "^2.0.3", "@nestjs/graphql": "^12.0.11", "@nestjs/microservices": "10.2.4", - "@nestjs/platform-express": "10.2.4", - "@nestjs/platform-socket.io": "10.2.4", + "@nestjs/platform-express": "10.4.19", + "@nestjs/platform-socket.io": "^10.2.4", "@nestjs/schedule": "3.0.3", - "@nestjs/swagger": "7.1.16", + "@nestjs/swagger": "7.4.2", "@nestjs/typeorm": "10.0.0", "@nestjs/websockets": "^10.2.8", - "@sendgrid/mail": "^7.7.0", + "@sendgrid/mail": "^8.1.5", "agentkeepalive": "^4.2.1", "amqp-connection-manager": "^4.1.3", + "anchorme": "^3.0.8", "amqplib": "^0.10.0", - "anchorme": "^2.1.2", "apollo-server-core": "^3.13.0", "apollo-server-express": "3.13.0", "bignumber.js": "^9.0.2", + "compression": "^1.8.0", "crypto-js": "^4.1.1", - "dataloader": "^2.1.0", - "dd-trace": "^1.6.0", + "dataloader": "^2.2.2", + "dd-trace": "5.56.0", "fluent-ffmpeg": "^2.1.2", "graphql": "^16.8.1", "graphql-fields-list": "^2.2.4", @@ -130,9 +131,8 @@ "ioredis": "^5.2.3", "js-yaml": "^4.1.0", "json-diff": "^0.7.1", - "jsonwebtoken": "^8.5.1", - "mongodb": "^3.6.4", - "mysql2": "^2.3.3", + "mongodb": "^6.17.0", + "mysql2": "^3.9.8", "nest-winston": "^1.6.2", "node-fetch": "^2.6.7", "node-object-hash": "^2.3.10", @@ -140,14 +140,14 @@ "prom-client": "^14.0.1", "redis": "^3.1.2", "reflect-metadata": "^0.1.13", - "request-ip": "^2.1.3", - "rimraf": "^3.0.2", + "request-ip": "^3.3.0", + "rimraf": "^5.0.0", "rxjs": "^7.1.0", - "sharp": "^0.32.6", + "sharp": "^0.34.2", "simple-git": "^3.16.0", "swagger-ui-express": "^4.3.0", "tiny-async-pool": "^1.2.0", - "typeorm": "0.3.10", + "typeorm": "^0.3.25", "winston": "^3.6.0", "winston-daily-rotate-file": "^4.7.1", "yup": "^0.32.11" @@ -156,10 +156,11 @@ "@automock/adapters.nestjs": "^2.1.0", "@automock/jest": "^2.1.0", "@jest/test-sequencer": "^29.7.0", - "@nestjs/cli": "10.1.17", + "@nestjs/cli": "10.4.9", "@nestjs/schematics": "10.0.2", "@nestjs/testing": "10.2.4", "@testing-library/jest-dom": "6.1.4", + "@types/compression": "^1.8.1", "@types/cron": "^1.7.3", "@types/crypto-js": "^4.0.2", "@types/express": "^4.17.13", diff --git a/src/common/api-config/api.config.service.ts b/src/common/api-config/api.config.service.ts index a141254ad..85b1a93f0 100644 --- a/src/common/api-config/api.config.service.ts +++ b/src/common/api-config/api.config.service.ts @@ -407,6 +407,10 @@ export class ApiConfigService { }; } + getElasticMigratedIndicesConfig(): Record { + return this.configService.get>('features.elasticMigratedIndices') ?? {}; + } + getIsWebsocketApiActive(): boolean { return this.configService.get('api.websocket') ?? true; } @@ -561,7 +565,7 @@ export class ApiConfigService { getAwsS3Endpoint(): string | undefined { const s3Endpoint = this.configService.get('aws.s3Endpoint'); - return s3Endpoint ?? undefined; + return s3Endpoint && s3Endpoint.length > 0 ? s3Endpoint : undefined; } getMetaChainShardId(): number { @@ -955,4 +959,20 @@ export class ApiConfigService { getMediaRedirectFileStorageUrls(): string[] { return this.configService.get('features.mediaRedirect.storageUrls') ?? []; } + + getCompressionEnabled(): boolean { + return this.configService.get('compression.enabled') ?? false; + } + + getCompressionLevel(): number { + return this.configService.get('compression.level') ?? 6; + } + + getCompressionThreshold(): number { + return this.configService.get('compression.threshold') ?? 1024; + } + + getCompressionChunkSize(): number { + return this.configService.get('compression.chunkSize') ?? 16384; + } } diff --git a/src/common/assets/entities/token.assets.price.source.ts b/src/common/assets/entities/token.assets.price.source.ts index 489935414..55a07918f 100644 --- a/src/common/assets/entities/token.assets.price.source.ts +++ b/src/common/assets/entities/token.assets.price.source.ts @@ -2,7 +2,7 @@ import { ApiProperty } from "@nestjs/swagger"; import { TokenAssetsPriceSourceType } from "./token.assets.price.source.type"; export class TokenAssetsPriceSource { - @ApiProperty({ type: TokenAssetsPriceSourceType, nullable: true }) + @ApiProperty({ enum: TokenAssetsPriceSourceType, nullable: true }) type: TokenAssetsPriceSourceType | undefined = undefined; @ApiProperty({ type: String, nullable: true }) diff --git a/src/common/assets/entities/token.assets.ts b/src/common/assets/entities/token.assets.ts index 5455abfeb..de9d9459a 100644 --- a/src/common/assets/entities/token.assets.ts +++ b/src/common/assets/entities/token.assets.ts @@ -38,6 +38,6 @@ export class TokenAssets { @ApiProperty({ enum: NftRankAlgorithm, nullable: true }) preferredRankAlgorithm: NftRankAlgorithm | undefined = undefined; - @ApiProperty({ enum: TokenAssetsPriceSource, nullable: true }) + @ApiProperty({ type: TokenAssetsPriceSource, nullable: true }) priceSource: TokenAssetsPriceSource | undefined = undefined; } diff --git a/src/common/indexer/elastic/elastic.indexer.helper.ts b/src/common/indexer/elastic/elastic.indexer.helper.ts index 19d7e0e97..efcc098c4 100644 --- a/src/common/indexer/elastic/elastic.indexer.helper.ts +++ b/src/common/indexer/elastic/elastic.indexer.helper.ts @@ -1,5 +1,5 @@ import { AddressUtils, BinaryUtils } from "@multiversx/sdk-nestjs-common"; -import { AbstractQuery, ElasticQuery, MatchQuery, QueryConditionOptions, QueryOperator, QueryType, RangeGreaterThanOrEqual, RangeLowerThan, RangeLowerThanOrEqual } from "@multiversx/sdk-nestjs-elastic"; +import { AbstractQuery, ElasticQuery, MatchQuery, QueryConditionOptions, QueryOperator, QueryType, RangeGreaterThan, RangeGreaterThanOrEqual, RangeLowerThan, RangeLowerThanOrEqual } from "@multiversx/sdk-nestjs-elastic"; import { Injectable } from "@nestjs/common"; import { ApiConfigService } from "src/common/api-config/api.config.service"; import { QueryPagination } from "src/common/entities/query.pagination"; @@ -728,6 +728,14 @@ export class ElasticIndexerHelper { elasticQuery = elasticQuery.withSearchWildcardCondition(filter.search, ['address', 'api_assets.name']); } + if (filter.withBalance !== undefined) { + if (filter.withBalance) { + elasticQuery = elasticQuery.withRangeFilter('balanceNum', new RangeGreaterThan(0)); + } else { + elasticQuery = elasticQuery.withMustCondition(QueryType.Match('balanceNum', 0)); + } + } + return elasticQuery; } @@ -813,6 +821,10 @@ export class ElasticIndexerHelper { elasticQuery = elasticQuery.withMustMatchCondition('address', filter.address); } + if (filter.order) { + elasticQuery = elasticQuery.withCondition(QueryConditionOptions.must, QueryType.Match('order', filter.order)); + } + return elasticQuery; } } diff --git a/src/common/indexer/elastic/elastic.indexer.service.ts b/src/common/indexer/elastic/elastic.indexer.service.ts index ada83218e..fc7438ff7 100644 --- a/src/common/indexer/elastic/elastic.indexer.service.ts +++ b/src/common/indexer/elastic/elastic.indexer.service.ts @@ -250,6 +250,15 @@ export class ElasticIndexerService implements IndexerInterface { return await this.elasticService.getItem('blocks', 'hash', hash); } + async getBlockByMiniBlockHash(miniBlockHash: string): Promise { + const elasticQuery = ElasticQuery.create() + .withCondition(QueryConditionOptions.must, [QueryType.Match('miniBlocksHashes', miniBlockHash)]) + .withSort([{ name: 'timestamp', order: ElasticSortOrder.descending }]); + + const result = await this.elasticService.getList('blocks', '_search', elasticQuery); + return result.length > 0 ? result[0] : undefined; + } + async getMiniBlock(miniBlockHash: string): Promise { return await this.elasticService.getItem('miniblocks', 'miniBlockHash', miniBlockHash); } @@ -582,17 +591,17 @@ export class ElasticIndexerService implements IndexerInterface { return query; } - async getTransactionLogs(hashes: string[]): Promise { + async getTransactionLogs(hashes: string[], eventsIndex: string, txHashField: string): Promise { const queries = []; for (const hash of hashes) { - queries.push(QueryType.Match('_id', hash)); + queries.push(QueryType.Match(txHashField, hash)); } const elasticQueryLogs = ElasticQuery.create() .withPagination({ from: 0, size: 10000 }) .withCondition(QueryConditionOptions.should, queries); - return await this.elasticService.getList('logs', 'id', elasticQueryLogs); + return await this.elasticService.getList(eventsIndex, 'id', elasticQueryLogs); } async getTransactionScResults(txHash: string): Promise { diff --git a/src/common/indexer/entities/block.ts b/src/common/indexer/entities/block.ts index a049fc878..e552caf36 100644 --- a/src/common/indexer/entities/block.ts +++ b/src/common/indexer/entities/block.ts @@ -4,6 +4,7 @@ export interface Block { round: number; epoch: number; miniBlocksHashes: string[]; + miniBlocksDetails?: MiniBlockDetails[]; notarizedBlocksHashes?: string[]; proposer: number; validators: number[], @@ -25,3 +26,15 @@ export interface Block { gasPenalized: number; maxGasLimit: string; } + +export interface MiniBlockDetails { + firstProcessedTx: number; + lastProcessedTx: number; + senderShard: number; + receiverShard: number; + mbIndex: number; + type: string; + procType: string; + txsHashes: string[]; + executionOrderTxsIndices: number[]; +} diff --git a/src/common/indexer/entities/index.ts b/src/common/indexer/entities/index.ts index d320c2ec6..2cc7597c3 100644 --- a/src/common/indexer/entities/index.ts +++ b/src/common/indexer/entities/index.ts @@ -1,7 +1,7 @@ export { Account } from './account'; export { AccountHistory } from './account.history'; export { AccountTokenHistory } from './account.token.history'; -export { Block } from './block'; +export { Block, MiniBlockDetails } from './block'; export { Collection } from './collection'; export { MiniBlock } from './miniblock'; export { Operation } from './operation'; @@ -12,5 +12,5 @@ export { Tag } from './tag'; export { Token } from './token'; export { TokenAccount, TokenType } from './token.account'; export { Transaction } from './transaction'; -export { TransactionLog, TransactionLogEvent } from './transaction.log'; +export { TransactionLog, TransactionLogEvent, ElasticTransactionLogEvent } from './transaction.log'; export { TransactionReceipt } from './transaction.receipt'; diff --git a/src/common/indexer/entities/transaction.log.ts b/src/common/indexer/entities/transaction.log.ts index a9a3c1d6d..3a71225a3 100644 --- a/src/common/indexer/entities/transaction.log.ts +++ b/src/common/indexer/entities/transaction.log.ts @@ -13,3 +13,15 @@ export interface TransactionLogEvent { data?: string; order: number; } + +export interface ElasticTransactionLogEvent { + address: string; + identifier: string; + topics: string[]; + data?: string; + order: number; + txHash: string; + originalTxHash: string; + logAddress: string; + additionalData?: string[]; +} diff --git a/src/common/indexer/entities/transaction.ts b/src/common/indexer/entities/transaction.ts index f759ec1ea..a65abd524 100644 --- a/src/common/indexer/entities/transaction.ts +++ b/src/common/indexer/entities/transaction.ts @@ -35,4 +35,5 @@ export interface Transaction { relayerSignature: string; isRelayed: boolean; isScCall: boolean; + timestampMs: number; } diff --git a/src/common/indexer/indexer.interface.ts b/src/common/indexer/indexer.interface.ts index 355dfc0d6..8ede69e50 100644 --- a/src/common/indexer/indexer.interface.ts +++ b/src/common/indexer/indexer.interface.ts @@ -12,7 +12,7 @@ import { TokenWithRolesFilter } from "src/endpoints/tokens/entities/token.with.r import { TransactionFilter } from "src/endpoints/transactions/entities/transaction.filter"; import { TokenAssets } from "../assets/entities/token.assets"; import { QueryPagination } from "../entities/query.pagination"; -import { Account, AccountHistory, AccountTokenHistory, Block, Collection, MiniBlock, Operation, Round, ScDeploy, ScResult, Tag, Token, TokenAccount, Transaction, TransactionLog, TransactionReceipt } from "./entities"; +import { Account, AccountHistory, AccountTokenHistory, Block, Collection, MiniBlock, Operation, Round, ScDeploy, ScResult, Tag, Token, TokenAccount, Transaction, ElasticTransactionLogEvent, TransactionReceipt } from "./entities"; import { AccountAssets } from "../assets/entities/account.assets"; import { ProviderDelegators } from "./entities/provider.delegators"; import { ApplicationFilter } from "src/endpoints/applications/entities/application.filter"; @@ -74,6 +74,8 @@ export interface IndexerInterface { getBlock(hash: string): Promise + getBlockByMiniBlockHash(miniBlockHash: string): Promise + getMiniBlock(miniBlockHash: string): Promise getMiniBlocks(pagination: QueryPagination, filter: MiniBlockFilter): Promise @@ -132,7 +134,7 @@ export interface IndexerInterface { getTokensForAddress(address: string, queryPagination: QueryPagination, filter: TokenFilter): Promise - getTransactionLogs(hashes: string[]): Promise + getTransactionLogs(hashes: string[], eventsIndex: string, txHashField: string): Promise getTransactionScResults(txHash: string): Promise diff --git a/src/common/indexer/indexer.service.ts b/src/common/indexer/indexer.service.ts index ac168ed75..3798f604e 100644 --- a/src/common/indexer/indexer.service.ts +++ b/src/common/indexer/indexer.service.ts @@ -11,7 +11,7 @@ import { TransactionFilter } from "src/endpoints/transactions/entities/transacti import { MetricsEvents } from "src/utils/metrics-events.constants"; import { TokenAssets } from "../assets/entities/token.assets"; import { QueryPagination } from "../entities/query.pagination"; -import { Account, AccountHistory, AccountTokenHistory, Block, Collection, MiniBlock, Operation, Round, ScDeploy, ScResult, Tag, Token, TokenAccount, Transaction, TransactionLog, TransactionReceipt } from "./entities"; +import { Account, AccountHistory, AccountTokenHistory, Block, Collection, MiniBlock, Operation, Round, ScDeploy, ScResult, Tag, Token, TokenAccount, Transaction, ElasticTransactionLogEvent, TransactionReceipt } from "./entities"; import { IndexerInterface } from "./indexer.interface"; import { LogPerformanceAsync } from "src/utils/log.performance.decorator"; import { AccountQueryOptions } from "src/endpoints/accounts/entities/account.query.options"; @@ -166,6 +166,11 @@ export class IndexerService implements IndexerInterface { return await this.indexerInterface.getBlock(hash); } + @LogPerformanceAsync(MetricsEvents.SetIndexerDuration) + async getBlockByMiniBlockHash(miniBlockHash: string): Promise { + return await this.indexerInterface.getBlockByMiniBlockHash(miniBlockHash); + } + @LogPerformanceAsync(MetricsEvents.SetIndexerDuration) async getMiniBlock(miniBlockHash: string): Promise { return await this.indexerInterface.getMiniBlock(miniBlockHash); @@ -297,8 +302,8 @@ export class IndexerService implements IndexerInterface { } @LogPerformanceAsync(MetricsEvents.SetIndexerDuration) - async getTransactionLogs(hashes: string[]): Promise { - return await this.indexerInterface.getTransactionLogs(hashes); + async getTransactionLogs(hashes: string[], eventsIndex: string, txHashField: string): Promise { + return await this.indexerInterface.getTransactionLogs(hashes, eventsIndex, txHashField); } @LogPerformanceAsync(MetricsEvents.SetIndexerDuration) diff --git a/src/common/persistence/persistence.module.ts b/src/common/persistence/persistence.module.ts index fa12672aa..c20bbe773 100644 --- a/src/common/persistence/persistence.module.ts +++ b/src/common/persistence/persistence.module.ts @@ -58,10 +58,8 @@ export class PersistenceModule { type: 'mongodb', entities: [NftMetadataDb, NftMediaDb, NftTraitSummaryDb, KeybaseConfirmationDb, HotSwappableSettingDb], url: apiConfigService.getDatabaseUrl(), - keepAlive: 120000, - sslValidate: false, + tlsAllowInvalidCertificates: true, retryAttempts: 300, - useUnifiedTopology: true, synchronize: true, }; diff --git a/src/common/plugins/plugin.service.ts b/src/common/plugins/plugin.service.ts index 317c32e99..5fc80c2c6 100644 --- a/src/common/plugins/plugin.service.ts +++ b/src/common/plugins/plugin.service.ts @@ -4,6 +4,7 @@ import { AccountDetailed } from "src/endpoints/accounts/entities/account.detaile import { About } from "src/endpoints/network/entities/about"; import { Nft } from "src/endpoints/nfts/entities/nft"; import { Transaction } from "src/endpoints/transactions/entities/transaction"; +import { EsdtSupply } from "../gateway/entities/esdt.supply"; @Injectable() export class PluginService { @@ -18,4 +19,6 @@ export class PluginService { async batchProcessNfts(_nfts: Nft[], _withScamInfo?: boolean): Promise { } async processAbout(_about: About): Promise { } + + formatTokenSupply(_identifier: string, _esdtSupply: EsdtSupply) { } } diff --git a/src/common/pubsub/pub.sub.listener.controller.ts b/src/common/pubsub/pub.sub.listener.controller.ts index 99a2cdf37..0ad76e331 100644 --- a/src/common/pubsub/pub.sub.listener.controller.ts +++ b/src/common/pubsub/pub.sub.listener.controller.ts @@ -12,10 +12,10 @@ export class PubSubListenerController { ) { } @EventPattern('deleteCacheKeys') - async deleteCacheKey(keys: string[]) { + deleteCacheKey(keys: string[]) { for (const key of keys) { this.logger.log(`Deleting local cache key ${key}`); - await this.cachingService.deleteLocal(key); + this.cachingService.deleteLocal(key); } } diff --git a/src/common/rabbitmq/entities/notifier.event.identifier.ts b/src/common/rabbitmq/entities/notifier.event.identifier.ts index a944e0898..e3ebad9ed 100644 --- a/src/common/rabbitmq/entities/notifier.event.identifier.ts +++ b/src/common/rabbitmq/entities/notifier.event.identifier.ts @@ -1,5 +1,9 @@ export enum NotifierEventIdentifier { ESDTNFTCreate = 'ESDTNFTCreate', ESDTNFTUpdateAttributes = 'ESDTNFTUpdateAttributes', + ESDTNFTBurn = 'ESDTNFTBurn', + ESDTMetaDataUpdate = 'ESDTMetaDataUpdate', + ESDTMetaDataRecreate = 'ESDTMetaDataRecreate', + ESDTModifyCreator = 'ESDTModifyCreator', transferOwnership = 'transferOwnership', } diff --git a/src/common/rabbitmq/rabbitmq.consumer.ts b/src/common/rabbitmq/rabbitmq.consumer.ts index 117e3e671..4110fa1d9 100644 --- a/src/common/rabbitmq/rabbitmq.consumer.ts +++ b/src/common/rabbitmq/rabbitmq.consumer.ts @@ -43,6 +43,16 @@ export class RabbitMqConsumer { this.logger.log(`Detected 'ESDTNFTUpdateAttributes' event`); await this.nftHandlerService.handleNftUpdateAttributesEvent(event); break; + case NotifierEventIdentifier.ESDTNFTBurn: + await this.nftHandlerService.handleNftBurnEvent(event); + break; + case NotifierEventIdentifier.ESDTMetaDataUpdate: + case NotifierEventIdentifier.ESDTMetaDataRecreate: + await this.nftHandlerService.handleNftMetadataEvent(event); + break; + case NotifierEventIdentifier.ESDTModifyCreator: + await this.nftHandlerService.handleNftModifyCreatorEvent(event); + break; case NotifierEventIdentifier.transferOwnership: await this.tokenHandlerService.handleTransferOwnershipEvent(event); break; diff --git a/src/common/rabbitmq/rabbitmq.nft.handler.service.ts b/src/common/rabbitmq/rabbitmq.nft.handler.service.ts index b2377e73b..b3766e312 100644 --- a/src/common/rabbitmq/rabbitmq.nft.handler.service.ts +++ b/src/common/rabbitmq/rabbitmq.nft.handler.service.ts @@ -8,6 +8,9 @@ import { NotifierEvent } from './entities/notifier.event'; import { CacheService } from "@multiversx/sdk-nestjs-cache"; import { BinaryUtils, OriginLogger, TokenUtils } from '@multiversx/sdk-nestjs-common'; import { IndexerService } from '../indexer/indexer.service'; +import { NftSubType } from 'src/endpoints/nfts/entities/nft.sub.type'; +import { Inject } from '@nestjs/common'; +import { ClientProxy } from '@nestjs/microservices'; @Injectable() export class RabbitMqNftHandlerService { @@ -18,10 +21,11 @@ export class RabbitMqNftHandlerService { private readonly nftService: NftService, private readonly indexerService: IndexerService, private readonly cachingService: CacheService, + @Inject('PUBSUB_SERVICE') private clientProxy: ClientProxy, ) { } private async getCollectionType(collectionIdentifier: string): Promise { - const type = await this.cachingService.getLocal(CacheInfo.CollectionType(collectionIdentifier).key) ?? + const type = this.cachingService.getLocal(CacheInfo.CollectionType(collectionIdentifier).key) ?? await this.getCollectionTypeRaw(collectionIdentifier); if (!type) { @@ -62,7 +66,19 @@ export class RabbitMqNftHandlerService { nft.attributes = attributes; try { - await this.nftWorkerService.addProcessNftQueueJob(nft, new ProcessNftSettings({ forceRefreshMetadata: true })); + const isDynamicNft = this.isDynamicNftType(nft.subType); + + if (isDynamicNft) { + this.logger.log(`Processing dynamic NFT with identifier '${identifier}', forcing refresh of metadata and media`); + + await this.nftWorkerService.addProcessNftQueueJob(nft, new ProcessNftSettings({ + forceRefreshMetadata: true, + forceRefreshMedia: true, + forceRefreshThumbnail: true, + })); + } else { + await this.nftWorkerService.addProcessNftQueueJob(nft, new ProcessNftSettings({ forceRefreshMetadata: true })); + } } catch (error) { this.logger.error(`An unhandled error occurred when processing NFT update attributes event for NFT with identifier '${identifier}'`); this.logger.error(error); @@ -71,6 +87,18 @@ export class RabbitMqNftHandlerService { } } + private isDynamicNftType(subType?: NftSubType): boolean { + if (subType) { + return [ + NftSubType.DynamicNonFungibleESDT, + NftSubType.DynamicSemiFungibleESDT, + NftSubType.DynamicMetaESDT, + ].includes(subType); + } + + return false; + } + public async handleNftCreateEvent(event: NotifierEvent): Promise { const identifier = this.getNftIdentifier(event.topics); @@ -95,6 +123,21 @@ export class RabbitMqNftHandlerService { } try { + const isDynamicNft = this.isDynamicNftType(nft.subType); + + if (isDynamicNft) { + this.logger.log(`Processing dynamic NFT creation with identifier '${identifier}', forcing full refresh`); + + await this.nftWorkerService.addProcessNftQueueJob(nft, new ProcessNftSettings({ + uploadAsset: true, + forceRefreshMetadata: true, + forceRefreshMedia: true, + forceRefreshThumbnail: true, + })); + + return true; + } + const needsProcessing = await this.nftWorkerService.needsProcessing(nft, new ProcessNftSettings()); if (needsProcessing) { await this.nftWorkerService.addProcessNftQueueJob(nft, new ProcessNftSettings({ uploadAsset: true })); @@ -108,6 +151,70 @@ export class RabbitMqNftHandlerService { } } + public async handleNftBurnEvent(event: NotifierEvent): Promise { + const identifier = this.getNftIdentifier(event.topics); + + this.logger.log(`Detected 'ESDTNFTBurn' event for NFT with identifier '${identifier}'`); + + try { + const cacheKey = `nft:${identifier}`; + await this.cachingService.delete(cacheKey); + + this.clientProxy.emit('deleteCacheKeys', [cacheKey]); + + this.logger.log(`Cache invalidated for NFT with identifier '${identifier}' across all instances`); + return true; + } catch (error) { + this.logger.error(`An unhandled error occurred when processing NFT Burn event for NFT with identifier '${identifier}'`); + this.logger.error(error); + return false; + } + } + + public async handleNftMetadataEvent(event: NotifierEvent): Promise { + const identifier = this.getNftIdentifier(event.topics); + + this.logger.log(`Detected '${event.identifier}' event for NFT with identifier '${identifier}'`); + + const nft = await this.nftService.getSingleNft(identifier); + if (!nft) { + this.logger.log(`Could not fetch NFT details for NFT with identifier '${identifier}'`); + return false; + } + + try { + await this.nftWorkerService.addProcessNftQueueJob(nft, new ProcessNftSettings({ + forceRefreshMetadata: true, + forceRefreshMedia: true, + })); + return true; + } catch (error) { + this.logger.error(`An unhandled error occurred when processing '${event.identifier}' event for NFT with identifier '${identifier}'`); + this.logger.error(error); + return false; + } + } + + public async handleNftModifyCreatorEvent(event: NotifierEvent): Promise { + const identifier = this.getNftIdentifier(event.topics); + + this.logger.log(`Detected 'ESDTModifyCreator' event for NFT with identifier '${identifier}'`); + + try { + const cacheKey = `nft:${identifier}`; + await this.cachingService.delete(cacheKey); + + this.clientProxy.emit('deleteCacheKeys', [cacheKey]); + + this.logger.log(`Cache invalidated for NFT with identifier '${identifier}' across all instances`); + return true; + } catch (error) { + this.logger.error(`An unhandled error occurred when processing NFT ModifyCreator event for NFT with identifier '${identifier}'`); + this.logger.error(error); + return false; + } + } + private getNftIdentifier(topics: string[]): string { const collection = BinaryUtils.base64Decode(topics[0]); const nonce = BinaryUtils.base64ToHex(topics[1]); diff --git a/src/crons/cache.warmer/cache.warmer.service.ts b/src/crons/cache.warmer/cache.warmer.service.ts index 5a5f7c44e..7fbc17c04 100644 --- a/src/crons/cache.warmer/cache.warmer.service.ts +++ b/src/crons/cache.warmer/cache.warmer.service.ts @@ -34,6 +34,7 @@ import * as JsonDiff from "json-diff"; import { QueryPagination } from "src/common/entities/query.pagination"; import { StakeService } from "src/endpoints/stake/stake.service"; import { ApplicationMostUsed } from "src/endpoints/accounts/entities/application.most.used"; +import { NftType } from '../../common/indexer/entities/nft.type'; @Injectable() export class CacheWarmerService { @@ -320,6 +321,13 @@ export class CacheWarmerService { @Lock({ name: 'Elastic updater: Update collection isVerified, nftCount, holderCount', verbose: true }) async handleUpdateCollectionExtraDetails() { const allAssets = await this.assetsService.getAllTokenAssets(); + const nftTypes = [ + NftType.NonFungibleESDT, + NftType.SemiFungibleESDT, + NftType.NonFungibleESDTv2, + NftType.DynamicNonFungibleESDT, + NftType.DynamicSemiFungibleESDT, + ]; for (const key of Object.keys(allAssets)) { const collection = await this.indexerService.getCollection(key); @@ -327,7 +335,7 @@ export class CacheWarmerService { continue; } - if (![TokenType.NonFungibleESDT, TokenType.SemiFungibleESDT].includes(collection.type as TokenType)) { + if (!nftTypes.includes(collection.type as NftType)) { continue; } diff --git a/src/endpoints/accounts/account.controller.ts b/src/endpoints/accounts/account.controller.ts index 1a2875a91..986352962 100644 --- a/src/endpoints/accounts/account.controller.ts +++ b/src/endpoints/accounts/account.controller.ts @@ -150,6 +150,7 @@ export class AccountController { @ApiQuery({ name: 'search', description: 'Search by account address, assets name', required: false }) @ApiQuery({ name: 'excludeTags', description: 'Exclude specific tags from result', required: false }) @ApiQuery({ name: 'hasAssets', description: 'Returns a list of accounts that have assets', required: false }) + @ApiQuery({ name: 'withBalance', description: 'Filter accounts by balance (true = balance > 0, false = balance = 0)', required: false, type: Boolean }) async getAccountsCount( @Query("ownerAddress", ParseAddressPipe) ownerAddress?: string, @Query("isSmartContract", ParseBoolPipe) isSmartContract?: boolean, @@ -158,6 +159,7 @@ export class AccountController { @Query("excludeTags", ParseArrayPipe) excludeTags?: string[], @Query("hasAssets", ParseBoolPipe) hasAssets?: boolean, @Query("search") search?: string, + @Query("withBalance", ParseBoolPipe) withBalance?: boolean, ): Promise { return await this.accountService.getAccountsCount( new AccountQueryOptions( @@ -169,6 +171,7 @@ export class AccountController { excludeTags, hasAssets, search, + withBalance, })); } @@ -182,6 +185,7 @@ export class AccountController { @Query("excludeTags", ParseArrayPipe) excludeTags?: string[], @Query("hasAssets", ParseBoolPipe) hasAssets?: boolean, @Query("search") search?: string, + @Query("withBalance", ParseBoolPipe) withBalance?: boolean, ): Promise { return await this.accountService.getAccountsCount( new AccountQueryOptions( @@ -193,6 +197,7 @@ export class AccountController { excludeTags, hasAssets, search, + withBalance, })); } diff --git a/src/endpoints/accounts/entities/account.query.options.ts b/src/endpoints/accounts/entities/account.query.options.ts index 91649d3c1..1dde2199b 100644 --- a/src/endpoints/accounts/entities/account.query.options.ts +++ b/src/endpoints/accounts/entities/account.query.options.ts @@ -22,6 +22,7 @@ export class AccountQueryOptions { excludeTags?: string[]; hasAssets?: boolean; search?: string; + withBalance?: boolean; validate(size: number) { if (this.withDeployInfo && size > 25) { @@ -53,6 +54,7 @@ export class AccountQueryOptions { this.excludeTags !== undefined || this.hasAssets !== undefined || this.search !== undefined || - this.addresses !== undefined; + this.addresses !== undefined || + this.withBalance !== undefined; } } diff --git a/src/endpoints/blocks/block.service.ts b/src/endpoints/blocks/block.service.ts index 16ae5edbe..4b35ad28a 100644 --- a/src/endpoints/blocks/block.service.ts +++ b/src/endpoints/blocks/block.service.ts @@ -82,7 +82,7 @@ export class BlockService { } async computeProposerAndValidators(item: any) { - const { shardId, epoch, searchOrder, ...rest } = item; + const { shardId, epoch, searchOrder, proposerBlsKey, ...rest } = item; let { proposer, validators } = item; let blses: any = await this.cachingService.getLocal(CacheInfo.ShardAndEpochBlses(shardId, epoch).key); @@ -93,13 +93,17 @@ export class BlockService { } } - proposer = blses[proposer]; + if (proposerBlsKey) { + proposer = proposerBlsKey; + } else { + proposer = blses[proposer]; + } if (validators) { validators = validators.map((index: number) => blses[index]); } - return {shardId, epoch, validators, ...rest, proposer}; + return { shardId, epoch, validators, ...rest, proposer }; } async getBlock(hash: string): Promise { @@ -110,7 +114,11 @@ export class BlockService { if (result.round > 0) { const publicKeys = await this.blsService.getPublicKeys(result.shardId, result.epoch); - result.proposer = publicKeys[result.proposer]; + if (result.proposerBlsKey) { + result.proposer = result.proposerBlsKey; + } else { + result.proposer = publicKeys[result.proposer]; + } if (!isChainAndromedaEnabled) { result.validators = result.validators.map((validator: number) => publicKeys[validator]); } else { diff --git a/src/endpoints/caching/local.cache.controller.ts b/src/endpoints/caching/local.cache.controller.ts index 1d492c8d7..f356827fb 100644 --- a/src/endpoints/caching/local.cache.controller.ts +++ b/src/endpoints/caching/local.cache.controller.ts @@ -50,7 +50,7 @@ export class LocalCacheController { status: 404, description: 'Key not found', }) - async delCache(@Param('key') key: string) { - await this.cachingService.deleteLocal(key); + delCache(@Param('key') key: string) { + this.cachingService.deleteLocal(key); } } diff --git a/src/endpoints/collections/collection.controller.ts b/src/endpoints/collections/collection.controller.ts index 732ad28c4..2137a49be 100644 --- a/src/endpoints/collections/collection.controller.ts +++ b/src/endpoints/collections/collection.controller.ts @@ -111,6 +111,7 @@ export class CollectionController { @ApiQuery({ name: 'canAddUri', description: 'Filter by address with canAddUri role', required: false }) @ApiQuery({ name: 'canTransferRole', description: 'Filter by address with canTransferRole role', required: false }) @ApiQuery({ name: 'excludeMetaESDT', description: 'Do not include collections of type "MetaESDT" in the response', required: false }) + @ApiQuery({ name: 'subType', description: 'Filter by type (NonFungibleESDTv2/DynamicNonFungibleESDT/DynamicSemiFungibleESDT)', required: false }) @ApiOkResponse({ type: Number }) async getCollectionCount( @Query('search') search?: string, diff --git a/src/endpoints/delegation/delegation.service.ts b/src/endpoints/delegation/delegation.service.ts index 414e6e249..c61484999 100644 --- a/src/endpoints/delegation/delegation.service.ts +++ b/src/endpoints/delegation/delegation.service.ts @@ -71,7 +71,11 @@ export class DelegationService { async getDelegationForAddress(address: string): Promise { try { const { data } = await this.apiService.get(`${this.apiConfigService.getDelegationUrl()}/accounts/${address}/delegations`); - return data; + + return data.map((delegation: any) => new AccountDelegation({ + ...delegation, + userUndelegatedList: delegation.userUndelegatedList ?? [], + })); } catch (error) { this.logger.error(`Error when getting account delegation details for address ${address}`); this.logger.error(error); diff --git a/src/endpoints/esdt/esdt.address.service.ts b/src/endpoints/esdt/esdt.address.service.ts index 80d8eac3a..289fa744c 100644 --- a/src/endpoints/esdt/esdt.address.service.ts +++ b/src/endpoints/esdt/esdt.address.service.ts @@ -392,7 +392,7 @@ export class EsdtAddressService { return result; } - const cachedValue = await this.cachingService.getLocal<{ [key: string]: any }>(`address:${address}:esdts`); + const cachedValue = this.cachingService.getLocal<{ [key: string]: any }>(`address:${address}:esdts`); if (cachedValue) { this.metricsService.incrementCachedApiHit('Gateway.AccountEsdts'); diff --git a/src/endpoints/esdt/esdt.module.ts b/src/endpoints/esdt/esdt.module.ts index a65e16605..53623b065 100644 --- a/src/endpoints/esdt/esdt.module.ts +++ b/src/endpoints/esdt/esdt.module.ts @@ -8,6 +8,7 @@ import { CollectionModule } from "../collections/collection.module"; import { TransactionModule } from "../transactions/transaction.module"; import { MexModule } from "../mex/mex.module"; import { AssetsModule } from "src/common/assets/assets.module"; +import { PluginModule } from "../../plugins/plugin.module"; @Module({ @@ -19,6 +20,7 @@ import { AssetsModule } from "src/common/assets/assets.module"; forwardRef(() => TransactionModule), forwardRef(() => MexModule.forRoot()), forwardRef(() => AssetsModule), + forwardRef(() => PluginModule), ], providers: [ EsdtService, EsdtAddressService, diff --git a/src/endpoints/esdt/esdt.service.ts b/src/endpoints/esdt/esdt.service.ts index 8489db69e..63b0dab71 100644 --- a/src/endpoints/esdt/esdt.service.ts +++ b/src/endpoints/esdt/esdt.service.ts @@ -16,6 +16,7 @@ import { EsdtType } from "./entities/esdt.type"; import { ElasticIndexerService } from "src/common/indexer/elastic/elastic.indexer.service"; import { randomUUID } from "crypto"; import { EsdtSubType } from "./entities/esdt.sub.type"; +import { PluginService } from "../../common/plugins/plugin.service"; @Injectable() export class EsdtService { @@ -27,6 +28,7 @@ export class EsdtService { private readonly cachingService: CacheService, private readonly vmQueryService: VmQueryService, private readonly indexerService: IndexerService, + private readonly pluginService: PluginService, @Inject(forwardRef(() => AssetsService)) private readonly assetsService: AssetsService, private readonly elasticIndexerService: ElasticIndexerService @@ -367,7 +369,9 @@ export class EsdtService { } async getTokenSupply(identifier: string): Promise { - const { supply, minted, burned, initialMinted } = await this.gatewayService.getEsdtSupply(identifier); + const esdtSupply = await this.gatewayService.getEsdtSupply(identifier); + this.pluginService.formatTokenSupply(identifier, esdtSupply); + const { supply, minted, burned, initialMinted } = esdtSupply; const isCollectionOrToken = identifier.split('-').length === 2; if (isCollectionOrToken) { diff --git a/src/endpoints/events/entities/events.filter.ts b/src/endpoints/events/entities/events.filter.ts index b8da8e3db..099a1ec45 100644 --- a/src/endpoints/events/entities/events.filter.ts +++ b/src/endpoints/events/entities/events.filter.ts @@ -10,4 +10,5 @@ export class EventsFilter { shard: number = 0; before: number = 0; after: number = 0; + order: number = 0; } diff --git a/src/endpoints/events/events.controller.ts b/src/endpoints/events/events.controller.ts index e58a1f6e8..ee18ec489 100644 --- a/src/endpoints/events/events.controller.ts +++ b/src/endpoints/events/events.controller.ts @@ -25,6 +25,7 @@ export class EventsController { @ApiQuery({ name: 'shard', description: 'Event shard id', required: false }) @ApiQuery({ name: 'before', description: 'Event before timestamp', required: false }) @ApiQuery({ name: 'after', description: 'Event after timestamp', required: false }) + @ApiQuery({ name: 'order', description: 'Event order', required: false }) async getEvents( @Query('from', new DefaultValuePipe(0), ParseIntPipe) from: number, @Query('size', new DefaultValuePipe(25), ParseIntPipe) size: number, @@ -34,10 +35,11 @@ export class EventsController { @Query('shard', ParseIntPipe) shard: number, @Query('before', ParseIntPipe) before: number, @Query('after', ParseIntPipe) after: number, + @Query('order', ParseIntPipe) order: number, ): Promise { return await this.eventsService.getEvents( new QueryPagination({ from, size }), - new EventsFilter({ address, identifier, txHash, shard, after, before })); + new EventsFilter({ address, identifier, txHash, shard, after, before, order })); } @Get('/events/count') diff --git a/src/endpoints/mex/mex.settings.service.ts b/src/endpoints/mex/mex.settings.service.ts index 1a53b84aa..faf14bfa4 100644 --- a/src/endpoints/mex/mex.settings.service.ts +++ b/src/endpoints/mex/mex.settings.service.ts @@ -62,7 +62,7 @@ export class MexSettingsService { } async getMexContracts(): Promise> { - let contracts = await this.cachingService.getLocal>(CacheInfo.MexContracts.key); + let contracts = this.cachingService.getLocal>(CacheInfo.MexContracts.key); if (!contracts) { contracts = await this.getMexContractsRaw(); this.cachingService.setLocal(CacheInfo.MexContracts.key, contracts, Constants.oneMinute() * 10); diff --git a/src/endpoints/mex/mex.token.service.ts b/src/endpoints/mex/mex.token.service.ts index 7bb8f1dc2..a7f8c1f3e 100644 --- a/src/endpoints/mex/mex.token.service.ts +++ b/src/endpoints/mex/mex.token.service.ts @@ -171,8 +171,22 @@ export class MexTokenService { private async getAllMexTokensRaw(): Promise { const pairs = await this.mexPairService.getAllMexPairs(); + const tokenVolumes: Record = {}; + + for (const pair of pairs) { + if (!tokenVolumes[pair.baseId]) { + tokenVolumes[pair.baseId] = 0; + } + tokenVolumes[pair.baseId] += Number(pair.volume24h || 0); + + if (!tokenVolumes[pair.quoteId]) { + tokenVolumes[pair.quoteId] = 0; + } + tokenVolumes[pair.quoteId] += Number(pair.volume24h || 0); + } + + const tokenPoolMap: Record = {}; - const mexTokens: MexToken[] = []; for (const pair of pairs) { if (pair.baseSymbol === 'WEGLD' && pair.quoteSymbol === "USDC") { const wegldToken = new MexToken(); @@ -181,9 +195,12 @@ export class MexTokenService { wegldToken.name = pair.baseName; wegldToken.price = pair.basePrice; wegldToken.previous24hPrice = pair.basePrevious24hPrice; - wegldToken.previous24hVolume = pair.volume24h; + wegldToken.previous24hVolume = tokenVolumes[pair.baseId]; wegldToken.tradesCount = this.computeTradesCountForMexToken(wegldToken, pairs); - mexTokens.push(wegldToken); + + if (!tokenPoolMap[wegldToken.id] || pair.totalValue > tokenPoolMap[wegldToken.id].liquidityValue) { + tokenPoolMap[wegldToken.id] = { token: wegldToken, liquidityValue: pair.totalValue }; + } } const mexToken = this.getMexToken(pair); @@ -191,12 +208,17 @@ export class MexTokenService { continue; } + mexToken.previous24hVolume = tokenVolumes[mexToken.id]; mexToken.tradesCount = this.computeTradesCountForMexToken(mexToken, pairs); - mexTokens.push(mexToken); + if (!tokenPoolMap[mexToken.id] || pair.totalValue > tokenPoolMap[mexToken.id].liquidityValue) { + tokenPoolMap[mexToken.id] = { token: mexToken, liquidityValue: pair.totalValue }; + } } - return mexTokens.distinct(x => x.id); + const mexTokens = Object.values(tokenPoolMap).map(entry => entry.token); + + return mexTokens; } private getMexToken(pair: MexPair): MexToken | null { @@ -207,7 +229,7 @@ export class MexTokenService { name: pair.quoteName, price: pair.quotePrice, previous24hPrice: pair.quotePrevious24hPrice, - previous24hVolume: pair.volume24h, + previous24hVolume: 0, tradesCount: 0, }; } @@ -219,7 +241,7 @@ export class MexTokenService { name: pair.baseName, price: pair.basePrice, previous24hPrice: pair.basePrevious24hPrice, - previous24hVolume: pair.volume24h, + previous24hVolume: 0, tradesCount: 0, }; } @@ -231,7 +253,7 @@ export class MexTokenService { name: pair.quoteName, price: pair.quotePrice, previous24hPrice: pair.quotePrevious24hPrice, - previous24hVolume: pair.volume24h, + previous24hVolume: 0, tradesCount: 0, }; } diff --git a/src/endpoints/nfts/nft.service.ts b/src/endpoints/nfts/nft.service.ts index 2cab3f75e..d7deef398 100644 --- a/src/endpoints/nfts/nft.service.ts +++ b/src/endpoints/nfts/nft.service.ts @@ -69,44 +69,92 @@ export class NftService { const nfts = await this.getNftsInternal({ from, size }, filter); - for (const nft of nfts) { - await this.applyAssetsAndTicker(nft); - } + await Promise.all([ + this.batchApplyAssetsAndTicker(nfts), + this.conditionallyApplyOwners(nfts, queryOptions), + this.conditionallyApplySupply(nfts, queryOptions), + this.batchProcessNfts(nfts), + ]); - if (queryOptions && queryOptions.withOwner) { - const nftsIdentifiers = nfts.filter(x => x.type === NftType.NonFungibleESDT).map(x => x.identifier); + await this.batchApplyUnlockFields(nfts); - const accountsEsdts = await this.getAccountEsdtByIdentifiers(nftsIdentifiers, { from: 0, size: nftsIdentifiers.length }); + return nfts; + } - for (const nft of nfts) { - if (nft.type === NftType.NonFungibleESDT) { - const accountEsdt = accountsEsdts.find((accountEsdt: any) => accountEsdt.identifier == nft.identifier); - if (accountEsdt) { - nft.owner = accountEsdt.address; - } + private async batchProcessNfts(nfts: Nft[], fields?: string[]) { + await Promise.all([ + this.batchApplyMedia(nfts, fields), + this.batchApplyMetadata(nfts, fields), + ]); + } + + private async batchApplyAssetsAndTicker(nfts: Nft[], fields?: string[]): Promise { + if (fields && fields.includesNone(['ticker', 'assets'])) { + return; + } + + await Promise.all( + nfts.map(async (nft) => { + nft.assets = await this.assetsService.getTokenAssets(nft.identifier) ?? + await this.assetsService.getTokenAssets(nft.collection); + + if (nft.assets) { + nft.ticker = nft.collection.split('-')[0]; + } else { + nft.ticker = nft.collection; } - } + }) + ); + } + + private async conditionallyApplyOwners(nfts: Nft[], queryOptions?: NftQueryOptions): Promise { + if (!queryOptions?.withOwner) { + return; } - if (queryOptions && queryOptions.withSupply) { - const supplyNfts = nfts.filter(nft => nft.type.in(NftType.SemiFungibleESDT, NftType.MetaESDT)); - await this.batchApplySupply(supplyNfts); + const nftsIdentifiers = nfts.filter(x => x.type === NftType.NonFungibleESDT).map(x => x.identifier); + + if (nftsIdentifiers.length === 0) { + return; } - await this.batchProcessNfts(nfts); + const accountsEsdts = await this.getAccountEsdtByIdentifiers(nftsIdentifiers, { + from: 0, + size: nftsIdentifiers.length, + }); + + const ownerMap = accountsEsdts.reduce((acc: Record, accountEsdt: any) => { + acc[accountEsdt.identifier] = accountEsdt.address; + return acc; + }, {}); for (const nft of nfts) { - await this.applyUnlockFields(nft); + if (nft.type === NftType.NonFungibleESDT && ownerMap[nft.identifier]) { + nft.owner = ownerMap[nft.identifier]; + } + } + } + + private async conditionallyApplySupply(nfts: Nft[], queryOptions?: NftQueryOptions): Promise { + if (!queryOptions?.withSupply) { + return; } - return nfts; + const supplyNfts = nfts.filter(nft => nft.type.in(NftType.SemiFungibleESDT, NftType.MetaESDT)); + + if (supplyNfts.length > 0) { + await this.batchApplySupply(supplyNfts); + } } - private async batchProcessNfts(nfts: Nft[], fields?: string[]) { - await Promise.all([ - this.batchApplyMedia(nfts, fields), - this.batchApplyMetadata(nfts, fields), - ]); + private async batchApplyUnlockFields(nfts: Nft[], fields?: string[]): Promise { + if (fields && fields.includesNone(['unlockSchedule', 'unlockEpoch'])) { + return; + } + + await Promise.all( + nfts.map(nft => this.applyUnlockFields(nft, fields)) + ); } private async applyNftOwner(nft: Nft): Promise { @@ -215,23 +263,29 @@ export class NftService { return undefined; } - if (nft.type && nft.type.in( - NftType.SemiFungibleESDT, NftType.MetaESDT, - NftSubType.DynamicSemiFungibleESDT, NftSubType.DynamicMetaESDT - )) { - await this.applySupply(nft); - } - - await this.applyNftOwner(nft); - - await this.applyNftAttributes(nft); + const types = [ + NftType.SemiFungibleESDT, + NftType.MetaESDT, + NftSubType.DynamicSemiFungibleESDT, + NftSubType.DynamicMetaESDT, + ]; - await this.applyAssetsAndTicker(nft); + await Promise.all([ + (async () => { + if (nft.type && types.includes(nft.type as NftType | NftSubType)) { + await this.applySupply(nft); + } + })(), + this.applyAssetsAndTicker(nft), + this.processNft(nft), + (async () => { + await this.applyNftOwner(nft); + await this.applyNftAttributes(nft); + })(), + ]); await this.applyUnlockFields(nft); - await this.processNft(nft); - return nft; } diff --git a/src/endpoints/transactions/entities/transaction.log.event.ts b/src/endpoints/transactions/entities/transaction.log.event.ts index 34a588f66..e4a68680a 100644 --- a/src/endpoints/transactions/entities/transaction.log.event.ts +++ b/src/endpoints/transactions/entities/transaction.log.event.ts @@ -21,6 +21,9 @@ export class TransactionLogEvent { @ApiProperty() data: string = ''; + @ApiProperty() + order: number = 0; + @ApiProperty() additionalData: string[] | undefined = undefined; } diff --git a/src/endpoints/transactions/entities/transaction.ts b/src/endpoints/transactions/entities/transaction.ts index 250917604..5e72409f3 100644 --- a/src/endpoints/transactions/entities/transaction.ts +++ b/src/endpoints/transactions/entities/transaction.ts @@ -77,6 +77,9 @@ export class Transaction { @ApiProperty({ type: Number }) timestamp: number = 0; + @ApiProperty({ type: Number }) + timestampMs: number = 0; + @ApiProperty({ type: String, nullable: true, required: false }) data: string | undefined = undefined; diff --git a/src/endpoints/transactions/entities/transactions.query.options.ts b/src/endpoints/transactions/entities/transactions.query.options.ts index 8e73a658a..b12af14cd 100644 --- a/src/endpoints/transactions/entities/transactions.query.options.ts +++ b/src/endpoints/transactions/entities/transactions.query.options.ts @@ -17,6 +17,7 @@ export class TransactionQueryOptions { withUsername?: boolean; withBlockInfo?: boolean; withActionTransferValue?: boolean; + withTxsOrder?: boolean; static applyDefaultOptions(size: number, options: TransactionQueryOptions): TransactionQueryOptions { if (size <= TransactionQueryOptions.SCAM_INFO_MAX_SIZE) { diff --git a/src/endpoints/transactions/transaction-action/recognizers/sc-calls/transaction.action.sc-calls.recognizer.service.ts b/src/endpoints/transactions/transaction-action/recognizers/sc-calls/transaction.action.sc-calls.recognizer.service.ts index a99289795..2ac23cf8f 100644 --- a/src/endpoints/transactions/transaction-action/recognizers/sc-calls/transaction.action.sc-calls.recognizer.service.ts +++ b/src/endpoints/transactions/transaction-action/recognizers/sc-calls/transaction.action.sc-calls.recognizer.service.ts @@ -54,6 +54,10 @@ export class SCCallActionRecognizerService implements TransactionActionRecognize } private isSmartContractCall(metadata: TransactionMetadata): boolean { + if (metadata.receiver.length === 0) { + return false; + } + return AddressUtils.isSmartContractAddress(metadata.receiver) || this.isSelfBuiltInFunctionCall(metadata); } diff --git a/src/endpoints/transactions/transaction-action/recognizers/staking/transaction.action.stake.recognizer.service.ts b/src/endpoints/transactions/transaction-action/recognizers/staking/transaction.action.stake.recognizer.service.ts index 429c7cf72..e0b467843 100644 --- a/src/endpoints/transactions/transaction-action/recognizers/staking/transaction.action.stake.recognizer.service.ts +++ b/src/endpoints/transactions/transaction-action/recognizers/staking/transaction.action.stake.recognizer.service.ts @@ -20,7 +20,7 @@ export class StakeActionRecognizerService implements TransactionActionRecognizer ) { } private async getProviders(): Promise<{ [key: string]: { providerName: string, providerAvatar: string } }> { - let providersDetails = await this.cachingService.getLocal<{ [key: string]: { providerName: string, providerAvatar: string } }>('plugins:staking:providerAddresses'); + let providersDetails = this.cachingService.getLocal<{ [key: string]: { providerName: string, providerAvatar: string } }>('plugins:staking:providerAddresses'); if (!providersDetails) { const providers = await this.providerService.getAllProviders(); const identities = await this.identitiesService.getAllIdentities(); diff --git a/src/endpoints/transactions/transaction-action/transaction.action.service.ts b/src/endpoints/transactions/transaction-action/transaction.action.service.ts index 07ffbe7de..1cd20ec5b 100644 --- a/src/endpoints/transactions/transaction-action/transaction.action.service.ts +++ b/src/endpoints/transactions/transaction-action/transaction.action.service.ts @@ -87,7 +87,8 @@ export class TransactionActionService { metadata.sender = transaction.sender; metadata.receiver = transaction.receiver; metadata.timestamp = transaction.timestamp; - metadata.value = BigInt(transaction.value); + const txValue = isNaN(Number(transaction.value)) ? '0' : transaction.value; + metadata.value = BigInt(txValue); if (transaction.senderShard !== undefined) { metadata.senderShard = transaction.senderShard; } diff --git a/src/endpoints/transactions/transaction.get.service.ts b/src/endpoints/transactions/transaction.get.service.ts index 1d098539d..ec3e97a1d 100644 --- a/src/endpoints/transactions/transaction.get.service.ts +++ b/src/endpoints/transactions/transaction.get.service.ts @@ -20,6 +20,7 @@ import { TransactionOperationType } from "./entities/transaction.operation.type" import { QueryPagination } from "src/common/entities/query.pagination"; import { NftFilter } from "../nfts/entities/nft.filter"; import { TokenAccount } from "src/common/indexer/entities"; +import { ApiConfigService } from "../../common/api-config/api.config.service"; @Injectable() export class TransactionGetService { @@ -30,6 +31,7 @@ export class TransactionGetService { private readonly gatewayService: GatewayService, @Inject(forwardRef(() => TokenTransferService)) private readonly tokenTransferService: TokenTransferService, + private readonly apiConfigService: ApiConfigService, ) { } private async tryGetTransactionFromElasticBySenderAndNonce(sender: string, nonce: number): Promise { @@ -51,8 +53,49 @@ export class TransactionGetService { return result.map(x => ApiUtils.mergeObjects(new TransactionLog(), x)); } - private async getTransactionLogsFromElasticInternal(hashes: string[]): Promise { - return await this.indexerService.getTransactionLogs(hashes); + private async getTransactionLogsFromElasticInternal(hashes: string[]) { + const esMigratedIndices = this.apiConfigService.getElasticMigratedIndicesConfig(); + const index = esMigratedIndices?.['logs'] ?? 'logs'; + if (index === 'events') { + return await this.getTransactionLogsFromElasticInternalEventsIndex(hashes); + } + + return await this.getTransactionLogsFromElasticInternalLogsIndex(hashes); + } + + private async getTransactionLogsFromElasticInternalLogsIndex(hashes: string[]): Promise { + return await this.indexerService.getTransactionLogs(hashes, 'logs', '_id'); + } + + private async getTransactionLogsFromElasticInternalEventsIndex(hashes: string[]): Promise { + const rawHits = await this.indexerService.getTransactionLogs(hashes, 'events', 'txHash'); + + const logsMap: Map = new Map(); + + for (const source of rawHits) { + const txHash = source.txHash; + + if (!logsMap.has(txHash)) { + logsMap.set(txHash, new TransactionLog({ + id: txHash, + address: source.logAddress, + events: [], + })); + } + + const event = { + identifier: source.identifier, + address: source.address, + data: source.data && source.data.length > 0 ? BinaryUtils.hexToBase64(source.data ?? '') : source.data, + additionalData: source.additionalData?.map(d => d && d.length > 0 ? BinaryUtils.hexToBase64(d) : d), + topics: source.topics?.map(t => t && t.length > 0 ? BinaryUtils.hexToBase64(t) : t), + order: source.order ?? 0, + }; + + logsMap.get(txHash)?.events.push(ApiUtils.mergeObjects(new TransactionLogEvent(), event)); + } + + return Array.from(logsMap.values()); } async getTransactionScResultsFromElastic(txHash: string): Promise { diff --git a/src/endpoints/transactions/transaction.service.ts b/src/endpoints/transactions/transaction.service.ts index 968c70fc3..f44c873ae 100644 --- a/src/endpoints/transactions/transaction.service.ts +++ b/src/endpoints/transactions/transaction.service.ts @@ -348,6 +348,9 @@ export class TransactionService { } async processTransactions(transactions: Transaction[], options: { withScamInfo: boolean, withUsername: boolean, withActionTransferValue: boolean }): Promise { + + this.normalizeTimestampMs(transactions); + try { await this.pluginsService.processTransactions(transactions, options.withScamInfo); } catch (error) { @@ -372,6 +375,15 @@ export class TransactionService { await this.applyAssets(transactions, { withUsernameAssets: options.withUsername }); } + + private normalizeTimestampMs(transactions: Transaction[]): void { + for (const transaction of transactions) { + if ((!transaction.timestampMs || transaction.timestampMs === 0) && transaction.timestamp) { + transaction.timestampMs = transaction.timestamp * 1000; + } + } + } + private async getPendingResults(transaction: Transaction): Promise { const twentyMinutes = Constants.oneMinute() * 20 * 1000; const timestampLimit = (new Date().getTime() - twentyMinutes) / 1000; diff --git a/src/endpoints/transfers/transfer.controller.ts b/src/endpoints/transfers/transfer.controller.ts index f127dd2bb..7cd6094fe 100644 --- a/src/endpoints/transfers/transfer.controller.ts +++ b/src/endpoints/transfers/transfer.controller.ts @@ -47,6 +47,7 @@ export class TransferController { @ApiQuery({ name: 'withLogs', description: 'Return logs for transfers. When "withLogs" parameter is applied, complexity estimation is 200', required: false }) @ApiQuery({ name: 'withOperations', description: 'Return operations for transfers. When "withOperations" parameter is applied, complexity estimation is 200', required: false }) @ApiQuery({ name: 'withActionTransferValue', description: 'Returns value in USD and EGLD for transferred tokens within the action attribute', required: false }) + @ApiQuery({ name: 'withTxsOrder', description: 'Sort transactions by execution order from block', required: false }) @ApiQuery({ name: 'withRefunds', description: 'Include refund transactions', required: false }) async getAccountTransfers( @Query('from', new DefaultValuePipe(0), ParseIntPipe) from: number, @@ -74,10 +75,11 @@ export class TransferController { @Query('withLogs', ParseBoolPipe) withLogs?: boolean, @Query('withOperations', ParseBoolPipe) withOperations?: boolean, @Query('withActionTransferValue', ParseBoolPipe) withActionTransferValue?: boolean, + @Query('withTxsOrder', ParseBoolPipe) withTxsOrder?: boolean, @Query('withRefunds', ParseBoolPipe) withRefunds?: boolean, ): Promise { const options = TransactionQueryOptions.applyDefaultOptions( - size, new TransactionQueryOptions({ withScamInfo, withUsername, withBlockInfo, withLogs, withOperations, withActionTransferValue }), + size, new TransactionQueryOptions({ withScamInfo, withUsername, withBlockInfo, withLogs, withOperations, withActionTransferValue, withTxsOrder }), ); return await this.transferService.getTransfers(new TransactionFilter({ diff --git a/src/endpoints/transfers/transfer.service.ts b/src/endpoints/transfers/transfer.service.ts index acb73e031..01df59bf1 100644 --- a/src/endpoints/transfers/transfer.service.ts +++ b/src/endpoints/transfers/transfer.service.ts @@ -8,9 +8,12 @@ import { ApiUtils } from "@multiversx/sdk-nestjs-http"; import { IndexerService } from "src/common/indexer/indexer.service"; import { TransactionQueryOptions } from "../transactions/entities/transactions.query.options"; import { TransactionDetailed } from "../transactions/entities/transaction.detailed"; +import { OriginLogger } from "@multiversx/sdk-nestjs-common"; @Injectable() export class TransferService { + private readonly logger = new OriginLogger(TransferService.name); + constructor( private readonly indexerService: IndexerService, @Inject(forwardRef(() => TransactionService)) @@ -31,20 +34,84 @@ export class TransferService { } } - elasticTransfers.sort((a, b) => { - if (a.timestamp !== b.timestamp) { - return b.timestamp - a.timestamp; + return elasticTransfers.sortedDescending( + (item) => item.timestamp, + (item) => item.order + ); + } + + private async sortElasticTransfersByTxsOrder(elasticTransfers: any[], miniBlockHash: string): Promise { + if (!miniBlockHash) { + return this.sortElasticTransfers(elasticTransfers); + } + + try { + const block = await this.indexerService.getBlockByMiniBlockHash(miniBlockHash); + + if (!block || !block.miniBlocksDetails) { + return this.sortElasticTransfers(elasticTransfers); } - return b.order - a.order; - }); + const miniBlockDetails = block.miniBlocksDetails.find((mb: any) => { + const miniBlockIndex = block.miniBlocksHashes?.indexOf(miniBlockHash); + return miniBlockIndex !== -1 && mb.mbIndex === miniBlockIndex; + }); + + if (!miniBlockDetails || !miniBlockDetails.executionOrderTxsIndices || !miniBlockDetails.txsHashes) { + return this.sortElasticTransfers(elasticTransfers); + } + + const txHashToOrder: Record = {}; + for (let i = 0; i < miniBlockDetails.txsHashes.length; i++) { + const txHash = miniBlockDetails.txsHashes[i]; + const executionIndex = miniBlockDetails.executionOrderTxsIndices[i]; + txHashToOrder[txHash] = executionIndex; + } - return elasticTransfers; + const txHashToTransfer: Record = {}; + for (const transfer of elasticTransfers) { + if (transfer.txHash) { + txHashToTransfer[transfer.txHash] = transfer; + } + } + + for (const elasticTransfer of elasticTransfers) { + const txHash = elasticTransfer.originalTxHash || elasticTransfer.txHash; + if (txHashToOrder.hasOwnProperty(txHash)) { + elasticTransfer.order = txHashToOrder[txHash]; + } else { + if (elasticTransfer.originalTxHash) { + const transaction = txHashToTransfer[elasticTransfer.originalTxHash]; + if (transaction) { + elasticTransfer.order = (transaction.nonce * 10) + 1; + } else { + elasticTransfer.order = 0; + } + } else { + elasticTransfer.order = elasticTransfer.nonce * 10; + } + } + } + + return elasticTransfers.sortedDescending( + (item) => -item.order, + (item) => item.timestamp + ); + + } catch (error) { + this.logger.error(`Error getting block execution order: ${error}`); + return this.sortElasticTransfers(elasticTransfers); + } } async getTransfers(filter: TransactionFilter, pagination: QueryPagination, queryOptions: TransactionQueryOptions, fields?: string[]): Promise { let elasticOperations = await this.indexerService.getTransfers(filter, pagination); - elasticOperations = this.sortElasticTransfers(elasticOperations); + + if (queryOptions.withTxsOrder && filter.miniBlockHash) { + elasticOperations = await this.sortElasticTransfersByTxsOrder(elasticOperations, filter.miniBlockHash); + } else { + elasticOperations = this.sortElasticTransfers(elasticOperations); + } let transactions: TransactionDetailed[] = []; diff --git a/src/main.ts b/src/main.ts index 85252e17c..179901168 100644 --- a/src/main.ts +++ b/src/main.ts @@ -8,8 +8,6 @@ import { PrivateAppModule } from './private.app.module'; import { CacheWarmerModule } from './crons/cache.warmer/cache.warmer.module'; import { MicroserviceOptions, Transport } from '@nestjs/microservices'; import { INestApplication, Logger, NestInterceptor } from '@nestjs/common'; -import * as bodyParser from 'body-parser'; -import * as requestIp from 'request-ip'; import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston'; import { RedisClient } from 'redis'; import { TransactionProcessorModule } from './crons/transaction.processor/transaction.processor.module'; @@ -36,6 +34,9 @@ import { WebSocketPublisherModule } from './common/websockets/web-socket-publish import { IndexerService } from './common/indexer/indexer.service'; import { NotWritableError } from './common/indexer/entities/not.writable.error'; import { LibraryConfig } from "@multiversx/sdk-core/out"; +import * as bodyParser from 'body-parser'; +import * as requestIp from 'request-ip'; +import compression from 'compression'; async function bootstrap() { const logger = new Logger('Bootstrapper'); @@ -182,6 +183,21 @@ async function bootstrap() { } async function configurePublicApp(publicApp: NestExpressApplication, apiConfigService: ApiConfigService) { + if (apiConfigService.getCompressionEnabled()) { + publicApp.use(compression({ + filter: (req: any, res: any) => { + if (req.headers['x-no-compression']) { + return false; + } + return compression.filter(req, res); + }, + level: apiConfigService.getCompressionLevel(), + threshold: apiConfigService.getCompressionThreshold(), + memLevel: 8, + chunkSize: apiConfigService.getCompressionChunkSize(), + })); + } + publicApp.use(bodyParser.json({ limit: '1mb' })); publicApp.use(requestIp.mw()); publicApp.enableCors(); @@ -301,6 +317,10 @@ async function configurePublicApp(publicApp: NestExpressApplication, apiConfigSe logger.log(`Use request caching: ${await settingsService.getUseRequestCachingFlag()}`); logger.log(`Use request logging: ${await settingsService.getUseRequestLoggingFlag()}`); logger.log(`Use vm query tracing: ${await settingsService.getUseVmQueryTracingFlag()}`); + logger.log(`Compression enabled: ${apiConfigService.getCompressionEnabled()}`); + if (apiConfigService.getCompressionEnabled()) { + logger.log(`Compression level: ${apiConfigService.getCompressionLevel()} (threshold: ${apiConfigService.getCompressionThreshold()} bytes)`); + } } async function configureCacheWarmerApp(cacheWarmerApp: INestApplication, apiConfigService: ApiConfigService): Promise { diff --git a/src/queue.worker/nft.worker/queue/job-services/media/nft.media.service.ts b/src/queue.worker/nft.worker/queue/job-services/media/nft.media.service.ts index 66d3b0cf3..fb7c9b433 100644 --- a/src/queue.worker/nft.worker/queue/job-services/media/nft.media.service.ts +++ b/src/queue.worker/nft.worker/queue/job-services/media/nft.media.service.ts @@ -164,7 +164,8 @@ export class NftMediaService { } private isContentTypeAccepted(contentType: string): boolean { - return Object.values(MediaMimeTypeEnum).includes(contentType as MediaMimeTypeEnum); + const baseContentType = contentType.split(';')[0].trim(); + return Object.values(MediaMimeTypeEnum).includes(baseContentType as MediaMimeTypeEnum); } private isFileSizeAccepted(fileSize: number): boolean { diff --git a/src/queue.worker/nft.worker/queue/job-services/thumbnails/aws.service.ts b/src/queue.worker/nft.worker/queue/job-services/thumbnails/aws.service.ts index 97174df97..1df705f49 100644 --- a/src/queue.worker/nft.worker/queue/job-services/thumbnails/aws.service.ts +++ b/src/queue.worker/nft.worker/queue/job-services/thumbnails/aws.service.ts @@ -23,7 +23,7 @@ export class AWSService { Key: path, Body: buffer, ContentType: type, - ACL: 'public-read', + ACL: "public-read", }); return this.getItemPath(path); diff --git a/src/test/unit/controllers/media.controller.spec.ts b/src/test/unit/controllers/media.controller.spec.ts deleted file mode 100644 index 1570042d4..000000000 --- a/src/test/unit/controllers/media.controller.spec.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { INestApplication } from "@nestjs/common"; -import { Test } from "@nestjs/testing"; -import request = require('supertest'); -import { MediaController } from "src/endpoints/media/media.controller"; -import { PublicAppModule } from "src/public.app.module"; -import { MediaService } from "src/endpoints/media/media.service"; - -describe('MediaController', () => { - let app: INestApplication; - const path: string = "/media"; - - const mediaService = { - getRedirectUrl: jest.fn(), - }; - - beforeAll(async () => { - const moduleRef = await Test.createTestingModule({ - controllers: [MediaController], - imports: [PublicAppModule], - }) - .overrideProvider(MediaService) - .useValue(mediaService) - .compile(); - - app = moduleRef.createNestApplication(); - await app.init(); - }); - - it(`/GET media/:uri(*)`, async () => { - const mockUrl = 'https://s3.amazonaws.com/media.elrond.com/nfts/thumbnail/XPACHIEVE-5a0519-e302a15d'; - - mediaService.getRedirectUrl.mockResolvedValue(mockUrl); - - await request(app.getHttpServer()) - .get(`${path}/nfts/thumbnail/XPACHIEVE-5a0519-e302a15d`) - .expect(200) - .expect('content-type', 'image/jpeg') - .expect('cache-control', 'max-age=60') - .expect('Access-Control-Allow-Origin', '*'); - - expect(mediaService.getRedirectUrl).toHaveBeenCalled(); - }); - - it(`/GET media/:uri(*) - not found`, async () => { - mediaService.getRedirectUrl.mockResolvedValue(undefined); - - await request(app.getHttpServer()) - .get(`${path}/nfts/thumbnail/XPACHIEVE-5a0519-e302a15d`) - .expect(404); - }); - - afterAll(async () => { - await app.close(); - }); -}); diff --git a/src/test/unit/services/accounts.spec.ts b/src/test/unit/services/accounts.spec.ts index 7407d3b8c..7a7933537 100644 --- a/src/test/unit/services/accounts.spec.ts +++ b/src/test/unit/services/accounts.spec.ts @@ -431,6 +431,7 @@ describe('Account Service', () => { isRelayed: false, isScCall: true, relayerSignature: '', + timestampMs: 1698322776000, }); const result = await service.getAccountDeployedAtRaw(address); diff --git a/src/test/unit/services/blocks.spec.ts b/src/test/unit/services/blocks.spec.ts index 6d6e05587..5684f66ce 100644 --- a/src/test/unit/services/blocks.spec.ts +++ b/src/test/unit/services/blocks.spec.ts @@ -230,7 +230,7 @@ describe('Block Service', () => { const blses = ['bls_key_0', 'bls_key_1', 'bls_key_2']; - jest.spyOn(cacheService, 'getLocal').mockImplementation(() => Promise.resolve(blses)); + jest.spyOn(cacheService, 'getLocal').mockImplementation(() => blses); jest.spyOn(blsService, 'getPublicKeys').mockImplementation(() => Promise.resolve(blses)); const result = await blockService.computeProposerAndValidators(inputItem); @@ -253,8 +253,8 @@ describe('Block Service', () => { const blses = ['bls_key_0', 'bls_key_1', 'bls_key_2']; - jest.spyOn(cacheService, 'getLocal').mockImplementationOnce(() => Promise.resolve(null)); - jest.spyOn(cacheService, 'setLocal').mockImplementation(() => Promise.resolve()); + jest.spyOn(cacheService, 'getLocal').mockImplementationOnce(() => null); + jest.spyOn(cacheService, 'setLocal').mockImplementation(); jest.spyOn(blsService, 'getPublicKeys').mockImplementation(() => Promise.resolve(blses)); await blockService.computeProposerAndValidators(inputItem); diff --git a/src/test/unit/services/delegation.spec.ts b/src/test/unit/services/delegation.spec.ts index b55a5515c..1681318d9 100644 --- a/src/test/unit/services/delegation.spec.ts +++ b/src/test/unit/services/delegation.spec.ts @@ -219,5 +219,59 @@ describe('Delegation Service', () => { await expect(delegationService.getDelegationForAddress(mockAddress)).rejects.toThrow(mockError); expect(mockGetFn).toHaveBeenCalledWith(`${apiConfigService.getDelegationUrl()}/accounts/${mockAddress}/delegations`); }); + + it('should initialize empty userUndelegatedList when the field is missing from external API response', async () => { + const mockResponseWithMissingField = [ + { + address: 'erd1qga7ze0l03chfgru0a32wxqf2226nzrxnyhzer9lmudqhjgy7ycqjjyknz', + contract: 'erd1qqqqqqqqqqqqqqqqqqqqqqqqqq6nzrxnyhzer9lmudqhjgy7ycqjjyknz', + userUnBondable: '1000000000000000000', + userActiveStake: '0', + claimableRewards: '0', + }, + ]; + + const expectedResult = [ + { + address: 'erd1qga7ze0l03chfgru0a32wxqf2226nzrxnyhzer9lmudqhjgy7ycqjjyknz', + contract: 'erd1qqqqqqqqqqqqqqqqqqqqqqqqqq6nzrxnyhzer9lmudqhjgy7ycqjjyknz', + userUnBondable: '1000000000000000000', + userActiveStake: '0', + claimableRewards: '0', + userUndelegatedList: [], + }, + ]; + + const mockGetFn = jest.fn().mockResolvedValue({ data: mockResponseWithMissingField }); + jest.spyOn(apiService, 'get').mockImplementation(mockGetFn); + + const result = await delegationService.getDelegationForAddress(mockAddress); + + expect(result).toEqual(expectedResult); + expect(result[0].userUndelegatedList).toEqual([]); + expect(mockGetFn).toHaveBeenCalledWith(`${apiConfigService.getDelegationUrl()}/accounts/${mockAddress}/delegations`); + }); + + it('should preserve explicitly returned empty userUndelegatedList arrays from external API', async () => { + const mockResponseWithExplicitEmptyArray = [ + { + address: 'erd1qga7ze0l03chfgru0a32wxqf2226nzrxnyhzer9lmudqhjgy7ycqjjyknz', + contract: 'erd1qqqqqqqqqqqqqqqqqqqqqqqqqq6nzrxnyhzer9lmudqhjgy7ycqjjyknz', + userUnBondable: '1000000000000000000', + userActiveStake: '0', + claimableRewards: '0', + userUndelegatedList: [], + }, + ]; + + const mockGetFn = jest.fn().mockResolvedValue({ data: mockResponseWithExplicitEmptyArray }); + jest.spyOn(apiService, 'get').mockImplementation(mockGetFn); + + const result = await delegationService.getDelegationForAddress(mockAddress); + + expect(result).toEqual(mockResponseWithExplicitEmptyArray); + expect(result[0].userUndelegatedList).toEqual([]); + expect(mockGetFn).toHaveBeenCalledWith(`${apiConfigService.getDelegationUrl()}/accounts/${mockAddress}/delegations`); + }); }); }); diff --git a/src/test/unit/services/esdt.address.spec.ts b/src/test/unit/services/esdt.address.spec.ts index 778baa2f2..1397d74c9 100644 --- a/src/test/unit/services/esdt.address.spec.ts +++ b/src/test/unit/services/esdt.address.spec.ts @@ -211,7 +211,7 @@ describe('EsdtAddressService', () => { }, }; - jest.spyOn(cacheService, 'getLocal').mockResolvedValue(cachedEsdts); + jest.spyOn(cacheService, 'getLocal').mockReturnValue(cachedEsdts); jest.spyOn(metricsService, 'incrementCachedApiHit'); const result = await service.getAllEsdtsForAddressFromGateway(address); @@ -224,7 +224,7 @@ describe('EsdtAddressService', () => { const address = 'some-address'; const ttl = 1000; - jest.spyOn(cacheService, 'getLocal').mockResolvedValueOnce(null); + jest.spyOn(cacheService, 'getLocal').mockReturnValueOnce(null); jest.spyOn(cacheService, 'setLocal'); jest.spyOn(protocolService, 'getSecondsRemainingUntilNextRound').mockResolvedValue(ttl); diff --git a/src/test/unit/services/events.spec.ts b/src/test/unit/services/events.spec.ts index 66c21324e..d8251fbcf 100644 --- a/src/test/unit/services/events.spec.ts +++ b/src/test/unit/services/events.spec.ts @@ -93,6 +93,50 @@ describe('EventsService', () => { expect(result).toEqual([]); expect(indexerService.getEvents).toHaveBeenCalledWith(pagination, filter); }); + + it('should return events in the correct order', async () => { + const pagination: QueryPagination = { from: 0, size: 10 }; + const filter: EventsFilter = new EventsFilter({ order: 1 }); + + const mockElasticEvents = [ + generateMockEvent(), + generateMockEvent({ _id: "5d4a7cd39caf55aaaef038d2fe5fd864b01db2170253c158-1-1", identifier: 'ESDTNFTCreate' }), + ]; + + const expectedEvents = [ + createExpectedEvent("7e3faa2a4ea5cfe8667f2e13eb27076b0452742dbe01044871c8ea109f73ebed", "transferValueOnly"), + createExpectedEvent("5d4a7cd39caf55aaaef038d2fe5fd864b01db2170253c158-1-1", "ESDTNFTCreate"), + ]; + + mockIndexerService.getEvents.mockResolvedValue(mockElasticEvents); + + const result = await service.getEvents(pagination, filter); + + expect(result).toEqual(expectedEvents); + expect(indexerService.getEvents).toHaveBeenCalledWith(pagination, filter); + }); + + it('should return events filtered by shard', async () => { + const pagination: QueryPagination = { from: 0, size: 10 }; + const filter: EventsFilter = new EventsFilter({ shard: 1 }); + + const mockElasticEvents = [ + generateMockEvent(), + generateMockEvent({ _id: "5d4a7cd39caf55aaaef038d2fe5fd864b01db2170253c158-1-1", identifier: 'ESDTNFTCreate' }), + ]; + + const expectedEvents = [ + createExpectedEvent("7e3faa2a4ea5cfe8667f2e13eb27076b0452742dbe01044871c8ea109f73ebed", "transferValueOnly"), + createExpectedEvent("5d4a7cd39caf55aaaef038d2fe5fd864b01db2170253c158-1-1", "ESDTNFTCreate"), + ]; + + mockIndexerService.getEvents.mockResolvedValue(mockElasticEvents); + + const result = await service.getEvents(pagination, filter); + + expect(result).toEqual(expectedEvents); + expect(indexerService.getEvents).toHaveBeenCalledWith(pagination, filter); + }); }); describe('getEventsCount', () => { diff --git a/src/test/unit/services/rabbitmq.consumer.spec.ts b/src/test/unit/services/rabbitmq.consumer.spec.ts index f9d3d9dda..31680407a 100644 --- a/src/test/unit/services/rabbitmq.consumer.spec.ts +++ b/src/test/unit/services/rabbitmq.consumer.spec.ts @@ -14,6 +14,9 @@ describe('RabbitMqConsumer', () => { const nftHandlerServiceMock = { handleNftCreateEvent: jest.fn(), handleNftUpdateAttributesEvent: jest.fn(), + handleNftBurnEvent: jest.fn(), + handleNftMetadataEvent: jest.fn(), + handleNftModifyCreatorEvent: jest.fn(), }; const tokenHandlerServiceMock = { @@ -54,10 +57,43 @@ describe('RabbitMqConsumer', () => { topics: [''], }; - await service.consumeEvents({ events: [event1, event2] }); + const event3: NotifierEvent = { + identifier: NotifierEventIdentifier.ESDTNFTBurn, + address: "erd1", + topics: [''], + }; + + const event4: NotifierEvent = { + identifier: NotifierEventIdentifier.ESDTMetaDataUpdate, + address: "erd1", + topics: [''], + }; + + const event5: NotifierEvent = { + identifier: NotifierEventIdentifier.ESDTModifyCreator, + address: "erd1", + topics: [''], + }; + + await service.consumeEvents({ events: [event1, event2, event3, event4, event5] }); expect(nftHandlerService.handleNftCreateEvent).toHaveBeenCalledWith(event1); expect(tokenHandlerService.handleTransferOwnershipEvent).toHaveBeenCalledWith(event2); + expect(nftHandlerService.handleNftBurnEvent).toHaveBeenCalledWith(event3); + expect(nftHandlerService.handleNftMetadataEvent).toHaveBeenCalledWith(event4); + expect(nftHandlerService.handleNftModifyCreatorEvent).toHaveBeenCalledWith(event5); + }); + + it('should handle ESDTMetaDataRecreate with the metadata event handler', async () => { + const event: NotifierEvent = { + identifier: NotifierEventIdentifier.ESDTMetaDataRecreate, + address: "erd1", + topics: [''], + }; + + await service.consumeEvents({ events: [event] }); + + expect(nftHandlerService.handleNftMetadataEvent).toHaveBeenCalledWith(event); }); it('should log the error when an unhandled error occurs', async () => { diff --git a/src/test/unit/services/rabbitmq.nft.handler.service.spec.ts b/src/test/unit/services/rabbitmq.nft.handler.service.spec.ts new file mode 100644 index 000000000..b20d3483c --- /dev/null +++ b/src/test/unit/services/rabbitmq.nft.handler.service.spec.ts @@ -0,0 +1,206 @@ +import { TestingModule, Test } from "@nestjs/testing"; +import { BinaryUtils } from "@multiversx/sdk-nestjs-common"; +import { CacheService } from "@multiversx/sdk-nestjs-cache"; +import { NotifierEvent } from "src/common/rabbitmq/entities/notifier.event"; +import { RabbitMqNftHandlerService } from "src/common/rabbitmq/rabbitmq.nft.handler.service"; +import { IndexerService } from "src/common/indexer/indexer.service"; +import { NftService } from "src/endpoints/nfts/nft.service"; +import { NftWorkerService } from "src/queue.worker/nft.worker/nft.worker.service"; + +describe('RabbitMqNftHandlerService', () => { + let service: RabbitMqNftHandlerService; + let nftService: NftService; + let nftWorkerService: NftWorkerService; + let cacheService: CacheService; + + beforeEach(async () => { + const nftServiceMock = { + getSingleNft: jest.fn(), + }; + + const nftWorkerServiceMock = { + addProcessNftQueueJob: jest.fn(), + needsProcessing: jest.fn(), + }; + + const indexerServiceMock = { + getCollection: jest.fn(), + }; + + const cacheServiceMock = { + getLocal: jest.fn(), + setLocal: jest.fn(), + delete: jest.fn(), + }; + + const clientProxyMock = { + emit: jest.fn(), + }; + + const module: TestingModule = await Test.createTestingModule({ + providers: [ + RabbitMqNftHandlerService, + { provide: NftService, useValue: nftServiceMock }, + { provide: NftWorkerService, useValue: nftWorkerServiceMock }, + { provide: IndexerService, useValue: indexerServiceMock }, + { provide: CacheService, useValue: cacheServiceMock }, + { provide: 'PUBSUB_SERVICE', useValue: clientProxyMock }, + ], + }).compile(); + + service = module.get(RabbitMqNftHandlerService); + nftService = module.get(NftService); + nftWorkerService = module.get(NftWorkerService); + cacheService = module.get(CacheService); + + jest.spyOn(BinaryUtils, 'base64Decode').mockImplementation((value) => { + if (value === 'collection') return 'TEST-abcdef'; + if (value === 'nonce') return '0123456789abcdef'; + if (value === 'attributes') return 'metadata:test'; + return value; + }); + + jest.spyOn(BinaryUtils, 'base64ToHex').mockImplementation(() => '01'); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); + + describe('handleNftBurnEvent', () => { + it('should invalidate cache for NFT', async () => { + const event: NotifierEvent = { + identifier: 'ESDTNFTBurn', + address: 'erd1', + topics: ['collection', 'nonce'], + }; + + const result = await service.handleNftBurnEvent(event); + + expect(result).toBe(true); + expect(cacheService.delete).toHaveBeenCalledWith('nft:TEST-abcdef-01'); + }); + + it('should handle errors and return false', async () => { + const event: NotifierEvent = { + identifier: 'ESDTNFTBurn', + address: 'erd1', + topics: ['collection', 'nonce'], + }; + + const error = new Error('Test error'); + jest.spyOn(cacheService, 'delete').mockImplementation(() => { + throw error; + }); + + const loggerSpy = jest.spyOn(service['logger'], 'error').mockImplementation(); + + const result = await service.handleNftBurnEvent(event); + + expect(result).toBe(false); + expect(loggerSpy).toHaveBeenCalledWith(`An unhandled error occurred when processing NFT Burn event for NFT with identifier 'TEST-abcdef-01'`); + expect(loggerSpy).toHaveBeenCalledWith(error); + }); + }); + + describe('handleNftMetadataEvent', () => { + it('should process NFT with metadata refresh', async () => { + const event: NotifierEvent = { + identifier: 'ESDTMetaDataUpdate', + address: 'erd1', + topics: ['collection', 'nonce'], + }; + + const nft = { identifier: 'TEST-abcdef-01' }; + jest.spyOn(nftService, 'getSingleNft').mockResolvedValue(nft as any); + + const result = await service.handleNftMetadataEvent(event); + + expect(result).toBe(true); + expect(nftService.getSingleNft).toHaveBeenCalledWith('TEST-abcdef-01'); + expect(nftWorkerService.addProcessNftQueueJob).toHaveBeenCalledWith( + nft, + expect.objectContaining({ + forceRefreshMetadata: true, + forceRefreshMedia: true, + }) + ); + }); + + it('should return false if NFT not found', async () => { + const event: NotifierEvent = { + identifier: 'ESDTMetaDataUpdate', + address: 'erd1', + topics: ['collection', 'nonce'], + }; + + jest.spyOn(nftService, 'getSingleNft').mockResolvedValue(undefined); + const loggerSpy = jest.spyOn(service['logger'], 'log').mockImplementation(); + + const result = await service.handleNftMetadataEvent(event); + + expect(result).toBe(false); + expect(loggerSpy).toHaveBeenCalledWith(`Could not fetch NFT details for NFT with identifier 'TEST-abcdef-01'`); + }); + + it('should handle errors', async () => { + const event: NotifierEvent = { + identifier: 'ESDTMetaDataUpdate', + address: 'erd1', + topics: ['collection', 'nonce'], + }; + + const nft = { identifier: 'TEST-abcdef-01' }; + jest.spyOn(nftService, 'getSingleNft').mockResolvedValue(nft as any); + + const error = new Error('Test error'); + jest.spyOn(nftWorkerService, 'addProcessNftQueueJob').mockImplementation(() => { + throw error; + }); + + const loggerSpy = jest.spyOn(service['logger'], 'error').mockImplementation(); + + const result = await service.handleNftMetadataEvent(event); + + expect(result).toBe(false); + expect(loggerSpy).toHaveBeenCalledWith(`An unhandled error occurred when processing 'ESDTMetaDataUpdate' event for NFT with identifier 'TEST-abcdef-01'`); + expect(loggerSpy).toHaveBeenCalledWith(error); + }); + }); + + describe('handleNftModifyCreatorEvent', () => { + it('should invalidate cache for NFT', async () => { + const event: NotifierEvent = { + identifier: 'ESDTModifyCreator', + address: 'erd1', + topics: ['collection', 'nonce'], + }; + + const result = await service.handleNftModifyCreatorEvent(event); + + expect(result).toBe(true); + expect(cacheService.delete).toHaveBeenCalledWith('nft:TEST-abcdef-01'); + }); + + it('should handle errors and return false', async () => { + const event: NotifierEvent = { + identifier: 'ESDTModifyCreator', + address: 'erd1', + topics: ['collection', 'nonce'], + }; + + const error = new Error('Test error'); + jest.spyOn(cacheService, 'delete').mockImplementation(() => { + throw error; + }); + + const loggerSpy = jest.spyOn(service['logger'], 'error').mockImplementation(); + + const result = await service.handleNftModifyCreatorEvent(event); + + expect(result).toBe(false); + expect(loggerSpy).toHaveBeenCalledWith(`An unhandled error occurred when processing NFT ModifyCreator event for NFT with identifier 'TEST-abcdef-01'`); + expect(loggerSpy).toHaveBeenCalledWith(error); + }); + }); +}); diff --git a/src/test/unit/services/transaction.get.spec.ts b/src/test/unit/services/transaction.get.spec.ts new file mode 100644 index 000000000..d6990b54f --- /dev/null +++ b/src/test/unit/services/transaction.get.spec.ts @@ -0,0 +1,734 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { BinaryUtils } from '@multiversx/sdk-nestjs-common'; +import { ApiUtils } from '@multiversx/sdk-nestjs-http'; +import { TransactionGetService } from '../../../endpoints/transactions/transaction.get.service'; +import { IndexerService } from '../../../common/indexer/indexer.service'; +import { GatewayService } from '../../../common/gateway/gateway.service'; +import { TokenTransferService } from '../../../endpoints/tokens/token.transfer.service'; +import { ApiConfigService } from '../../../common/api-config/api.config.service'; +import { TransactionLog } from '../../../endpoints/transactions/entities/transaction.log'; +import { TransactionLogEvent } from '../../../endpoints/transactions/entities/transaction.log.event'; +import { TransactionDetailed } from '../../../endpoints/transactions/entities/transaction.detailed'; +import { TransactionOptionalFieldOption } from '../../../endpoints/transactions/entities/transaction.optional.field.options'; +import { MiniBlockType } from '../../../endpoints/miniblocks/entities/mini.block.type'; +import { TransactionStatus } from '../../../endpoints/transactions/entities/transaction.status'; + +describe('TransactionGetService', () => { + let service: TransactionGetService; + let indexerService: jest.Mocked; + let gatewayService: jest.Mocked; + let tokenTransferService: jest.Mocked; + let apiConfigService: jest.Mocked; + + const mockTransactionHash = 'abc123def456'; + const mockSender = 'erd1qga7ze0l03chfgru0a32wxqf2226nzrxnyhzer9lmudqhjgy7ycqjjyknz'; + const mockReceiver = 'erd15hmuycqw4mkaksfp0yu0auy548urd0wp6wyd4vtjkg3t6h9he5ystm2sv6'; + + const createMockTransaction = (overrides?: any) => ({ + txHash: mockTransactionHash, + hash: mockTransactionHash, + miniBlockHash: 'mb123', + nonce: 1, + round: 12345, + epoch: 500, + value: '1000000000000000000', + receiver: mockReceiver, + sender: mockSender, + gasPrice: 1000000000, + gasLimit: 50000, + gasUsed: 25000, + data: '', + signature: 'sig123', + sourceShard: 0, + destinationShard: 1, + blockNonce: 12345, + blockHash: 'block123', + notarizedAtSourceInMetaNonce: 12340, + NotarizedAtSourceInMetaHash: 'meta123', + notarizedAtDestinationInMetaNonce: 12341, + notarizedAtDestinationInMetaHash: 'meta124', + miniblockType: 'TxBlock', + miniblockHash: 'mb123', + status: 'success', + hyperblockNonce: 12300, + hyperblockHash: 'hyper123', + timestamp: 1634567890, + searchOrder: 1, + hasScResults: false, + hasOperations: false, + tokens: [], + esdtValues: [], + operation: 'transfer', + function: '', + isRelayed: false, + ...overrides, + }); + + const createMockGatewayTransaction = (overrides?: any) => ({ + type: 'Transaction', + processingTypeOnSource: 'Normal', + processingTypeOnDestination: 'Normal', + hash: mockTransactionHash, + nonce: 1, + value: '1000000000000000000', + receiver: mockReceiver, + sender: mockSender, + gasPrice: 1000000000, + gasLimit: 50000, + gasUsed: 25000, + data: '', + signature: 'sig123', + sourceShard: 0, + destinationShard: 1, + blockNonce: 12345, + blockHash: 'block123', + miniblockHash: 'mb123', + status: 'success', + round: 12345, + fee: 100000000000000, + timestamp: 1634567890, + miniblockType: MiniBlockType.TxBlock, + receipt: undefined, + smartContractResults: undefined, + logs: undefined, + guardian: undefined, + guardianSignature: undefined, + relayerAddress: undefined, + relayerSignature: undefined, + receiverUsername: undefined, + senderUsername: undefined, + ...overrides, + }); + + beforeEach(async () => { + const indexerServiceMock = { + getTransactionBySenderAndNonce: jest.fn(), + getTransactionLogs: jest.fn(), + getTransaction: jest.fn(), + getTransactionScResults: jest.fn(), + getTransactionReceipts: jest.fn(), + getNfts: jest.fn(), + }; + + const gatewayServiceMock = { + getTransaction: jest.fn(), + }; + + const tokenTransferServiceMock = { + getOperationsForTransaction: jest.fn(), + }; + + const apiConfigServiceMock = { + getElasticMigratedIndicesConfig: jest.fn(), + }; + + const module: TestingModule = await Test.createTestingModule({ + providers: [ + TransactionGetService, + { provide: IndexerService, useValue: indexerServiceMock }, + { provide: GatewayService, useValue: gatewayServiceMock }, + { provide: TokenTransferService, useValue: tokenTransferServiceMock }, + { provide: ApiConfigService, useValue: apiConfigServiceMock }, + ], + }).compile(); + + service = module.get(TransactionGetService); + indexerService = module.get(IndexerService); + gatewayService = module.get(GatewayService); + tokenTransferService = module.get(TokenTransferService); + apiConfigService = module.get(ApiConfigService); + + jest.spyOn(BinaryUtils, 'hexToBase64').mockImplementation((hex: string) => { + if (!hex || hex.length === 0) return hex; + return Buffer.from(hex, 'hex').toString('base64'); + }); + + jest.spyOn(BinaryUtils, 'base64Encode').mockImplementation((str: string) => { + return Buffer.from(str).toString('base64'); + }); + + jest.spyOn(BinaryUtils, 'numberToHex').mockImplementation((num: number) => { + return num.toString(16); + }); + + jest.spyOn(ApiUtils, 'mergeObjects').mockImplementation((target: any, source: any) => { + return { ...target, ...source }; + }); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + describe('getTransactionLogsFromElastic', () => { + it('should handle small batch of hashes', async () => { + const hashes = ['hash1', 'hash2']; + const expectedLogs = [ + new TransactionLog({ id: 'hash1', address: 'addr1', events: [] }), + new TransactionLog({ id: 'hash2', address: 'addr2', events: [] }), + ]; + + jest.spyOn(service as any, 'getTransactionLogsFromElasticInternal') + .mockResolvedValue(expectedLogs); + + const result = await service.getTransactionLogsFromElastic(hashes); + + expect(result).toHaveLength(2); + expect(service['getTransactionLogsFromElasticInternal']).toHaveBeenCalledWith(hashes); + }); + + it('should handle large batch of hashes (>1000)', async () => { + const hashes = Array.from({ length: 1500 }, (_, i) => `hash${i}`); + const firstBatch = Array.from({ length: 1000 }, (_, i) => `hash${i}`); + const secondBatch = Array.from({ length: 500 }, (_, i) => `hash${i + 1000}`); + + const firstBatchLogs = firstBatch.map(hash => new TransactionLog({ id: hash, address: 'addr', events: [] })); + const secondBatchLogs = secondBatch.map(hash => new TransactionLog({ id: hash, address: 'addr', events: [] })); + + jest.spyOn(service as any, 'getTransactionLogsFromElasticInternal') + .mockResolvedValueOnce(firstBatchLogs) + .mockResolvedValueOnce(secondBatchLogs); + + const result = await service.getTransactionLogsFromElastic(hashes); + + expect(result).toHaveLength(1500); + expect(service['getTransactionLogsFromElasticInternal']).toHaveBeenCalledTimes(2); + expect(service['getTransactionLogsFromElasticInternal']).toHaveBeenNthCalledWith(1, firstBatch); + expect(service['getTransactionLogsFromElasticInternal']).toHaveBeenNthCalledWith(2, secondBatch); + }); + + it('should return empty array for empty hashes', async () => { + const result = await service.getTransactionLogsFromElastic([]); + expect(result).toEqual([]); + }); + }); + + describe('getTransactionLogsFromElasticInternal', () => { + it('should use events index when configured', async () => { + const hashes = ['hash1']; + apiConfigService.getElasticMigratedIndicesConfig.mockReturnValue({ logs: 'events' }); + + jest.spyOn(service as any, 'getTransactionLogsFromElasticInternalEventsIndex') + .mockResolvedValue([]); + + await service['getTransactionLogsFromElasticInternal'](hashes); + + expect(service['getTransactionLogsFromElasticInternalEventsIndex']).toHaveBeenCalledWith(hashes); + }); + + it('should use logs index by default', async () => { + const hashes = ['hash1']; + apiConfigService.getElasticMigratedIndicesConfig.mockReturnValue({}); + + jest.spyOn(service as any, 'getTransactionLogsFromElasticInternalLogsIndex') + .mockResolvedValue([]); + + await service['getTransactionLogsFromElasticInternal'](hashes); + + expect(service['getTransactionLogsFromElasticInternalLogsIndex']).toHaveBeenCalledWith(hashes); + }); + + it('should use logs index when no config is available', async () => { + const hashes = ['hash1']; + apiConfigService.getElasticMigratedIndicesConfig.mockReturnValue(null as any); + + jest.spyOn(service as any, 'getTransactionLogsFromElasticInternalLogsIndex') + .mockResolvedValue([]); + + await service['getTransactionLogsFromElasticInternal'](hashes); + + expect(service['getTransactionLogsFromElasticInternalLogsIndex']).toHaveBeenCalledWith(hashes); + }); + }); + + describe('getTransactionLogsFromElasticInternalLogsIndex', () => { + it('should call indexer service with correct parameters', async () => { + const hashes = ['hash1', 'hash2']; + const expectedResult = [ + { id: 'hash1', address: 'addr1', identifier: 'test', topics: [], order: 0, originalTxHash: 'hash1' }, + { id: 'hash2', address: 'addr2', identifier: 'test', topics: [], order: 0, originalTxHash: 'hash2' }, + ]; + + indexerService.getTransactionLogs.mockResolvedValue(expectedResult as any); + + const result = await service['getTransactionLogsFromElasticInternalLogsIndex'](hashes); + + expect(indexerService.getTransactionLogs).toHaveBeenCalledWith(hashes, 'logs', '_id'); + expect(result).toEqual(expectedResult); + }); + }); + + describe('getTransactionLogsFromElasticInternalEventsIndex', () => { + const mockEventsData = [ + { + txHash: 'hash1', + logAddress: 'erd1addr1', + identifier: 'ESDTTransfer', + address: 'erd1addr1', + data: '48656c6c6f', // "Hello" in hex + additionalData: ['576f726c64'], // ["World"] in hex + topics: ['746f70696331', '746f70696332'], // ["topic1", "topic2"] in hex + order: 1, + originalTxHash: 'hash1', + }, + { + txHash: 'hash1', + logAddress: 'erd1addr1', + identifier: 'transferValueOnly', + address: 'erd1addr1', + data: '4461746132', // "Data2" in hex + additionalData: undefined, + topics: ['746f70696333'], + order: 2, + originalTxHash: 'hash1', + }, + { + txHash: 'hash2', + logAddress: 'erd1addr2', + identifier: 'writeLog', + address: 'erd1addr2', + data: '', + additionalData: [], + topics: [], + order: 0, + originalTxHash: 'hash2', + }, + ]; + + it('should transform events data correctly', async () => { + indexerService.getTransactionLogs.mockResolvedValue(mockEventsData); + + const result = await service['getTransactionLogsFromElasticInternalEventsIndex'](['hash1', 'hash2']); + + expect(indexerService.getTransactionLogs).toHaveBeenCalledWith(['hash1', 'hash2'], 'events', 'txHash'); + expect(result).toHaveLength(2); + + const hash1Log = result.find(log => log.id === 'hash1'); + expect(hash1Log).toBeDefined(); + if (hash1Log) { + expect(hash1Log.id).toBe('hash1'); + expect(hash1Log.address).toBe('erd1addr1'); + expect(hash1Log.events).toHaveLength(2); + + const firstEvent = hash1Log.events[0]; + expect(firstEvent.identifier).toBe('ESDTTransfer'); + expect(firstEvent.address).toBe('erd1addr1'); + expect(firstEvent.order).toBe(1); + } + + const hash2Log = result.find(log => log.id === 'hash2'); + expect(hash2Log).toBeDefined(); + if (hash2Log) { + expect(hash2Log.id).toBe('hash2'); + expect(hash2Log.events).toHaveLength(1); + } + }); + + it('should handle empty data correctly', async () => { + const emptyDataEvent = { + txHash: 'hash1', + logAddress: 'erd1addr', + identifier: 'test', + address: 'erd1addr', + data: '', + additionalData: [''], + topics: [''], + order: 0, + originalTxHash: 'hash1', + }; + + indexerService.getTransactionLogs.mockResolvedValue([emptyDataEvent]); + + const result = await service['getTransactionLogsFromElasticInternalEventsIndex'](['hash1']); + + expect(result).toHaveLength(1); + const log = result[0]; + expect(log.events).toHaveLength(1); + expect(log.events[0].data).toBe(''); + expect(log.events[0].additionalData).toEqual(['']); + expect(log.events[0].topics).toEqual(['']); + }); + + it('should group events by transaction hash correctly', async () => { + const sameHashEvents = [ + { + txHash: 'hash1', + logAddress: 'erd1addr', + identifier: 'event1', + address: 'erd1addr', + data: '48656c6c6f', + topics: [], + order: 1, + originalTxHash: 'hash1', + }, + { + txHash: 'hash1', + logAddress: 'erd1addr', + identifier: 'event2', + address: 'erd1addr', + data: '576f726c64', + topics: [], + order: 2, + originalTxHash: 'hash1', + }, + ]; + + indexerService.getTransactionLogs.mockResolvedValue(sameHashEvents); + + const result = await service['getTransactionLogsFromElasticInternalEventsIndex'](['hash1']); + + expect(result).toHaveLength(1); + expect(result[0].id).toBe('hash1'); + expect(result[0].events).toHaveLength(2); + expect(result[0].events[0].identifier).toBe('event1'); + expect(result[0].events[1].identifier).toBe('event2'); + }); + + it('should return empty array when no events found', async () => { + indexerService.getTransactionLogs.mockResolvedValue([]); + + const result = await service['getTransactionLogsFromElasticInternalEventsIndex'](['hash1']); + + expect(result).toEqual([]); + }); + }); + + describe('tryGetTransactionFromElastic', () => { + const mockTransaction = createMockTransaction({ + hasScResults: true, + hasOperations: true, + senderUserName: 'c2VuZGVy', // "sender" in base64 + receiverUsername: 'cmVjZWl2ZXI=', // "receiver" in base64 + }); + + beforeEach(() => { + indexerService.getTransaction.mockResolvedValue(mockTransaction); + indexerService.getTransactionScResults.mockResolvedValue([]); + indexerService.getTransactionReceipts.mockResolvedValue([]); + jest.spyOn(service, 'getTransactionLogsFromElastic').mockResolvedValue([]); + tokenTransferService.getOperationsForTransaction.mockResolvedValue([]); + jest.spyOn(service as any, 'applyUsernamesToDetailedTransaction').mockImplementation(() => { }); + jest.spyOn(service, 'applyNftNameOnTransactionOperations').mockResolvedValue(); + }); + + it('should return null when transaction not found', async () => { + indexerService.getTransaction.mockResolvedValue(null); + + const result = await service.tryGetTransactionFromElastic(mockTransactionHash); + + expect(result).toBeNull(); + }); + + it('should handle transaction found successfully', async () => { + const result = await service.tryGetTransactionFromElastic(mockTransactionHash); + + expect(result).toBeDefined(); + expect(indexerService.getTransaction).toHaveBeenCalledWith(mockTransactionHash); + }); + + it('should handle scResults field mapping', async () => { + const transactionWithScResults = createMockTransaction({ + hasScResults: true, + hasOperations: true, + scResults: [{ hash: 'scr1' }], + }); + + indexerService.getTransaction.mockResolvedValue(transactionWithScResults); + + const result = await service.tryGetTransactionFromElastic(mockTransactionHash); + + expect(result).toBeDefined(); + }); + + it('should handle relayerAddr field mapping', async () => { + const transactionWithRelayer = createMockTransaction({ + hasScResults: true, + hasOperations: true, + relayerAddr: 'erd1relayer', + }); + + indexerService.getTransaction.mockResolvedValue(transactionWithRelayer); + + const result = await service.tryGetTransactionFromElastic(mockTransactionHash); + + expect(result).toBeDefined(); + }); + + it('should fetch receipts when no fields specified', async () => { + const mockReceipts = [{ + txHash: mockTransactionHash, + receiptHash: 'receipt123', + value: '1000', + sender: mockSender, + data: '', + timestamp: 123456789, + }]; + indexerService.getTransactionReceipts.mockResolvedValue(mockReceipts); + + await service.tryGetTransactionFromElastic(mockTransactionHash); + + expect(indexerService.getTransactionReceipts).toHaveBeenCalledWith(mockTransactionHash); + }); + + it('should skip receipts when receipt field not requested', async () => { + await service.tryGetTransactionFromElastic(mockTransactionHash, ['logs']); + + expect(indexerService.getTransactionReceipts).not.toHaveBeenCalled(); + }); + + it('should fetch logs and operations when requested', async () => { + const mockLogs = [new TransactionLog({ id: mockTransactionHash, events: [] })]; + jest.spyOn(service, 'getTransactionLogsFromElastic').mockResolvedValue(mockLogs); + + await service.tryGetTransactionFromElastic(mockTransactionHash, [TransactionOptionalFieldOption.logs]); + + expect(service.getTransactionLogsFromElastic).toHaveBeenCalled(); + }); + + it('should handle processing error and return null', async () => { + jest.spyOn(service, 'getTransactionLogsFromElastic').mockRejectedValue(new Error('Processing error')); + + const result = await service.tryGetTransactionFromElastic(mockTransactionHash, [TransactionOptionalFieldOption.logs]); + + expect(result).toBeNull(); + }); + }); + + describe('alterDuplicatedTransferValueOnlyEvents', () => { + it('should alter duplicated transferValueOnly events', () => { + const backTransferEncoded = Buffer.from('BackTransfer').toString('base64'); + const asyncCallbackEncoded = Buffer.from('AsyncCallback').toString('base64'); + + const events = [ + new TransactionLogEvent({ + identifier: 'transferValueOnly', + data: backTransferEncoded, + topics: ['topic1', 'topic2'], + }), + new TransactionLogEvent({ + identifier: 'transferValueOnly', + data: asyncCallbackEncoded, + topics: ['topic1', 'topic2'], + }), + new TransactionLogEvent({ + identifier: 'otherEvent', + data: 'otherData', + topics: ['topic3'], + }), + ]; + + service['alterDuplicatedTransferValueOnlyEvents'](events); + + expect(events[1].topics[0]).toBe(Buffer.from('0', 'hex').toString('base64')); + expect(events[0].topics[0]).toBe('topic1'); + expect(events[2].topics[0]).toBe('topic3'); + }); + + it('should not alter when conditions are not met', () => { + const events = [ + new TransactionLogEvent({ + identifier: 'transferValueOnly', + data: Buffer.from('BackTransfer').toString('base64'), + topics: ['topic1'], + }), + ]; + + const originalTopics = [...events[0].topics]; + + service['alterDuplicatedTransferValueOnlyEvents'](events); + + expect(events[0].topics).toEqual(originalTopics); + }); + }); + + describe('tryGetTransactionFromGatewayForList', () => { + it('should return transaction when gateway returns data', async () => { + const mockGatewayTransaction = { + txHash: mockTransactionHash, + sender: mockSender, + receiver: mockReceiver, + }; + + jest.spyOn(service, 'tryGetTransactionFromGateway').mockResolvedValue(mockGatewayTransaction as any); + + const result = await service.tryGetTransactionFromGatewayForList(mockTransactionHash); + + expect(result).toBeDefined(); + expect(service.tryGetTransactionFromGateway).toHaveBeenCalledWith(mockTransactionHash, false); + }); + + it('should return undefined when gateway returns null', async () => { + jest.spyOn(service, 'tryGetTransactionFromGateway').mockResolvedValue(null); + + const result = await service.tryGetTransactionFromGatewayForList(mockTransactionHash); + + expect(result).toBeUndefined(); + }); + }); + + describe('tryGetTransactionFromGateway', () => { + const mockGatewayResponse = createMockGatewayTransaction({ + data: 'test', + receipt: { value: 1000 }, + smartContractResults: [ + { + hash: 'scr1', + callType: 1, + value: 2000, + data: 'Hello', + }, + ], + logs: { events: [] }, + guardian: 'erd1guardian', + guardianSignature: 'guardianSig', + relayerAddress: 'erd1relayer', + relayerSignature: 'relayerSig', + }); + + beforeEach(() => { + gatewayService.getTransaction.mockResolvedValue(mockGatewayResponse); + }); + + it('should return null when gateway returns null', async () => { + gatewayService.getTransaction.mockResolvedValue(null as any); + + const result = await service.tryGetTransactionFromGateway(mockTransactionHash); + + expect(result).toBeNull(); + }); + + it('should return null for SmartContractResultBlock', async () => { + gatewayService.getTransaction.mockResolvedValue(createMockGatewayTransaction({ + miniblockType: MiniBlockType.SmartContractResultBlock, + })); + + const result = await service.tryGetTransactionFromGateway(mockTransactionHash); + + expect(result).toBeNull(); + }); + + it('should check elastic for pending transactions', async () => { + const pendingTransaction = createMockGatewayTransaction({ + status: 'pending', + }); + + gatewayService.getTransaction.mockResolvedValue(pendingTransaction); + jest.spyOn(service as any, 'tryGetTransactionFromElasticBySenderAndNonce') + .mockResolvedValue(null); + + const result = await service.tryGetTransactionFromGateway(mockTransactionHash, true); + + expect(service['tryGetTransactionFromElasticBySenderAndNonce']) + .toHaveBeenCalledWith(mockSender, 1); + expect(result).toBeDefined(); + }); + + it('should return null if different transaction found in elastic', async () => { + const pendingTransaction = createMockGatewayTransaction({ + status: 'pending', + }); + + gatewayService.getTransaction.mockResolvedValue(pendingTransaction); + jest.spyOn(service as any, 'tryGetTransactionFromElasticBySenderAndNonce') + .mockResolvedValue({ txHash: 'different-hash' }); + + const result = await service.tryGetTransactionFromGateway(mockTransactionHash, true); + + expect(result).toBeNull(); + }); + + it('should transform gateway response correctly', async () => { + const result = await service.tryGetTransactionFromGateway(mockTransactionHash); + + expect(result).toBeDefined(); + if (result) { + expect(result.txHash).toBe(mockTransactionHash); + expect(result.sender).toBe(mockSender); + expect(result.receiver).toBe(mockReceiver); + expect(result.senderShard).toBe(0); + expect(result.receiverShard).toBe(1); + expect(result.inTransit).toBe(false); + } + }); + + it('should handle inTransit status correctly', async () => { + const pendingTransactionWithMiniblock = createMockGatewayTransaction({ + status: TransactionStatus.pending, + miniblockHash: 'mb123', + }); + + gatewayService.getTransaction.mockResolvedValue(pendingTransactionWithMiniblock); + jest.spyOn(service as any, 'tryGetTransactionFromElasticBySenderAndNonce') + .mockResolvedValue(null); + + const result = await service.tryGetTransactionFromGateway(mockTransactionHash, true); + + if (result) { + expect(result.inTransit).toBe(true); + } + }); + + it('should handle error and return null', async () => { + gatewayService.getTransaction.mockRejectedValue(new Error('Gateway error')); + + const result = await service.tryGetTransactionFromGateway(mockTransactionHash); + + expect(result).toBeNull(); + }); + + it('should skip elastic check when queryInElastic is false', async () => { + const pendingTransaction = createMockGatewayTransaction({ + status: 'pending', + }); + + gatewayService.getTransaction.mockResolvedValue(pendingTransaction); + jest.spyOn(service as any, 'tryGetTransactionFromElasticBySenderAndNonce'); + + await service.tryGetTransactionFromGateway(mockTransactionHash, false); + + expect(service['tryGetTransactionFromElasticBySenderAndNonce']).not.toHaveBeenCalled(); + }); + }); + + describe('applyNftNameOnTransactionOperations', () => { + it('should handle empty operations', async () => { + const mockTransactions = [new TransactionDetailed({ operations: [] })]; + + await service.applyNftNameOnTransactionOperations(mockTransactions); + + expect(indexerService.getNfts).not.toHaveBeenCalled(); + }); + + it('should handle transactions without operations', async () => { + const mockTransactions = [new TransactionDetailed()]; + + await service.applyNftNameOnTransactionOperations(mockTransactions); + + expect(indexerService.getNfts).not.toHaveBeenCalled(); + }); + }); + + describe('tryGetTransactionFromElasticBySenderAndNonce', () => { + it('should return first transaction found', async () => { + const mockTransactions = [ + { txHash: 'hash1', sender: mockSender, nonce: 1 }, + { txHash: 'hash2', sender: mockSender, nonce: 1 }, + ]; + + indexerService.getTransactionBySenderAndNonce.mockResolvedValue(mockTransactions as any); + + const result = await service['tryGetTransactionFromElasticBySenderAndNonce'](mockSender, 1); + + expect(result).toEqual(mockTransactions[0]); + expect(indexerService.getTransactionBySenderAndNonce).toHaveBeenCalledWith(mockSender, 1); + }); + + it('should return undefined when no transactions found', async () => { + indexerService.getTransactionBySenderAndNonce.mockResolvedValue([]); + + const result = await service['tryGetTransactionFromElasticBySenderAndNonce'](mockSender, 1); + + expect(result).toBeUndefined(); + }); + }); +}); diff --git a/src/test/unit/services/transactions.spec.ts b/src/test/unit/services/transactions.spec.ts index f943a2637..962ac2da1 100644 --- a/src/test/unit/services/transactions.spec.ts +++ b/src/test/unit/services/transactions.spec.ts @@ -211,6 +211,7 @@ describe('TransactionService', () => { isRelayed: true, isScCall: true, relayerSignature: 'bc51e9032332740d60c404d4bf553ae225ca77a70ad799a1cdfc6e73609be8ec62e89ac6e2c2621ffbfb89e6fab620c137010662f3ebea9c422c9f1dbec04a03', + timestampMs: 1698322776000, }, { hash: '2b1ce5558f5faa533afd437a42a5aeadea8302dc3cca778c0ed50d19c0a047a4', @@ -252,6 +253,7 @@ describe('TransactionService', () => { isRelayed: true, isScCall: true, relayerSignature: 'bc51e9032332740d60c404d4bf553ae225ca77a70ad799a1cdfc6e73609be8ec62e89ac6e2c2621ffbfb89e6fab620c137010662f3ebea9c422c9f1dbec04a03', + timestampMs: 1698322776000, }, ];