From 3fc3d5441e6df90c3c672a02e36b3eae19f4e780 Mon Sep 17 00:00:00 2001 From: Claudiu Lataretu Date: Wed, 13 Mar 2024 14:18:46 +0200 Subject: [PATCH 1/6] SERVICES-2155: add interceptor for field resolver enhancers Signed-off-by: Claudiu Lataretu --- src/public.app.module.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/public.app.module.ts b/src/public.app.module.ts index 45af2ce73..7f0d2f237 100644 --- a/src/public.app.module.ts +++ b/src/public.app.module.ts @@ -68,7 +68,7 @@ import '@multiversx/sdk-nestjs-common/lib/utils/extensions/array.extensions'; }, }; }, - fieldResolverEnhancers: ['guards'], + fieldResolverEnhancers: ['guards', 'interceptors'], }), inject: [WINSTON_MODULE_NEST_PROVIDER], }), From f88ff411d169473e81af80352ef7f7185f588fb9 Mon Sep 17 00:00:00 2001 From: Claudiu Lataretu Date: Mon, 18 Mar 2024 12:50:53 +0200 Subject: [PATCH 2/6] SERVICES-2155: fix timestamp duplicates Signed-off-by: Claudiu Lataretu --- src/services/multiversx-communication/mx.api.service.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/services/multiversx-communication/mx.api.service.ts b/src/services/multiversx-communication/mx.api.service.ts index 9f92cb551..ef48cfcdd 100644 --- a/src/services/multiversx-communication/mx.api.service.ts +++ b/src/services/multiversx-communication/mx.api.service.ts @@ -87,7 +87,8 @@ export class MXApiService { if ( this.apiConfigService.isDeephistoryActive() && context && - context.deepHistoryTimestamp + context.deepHistoryTimestamp && + !resourceUrl.includes('timestamp=') ) { resourceUrl = resourceUrl.includes('?') ? `${resourceUrl}×tamp=${context.deepHistoryTimestamp}` From aa1a6c94615c0a7c7de90b10282f6fee254fdff2 Mon Sep 17 00:00:00 2001 From: Claudiu Lataretu Date: Wed, 10 Apr 2024 17:19:55 +0300 Subject: [PATCH 3/6] SERVICES-2155: filter farms address based on deploy timestamp Signed-off-by: Claudiu Lataretu --- .../services/analytics.compute.service.ts | 23 +++++++------ .../analytics/specs/analytics.service.spec.ts | 2 ++ src/modules/farm/base-module/farm.resolver.ts | 1 - .../base-module/services/farm.abi.service.ts | 28 ++++++++++++++++ .../farm/base-module/services/interfaces.ts | 1 + src/modules/farm/farm.abi.factory.ts | 12 +++++-- src/modules/farm/farm.factory.ts | 32 +++++++++++++++++-- src/modules/farm/farm.module.ts | 1 - .../farm/mocks/farm.abi.service.mock.ts | 4 +++ src/modules/farm/specs/farm.service.spec.ts | 2 +- src/modules/rabbitmq/rabbitmq.consumer.ts | 6 ++-- .../user/services/user.metaEsdt.service.ts | 11 ++++--- .../crons/farm.cache.warmer.service.ts | 21 ++++++++---- 13 files changed, 111 insertions(+), 33 deletions(-) diff --git a/src/modules/analytics/services/analytics.compute.service.ts b/src/modules/analytics/services/analytics.compute.service.ts index 69609147a..6fd6716fa 100644 --- a/src/modules/analytics/services/analytics.compute.service.ts +++ b/src/modules/analytics/services/analytics.compute.service.ts @@ -5,7 +5,7 @@ import { FarmRewardType, FarmVersion, } from 'src/modules/farm/models/farm.model'; -import { farmsAddresses, farmType, farmVersion } from 'src/utils/farm.utils'; +import { farmType, farmVersion } from 'src/utils/farm.utils'; import { FarmComputeFactory } from 'src/modules/farm/farm.compute.factory'; import { AnalyticsQueryService } from 'src/services/analytics/services/analytics.query.service'; import { RemoteConfigGetterService } from '../../remote-config/remote-config.getter.service'; @@ -21,6 +21,7 @@ import { FarmAbiFactory } from 'src/modules/farm/farm.abi.factory'; import { TokenComputeService } from 'src/modules/tokens/services/token.compute.service'; import { TokenService } from 'src/modules/tokens/services/token.service'; import { ErrorLoggerAsync } from '@multiversx/sdk-nestjs-common'; +import { FarmFactoryService } from 'src/modules/farm/farm.factory'; @Injectable() export class AnalyticsComputeService { @@ -28,6 +29,7 @@ export class AnalyticsComputeService { private readonly routerAbi: RouterAbiService, private readonly farmAbi: FarmAbiFactory, private readonly farmCompute: FarmComputeFactory, + private readonly farmFactory: FarmFactoryService, private readonly pairAbi: PairAbiService, private readonly pairCompute: PairComputeService, private readonly stakingCompute: StakingComputeService, @@ -51,9 +53,9 @@ export class AnalyticsComputeService { async computeLockedValueUSDFarms(): Promise { let totalLockedValue = new BigNumber(0); - + const farmsAddresses = await this.farmFactory.getFarmsAddresses(); const promises: Promise[] = []; - for (const farmAddress of farmsAddresses()) { + for (const farmAddress of farmsAddresses) { promises.push( this.farmCompute .useCompute(farmAddress) @@ -124,19 +126,20 @@ export class AnalyticsComputeService { ); promises.push(this.computeTotalLockedMexStakedUSD()); + const farmsAddresses = await this.farmFactory.getFarmsAddresses(); - if (farmsAddresses()[5] !== undefined) { + if (farmsAddresses[5] !== undefined) { promises.push( this.farmCompute - .useCompute(farmsAddresses()[5]) - .computeFarmLockedValueUSD(farmsAddresses()[5]), + .useCompute(farmsAddresses[5]) + .computeFarmLockedValueUSD(farmsAddresses[5]), ); } - if (farmsAddresses()[13] !== undefined) { + if (farmsAddresses[13] !== undefined) { promises.push( this.farmCompute - .useCompute(farmsAddresses()[13]) - .computeFarmLockedValueUSD(farmsAddresses()[13]), + .useCompute(farmsAddresses[13]) + .computeFarmLockedValueUSD(farmsAddresses[13]), ); } @@ -163,7 +166,7 @@ export class AnalyticsComputeService { } async computeTotalAggregatedRewards(days: number): Promise { - const addresses: string[] = farmsAddresses(); + const addresses: string[] = await this.farmFactory.getFarmsAddresses(); const promises = addresses.map(async (farmAddress) => { if ( farmType(farmAddress) === FarmRewardType.CUSTOM_REWARDS || diff --git a/src/modules/analytics/specs/analytics.service.spec.ts b/src/modules/analytics/specs/analytics.service.spec.ts index 94274ded5..71f9e1115 100644 --- a/src/modules/analytics/specs/analytics.service.spec.ts +++ b/src/modules/analytics/specs/analytics.service.spec.ts @@ -45,6 +45,7 @@ import { WinstonModule } from 'nest-winston'; import { ApiConfigService } from 'src/helpers/api.config.service'; import winston from 'winston'; import { DynamicModuleUtils } from 'src/utils/dynamic.module.utils'; +import { FarmFactoryService } from 'src/modules/farm/farm.factory'; describe('AnalyticsService', () => { let module: TestingModule; @@ -74,6 +75,7 @@ describe('AnalyticsService', () => { FarmComputeServiceV1_2, FarmComputeServiceV1_3, FarmComputeServiceV2, + FarmFactoryService, FarmServiceV1_2, FarmServiceV1_3, FarmServiceV2, diff --git a/src/modules/farm/base-module/farm.resolver.ts b/src/modules/farm/base-module/farm.resolver.ts index 25a75b12d..fae636ea4 100644 --- a/src/modules/farm/base-module/farm.resolver.ts +++ b/src/modules/farm/base-module/farm.resolver.ts @@ -1,7 +1,6 @@ import { Resolver, ResolveField, Parent } from '@nestjs/graphql'; import { BaseFarmModel } from '../models/farm.model'; import { PairModel } from '../../pair/models/pair.model'; -import { LockedAssetModel } from '../../locked-asset-factory/models/locked-asset.model'; import { EsdtToken } from '../../tokens/models/esdtToken.model'; import { NftCollection } from '../../tokens/models/nftCollection.model'; import { Address } from '@multiversx/sdk-core'; diff --git a/src/modules/farm/base-module/services/farm.abi.service.ts b/src/modules/farm/base-module/services/farm.abi.service.ts index 9e87c3a6c..394b719dc 100644 --- a/src/modules/farm/base-module/services/farm.abi.service.ts +++ b/src/modules/farm/base-module/services/farm.abi.service.ts @@ -420,4 +420,32 @@ export class FarmAbiService async getFarmShardRaw(farmAddress: string): Promise { return (await this.apiService.getAccountStats(farmAddress)).shard; } + + @ErrorLoggerAsync({ + logArgs: true, + }) + @GetOrSetCache({ + baseKey: 'farm', + remoteTtl: CacheTtlInfo.ContractInfo.remoteTtl, + localTtl: CacheTtlInfo.ContractInfo.localTtl, + }) + async farmDeployedTimestamp(farmAddress: string): Promise { + return await this.getFarmDeployedTimestampRaw(farmAddress); + } + + async getFarmDeployedTimestampRaw( + farmAddress: string, + ): Promise { + try { + const addressDetails = await this.apiService.getAccountStats( + farmAddress, + ); + return addressDetails.deployedAt ?? undefined; + } catch (error) { + if (error.message.includes('Account not found')) { + return undefined; + } + throw error; + } + } } diff --git a/src/modules/farm/base-module/services/interfaces.ts b/src/modules/farm/base-module/services/interfaces.ts index fd6a344db..33ca123d0 100644 --- a/src/modules/farm/base-module/services/interfaces.ts +++ b/src/modules/farm/base-module/services/interfaces.ts @@ -24,6 +24,7 @@ export interface IFarmAbiService { lastErrorMessage(farmAddress: string): Promise; ownerAddress(farmAddress: string): Promise; farmShard(farmAddress: string): Promise; + farmDeployedTimestamp(farmAddress: string): Promise; } export interface IFarmComputeService { diff --git a/src/modules/farm/farm.abi.factory.ts b/src/modules/farm/farm.abi.factory.ts index 5b28c8504..37fe1d7f5 100644 --- a/src/modules/farm/farm.abi.factory.ts +++ b/src/modules/farm/farm.abi.factory.ts @@ -1,5 +1,5 @@ import { Injectable } from '@nestjs/common'; -import { farmVersion, farmsAddresses } from 'src/utils/farm.utils'; +import { farmVersion } from 'src/utils/farm.utils'; import { FarmAbiService } from './base-module/services/farm.abi.service'; import { FarmVersion } from './models/farm.model'; import { FarmAbiServiceV1_2 } from './v1.2/services/farm.v1.2.abi.service'; @@ -7,6 +7,7 @@ import { FarmAbiServiceV1_3 } from './v1.3/services/farm.v1.3.abi.service'; import { FarmAbiServiceV2 } from './v2/services/farm.v2.abi.service'; import { CacheService } from '@multiversx/sdk-nestjs-cache'; import { Constants } from '@multiversx/sdk-nestjs-common'; +import { FarmFactoryService } from './farm.factory'; @Injectable() export class FarmAbiFactory { @@ -14,6 +15,7 @@ export class FarmAbiFactory { private readonly abiServiceV1_2: FarmAbiServiceV1_2, private readonly abiServiceV1_3: FarmAbiServiceV1_3, private readonly abiServiceV2: FarmAbiServiceV2, + private readonly farmFactory: FarmFactoryService, private readonly cachingService: CacheService, ) {} @@ -29,7 +31,8 @@ export class FarmAbiFactory { } async isFarmToken(tokenID: string): Promise { - for (const farmAddress of farmsAddresses()) { + const farmsAddresses = await this.farmFactory.getFarmsAddresses(); + for (const farmAddress of farmsAddresses) { const farmTokenID = await this.useAbi(farmAddress).farmTokenID( farmAddress, ); @@ -49,7 +52,10 @@ export class FarmAbiFactory { if (cachedValue && cachedValue !== undefined) { return cachedValue; } - for (const farmAddress of farmsAddresses()) { + + const farmsAddresses = await this.farmFactory.getFarmsAddresses(); + + for (const farmAddress of farmsAddresses) { const farmTokenID = await this.useAbi(farmAddress).farmTokenID( farmAddress, ); diff --git a/src/modules/farm/farm.factory.ts b/src/modules/farm/farm.factory.ts index 68768c6eb..0ae138584 100644 --- a/src/modules/farm/farm.factory.ts +++ b/src/modules/farm/farm.factory.ts @@ -1,6 +1,6 @@ import { Injectable } from '@nestjs/common'; import { FarmVersion } from './models/farm.model'; -import { farmsAddresses, farmType, farmVersion } from 'src/utils/farm.utils'; +import { farmType, farmVersion, farmsAddresses } from 'src/utils/farm.utils'; import { FarmModelV1_2 } from './models/farm.v1.2.model'; import { FarmModelV1_3 } from './models/farm.v1.3.model'; import { FarmCustomModel } from './models/farm.custom.model'; @@ -10,6 +10,8 @@ import { FarmServiceV1_3 } from './v1.3/services/farm.v1.3.service'; import { FarmServiceV2 } from './v2/services/farm.v2.service'; import { FarmServiceBase } from './base-module/services/farm.base.service'; import { FarmModelV2 } from './models/farm.v2.model'; +import { ContextTracker } from '@multiversx/sdk-nestjs-common'; +import { FarmAbiServiceV1_2 } from './v1.2/services/farm.v1.2.abi.service'; @Injectable() export class FarmFactoryService { @@ -17,11 +19,35 @@ export class FarmFactoryService { private readonly farmServiceV1_2: FarmServiceV1_2, private readonly farmServiceV1_3: FarmServiceV1_3, private readonly farmServiceV2: FarmServiceV2, + private readonly farmAbi: FarmAbiServiceV1_2, ) {} - getFarms(): Array { + async getFarmsAddresses(versions?: string[]): Promise { + let addresses = farmsAddresses(versions); + + const context = ContextTracker.get(); + if (context && context.deepHistoryTimestamp) { + const farmsDeployedTimestamps = await Promise.all( + addresses.map((address) => + this.farmAbi.farmDeployedTimestamp(address), + ), + ); + addresses = addresses.filter((_, index) => { + return ( + farmsDeployedTimestamps[index] !== undefined && + farmsDeployedTimestamps[index] <= + context.deepHistoryTimestamp + ); + }); + } + + return addresses; + } + + async getFarms(): Promise> { const farms: Array = []; - for (const address of farmsAddresses()) { + const farmsAddresses = await this.getFarmsAddresses(); + for (const address of farmsAddresses) { const version = farmVersion(address); switch (version) { case FarmVersion.V1_2: diff --git a/src/modules/farm/farm.module.ts b/src/modules/farm/farm.module.ts index 6d23b30ef..348d34fc1 100644 --- a/src/modules/farm/farm.module.ts +++ b/src/modules/farm/farm.module.ts @@ -23,7 +23,6 @@ import { FarmSetterFactory } from './farm.setter.factory'; ContextModule, PairModule, TokenModule, - FarmCustomModule, FarmModuleV1_2, FarmModuleV1_3, FarmModuleV2, diff --git a/src/modules/farm/mocks/farm.abi.service.mock.ts b/src/modules/farm/mocks/farm.abi.service.mock.ts index c8f48a137..41773aab2 100644 --- a/src/modules/farm/mocks/farm.abi.service.mock.ts +++ b/src/modules/farm/mocks/farm.abi.service.mock.ts @@ -80,6 +80,10 @@ export class FarmAbiServiceMock implements IFarmAbiService { async farmShard(farmAddress: string): Promise { return 1; } + + async farmDeployedTimestamp(farmAddress: string): Promise { + return 1636895880; + } } export const FarmAbiServiceProvider = { diff --git a/src/modules/farm/specs/farm.service.spec.ts b/src/modules/farm/specs/farm.service.spec.ts index d3f01b329..6e24ce265 100644 --- a/src/modules/farm/specs/farm.service.spec.ts +++ b/src/modules/farm/specs/farm.service.spec.ts @@ -135,7 +135,7 @@ describe('FarmService', () => { it('should get farms', async () => { const factory = module.get(FarmFactoryService); - const farms = factory.getFarms(); + const farms = await factory.getFarms(); expect(farms).toEqual([ { address: diff --git a/src/modules/rabbitmq/rabbitmq.consumer.ts b/src/modules/rabbitmq/rabbitmq.consumer.ts index 49976d624..f1a8af6e3 100644 --- a/src/modules/rabbitmq/rabbitmq.consumer.ts +++ b/src/modules/rabbitmq/rabbitmq.consumer.ts @@ -6,7 +6,6 @@ import { RabbitMQProxyHandlerService } from './rabbitmq.proxy.handler.service'; import { CompetingRabbitConsumer } from './rabbitmq.consumers'; import { scAddress } from 'src/config'; import { RabbitMQEsdtTokenHandlerService } from './rabbitmq.esdtToken.handler.service'; -import { farmsAddresses } from 'src/utils/farm.utils'; import { RouterHandlerService } from './handlers/router.handler.service'; import { RabbitMQMetabondingHandlerService } from './rabbitmq.metabonding.handler.service'; import { PriceDiscoveryEventHandler } from './handlers/price.discovery.handler.service'; @@ -64,6 +63,7 @@ import { RouterAbiService } from '../router/services/router.abi.service'; import { EscrowHandlerService } from './handlers/escrow.handler.service'; import { governanceContractsAddresses } from '../../utils/governance'; import { GovernanceHandlerService } from './handlers/governance.handler.service'; +import { FarmFactoryService } from '../farm/farm.factory'; @Injectable() export class RabbitMqConsumer { @@ -72,6 +72,7 @@ export class RabbitMqConsumer { constructor( private readonly routerAbi: RouterAbiService, + private readonly farmFactory: FarmFactoryService, private readonly liquidityHandler: LiquidityHandler, private readonly swapHandler: SwapEventHandler, private readonly wsFarmHandler: FarmHandlerService, @@ -326,7 +327,8 @@ export class RabbitMqConsumer { async getFilterAddresses(): Promise { this.filterAddresses = []; this.filterAddresses = await this.routerAbi.getAllPairsAddressRaw(); - this.filterAddresses.push(...farmsAddresses()); + const farmsAddresses = await this.farmFactory.getFarmsAddresses(); + this.filterAddresses.push(...farmsAddresses); this.filterAddresses.push(scAddress.routerAddress); this.filterAddresses.push(scAddress.metabondingStakingAddress); this.filterAddresses.push(...scAddress.priceDiscovery); diff --git a/src/modules/user/services/user.metaEsdt.service.ts b/src/modules/user/services/user.metaEsdt.service.ts index 776bdceb0..7e674e409 100644 --- a/src/modules/user/services/user.metaEsdt.service.ts +++ b/src/modules/user/services/user.metaEsdt.service.ts @@ -1,6 +1,5 @@ import { Inject, Injectable, Logger } from '@nestjs/common'; import { NftToken } from 'src/modules/tokens/models/nftToken.model'; -import { MXApiService } from '../../../services/multiversx-communication/mx.api.service'; import { UserNftTokens } from '../models/nfttokens.union'; import { UserMetaEsdtComputeService } from './metaEsdt.compute.service'; import { LockedAssetToken } from 'src/modules/tokens/models/lockedAssetToken.model'; @@ -16,7 +15,6 @@ import { Constants } from '@multiversx/sdk-nestjs-common'; import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston'; import { PaginationArgs } from '../../dex.model'; import { LockedAssetGetterService } from '../../locked-asset-factory/services/locked.asset.getter.service'; -import { farmsAddresses } from 'src/utils/farm.utils'; import { StakeFarmToken } from 'src/modules/tokens/models/stakeFarmToken.model'; import { DualYieldToken } from 'src/modules/tokens/models/dualYieldToken.model'; import { PriceDiscoveryService } from '../../price-discovery/services/price.discovery.service'; @@ -53,6 +51,7 @@ import { FarmAbiFactory } from 'src/modules/farm/farm.abi.factory'; import { GetOrSetCache } from 'src/helpers/decorators/caching.decorator'; import { ErrorLoggerAsync } from '@multiversx/sdk-nestjs-common'; import { ContextGetterService } from 'src/services/context/context.getter.service'; +import { FarmFactoryService } from 'src/modules/farm/farm.factory'; enum NftTokenType { FarmToken, LockedAssetToken, @@ -74,10 +73,10 @@ enum NftTokenType { export class UserMetaEsdtService { constructor( private readonly userComputeService: UserMetaEsdtComputeService, - private readonly apiService: MXApiService, private readonly proxyPairAbi: ProxyPairAbiService, private readonly proxyFarmAbi: ProxyFarmAbiService, private readonly farmAbi: FarmAbiFactory, + private readonly farmFactory: FarmFactoryService, private readonly lockedAssetGetter: LockedAssetGetterService, private readonly stakingAbi: StakingAbiService, private readonly proxyStakeAbi: StakingProxyAbiService, @@ -118,8 +117,9 @@ export class UserMetaEsdtService { pagination: PaginationArgs, calculateUSD = true, ): Promise { + const farmsAddresses = await this.farmFactory.getFarmsAddresses(); const farmTokenIDs = await Promise.all( - farmsAddresses().map((address) => + farmsAddresses.map((address) => this.farmAbi.useAbi(address).farmTokenID(address), ), ); @@ -677,7 +677,8 @@ export class UserMetaEsdtService { } let promises: Promise[] = []; - for (const farmAddress of farmsAddresses()) { + const farmsAddresses = await this.farmFactory.getFarmsAddresses(); + for (const farmAddress of farmsAddresses) { promises.push( this.farmAbi.useAbi(farmAddress).farmTokenID(farmAddress), ); diff --git a/src/services/crons/farm.cache.warmer.service.ts b/src/services/crons/farm.cache.warmer.service.ts index 1cd5b02c9..42ec7579a 100644 --- a/src/services/crons/farm.cache.warmer.service.ts +++ b/src/services/crons/farm.cache.warmer.service.ts @@ -2,7 +2,7 @@ import { Inject, Injectable } from '@nestjs/common'; import { Cron, CronExpression } from '@nestjs/schedule'; import { RedisPubSub } from 'graphql-redis-subscriptions'; import { PUB_SUB } from '../redis.pubSub.module'; -import { farmsAddresses, farmVersion } from 'src/utils/farm.utils'; +import { farmVersion } from 'src/utils/farm.utils'; import { FarmVersion } from 'src/modules/farm/models/farm.model'; import { FarmComputeServiceV1_2 } from 'src/modules/farm/v1.2/services/farm.v1.2.compute.service'; import { FarmComputeServiceV1_3 } from 'src/modules/farm/v1.3/services/farm.v1.3.compute.service'; @@ -10,6 +10,7 @@ import { FarmAbiFactory } from 'src/modules/farm/farm.abi.factory'; import { FarmAbiServiceV1_2 } from 'src/modules/farm/v1.2/services/farm.v1.2.abi.service'; import { FarmComputeFactory } from 'src/modules/farm/farm.compute.factory'; import { FarmSetterFactory } from 'src/modules/farm/farm.setter.factory'; +import { FarmFactoryService } from 'src/modules/farm/farm.factory'; @Injectable() export class FarmCacheWarmerService { @@ -18,6 +19,7 @@ export class FarmCacheWarmerService { constructor( private readonly farmAbiFactory: FarmAbiFactory, private readonly farmAbiV1_2: FarmAbiServiceV1_2, + private readonly farmFactory: FarmFactoryService, private readonly farmComputeFactory: FarmComputeFactory, private readonly farmComputeV1_2: FarmComputeServiceV1_2, private readonly farmComputeV1_3: FarmComputeServiceV1_3, @@ -27,7 +29,7 @@ export class FarmCacheWarmerService { @Cron(CronExpression.EVERY_HOUR) async cacheFarmsTokens(): Promise { - const farmsAddress: string[] = farmsAddresses(); + const farmsAddress = await this.farmFactory.getFarmsAddresses(); const promises = farmsAddress.map(async (farmAddress) => { const [farmTokenID, farmingTokenID, farmedTokenID] = await Promise.all([ @@ -62,7 +64,8 @@ export class FarmCacheWarmerService { @Cron(CronExpression.EVERY_30_SECONDS) async cacheFarmsV1_2(): Promise { - for (const address of farmsAddresses()) { + const farmsAddresses = await this.farmFactory.getFarmsAddresses(); + for (const address of farmsAddresses) { if (farmVersion(address) !== FarmVersion.V1_2) { continue; } @@ -99,7 +102,8 @@ export class FarmCacheWarmerService { @Cron(CronExpression.EVERY_30_SECONDS) async cacheFarmsV1_3(): Promise { - for (const address of farmsAddresses()) { + const farmsAddresses = await this.farmFactory.getFarmsAddresses(); + for (const address of farmsAddresses) { if (farmVersion(address) !== FarmVersion.V1_3) { continue; } @@ -119,7 +123,8 @@ export class FarmCacheWarmerService { @Cron(CronExpression.EVERY_MINUTE) async cacheFarmInfo(): Promise { - for (const farmAddress of farmsAddresses()) { + const farmsAddresses = await this.farmFactory.getFarmsAddresses(); + for (const farmAddress of farmsAddresses) { const [ minimumFarmingEpochs, penaltyPercent, @@ -171,7 +176,8 @@ export class FarmCacheWarmerService { @Cron(CronExpression.EVERY_30_SECONDS) async cacheFarmReserves(): Promise { - for (const farmAddress of farmsAddresses()) { + const farmsAddresses = await this.farmFactory.getFarmsAddresses(); + for (const farmAddress of farmsAddresses) { const [ farmTokenSupply, lastRewardBlockNonce, @@ -212,7 +218,8 @@ export class FarmCacheWarmerService { @Cron(CronExpression.EVERY_30_SECONDS) async cacheFarmTokensPrices(): Promise { - for (const farmAddress of farmsAddresses()) { + const farmsAddresses = await this.farmFactory.getFarmsAddresses(); + for (const farmAddress of farmsAddresses) { const [ farmedTokenPriceUSD, farmingTokenPriceUSD, From 833e4055adf2b0dd818a3106e5178291f402ef6e Mon Sep 17 00:00:00 2001 From: Claudiu Lataretu Date: Wed, 10 Apr 2024 18:40:13 +0300 Subject: [PATCH 4/6] SERVICES-2155: use cache decorator for remote config service Signed-off-by: Claudiu Lataretu --- .../remote-config.getter.service.ts | 51 +++++++++---------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/src/modules/remote-config/remote-config.getter.service.ts b/src/modules/remote-config/remote-config.getter.service.ts index ff27d0be4..945116b8c 100644 --- a/src/modules/remote-config/remote-config.getter.service.ts +++ b/src/modules/remote-config/remote-config.getter.service.ts @@ -8,6 +8,7 @@ import { GenericGetterService } from 'src/services/generics/generic.getter.servi import { SCAddressType } from './models/sc-address.model'; import { Constants } from '@multiversx/sdk-nestjs-common'; import { AnalyticsRepositoryService } from 'src/services/database/repositories/analytics.repository'; +import { GetOrSetCache } from 'src/helpers/decorators/caching.decorator'; @Injectable() export class RemoteConfigGetterService extends GenericGetterService { @@ -73,37 +74,31 @@ export class RemoteConfigGetterService extends GenericGetterService { ); } + @GetOrSetCache({ + baseKey: 'scAddress', + remoteTtl: Constants.oneHour(), + }) async getStakingAddresses(): Promise { - this.baseKey = 'scAddress'; - const cacheKey = this.getCacheKey(SCAddressType.STAKING); - return await this.getData( - cacheKey, - () => - this.scAddressRepositoryService - .find({ - category: SCAddressType.STAKING, - }) - .then((res) => { - return res.map((scAddress) => scAddress.address); - }), - Constants.oneHour(), - ); + return this.scAddressRepositoryService + .find({ + category: SCAddressType.STAKING, + }) + .then((res) => { + return res.map((scAddress) => scAddress.address); + }); } + @GetOrSetCache({ + baseKey: 'scAddress', + remoteTtl: Constants.oneHour(), + }) async getStakingProxyAddresses(): Promise { - this.baseKey = 'scAddress'; - const cacheKey = this.getCacheKey(SCAddressType.STAKING_PROXY); - return await this.getData( - cacheKey, - () => - this.scAddressRepositoryService - .find({ - category: SCAddressType.STAKING_PROXY, - }) - .then((res) => { - return res.map((scAddress) => scAddress.address); - }), - Constants.oneHour(), - ); + return this.scAddressRepositoryService + .find({ + category: SCAddressType.STAKING_PROXY, + }) + .then((res) => { + return res.map((scAddress) => scAddress.address); + }); } } From 3c66cde3895e0d27c9382fba8f3d6c41c17d88ee Mon Sep 17 00:00:00 2001 From: Claudiu Lataretu Date: Wed, 10 Apr 2024 18:44:45 +0300 Subject: [PATCH 5/6] SERVICES-2155: add methods to get the staking and staking proxy addresses filtered by timestamp Signed-off-by: Claudiu Lataretu --- .../services/analytics.compute.service.ts | 6 +-- .../services/staking.proxy.abi.service.ts | 38 ++++++++++++++++++- .../services/staking.proxy.service.ts | 29 ++++++++++++-- .../staking/services/staking.abi.service.ts | 30 +++++++++++++++ .../staking/services/staking.service.ts | 25 +++++++++++- .../user/services/user.metaEsdt.service.ts | 17 +++++---- .../crons/staking.cache.warmer.service.ts | 10 ++--- .../staking.proxy.cache.warmer.service.ts | 6 +-- 8 files changed, 135 insertions(+), 26 deletions(-) diff --git a/src/modules/analytics/services/analytics.compute.service.ts b/src/modules/analytics/services/analytics.compute.service.ts index 6fd6716fa..eae69caae 100644 --- a/src/modules/analytics/services/analytics.compute.service.ts +++ b/src/modules/analytics/services/analytics.compute.service.ts @@ -8,7 +8,6 @@ import { import { farmType, farmVersion } from 'src/utils/farm.utils'; import { FarmComputeFactory } from 'src/modules/farm/farm.compute.factory'; import { AnalyticsQueryService } from 'src/services/analytics/services/analytics.query.service'; -import { RemoteConfigGetterService } from '../../remote-config/remote-config.getter.service'; import { WeekTimekeepingAbiService } from 'src/submodules/week-timekeeping/services/week-timekeeping.abi.service'; import { WeeklyRewardsSplittingAbiService } from 'src/submodules/weekly-rewards-splitting/services/weekly-rewards-splitting.abi.service'; import { PairAbiService } from 'src/modules/pair/services/pair.abi.service'; @@ -22,6 +21,7 @@ import { TokenComputeService } from 'src/modules/tokens/services/token.compute.s import { TokenService } from 'src/modules/tokens/services/token.service'; import { ErrorLoggerAsync } from '@multiversx/sdk-nestjs-common'; import { FarmFactoryService } from 'src/modules/farm/farm.factory'; +import { StakingService } from 'src/modules/staking/services/staking.service'; @Injectable() export class AnalyticsComputeService { @@ -32,12 +32,12 @@ export class AnalyticsComputeService { private readonly farmFactory: FarmFactoryService, private readonly pairAbi: PairAbiService, private readonly pairCompute: PairComputeService, + private readonly stakingService: StakingService, private readonly stakingCompute: StakingComputeService, private readonly tokenCompute: TokenComputeService, private readonly tokenService: TokenService, private readonly weekTimekeepingAbi: WeekTimekeepingAbiService, private readonly weeklyRewardsSplittingAbi: WeeklyRewardsSplittingAbiService, - private readonly remoteConfigGetterService: RemoteConfigGetterService, private readonly analyticsQuery: AnalyticsQueryService, ) {} @@ -120,7 +120,7 @@ export class AnalyticsComputeService { let totalValueLockedUSD = new BigNumber(0); const stakingAddresses = - await this.remoteConfigGetterService.getStakingAddresses(); + await this.stakingService.getStakingAddresses(); const promises = stakingAddresses.map((stakingAddress) => this.stakingCompute.stakedValueUSD(stakingAddress), ); diff --git a/src/modules/staking-proxy/services/staking.proxy.abi.service.ts b/src/modules/staking-proxy/services/staking.proxy.abi.service.ts index 4b7cbb989..b32e81c0c 100644 --- a/src/modules/staking-proxy/services/staking.proxy.abi.service.ts +++ b/src/modules/staking-proxy/services/staking.proxy.abi.service.ts @@ -7,13 +7,17 @@ import { GetOrSetCache } from 'src/helpers/decorators/caching.decorator'; import { CacheTtlInfo } from 'src/services/caching/cache.ttl.info'; import { Constants } from '@multiversx/sdk-nestjs-common'; import { IStakingProxyAbiService } from './interfaces'; +import { MXApiService } from 'src/services/multiversx-communication/mx.api.service'; @Injectable() export class StakingProxyAbiService extends GenericAbiService implements IStakingProxyAbiService { - constructor(protected readonly mxProxy: MXProxyService) { + constructor( + protected readonly mxProxy: MXProxyService, + private readonly apiService: MXApiService, + ) { super(mxProxy); } @@ -168,4 +172,36 @@ export class StakingProxyAbiService const response = await this.getGenericData(interaction); return response.firstValue.valueOf().toString(); } + + @ErrorLoggerAsync({ + logArgs: true, + }) + @GetOrSetCache({ + baseKey: 'stakeProxy', + remoteTtl: CacheTtlInfo.ContractInfo.remoteTtl, + localTtl: CacheTtlInfo.ContractInfo.localTtl, + }) + async stakingProxyDeployedTimestamp( + stakingProxyAddress: string, + ): Promise { + return await this.getStakingProxyDeployedTimestampRaw( + stakingProxyAddress, + ); + } + + async getStakingProxyDeployedTimestampRaw( + stakingProxyAddress: string, + ): Promise { + try { + const addressDetails = await this.apiService.getAccountStats( + stakingProxyAddress, + ); + return addressDetails.deployedAt ?? undefined; + } catch (error) { + if (error.message.includes('Account not found')) { + return undefined; + } + throw error; + } + } } diff --git a/src/modules/staking-proxy/services/staking.proxy.service.ts b/src/modules/staking-proxy/services/staking.proxy.service.ts index 521490664..010009380 100644 --- a/src/modules/staking-proxy/services/staking.proxy.service.ts +++ b/src/modules/staking-proxy/services/staking.proxy.service.ts @@ -3,7 +3,7 @@ import { Inject, Injectable } from '@nestjs/common'; import BigNumber from 'bignumber.js'; import { WINSTON_MODULE_PROVIDER } from 'nest-winston'; import { ruleOfThree } from 'src/helpers/helpers'; -import { Constants } from '@multiversx/sdk-nestjs-common'; +import { Constants, ContextTracker } from '@multiversx/sdk-nestjs-common'; import { CalculateRewardsArgs } from 'src/modules/farm/models/farm.args'; import { PairService } from 'src/modules/pair/services/pair.service'; import { DecodeAttributesArgs } from 'src/modules/proxy/models/proxy.args'; @@ -39,10 +39,31 @@ export class StakingProxyService { @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger, ) {} - async getStakingProxies(): Promise { - const stakingProxiesAddress: string[] = + async getStakingProxyAddresses(): Promise { + let stakingProxiesAddress: string[] = await this.remoteConfigGetterService.getStakingProxyAddresses(); + const context = ContextTracker.get(); + if (context && context.deepHistoryTimestamp) { + const timestamps = await Promise.all( + stakingProxiesAddress.map((address) => + this.stakingProxyAbi.stakingProxyDeployedTimestamp(address), + ), + ); + stakingProxiesAddress = stakingProxiesAddress.filter((_, index) => { + return ( + timestamps[index] !== undefined && + timestamps[index] <= context.deepHistoryTimestamp + ); + }); + } + + return stakingProxiesAddress; + } + + async getStakingProxies(): Promise { + const stakingProxiesAddress = await this.getStakingProxyAddresses(); + const stakingProxies: StakingProxyModel[] = []; for (const address of stakingProxiesAddress) { stakingProxies.push( @@ -229,7 +250,7 @@ export class StakingProxyService { return cachedValue; } const stakingProxiesAddress: string[] = - await this.remoteConfigGetterService.getStakingProxyAddresses(); + await this.getStakingProxyAddresses(); for (const address of stakingProxiesAddress) { const dualYieldTokenID = diff --git a/src/modules/staking/services/staking.abi.service.ts b/src/modules/staking/services/staking.abi.service.ts index aa03d7f3f..ebdf9ace8 100644 --- a/src/modules/staking/services/staking.abi.service.ts +++ b/src/modules/staking/services/staking.abi.service.ts @@ -16,6 +16,7 @@ import { GetOrSetCache } from 'src/helpers/decorators/caching.decorator'; import { Constants } from '@multiversx/sdk-nestjs-common'; import { CacheTtlInfo } from 'src/services/caching/cache.ttl.info'; import { IStakingAbiService } from './interfaces'; +import { MXApiService } from 'src/services/multiversx-communication/mx.api.service'; @Injectable() export class StakingAbiService @@ -25,6 +26,7 @@ export class StakingAbiService constructor( protected readonly mxProxy: MXProxyService, private readonly gatewayService: MXGatewayService, + private readonly apiService: MXApiService, ) { super(mxProxy); } @@ -498,4 +500,32 @@ export class StakingAbiService const response = await this.getGenericData(interaction); return response.firstValue.valueOf().toString(); } + + @ErrorLoggerAsync({ + logArgs: true, + }) + @GetOrSetCache({ + baseKey: 'stake', + remoteTtl: CacheTtlInfo.ContractInfo.remoteTtl, + localTtl: CacheTtlInfo.ContractInfo.localTtl, + }) + async stakingDeployedTimestamp(stakingAddress: string): Promise { + return await this.getStakingDeployedTimestampRaw(stakingAddress); + } + + async getStakingDeployedTimestampRaw( + stakingAddress: string, + ): Promise { + try { + const addressDetails = await this.apiService.getAccountStats( + stakingAddress, + ); + return addressDetails.deployedAt ?? undefined; + } catch (error) { + if (error.message.includes('Account not found')) { + return undefined; + } + throw error; + } + } } diff --git a/src/modules/staking/services/staking.service.ts b/src/modules/staking/services/staking.service.ts index 84f3f5875..5d761bbd4 100644 --- a/src/modules/staking/services/staking.service.ts +++ b/src/modules/staking/services/staking.service.ts @@ -19,6 +19,7 @@ import { StakingComputeService } from './staking.compute.service'; import { NftCollection } from 'src/modules/tokens/models/nftCollection.model'; import { EsdtToken } from 'src/modules/tokens/models/esdtToken.model'; import { TokenService } from 'src/modules/tokens/services/token.service'; +import { ContextTracker } from '@multiversx/sdk-nestjs-common'; @Injectable() export class StakingService { @@ -32,10 +33,30 @@ export class StakingService { private readonly remoteConfigGetter: RemoteConfigGetterService, ) {} - async getFarmsStaking(): Promise { - const farmsStakingAddresses = + async getStakingAddresses(): Promise { + let farmsStakingAddresses = await this.remoteConfigGetter.getStakingAddresses(); + const context = ContextTracker.get(); + if (context && context.deepHistoryTimestamp) { + const timestamps = await Promise.all( + farmsStakingAddresses.map((address) => + this.stakingAbi.stakingDeployedTimestamp(address), + ), + ); + farmsStakingAddresses = farmsStakingAddresses.filter((_, index) => { + return ( + timestamps[index] !== undefined && + timestamps[index] <= context.deepHistoryTimestamp + ); + }); + } + + return farmsStakingAddresses; + } + + async getFarmsStaking(): Promise { + const farmsStakingAddresses = await this.getStakingAddresses(); const farmsStaking: StakingModel[] = []; for (const address of farmsStakingAddresses) { farmsStaking.push( diff --git a/src/modules/user/services/user.metaEsdt.service.ts b/src/modules/user/services/user.metaEsdt.service.ts index 7e674e409..5611b4d27 100644 --- a/src/modules/user/services/user.metaEsdt.service.ts +++ b/src/modules/user/services/user.metaEsdt.service.ts @@ -18,7 +18,6 @@ import { LockedAssetGetterService } from '../../locked-asset-factory/services/lo import { StakeFarmToken } from 'src/modules/tokens/models/stakeFarmToken.model'; import { DualYieldToken } from 'src/modules/tokens/models/dualYieldToken.model'; import { PriceDiscoveryService } from '../../price-discovery/services/price.discovery.service'; -import { RemoteConfigGetterService } from '../../remote-config/remote-config.getter.service'; import { INFTToken } from '../../tokens/models/nft.interface'; import { constantsConfig, scAddress } from 'src/config'; import { @@ -52,6 +51,8 @@ import { GetOrSetCache } from 'src/helpers/decorators/caching.decorator'; import { ErrorLoggerAsync } from '@multiversx/sdk-nestjs-common'; import { ContextGetterService } from 'src/services/context/context.getter.service'; import { FarmFactoryService } from 'src/modules/farm/farm.factory'; +import { StakingProxyService } from 'src/modules/staking-proxy/services/staking.proxy.service'; +import { StakingService } from 'src/modules/staking/services/staking.service'; enum NftTokenType { FarmToken, LockedAssetToken, @@ -79,13 +80,14 @@ export class UserMetaEsdtService { private readonly farmFactory: FarmFactoryService, private readonly lockedAssetGetter: LockedAssetGetterService, private readonly stakingAbi: StakingAbiService, + private readonly stakingService: StakingService, private readonly proxyStakeAbi: StakingProxyAbiService, + private readonly stakingProxyService: StakingProxyService, private readonly priceDiscoveryService: PriceDiscoveryService, private readonly priceDiscoveryAbi: PriceDiscoveryAbiService, private readonly simpleLockAbi: SimpleLockAbiService, private readonly energyAbi: EnergyAbiService, private readonly lockedTokenWrapperAbi: LockedTokenWrapperAbiService, - private readonly remoteConfigGetterService: RemoteConfigGetterService, private readonly contextGetter: ContextGetterService, @Inject(WINSTON_MODULE_NEST_PROVIDER) private readonly logger: Logger, ) {} @@ -253,7 +255,7 @@ export class UserMetaEsdtService { pagination: PaginationArgs, ): Promise { const stakingAddresses = - await this.remoteConfigGetterService.getStakingAddresses(); + await this.stakingService.getStakingAddresses(); const stakingTokenIDs = await Promise.all( stakingAddresses.map((address) => this.stakingAbi.farmTokenID(address), @@ -288,7 +290,7 @@ export class UserMetaEsdtService { pagination: PaginationArgs, ): Promise { const stakingAddresses = - await this.remoteConfigGetterService.getStakingAddresses(); + await this.stakingService.getStakingAddresses(); const stakingTokenIDs = await Promise.all( stakingAddresses.map((address) => this.stakingAbi.farmTokenID(address), @@ -323,7 +325,7 @@ export class UserMetaEsdtService { calculateUSD = true, ): Promise { const stakingProxyAddresses = - await this.remoteConfigGetterService.getStakingProxyAddresses(); + await this.stakingProxyService.getStakingProxyAddresses(); const dualYieldTokenIDs = await Promise.all( stakingProxyAddresses.map((address) => this.proxyStakeAbi.dualYieldTokenID(address), @@ -689,8 +691,7 @@ export class UserMetaEsdtService { } promises = []; - const staking = - await this.remoteConfigGetterService.getStakingAddresses(); + const staking = await this.stakingService.getStakingAddresses(); for (const address of staking) { promises.push(this.stakingAbi.farmTokenID(address)); } @@ -705,7 +706,7 @@ export class UserMetaEsdtService { promises = []; const stakingProxy = - await this.remoteConfigGetterService.getStakingProxyAddresses(); + await this.stakingProxyService.getStakingProxyAddresses(); for (const address of stakingProxy) { promises.push(this.proxyStakeAbi.dualYieldTokenID(address)); } diff --git a/src/services/crons/staking.cache.warmer.service.ts b/src/services/crons/staking.cache.warmer.service.ts index 0a74e227a..49b19a975 100644 --- a/src/services/crons/staking.cache.warmer.service.ts +++ b/src/services/crons/staking.cache.warmer.service.ts @@ -1,11 +1,11 @@ import { Inject, Injectable } from '@nestjs/common'; import { Cron, CronExpression } from '@nestjs/schedule'; import { RedisPubSub } from 'graphql-redis-subscriptions'; -import { RemoteConfigGetterService } from 'src/modules/remote-config/remote-config.getter.service'; import { StakingAbiService } from 'src/modules/staking/services/staking.abi.service'; import { StakingComputeService } from 'src/modules/staking/services/staking.compute.service'; import { StakingSetterService } from 'src/modules/staking/services/staking.setter.service'; import { PUB_SUB } from '../redis.pubSub.module'; +import { StakingService } from 'src/modules/staking/services/staking.service'; @Injectable() export class StakingCacheWarmerService { @@ -13,14 +13,14 @@ export class StakingCacheWarmerService { private readonly stakingAbi: StakingAbiService, private readonly stakeSetterService: StakingSetterService, private readonly stakeCompute: StakingComputeService, - private readonly remoteConfigGetterService: RemoteConfigGetterService, + private readonly stakingService: StakingService, @Inject(PUB_SUB) private pubSub: RedisPubSub, ) {} @Cron(CronExpression.EVERY_HOUR) async cacheFarmsStaking(): Promise { const farmsStakingAddresses = - await this.remoteConfigGetterService.getStakingAddresses(); + await this.stakingService.getStakingAddresses(); for (const address of farmsStakingAddresses) { const [farmTokenID, farmingTokenID, rewardTokenID] = await Promise.all([ @@ -48,7 +48,7 @@ export class StakingCacheWarmerService { @Cron(CronExpression.EVERY_MINUTE) async cacheStakingInfo(): Promise { const farmsStakingAddresses = - await this.remoteConfigGetterService.getStakingAddresses(); + await this.stakingService.getStakingAddresses(); for (const address of farmsStakingAddresses) { const [ annualPercentageRewards, @@ -88,7 +88,7 @@ export class StakingCacheWarmerService { @Cron(CronExpression.EVERY_30_SECONDS) async cacheStakingRewards(): Promise { const farmsStakingAddresses = - await this.remoteConfigGetterService.getStakingAddresses(); + await this.stakingService.getStakingAddresses(); for (const address of farmsStakingAddresses) { const [ farmTokenSupply, diff --git a/src/services/crons/staking.proxy.cache.warmer.service.ts b/src/services/crons/staking.proxy.cache.warmer.service.ts index b0efd36be..4134273b8 100644 --- a/src/services/crons/staking.proxy.cache.warmer.service.ts +++ b/src/services/crons/staking.proxy.cache.warmer.service.ts @@ -1,24 +1,24 @@ import { Inject, Injectable } from '@nestjs/common'; import { Cron, CronExpression } from '@nestjs/schedule'; import { RedisPubSub } from 'graphql-redis-subscriptions'; -import { RemoteConfigGetterService } from 'src/modules/remote-config/remote-config.getter.service'; import { StakingProxyAbiService } from 'src/modules/staking-proxy/services/staking.proxy.abi.service'; import { StakingProxySetterService } from 'src/modules/staking-proxy/services/staking.proxy.setter.service'; import { PUB_SUB } from '../redis.pubSub.module'; +import { StakingProxyService } from 'src/modules/staking-proxy/services/staking.proxy.service'; @Injectable() export class StakingProxyCacheWarmerService { constructor( private readonly abiService: StakingProxyAbiService, private readonly stakingProxySetter: StakingProxySetterService, - private readonly remoteConfigGetterService: RemoteConfigGetterService, + private readonly stakingProxyService: StakingProxyService, @Inject(PUB_SUB) private pubSub: RedisPubSub, ) {} @Cron(CronExpression.EVERY_HOUR) async cacheFarmsStaking(): Promise { const stakingProxiesAddress: string[] = - await this.remoteConfigGetterService.getStakingProxyAddresses(); + await this.stakingProxyService.getStakingProxyAddresses(); for (const address of stakingProxiesAddress) { const [ lpFarmAddress, From 37735b908b8bb39a5a093519cc2f9bd2b30beeb1 Mon Sep 17 00:00:00 2001 From: Claudiu Lataretu Date: Thu, 18 Apr 2024 11:02:04 +0300 Subject: [PATCH 6/6] SERVICES-2155: enable datadog tracing Signed-off-by: Claudiu Lataretu --- package-lock.json | 593 ++++++++++++++++++++++++++++++++++++++++++++-- package.json | 1 + src/main.ts | 1 + 3 files changed, 581 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index d8172301e..f51e6220e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,6 +48,7 @@ "class-validator": "^0.14.0", "config": "^3.3.7", "cookie-parser": "^1.4.6", + "dd-trace": "^5.10.0", "express": "^4.18.1", "graphql": "^16.5.0", "graphql-redis-subscriptions": "^2.4.2", @@ -1869,6 +1870,118 @@ "kuler": "^2.0.0" } }, + "node_modules/@datadog/native-appsec": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@datadog/native-appsec/-/native-appsec-7.1.1.tgz", + "integrity": "sha512-1XVrCY4g1ArN79SQANMtiIkaxKSPfgdAGv0VAM4Pz+NQuxKfl+2xQPXjQPm87LI1KQIO6MU6qzv3sUUSesb9lA==", + "hasInstallScript": true, + "dependencies": { + "node-gyp-build": "^3.9.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@datadog/native-appsec/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==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/@datadog/native-iast-rewriter": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-rewriter/-/native-iast-rewriter-2.3.0.tgz", + "integrity": "sha512-78ivSaaSXOaHn3VumF9kcSI443nbPfVAWsnDTH9X1ZbqXjHpSlHHTZgK9z/TNbkvuJarS/X1GBioPMcgea1Ejg==", + "dependencies": { + "lru-cache": "^7.14.0", + "node-gyp-build": "^4.5.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@datadog/native-iast-taint-tracking": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-taint-tracking/-/native-iast-taint-tracking-1.7.0.tgz", + "integrity": "sha512-p3qnYJrUr9TQ38tuOFoutDAQWOobLdaaWpTl0SHu126JH3ANBxWL/QirtJy6czfzLpm5eXwYHwHidD1Y0mNPdg==", + "hasInstallScript": true, + "dependencies": { + "node-gyp-build": "^3.9.0" + } + }, + "node_modules/@datadog/native-iast-taint-tracking/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==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/@datadog/native-metrics": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@datadog/native-metrics/-/native-metrics-2.0.0.tgz", + "integrity": "sha512-YklGVwUtmKGYqFf1MNZuOHvTYdKuR4+Af1XkWcMD8BwOAjxmd9Z+97328rCOY8TFUJzlGUPaXzB8j2qgG/BMwA==", + "hasInstallScript": true, + "dependencies": { + "node-addon-api": "^6.1.0", + "node-gyp-build": "^3.9.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@datadog/native-metrics/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/@datadog/native-metrics/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==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/@datadog/pprof": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@datadog/pprof/-/pprof-5.2.0.tgz", + "integrity": "sha512-pSwLARpNLAIV1JttxXOBRKTn/NQYXDy1PJaV458YFDdAYxnBqpsYTat3/nX+8V5GoN4SfdHDci3zqXM+Ym66gQ==", + "hasInstallScript": true, + "dependencies": { + "delay": "^5.0.0", + "node-gyp-build": "<4.0", + "p-limit": "^3.1.0", + "pprof-format": "^2.1.0", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@datadog/pprof/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==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/@datadog/sketches-js": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@datadog/sketches-js/-/sketches-js-2.1.0.tgz", + "integrity": "sha512-smLocSfrt3s53H/XSVP3/1kP42oqvrkjUPtyaFd1F79ux24oE31BKt+q0c6lsa6hOYrFzsIwyc5GXAI5JmfOew==" + }, "node_modules/@datastructures-js/heap": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/@datastructures-js/heap/-/heap-4.3.2.tgz", @@ -4017,6 +4130,28 @@ "node": ">=8.0.0" } }, + "node_modules/@opentelemetry/core": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.23.0.tgz", + "integrity": "sha512-hdQ/a9TMzMQF/BO8Cz1juA43/L5YGtCSiKoOHmrTEf7VMDAZgy8ucpWx3eQTnQ3gBloRcWtzvcrMZABC3PTSKQ==", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.23.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.23.0.tgz", + "integrity": "sha512-MiqFvfOzfR31t8cc74CTP1OZfz7MbqpAnLCra8NqQoaHJX6ncIRTdYOQYBDQ2uFISDq0WY8Y9dDTWvsgzzBYRg==", + "engines": { + "node": ">=14" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -5779,7 +5914,6 @@ "version": "8.10.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "devOptional": true, "bin": { "acorn": "bin/acorn" }, @@ -5791,7 +5925,6 @@ "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==", - "dev": true, "peerDependencies": { "acorn": "^8" } @@ -7694,6 +7827,11 @@ "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" }, + "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==" + }, "node_modules/cssfilter": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz", @@ -7714,6 +7852,98 @@ "url": "https://opencollective.com/date-fns" } }, + "node_modules/dc-polyfill": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/dc-polyfill/-/dc-polyfill-0.1.4.tgz", + "integrity": "sha512-8iwEduR2jR9wWYggeaYtYZWRiUe3XZPyAQtMTL1otv8X3kfR8xUIVb4l5awHEeyDrH6Je7N324lKzMKlMMN6Yw==", + "engines": { + "node": ">=12.17" + } + }, + "node_modules/dd-trace": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.10.0.tgz", + "integrity": "sha512-+JyAf8DKGlCGPxhVhIHcG2+oD5h9/oGFbNj35Jlsl+EEMD/hqOWihgzZ2UzWNCVmOtVGQip3bdRGE4uqkRY+/g==", + "hasInstallScript": true, + "dependencies": { + "@datadog/native-appsec": "7.1.1", + "@datadog/native-iast-rewriter": "2.3.0", + "@datadog/native-iast-taint-tracking": "1.7.0", + "@datadog/native-metrics": "^2.0.0", + "@datadog/pprof": "5.2.0", + "@datadog/sketches-js": "^2.1.0", + "@opentelemetry/api": "^1.0.0", + "@opentelemetry/core": "^1.14.0", + "crypto-randomuuid": "^1.0.0", + "dc-polyfill": "^0.1.4", + "ignore": "^5.2.4", + "import-in-the-middle": "^1.7.3", + "int64-buffer": "^0.1.9", + "ipaddr.js": "^2.1.0", + "istanbul-lib-coverage": "3.2.0", + "jest-docblock": "^29.7.0", + "koalas": "^1.0.2", + "limiter": "1.1.5", + "lodash.sortby": "^4.7.0", + "lru-cache": "^7.14.0", + "methods": "^1.1.2", + "module-details-from-path": "^1.0.3", + "msgpack-lite": "^0.1.26", + "node-abort-controller": "^3.1.1", + "opentracing": ">=0.12.1", + "path-to-regexp": "^0.1.2", + "pprof-format": "^2.1.0", + "protobufjs": "^7.2.5", + "retry": "^0.13.1", + "semver": "^7.5.4", + "shell-quote": "^1.8.1", + "tlhunter-sorted-set": "^0.1.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/dd-trace/node_modules/ipaddr.js": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", + "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/dd-trace/node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + }, + "node_modules/dd-trace/node_modules/path-to-regexp": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.8.tgz", + "integrity": "sha512-EErxvEqTuliG5GCVHNt3K3UmfKhlOM26QtiJZ6XBnZgCd7n+P5aHNV37wFHGJSpbjN4danT+1CpOFT4giETmRQ==" + }, + "node_modules/dd-trace/node_modules/protobufjs": { + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.6.tgz", + "integrity": "sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==", + "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/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -7853,6 +8083,17 @@ "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==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -8662,6 +8903,11 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" }, + "node_modules/event-lite": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/event-lite/-/event-lite-0.1.3.tgz", + "integrity": "sha512-8qz9nOz5VeD2z96elrEKD2U433+L3DWdUdDkOINLGOJvx1GsMBbMn0aCeu28y8/e85A6mCigBiFlYMnTBEGlSw==" + }, "node_modules/eventemitter3": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", @@ -9974,7 +10220,6 @@ "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true, "engines": { "node": ">= 4" } @@ -9995,6 +10240,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-in-the-middle": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.7.3.tgz", + "integrity": "sha512-R2I11NRi0lI3jD2+qjqyVlVEahsejw7LDnYEbGb47QEFjczE3bZYsmWheCTQA+LFs2DzOQxR7Pms7naHW1V4bQ==", + "dependencies": { + "acorn": "^8.8.2", + "acorn-import-assertions": "^1.9.0", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, "node_modules/import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -10069,6 +10325,11 @@ "node": ">=12.0.0" } }, + "node_modules/int64-buffer": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.1.10.tgz", + "integrity": "sha512-v7cSY1J8ydZ0GyjUHqF+1bshJ6cnEVLo9EnjB8p+4HDRPZc9N5jjmvUV7NvEsqQOKyH0pmIBFWXVQbiS0+OBbA==" + }, "node_modules/internal-slot": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", @@ -11421,6 +11682,14 @@ "node": ">=6" } }, + "node_modules/koalas": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/koalas/-/koalas-1.0.2.tgz", + "integrity": "sha512-RYhBbYaTTTHId3l6fnMZc3eGQNW6FVCqMG6AMwA5I1Mafr6AflaXeoi6x3xQuATRotGYRLk6+1ELZH4dstFNOA==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/kuler": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", @@ -11452,6 +11721,11 @@ "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.44.tgz", "integrity": "sha512-svlRdNBI5WgBjRC20GrCfbFiclbF0Cx+sCcQob/C1r57nsoq0xg8r65QbTyVyweQIlB33P+Uahyho6EMYgcOyQ==" }, + "node_modules/limiter": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", + "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -12144,6 +12418,11 @@ "mkdirp": "bin/cmd.js" } }, + "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==" + }, "node_modules/moment": { "version": "2.29.4", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", @@ -12275,6 +12554,25 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, + "node_modules/msgpack-lite": { + "version": "0.1.26", + "resolved": "https://registry.npmjs.org/msgpack-lite/-/msgpack-lite-0.1.26.tgz", + "integrity": "sha512-SZ2IxeqZ1oRFGo0xFGbvBJWMp3yLIY9rlIJyxy8CGrwZn1f0ZK4r6jV/AM1r0FZMDUkWkglOk/eeKIL9g77Nxw==", + "dependencies": { + "event-lite": "^0.1.1", + "ieee754": "^1.1.8", + "int64-buffer": "^0.1.9", + "isarray": "^1.0.0" + }, + "bin": { + "msgpack": "bin/msgpack" + } + }, + "node_modules/msgpack-lite/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/multer": { "version": "1.4.4-lts.1", "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.4-lts.1.tgz", @@ -12844,6 +13142,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/opentracing": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/opentracing/-/opentracing-0.14.7.tgz", + "integrity": "sha512-vz9iS7MJ5+Bp1URw8Khvdyw1H/hGvzHWlKQ7eRrQojSCDL1/SrWfrY9QebLw97n2deyRtzHRC3MkQfVNUCo91Q==", + "engines": { + "node": ">=0.10" + } + }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -13430,6 +13736,11 @@ "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==" + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -14421,7 +14732,6 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -14555,7 +14865,6 @@ "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, "engines": { "node": ">= 8" } @@ -15282,6 +15591,11 @@ "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==" + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -18216,6 +18530,90 @@ "kuler": "^2.0.0" } }, + "@datadog/native-appsec": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@datadog/native-appsec/-/native-appsec-7.1.1.tgz", + "integrity": "sha512-1XVrCY4g1ArN79SQANMtiIkaxKSPfgdAGv0VAM4Pz+NQuxKfl+2xQPXjQPm87LI1KQIO6MU6qzv3sUUSesb9lA==", + "requires": { + "node-gyp-build": "^3.9.0" + }, + "dependencies": { + "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==" + } + } + }, + "@datadog/native-iast-rewriter": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-rewriter/-/native-iast-rewriter-2.3.0.tgz", + "integrity": "sha512-78ivSaaSXOaHn3VumF9kcSI443nbPfVAWsnDTH9X1ZbqXjHpSlHHTZgK9z/TNbkvuJarS/X1GBioPMcgea1Ejg==", + "requires": { + "lru-cache": "^7.14.0", + "node-gyp-build": "^4.5.0" + } + }, + "@datadog/native-iast-taint-tracking": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-taint-tracking/-/native-iast-taint-tracking-1.7.0.tgz", + "integrity": "sha512-p3qnYJrUr9TQ38tuOFoutDAQWOobLdaaWpTl0SHu126JH3ANBxWL/QirtJy6czfzLpm5eXwYHwHidD1Y0mNPdg==", + "requires": { + "node-gyp-build": "^3.9.0" + }, + "dependencies": { + "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==" + } + } + }, + "@datadog/native-metrics": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@datadog/native-metrics/-/native-metrics-2.0.0.tgz", + "integrity": "sha512-YklGVwUtmKGYqFf1MNZuOHvTYdKuR4+Af1XkWcMD8BwOAjxmd9Z+97328rCOY8TFUJzlGUPaXzB8j2qgG/BMwA==", + "requires": { + "node-addon-api": "^6.1.0", + "node-gyp-build": "^3.9.0" + }, + "dependencies": { + "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-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==" + } + } + }, + "@datadog/pprof": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@datadog/pprof/-/pprof-5.2.0.tgz", + "integrity": "sha512-pSwLARpNLAIV1JttxXOBRKTn/NQYXDy1PJaV458YFDdAYxnBqpsYTat3/nX+8V5GoN4SfdHDci3zqXM+Ym66gQ==", + "requires": { + "delay": "^5.0.0", + "node-gyp-build": "<4.0", + "p-limit": "^3.1.0", + "pprof-format": "^2.1.0", + "source-map": "^0.7.4" + }, + "dependencies": { + "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==" + } + } + }, + "@datadog/sketches-js": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@datadog/sketches-js/-/sketches-js-2.1.0.tgz", + "integrity": "sha512-smLocSfrt3s53H/XSVP3/1kP42oqvrkjUPtyaFd1F79ux24oE31BKt+q0c6lsa6hOYrFzsIwyc5GXAI5JmfOew==" + }, "@datastructures-js/heap": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/@datastructures-js/heap/-/heap-4.3.2.tgz", @@ -19739,6 +20137,19 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.5.0.tgz", "integrity": "sha512-636km3y3pVyJldKGp9qM+lPvxuOvhThUED9cHNPsERkp+APbdtCtj0sALW+mZsbQqnqQkNRHqoGw/Uc82UP6fQ==" }, + "@opentelemetry/core": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.23.0.tgz", + "integrity": "sha512-hdQ/a9TMzMQF/BO8Cz1juA43/L5YGtCSiKoOHmrTEf7VMDAZgy8ucpWx3eQTnQ3gBloRcWtzvcrMZABC3PTSKQ==", + "requires": { + "@opentelemetry/semantic-conventions": "1.23.0" + } + }, + "@opentelemetry/semantic-conventions": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.23.0.tgz", + "integrity": "sha512-MiqFvfOzfR31t8cc74CTP1OZfz7MbqpAnLCra8NqQoaHJX6ncIRTdYOQYBDQ2uFISDq0WY8Y9dDTWvsgzzBYRg==" + }, "@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -21145,14 +21556,12 @@ "acorn": { "version": "8.10.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "devOptional": true + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==" }, "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==", - "dev": true, "requires": {} }, "acorn-jsx": { @@ -22559,6 +22968,11 @@ "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" }, + "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==" + }, "cssfilter": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz", @@ -22572,6 +22986,86 @@ "@babel/runtime": "^7.21.0" } }, + "dc-polyfill": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/dc-polyfill/-/dc-polyfill-0.1.4.tgz", + "integrity": "sha512-8iwEduR2jR9wWYggeaYtYZWRiUe3XZPyAQtMTL1otv8X3kfR8xUIVb4l5awHEeyDrH6Je7N324lKzMKlMMN6Yw==" + }, + "dd-trace": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.10.0.tgz", + "integrity": "sha512-+JyAf8DKGlCGPxhVhIHcG2+oD5h9/oGFbNj35Jlsl+EEMD/hqOWihgzZ2UzWNCVmOtVGQip3bdRGE4uqkRY+/g==", + "requires": { + "@datadog/native-appsec": "7.1.1", + "@datadog/native-iast-rewriter": "2.3.0", + "@datadog/native-iast-taint-tracking": "1.7.0", + "@datadog/native-metrics": "^2.0.0", + "@datadog/pprof": "5.2.0", + "@datadog/sketches-js": "^2.1.0", + "@opentelemetry/api": "^1.0.0", + "@opentelemetry/core": "^1.14.0", + "crypto-randomuuid": "^1.0.0", + "dc-polyfill": "^0.1.4", + "ignore": "^5.2.4", + "import-in-the-middle": "^1.7.3", + "int64-buffer": "^0.1.9", + "ipaddr.js": "^2.1.0", + "istanbul-lib-coverage": "3.2.0", + "jest-docblock": "^29.7.0", + "koalas": "^1.0.2", + "limiter": "1.1.5", + "lodash.sortby": "^4.7.0", + "lru-cache": "^7.14.0", + "methods": "^1.1.2", + "module-details-from-path": "^1.0.3", + "msgpack-lite": "^0.1.26", + "node-abort-controller": "^3.1.1", + "opentracing": ">=0.12.1", + "path-to-regexp": "^0.1.2", + "pprof-format": "^2.1.0", + "protobufjs": "^7.2.5", + "retry": "^0.13.1", + "semver": "^7.5.4", + "shell-quote": "^1.8.1", + "tlhunter-sorted-set": "^0.1.0" + }, + "dependencies": { + "ipaddr.js": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", + "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==" + }, + "long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + }, + "path-to-regexp": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.8.tgz", + "integrity": "sha512-EErxvEqTuliG5GCVHNt3K3UmfKhlOM26QtiJZ6XBnZgCd7n+P5aHNV37wFHGJSpbjN4danT+1CpOFT4giETmRQ==" + }, + "protobufjs": { + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.6.tgz", + "integrity": "sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==", + "requires": { + "@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/node": ">=13.7.0", + "long": "^5.0.0" + } + } + } + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -22670,6 +23164,11 @@ "object-keys": "^1.1.1" } }, + "delay": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", + "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==" + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -23309,6 +23808,11 @@ } } }, + "event-lite": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/event-lite/-/event-lite-0.1.3.tgz", + "integrity": "sha512-8qz9nOz5VeD2z96elrEKD2U433+L3DWdUdDkOINLGOJvx1GsMBbMn0aCeu28y8/e85A6mCigBiFlYMnTBEGlSw==" + }, "eventemitter3": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", @@ -24264,8 +24768,7 @@ "ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==" }, "import-fresh": { "version": "3.3.0", @@ -24277,6 +24780,17 @@ "resolve-from": "^4.0.0" } }, + "import-in-the-middle": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.7.3.tgz", + "integrity": "sha512-R2I11NRi0lI3jD2+qjqyVlVEahsejw7LDnYEbGb47QEFjczE3bZYsmWheCTQA+LFs2DzOQxR7Pms7naHW1V4bQ==", + "requires": { + "acorn": "^8.8.2", + "acorn-import-assertions": "^1.9.0", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, "import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -24333,6 +24847,11 @@ "wrap-ansi": "^6.0.1" } }, + "int64-buffer": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.1.10.tgz", + "integrity": "sha512-v7cSY1J8ydZ0GyjUHqF+1bshJ6cnEVLo9EnjB8p+4HDRPZc9N5jjmvUV7NvEsqQOKyH0pmIBFWXVQbiS0+OBbA==" + }, "internal-slot": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", @@ -25317,6 +25836,11 @@ "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" }, + "koalas": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/koalas/-/koalas-1.0.2.tgz", + "integrity": "sha512-RYhBbYaTTTHId3l6fnMZc3eGQNW6FVCqMG6AMwA5I1Mafr6AflaXeoi6x3xQuATRotGYRLk6+1ELZH4dstFNOA==" + }, "kuler": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", @@ -25342,6 +25866,11 @@ "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.44.tgz", "integrity": "sha512-svlRdNBI5WgBjRC20GrCfbFiclbF0Cx+sCcQob/C1r57nsoq0xg8r65QbTyVyweQIlB33P+Uahyho6EMYgcOyQ==" }, + "limiter": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", + "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" + }, "lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -25893,6 +26422,11 @@ "minimist": "^1.2.6" } }, + "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==" + }, "moment": { "version": "2.29.4", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", @@ -25975,6 +26509,24 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, + "msgpack-lite": { + "version": "0.1.26", + "resolved": "https://registry.npmjs.org/msgpack-lite/-/msgpack-lite-0.1.26.tgz", + "integrity": "sha512-SZ2IxeqZ1oRFGo0xFGbvBJWMp3yLIY9rlIJyxy8CGrwZn1f0ZK4r6jV/AM1r0FZMDUkWkglOk/eeKIL9g77Nxw==", + "requires": { + "event-lite": "^0.1.1", + "ieee754": "^1.1.8", + "int64-buffer": "^0.1.9", + "isarray": "^1.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + } + } + }, "multer": { "version": "1.4.4-lts.1", "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.4-lts.1.tgz", @@ -26408,6 +26960,11 @@ "mimic-fn": "^2.1.0" } }, + "opentracing": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/opentracing/-/opentracing-0.14.7.tgz", + "integrity": "sha512-vz9iS7MJ5+Bp1URw8Khvdyw1H/hGvzHWlKQ7eRrQojSCDL1/SrWfrY9QebLw97n2deyRtzHRC3MkQfVNUCo91Q==" + }, "optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -26824,6 +27381,11 @@ "xtend": "^4.0.0" } }, + "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==" + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -27552,8 +28114,7 @@ "shell-quote": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", - "dev": true + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==" }, "shelljs": { "version": "0.8.5", @@ -27656,8 +28217,7 @@ "source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==" }, "source-map-support": { "version": "0.5.21", @@ -28193,6 +28753,11 @@ } } }, + "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==" + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", diff --git a/package.json b/package.json index 201c04415..8461f5f19 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "class-validator": "^0.14.0", "config": "^3.3.7", "cookie-parser": "^1.4.6", + "dd-trace": "^5.10.0", "express": "^4.18.1", "graphql": "^16.5.0", "graphql-redis-subscriptions": "^2.4.2", diff --git a/src/main.ts b/src/main.ts index c21d322c9..8cab057f0 100644 --- a/src/main.ts +++ b/src/main.ts @@ -13,6 +13,7 @@ import cookieParser from 'cookie-parser'; import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston'; import { LoggerService } from '@nestjs/common'; import { NestExpressApplication } from '@nestjs/platform-express'; +import 'dd-trace/init'; async function bootstrap() { BigNumber.config({ EXPONENTIAL_AT: [-30, 30] });