diff --git a/package.json b/package.json index ffbcd9b..1fc66f0 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,8 @@ "ws": "^8.14.2" }, "devDependencies": { + "@jest/globals": "^29.3.1", + "@types/jest": "^29.4.0", "@types/k6": "^0.45.0", "@typescript-eslint/eslint-plugin": "^4.28.0", "@typescript-eslint/parser": "^4.28.0", @@ -51,9 +53,11 @@ "eslint-config-prettier": "^8.3.0", "eslint-plugin-prettier": "^3.4.0", "husky": "^7.0.4", + "jest": "^29.7.0", "k6": "^0.0.0", "prettier": "^2.4.1", "tiny-glob": "^0.2.9", + "ts-jest": "^29.1.0", "ts-node": "^10.9.1" }, "scripts": { @@ -77,7 +81,27 @@ "prettify:fix": "prettier --write './src/**/*.ts'", "lint": "eslint . --ext ts --quiet", "lint:fix": "eslint . --ext ts --fix", - "playground": "ts-node src/playground.ts" + "playground": "ts-node src/playground.ts", + "test": "jest src/utils/tests/auctionParams.test.ts", + "test:watch": "jest src/utils/tests/auctionParams.test.ts --watch" + }, + "jest": { + "preset": "ts-jest", + "testEnvironment": "node", + "moduleFileExtensions": [ + "ts", + "js" + ], + "transform": { + "^.+\\.ts$": "ts-jest" + }, + "testMatch": [ + "**/*.test.ts" + ], + "moduleNameMapper": { + "^@drift-labs/sdk$": "/drift-common/protocol/sdk/lib/node/index.js", + "^@drift/common$": "/drift-common/common-ts/lib/index.js" + } }, "resolutions": { "rpc-websockets": "^10.0.0" diff --git a/src/index.ts b/src/index.ts index 4cb4dd3..0158648 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,6 +18,10 @@ import { isVariant, OrderSubscriber, DelistedMarketSetting, + BigNum, + PRICE_PRECISION_EXP, + MarketTypeStr, + AssetType, } from '@drift-labs/sdk'; import { RedisClient, RedisClientPrefix } from '@drift/common/clients'; @@ -41,11 +45,19 @@ import { getAccountFromId, getRawAccountFromId, selectMostRecentBySlot, + createMarketBasedAuctionParams, + parseBoolean, + parseNumber, + mapToMarketOrderParams, + formatAuctionParamsForResponse, + fetchL2FromRedis, } from './utils/utils'; import FEATURE_FLAGS from './utils/featureFlags'; import { getDLOBProviderFromOrderSubscriber } from './dlobProvider'; import { setGlobalDispatcher, Agent } from 'undici'; import { HermesClient } from '@pythnetwork/hermes-client'; +import { COMMON_UI_UTILS } from '@drift/common'; +import { AuctionParamArgs } from './utils/types'; setGlobalDispatcher( new Agent({ @@ -546,11 +558,12 @@ const main = async (): Promise => { const adjustedDepth = depth ?? '100'; let l2Formatted: any; - const redisL2 = await fetchFromRedis( - `last_update_orderbook_${ - isSpot ? 'spot' : 'perp' - }_${normedMarketIndex}${includeIndicativeStr ? '_indicative' : ''}`, - selectMostRecentBySlot + const redisL2 = await fetchL2FromRedis( + fetchFromRedis, + selectMostRecentBySlot, + normedMarketType, + normedMarketIndex, + includeIndicativeStr ); const depthToUse = Math.min(parseInt(adjustedDepth as string) ?? 1, 100); let cacheMiss = true; @@ -660,13 +673,12 @@ const main = async (): Promise => { const adjustedDepth = normedParam['depth'] ?? '100'; let l2Formatted: any; - const redisL2 = await fetchFromRedis( - `last_update_orderbook_${ - isSpot ? 'spot' : 'perp' - }_${normedMarketIndex}${ - normedIncludeIndicative ? '_indicative' : '' - }`, - selectMostRecentBySlot + const redisL2 = await fetchL2FromRedis( + fetchFromRedis, + selectMostRecentBySlot, + normedMarketType, + normedMarketIndex, + normedIncludeIndicative ); const depth = Math.min(parseInt(adjustedDepth as string) ?? 1, 100); let cacheMiss = true; @@ -903,6 +915,139 @@ const main = async (): Promise => { } }); + app.get('/auctionParams', async (req, res, next) => { + try { + const { + marketIndex, + marketType, + direction, + amount, + assetType, + reduceOnly, + allowInfSlippage, + slippageTolerance, + isOracleOrder, + auctionDuration, + auctionStartPriceOffset, + auctionEndPriceOffset, + auctionStartPriceOffsetFrom, + auctionEndPriceOffsetFrom, + additionalEndPriceBuffer, + userOrderId, + } = req.query; + + // Validate required parameters + if (!marketIndex || !marketType || !direction || !amount || !assetType) { + res + .status(400) + .send( + 'Bad Request: marketIndex, marketType, direction, amount, and assetType are required' + ); + return; + } + + // Parse and validate values + const parsedMarketIndex = parseInt(marketIndex as string); + if (isNaN(parsedMarketIndex)) { + res.status(400).send('Bad Request: marketIndex must be a valid number'); + return; + } + + if (direction !== 'long' && direction !== 'short') { + res + .status(400) + .send('Bad Request: direction must be either "long" or "short"'); + return; + } + + if (assetType !== 'base' && assetType !== 'quote') { + res + .status(400) + .send('Bad Request: assetType must be either "base" or "quote"'); + return; + } + + // Build auction params object + const auctionParamsInput: AuctionParamArgs = { + marketIndex: parsedMarketIndex, + marketType: marketType as MarketTypeStr, + direction: direction as 'long' | 'short', + amount: amount as string, + assetType: assetType as AssetType, + }; + + // Add optional parameters if provided + const optionalParams = { + reduceOnly: parseBoolean(reduceOnly as string), + allowInfSlippage: parseBoolean(allowInfSlippage as string), + slippageTolerance: + slippageTolerance === 'dynamic' + ? undefined + : parseNumber(slippageTolerance as string), // Convert "dynamic" to undefined for dynamic calculation + isOracleOrder: parseBoolean(isOracleOrder as string), + auctionDuration: parseNumber(auctionDuration as string), + auctionStartPriceOffset: + auctionStartPriceOffset === 'marketBased' + ? 'marketBased' + : parseNumber(auctionStartPriceOffset as string), + auctionEndPriceOffset: parseNumber(auctionEndPriceOffset as string), + auctionStartPriceOffsetFrom: + auctionStartPriceOffsetFrom === 'marketBased' + ? 'marketBased' + : (auctionStartPriceOffsetFrom as any), + auctionEndPriceOffsetFrom: auctionEndPriceOffsetFrom as any, + additionalEndPriceBuffer: additionalEndPriceBuffer as string, + userOrderId: parseNumber(userOrderId as string), + }; + + // Only add non-undefined values + Object.entries(optionalParams).forEach(([key, value]) => { + if (value !== undefined) { + auctionParamsInput[key] = value; + } + }); + + const inputParams = createMarketBasedAuctionParams(auctionParamsInput); + + const result = await mapToMarketOrderParams( + inputParams, + driftClient, + fetchFromRedis, + selectMostRecentBySlot + ); + + if (!result.success) { + res.status(400).json({ + error: result.error, + }); + return; + } + + const auctionParams = COMMON_UI_UTILS.deriveMarketOrderParams( + result.data.marketOrderParams + ); + + const response = { + data: { + params: formatAuctionParamsForResponse(auctionParams), + entryPrice: result.data.estimatedPrices.entryPrice.toString(), + bestPrice: result.data.estimatedPrices.bestPrice.toString(), + worstPrice: result.data.estimatedPrices.worstPrice.toString(), + priceImpact: BigNum.from( + result.data.estimatedPrices.priceImpact, + PRICE_PRECISION_EXP + ).toNum(), + slippageTolerance: result.data.marketOrderParams.slippageTolerance, + baseFilled: result.data.estimatedPrices.baseFilled, + }, + }; + + res.status(200).json(response); + } catch (err) { + next(err); + } + }); + server.listen(serverPort, () => { logger.info(`DLOB server listening on port http://localhost:${serverPort}`); }); @@ -920,4 +1065,4 @@ async function recursiveTryCatch(f: () => Promise) { recursiveTryCatch(() => main()); -export { commitHash, driftClient, driftEnv, endpoint, sdkConfig, wsEndpoint }; +export { commitHash, driftClient, driftEnv, endpoint, sdkConfig, wsEndpoint }; \ No newline at end of file diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 04eddd6..67e3418 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -1,3 +1,5 @@ +import { AuctionParamArgs } from "./types"; + export const MEASURED_ENDPOINTS = [ '/priorityFees', '/batchPriorityFees', @@ -7,3 +9,17 @@ export const MEASURED_ENDPOINTS = [ '/batchL2Cache', '/l3', ]; + +export const DEFAULT_MARKET_AUCTION_DURATION = 20; +export const DEFAULT_LIMIT_AUCTION_DURATION = 60; +const DEFAULT_AUCTION_END_PRICE_OFFSET = 0.1; +const DEFAULT_AUCTION_END_PRICE_FROM = 'worst'; + +export const DEFAULT_AUCTION_PARAMS: Partial = { + isOracleOrder: true, + auctionDuration: DEFAULT_MARKET_AUCTION_DURATION, + auctionStartPriceOffset: 'marketBased', + auctionEndPriceOffset: DEFAULT_AUCTION_END_PRICE_OFFSET, + auctionStartPriceOffsetFrom: 'marketBased', + auctionEndPriceOffsetFrom: DEFAULT_AUCTION_END_PRICE_FROM, +}; diff --git a/src/utils/tests/auctionParams.test.ts b/src/utils/tests/auctionParams.test.ts new file mode 100644 index 0000000..ab9ea1d --- /dev/null +++ b/src/utils/tests/auctionParams.test.ts @@ -0,0 +1,682 @@ +import { describe, it, expect, jest, beforeEach } from '@jest/globals'; +import { + BN, + PositionDirection, + MarketType, + ZERO, + QUOTE_PRECISION, + PRICE_PRECISION +} from '@drift-labs/sdk'; +import { + createMarketBasedAuctionParams, + mapToMarketOrderParams, + formatAuctionParamsForResponse, +} from '../utils'; + +describe('Auction Parameters Functions', () => { + describe('createMarketBasedAuctionParams', () => { + it('should apply market-based logic for major PERP markets (0, 1, 2)', () => { + [0, 1, 2].forEach(marketIndex => { + const args = { + marketIndex, + marketType: 'perp' as any, + direction: 'long' as any, + amount: '100', + assetType: 'base' as any, + auctionStartPriceOffsetFrom: 'marketBased' as any, + auctionStartPriceOffset: 'marketBased' as any, + }; + + const result = createMarketBasedAuctionParams(args); + + expect(result.auctionStartPriceOffsetFrom).toBe('mark'); + expect(result.auctionStartPriceOffset).toBe(0); + }); + }); + + it('should apply market-based logic for minor PERP markets (>2)', () => { + [3, 4, 5, 10].forEach(marketIndex => { + const args = { + marketIndex, + marketType: 'perp' as any, + direction: 'long' as any, + amount: '100', + assetType: 'base' as any, + auctionStartPriceOffsetFrom: 'marketBased' as any, + auctionStartPriceOffset: 'marketBased' as any, + }; + + const result = createMarketBasedAuctionParams(args); + + expect(result.auctionStartPriceOffsetFrom).toBe('bestOffer'); + expect(result.auctionStartPriceOffset).toBe(-0.1); + }); + }); + + it('should apply market-based logic for SPOT markets when "marketBased" is passed', () => { + [0, 1, 2, 5, 10].forEach(marketIndex => { + const args = { + marketIndex, + marketType: 'spot' as any, + direction: 'long' as any, + amount: '100', + assetType: 'base' as any, + auctionStartPriceOffsetFrom: 'marketBased' as any, + auctionStartPriceOffset: 'marketBased' as any, + }; + + const result = createMarketBasedAuctionParams(args); + + expect(result.auctionStartPriceOffsetFrom).toBe('bestOffer'); + expect(result.auctionStartPriceOffset).toBe(-0.1); + }); + }); + + it('should treat undefined values the same as "marketBased"', () => { + const majorMarketArgs = { + marketIndex: 0, + marketType: 'perp' as any, + direction: 'long' as any, + amount: '100', + assetType: 'base' as any, + // auctionStartPriceOffsetFrom and auctionStartPriceOffset are undefined + }; + + const minorMarketArgs = { + marketIndex: 5, + marketType: 'perp' as any, + direction: 'long' as any, + amount: '100', + assetType: 'base' as any, + // auctionStartPriceOffsetFrom and auctionStartPriceOffset are undefined + }; + + const majorResult = createMarketBasedAuctionParams(majorMarketArgs); + const minorResult = createMarketBasedAuctionParams(minorMarketArgs); + + // Major market behavior + expect(majorResult.auctionStartPriceOffsetFrom).toBe('mark'); + expect(majorResult.auctionStartPriceOffset).toBe(0); + + // Minor market behavior + expect(minorResult.auctionStartPriceOffsetFrom).toBe('bestOffer'); + expect(minorResult.auctionStartPriceOffset).toBe(-0.1); + }); + + it('should preserve explicit values over market-based defaults', () => { + const args = { + marketIndex: 0, // Major market + marketType: 'perp' as any, + direction: 'long' as any, + amount: '100', + assetType: 'base' as any, + auctionStartPriceOffsetFrom: 'oracle' as any, + auctionStartPriceOffset: 0.5, + auctionEndPriceOffset: 0.2, + auctionDuration: 45, + }; + + const result = createMarketBasedAuctionParams(args); + + // Should use explicit values, not market-based defaults + expect(result.auctionStartPriceOffsetFrom).toBe('oracle'); + expect(result.auctionStartPriceOffset).toBe(0.5); + expect(result.auctionEndPriceOffset).toBe(0.2); + expect(result.auctionDuration).toBe(45); + }); + + it('should handle mixed explicit and market-based values', () => { + const args = { + marketIndex: 0, + marketType: 'perp' as any, + direction: 'long' as any, + amount: '100', + assetType: 'base' as any, + auctionStartPriceOffsetFrom: 'oracle' as any, // explicit + auctionStartPriceOffset: 'marketBased' as any, // market-based + auctionDuration: 45, // explicit + }; + + const result = createMarketBasedAuctionParams(args); + + expect(result.auctionStartPriceOffsetFrom).toBe('oracle'); // explicit value + expect(result.auctionStartPriceOffset).toBe(0); // market-based for major market + expect(result.auctionDuration).toBe(45); // explicit value + }); + + it('should include all original parameters in the result', () => { + const args = { + marketIndex: 3, + marketType: 'perp' as any, + direction: 'short' as any, + amount: '250', + assetType: 'quote' as any, + reduceOnly: true, + allowInfSlippage: false, + slippageTolerance: 0.02, + userOrderId: 12345, + auctionStartPriceOffsetFrom: 'marketBased' as any, + auctionStartPriceOffset: 'marketBased' as any, + }; + + const result = createMarketBasedAuctionParams(args); + + // Should preserve all original parameters + expect(result.marketIndex).toBe(3); + expect(result.marketType).toBe('perp'); + expect(result.direction).toBe('short'); + expect(result.amount).toBe('250'); + expect(result.assetType).toBe('quote'); + expect(result.reduceOnly).toBe(true); + expect(result.allowInfSlippage).toBe(false); + expect(result.slippageTolerance).toBe(0.02); + expect(result.userOrderId).toBe(12345); + + // Should apply market-based logic + expect(result.auctionStartPriceOffsetFrom).toBe('bestOffer'); + expect(result.auctionStartPriceOffset).toBe(-0.1); + }); + }); + + describe('mapToMarketOrderParams with Mock L2 Data', () => { + const mockDriftClient = { + getOracleDataForPerpMarket: jest.fn(), + getOracleDataForSpotMarket: jest.fn(), + }; + + const mockFetchFromRedis = jest.fn() as any; + const mockSelectMostRecentBySlot = jest.fn() as any; + + const validParams = { + marketIndex: 0, + marketType: 'perp' as any, + direction: 'long' as any, + amount: '100', + assetType: 'base' as any, + auctionDuration: 30, + auctionStartPriceOffset: 0, + auctionEndPriceOffset: 0.1, + auctionStartPriceOffsetFrom: 'mark' as any, + auctionEndPriceOffsetFrom: 'mark' as any, + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should successfully calculate prices with mock L2 orderbook data', async () => { + const solPrice = 160; // $160 SOL price + + mockDriftClient.getOracleDataForPerpMarket.mockReturnValue({ + price: new BN(solPrice).mul(PRICE_PRECISION), + }); + + // Mock realistic L2 orderbook data + mockFetchFromRedis.mockImplementation(async (key: string) => { + if (key.includes('dlob_orderbook')) { + return { + bids: [ + { price: '159950000', size: '1000000000' }, // $159.95, 1 SOL + { price: '159900000', size: '2000000000' }, // $159.90, 2 SOL + { price: '159850000', size: '1500000000' }, // $159.85, 1.5 SOL + ], + asks: [ + { price: '160050000', size: '1500000000' }, // $160.05, 1.5 SOL + { price: '160100000', size: '1000000000' }, // $160.10, 1 SOL + { price: '160150000', size: '2000000000' }, // $160.15, 2 SOL + ], + }; + } + return null; + }); + + const result = await mapToMarketOrderParams( + validParams, + mockDriftClient as any, + mockFetchFromRedis as any, + mockSelectMostRecentBySlot as any + ); + + expect(result.success).toBe(true); + expect(result.data).toBeDefined(); + expect(result.data?.marketOrderParams).toBeDefined(); + expect(result.data?.estimatedPrices).toBeDefined(); + expect(result.error).toBeUndefined(); + + // Verify price calculations + const prices = result.data?.estimatedPrices; + expect(prices?.entryPrice.gt(ZERO)).toBe(true); + expect(prices?.bestPrice.gt(ZERO)).toBe(true); + expect(prices?.worstPrice.gt(ZERO)).toBe(true); + expect(prices?.oraclePrice.gt(ZERO)).toBe(true); + + // Verify market order params structure + const marketOrderParams = result.data?.marketOrderParams; + expect(marketOrderParams?.marketType).toBe(MarketType.PERP); + expect(marketOrderParams?.direction).toBe(PositionDirection.LONG); + expect(marketOrderParams?.baseAmount).toBeDefined(); + expect(marketOrderParams?.baseAmount.gt(ZERO)).toBe(true); + }); + + it('should handle quote-to-base conversion with realistic prices', async () => { + const solPrice = 160; // $160 SOL price + const quoteAmount = 1000; // $1,000 worth + + mockDriftClient.getOracleDataForPerpMarket.mockReturnValue({ + price: new BN(solPrice).mul(PRICE_PRECISION), + }); + + mockFetchFromRedis.mockImplementation(async (key: string) => { + if (key.includes('dlob_orderbook')) { + return { + bids: [ + { price: '160000000', size: '1000000000' }, // $160.00, 1 SOL + ], + asks: [ + { price: '160000000', size: '1000000000' }, // $160.00, 1 SOL + ], + }; + } + return null; + }); + + const quoteParams = { + ...validParams, + amount: quoteAmount.toString(), + assetType: 'quote' as any, + }; + + const result = await mapToMarketOrderParams( + quoteParams, + mockDriftClient as any, + mockFetchFromRedis as any, + mockSelectMostRecentBySlot as any + ); + + expect(result.success).toBe(true); + + // With $1,000 at $160 per SOL, we should get ~6.25 SOL + const baseAmount = result.data?.marketOrderParams.baseAmount; + expect(baseAmount).toBeDefined(); + expect(baseAmount.gt(ZERO)).toBe(true); + + // Calculate expected base amount: (quoteAmount * QUOTE_PRECISION * BASE_PRECISION) / entryPrice + const expectedBaseAmount = new BN(quoteAmount) + .mul(QUOTE_PRECISION) + .mul(new BN(10).pow(new BN(9))) // BASE_PRECISION = 10^9 + .div(result.data?.estimatedPrices.entryPrice); + + expect(baseAmount.toString()).toBe(expectedBaseAmount.toString()); + }); + + it('should handle different market types correctly', async () => { + const usdcPrice = 1; // $1 USDC price + + mockDriftClient.getOracleDataForSpotMarket.mockReturnValue({ + price: new BN(usdcPrice).mul(PRICE_PRECISION), + }); + + mockFetchFromRedis.mockImplementation(async (key: string) => { + if (key.includes('dlob_orderbook')) { + return { + bids: [ + { price: '1000000', size: '10000000000' }, // $1.00, 10,000 USDC + ], + asks: [ + { price: '1000000', size: '10000000000' }, // $1.00, 10,000 USDC + ], + }; + } + return null; + }); + + const spotParams = { + ...validParams, + marketType: 'spot' as any, + }; + + const result = await mapToMarketOrderParams( + spotParams, + mockDriftClient as any, + mockFetchFromRedis as any, + mockSelectMostRecentBySlot as any + ); + + expect(result.success).toBe(true); + expect(result.data?.marketOrderParams.marketType).toBe(MarketType.SPOT); + expect(result.data?.estimatedPrices.entryPrice.gt(ZERO)).toBe(true); + }); + + it('should handle different directions correctly', async () => { + const solPrice = 160; // $160 SOL price + + mockDriftClient.getOracleDataForPerpMarket.mockReturnValue({ + price: new BN(solPrice).mul(PRICE_PRECISION), + }); + + mockFetchFromRedis.mockImplementation(async (key: string) => { + if (key.includes('dlob_orderbook')) { + return { + bids: [ + { price: '159950000', size: '1000000000' }, // $159.95, 1 SOL + ], + asks: [ + { price: '160050000', size: '1000000000' }, // $160.05, 1 SOL + ], + }; + } + return null; + }); + + const shortParams = { + ...validParams, + direction: 'short' as any, + }; + + const result = await mapToMarketOrderParams( + shortParams, + mockDriftClient as any, + mockFetchFromRedis as any, + mockSelectMostRecentBySlot as any + ); + + expect(result.success).toBe(true); + expect(result.data?.marketOrderParams.direction).toBe(PositionDirection.SHORT); + expect(result.data?.estimatedPrices.entryPrice.gt(ZERO)).toBe(true); + }); + + it('should handle various order sizes with L2 depth', async () => { + const solPrice = 160; // $160 SOL price + + mockDriftClient.getOracleDataForPerpMarket.mockReturnValue({ + price: new BN(solPrice).mul(PRICE_PRECISION), + }); + + // Mock L2 with multiple levels of depth + mockFetchFromRedis.mockImplementation(async (key: string) => { + if (key.includes('dlob_orderbook')) { + return { + bids: [ + { price: '159950000', size: '500000000' }, // $159.95, 0.5 SOL + { price: '159900000', size: '1000000000' }, // $159.90, 1 SOL + { price: '159850000', size: '2000000000' }, // $159.85, 2 SOL + ], + asks: [ + { price: '160050000', size: '500000000' }, // $160.05, 0.5 SOL + { price: '160100000', size: '1000000000' }, // $160.10, 1 SOL + { price: '160150000', size: '2000000000' }, // $160.15, 2 SOL + ], + }; + } + return null; + }); + + // Test small order + const smallOrderParams = { + ...validParams, + amount: '10', // Small order + }; + + const smallResult = await mapToMarketOrderParams( + smallOrderParams, + mockDriftClient as any, + mockFetchFromRedis as any, + mockSelectMostRecentBySlot as any + ); + + expect(smallResult.success).toBe(true); + expect(smallResult.data?.estimatedPrices.entryPrice.gt(ZERO)).toBe(true); + + // Test large order + const largeOrderParams = { + ...validParams, + amount: '1000', // Large order + }; + + const largeResult = await mapToMarketOrderParams( + largeOrderParams, + mockDriftClient as any, + mockFetchFromRedis as any, + mockSelectMostRecentBySlot as any + ); + + expect(largeResult.success).toBe(true); + expect(largeResult.data?.estimatedPrices.entryPrice.gt(ZERO)).toBe(true); + + // Large orders should have higher price impact + expect(largeResult.data?.estimatedPrices.priceImpact.gte(smallResult.data?.estimatedPrices.priceImpact)).toBe(true); + }); + + it('should handle zero oracle price scenario', async () => { + mockDriftClient.getOracleDataForPerpMarket.mockReturnValue({ + price: ZERO, + }); + + mockFetchFromRedis.mockImplementation(async (key: string) => { + if (key.includes('dlob_orderbook')) { + return { + bids: [ + { price: '159950000', size: '1000000000' }, // $159.95, 1 SOL + ], + asks: [ + { price: '160050000', size: '1000000000' }, // $160.05, 1 SOL + ], + }; + } + return null; + }); + + const result = await mapToMarketOrderParams( + validParams, + mockDriftClient as any, + mockFetchFromRedis as any, + mockSelectMostRecentBySlot as any + ); + + expect(result.success).toBe(true); + expect(result.data).toBeDefined(); + expect(result.data?.estimatedPrices.oraclePrice.eq(ZERO)).toBe(true); + // Entry price should be calculated from L2 data even if oracle price is zero + expect(result.data?.estimatedPrices.entryPrice).toBeDefined(); + }); + }); + + describe('formatAuctionParamsForResponse', () => { + it('should format BN values to strings', () => { + const mockAuctionParams = { + auctionStartPriceOffsetFrom: 'mark', + auctionStartPriceOffset: new BN(0), + auctionEndPriceOffsetFrom: 'best', + auctionEndPriceOffset: new BN(100000), // 0.1 with PRICE_PRECISION (1e6) + auctionDuration: 30, + slippageTolerance: 0.05, + additionalEndPriceBuffer: new BN(50000), // 0.05 with PRICE_PRECISION + userOrderId: 123, + isOracleOrder: false, + }; + + const result = formatAuctionParamsForResponse(mockAuctionParams); + + expect(result.auctionStartPriceOffsetFrom).toBe('mark'); + expect(result.auctionStartPriceOffset).toBe('0'); + expect(result.auctionEndPriceOffsetFrom).toBe('best'); + expect(result.auctionEndPriceOffset).toBe('100000'); + expect(result.auctionDuration).toBe(30); + expect(result.slippageTolerance).toBe(0.05); + expect(result.additionalEndPriceBuffer).toBe('50000'); + expect(result.userOrderId).toBe(123); + expect(result.isOracleOrder).toBe(false); + }); + + it('should handle different BN values correctly', () => { + const mockAuctionParams = { + auctionStartPriceOffsetFrom: 'oracle', + auctionStartPriceOffset: new BN(250000), // 0.25 with PRICE_PRECISION + auctionEndPriceOffsetFrom: 'worst', + auctionEndPriceOffset: new BN(1500000), // 1.5 with PRICE_PRECISION + auctionDuration: 60, + slippageTolerance: 0.1, + additionalEndPriceBuffer: new BN(0), // 0 with PRICE_PRECISION + userOrderId: 456, + isOracleOrder: true, + }; + + const result = formatAuctionParamsForResponse(mockAuctionParams); + + expect(result.auctionStartPriceOffset).toBe('250000'); + expect(result.auctionEndPriceOffset).toBe('1500000'); + expect(result.additionalEndPriceBuffer).toBe('0'); + expect(result.isOracleOrder).toBe(true); + }); + + it('should handle undefined/null values gracefully', () => { + const mockAuctionParams = { + auctionStartPriceOffsetFrom: 'mark', + auctionStartPriceOffset: new BN(0), + auctionEndPriceOffsetFrom: 'mark', + auctionEndPriceOffset: new BN(100000), + auctionDuration: 30, + slippageTolerance: undefined, + additionalEndPriceBuffer: undefined, + userOrderId: undefined, + isOracleOrder: undefined, + }; + + const result = formatAuctionParamsForResponse(mockAuctionParams); + + expect(result.auctionStartPriceOffsetFrom).toBe('mark'); + expect(result.auctionStartPriceOffset).toBe('0'); + expect(result.auctionEndPriceOffsetFrom).toBe('mark'); + expect(result.auctionEndPriceOffset).toBe('100000'); + expect(result.auctionDuration).toBe(30); + expect(result.slippageTolerance).toBeUndefined(); + expect(result.additionalEndPriceBuffer).toBeUndefined(); + expect(result.userOrderId).toBeUndefined(); + expect(result.isOracleOrder).toBeUndefined(); + }); + }); + + describe('Business Logic Integration', () => { + it('should demonstrate complete parameter flow for different market types', () => { + const scenarios = [ + { + name: 'Major PERP market with market-based params', + input: { + marketIndex: 0, + marketType: 'perp' as any, + direction: 'long' as any, + amount: '100', + assetType: 'base' as any, + auctionStartPriceOffsetFrom: 'marketBased' as any, + auctionStartPriceOffset: 'marketBased' as any, + }, + expectedOffset: { from: 'mark', value: 0 }, + }, + { + name: 'Minor PERP market with market-based params', + input: { + marketIndex: 5, + marketType: 'perp' as any, + direction: 'short' as any, + amount: '500', + assetType: 'quote' as any, + auctionStartPriceOffsetFrom: 'marketBased' as any, + auctionStartPriceOffset: 'marketBased' as any, + }, + expectedOffset: { from: 'bestOffer', value: -0.1 }, + }, + { + name: 'SPOT market with market-based params', + input: { + marketIndex: 2, + marketType: 'spot' as any, + direction: 'long' as any, + amount: '1000', + assetType: 'base' as any, + auctionStartPriceOffsetFrom: 'marketBased' as any, + auctionStartPriceOffset: 'marketBased' as any, + }, + expectedOffset: { from: 'bestOffer', value: -0.1 }, + }, + ]; + + scenarios.forEach(scenario => { + const result = createMarketBasedAuctionParams(scenario.input); + + expect(result.auctionStartPriceOffsetFrom).toBe(scenario.expectedOffset.from); + expect(result.auctionStartPriceOffset).toBe(scenario.expectedOffset.value); + + // Verify all original parameters are preserved + expect(result.marketIndex).toBe(scenario.input.marketIndex); + expect(result.marketType).toBe(scenario.input.marketType); + expect(result.direction).toBe(scenario.input.direction); + expect(result.amount).toBe(scenario.input.amount); + expect(result.assetType).toBe(scenario.input.assetType); + }); + }); + + it('should handle parameter precedence correctly', () => { + // Test that explicit values always take precedence over market-based logic + const input = { + marketIndex: 0, // Major market - would normally get 'mark' and 0 + marketType: 'perp' as any, + direction: 'long' as any, + amount: '100', + assetType: 'base' as any, + auctionStartPriceOffsetFrom: 'oracle' as any, // explicit value + auctionStartPriceOffset: 0.25, // explicit value + auctionEndPriceOffset: 0.5, // explicit value + auctionDuration: 45, // explicit value + }; + + const result = createMarketBasedAuctionParams(input); + + // Should use explicit values, not market-based defaults + expect(result.auctionStartPriceOffsetFrom).toBe('oracle'); + expect(result.auctionStartPriceOffset).toBe(0.25); + expect(result.auctionEndPriceOffset).toBe(0.5); + expect(result.auctionDuration).toBe(45); + }); + + it('should demonstrate end-to-end parameter formatting', () => { + // Create auction params with market-based logic + const input = { + marketIndex: 1, + marketType: 'perp' as any, + direction: 'long' as any, + amount: '100', + assetType: 'base' as any, + auctionStartPriceOffsetFrom: 'marketBased' as any, + auctionStartPriceOffset: 'marketBased' as any, + auctionDuration: 30, + }; + + const auctionParams = createMarketBasedAuctionParams(input); + + // Simulate the structure that would come from deriveMarketOrderParams + const mockDerivedParams = { + auctionStartPriceOffsetFrom: auctionParams.auctionStartPriceOffsetFrom, + auctionStartPriceOffset: new BN(0), // 0 for major market + auctionEndPriceOffsetFrom: auctionParams.auctionEndPriceOffsetFrom, + auctionEndPriceOffset: new BN(100000), // 0.1 with PRICE_PRECISION + auctionDuration: auctionParams.auctionDuration, + slippageTolerance: 0.05, + additionalEndPriceBuffer: new BN(50000), // 0.05 with PRICE_PRECISION + userOrderId: 123, + isOracleOrder: true, + }; + + const formattedResponse = formatAuctionParamsForResponse(mockDerivedParams); + + // Verify the complete flow + expect(formattedResponse.auctionStartPriceOffsetFrom).toBe('mark'); // Market-based for major market + expect(formattedResponse.auctionStartPriceOffset).toBe('0'); // Market-based for major market + expect(formattedResponse.auctionEndPriceOffset).toBe('100000'); // Formatted from BN + expect(formattedResponse.auctionDuration).toBe(30); // Preserved from input + expect(formattedResponse.slippageTolerance).toBe(0.05); // Preserved as number + expect(formattedResponse.additionalEndPriceBuffer).toBe('50000'); // Formatted from BN + expect(formattedResponse.userOrderId).toBe(123); // Preserved as number + expect(formattedResponse.isOracleOrder).toBe(true); // Preserved as boolean + }); + }); +}); diff --git a/src/utils/types.ts b/src/utils/types.ts new file mode 100644 index 0000000..1f514ce --- /dev/null +++ b/src/utils/types.ts @@ -0,0 +1,24 @@ +import { AssetType, MarketTypeStr } from "@drift-labs/sdk"; +import { TradeOffsetPrice } from "@drift/common"; + +export type AuctionParamArgs = { + // mandatory args + marketIndex: number; + marketType: MarketTypeStr; + direction: 'long' | 'short'; + amount: string; + assetType: AssetType; + + // optional settings args + reduceOnly?: boolean; + allowInfSlippage?: boolean; + slippageTolerance?: number; + isOracleOrder?: boolean; + auctionDuration?: number; + auctionStartPriceOffset?: number | 'marketBased'; + auctionEndPriceOffset?: number; + auctionStartPriceOffsetFrom?: TradeOffsetPrice | 'marketBased'; + auctionEndPriceOffsetFrom?: TradeOffsetPrice; + additionalEndPriceBuffer?: string; + userOrderId?: number; +}; \ No newline at end of file diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 1257e95..612f1a0 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -14,14 +14,26 @@ import { SpotMarketConfig, decodeUser, isVariant, + PositionDirection, + ZERO, + BASE_PRECISION, + PRICE_PRECISION, + calculateEstimatedEntryPriceWithL2, + AssetType, + MainnetSpotMarkets, + DevnetSpotMarkets, + QUOTE_PRECISION, + PERCENTAGE_PRECISION_EXP, } from '@drift-labs/sdk'; import { RedisClient } from '@drift/common/clients'; - import { logger } from './logger'; import { NextFunction, Request, Response } from 'express'; import FEATURE_FLAGS from './featureFlags'; import { Connection } from '@solana/web3.js'; import { wsMarketArgs } from 'src/dlob-subscriber/DLOBSubscriberIO'; +import { DEFAULT_AUCTION_PARAMS } from './constants'; +import { AuctionParamArgs } from './types'; +import { COMMON_MATH, ENUM_UTILS } from '@drift/common'; export const GROUPING_OPTIONS = [1, 10, 100, 500, 1000]; export const GROUPING_DEPENDENCIES = { @@ -632,3 +644,581 @@ export const selectMostRecentBySlot = ( return !mostRecent || current.slot > mostRecent.slot ? current : mostRecent; }, null); }; + +export function createMarketBasedAuctionParams( + args: AuctionParamArgs, + overrideDefaults?: Partial +): AuctionParamArgs { + // Determine if this is a major market (PERP with marketIndex 0, 1, or 2) + const isMajorMarket = + args.marketType?.toLowerCase() === 'perp' && + [0, 1, 2].includes(args.marketIndex); + + // Resolve "marketBased" values and undefined values (both should use market-based logic) + const resolvedAuctionStartPriceOffsetFrom = + args.auctionStartPriceOffsetFrom === 'marketBased' || args.auctionStartPriceOffsetFrom === undefined + ? isMajorMarket + ? 'mark' + : 'bestOffer' + : args.auctionStartPriceOffsetFrom; + + const resolvedAuctionStartPriceOffset = + args.auctionStartPriceOffset === 'marketBased' || args.auctionStartPriceOffset === undefined + ? isMajorMarket + ? 0 + : -0.1 + : args.auctionStartPriceOffset; + + // Set market-specific defaults (only used if values are undefined) + const marketSpecificDefaults: Partial = { + ...DEFAULT_AUCTION_PARAMS, + auctionStartPriceOffsetFrom: isMajorMarket ? 'mark' : 'bestOffer', + auctionStartPriceOffset: isMajorMarket ? 0 : -0.1, + }; + + // Apply custom overrides if provided + const finalDefaults = overrideDefaults + ? { ...marketSpecificDefaults, ...overrideDefaults } + : marketSpecificDefaults; + + return { + ...finalDefaults, + ...args, + // Override with resolved "marketBased" values if were provided + auctionStartPriceOffsetFrom: + resolvedAuctionStartPriceOffsetFrom ?? + finalDefaults.auctionStartPriceOffsetFrom, + auctionStartPriceOffset: + resolvedAuctionStartPriceOffset ?? finalDefaults.auctionStartPriceOffset, + }; +} + +/** + * Parse boolean values from string query parameters + * @param value - string value from query parameter + * @returns boolean | undefined - true for 'true'/'1', false for other values, undefined if input is undefined + */ +export const parseBoolean = ( + value: string | undefined +): boolean | undefined => { + if (value === undefined) return undefined; + return value === 'true' || value === '1'; +}; + +/** + * Safely parse numeric values from string query parameters + * @param value - string value from query parameter + * @returns number | undefined - parsed number or undefined if invalid/empty + */ +export const parseNumber = (value: string | undefined): number | undefined => { + if (!value) return undefined; + const parsed = parseFloat(value); + return isNaN(parsed) ? undefined : parsed; +}; + +/** + * Convert string to BN + * @param value - string value to convert + * @returns BN + */ +export const stringToBN = (value: string): BN => { + if (!value) return ZERO; + return new BN(value); +}; + +/** + * Convert raw Redis L2 data (with string prices/sizes) to proper L2OrderBook format (with BN values) + * @param rawL2 - Raw L2 data from Redis with string values + * @returns L2OrderBook with proper BN values + */ +export const convertRawL2ToBN = (rawL2: any): L2OrderBook => { + const convertLevel = (level: any) => ({ + ...level, + price: new BN(level.price), + size: new BN(level.size), + }); + + return { + ...rawL2, + bids: rawL2.bids?.map(convertLevel) || [], + asks: rawL2.asks?.map(convertLevel) || [], + }; +}; + +/** + * Get L2 orderbook data and calculate estimated prices + * @param driftClient - DriftClient instance + * @param marketType - MarketType enum + * @param marketIndex - Market index number + * @param direction - Position direction + * @param amount - Amount as BN (could be base or quote amount) + * @param assetType - Whether amount is 'base' or 'quote' + * @param fetchFromRedis - Redis fetch function + * @param selectMostRecentBySlot - Slot selection function + * @returns Price data object with oracle, best, entry, worst, and mark prices + */ +export const getEstimatedPrices = async ( + driftClient: DriftClient, + marketType: MarketType, + marketIndex: number, + direction: PositionDirection, + amount: BN, + assetType: AssetType, + fetchFromRedis: ( + key: string, + selectionCriteria: (responses: any) => any + ) => Promise, + selectMostRecentBySlot: (responses: any[]) => any +): Promise<{ + oraclePrice: BN; + bestPrice: BN; + entryPrice: BN; + worstPrice: BN; + markPrice: BN; + priceImpact: BN; +}> => { + const isSpot = isVariant(marketType, 'spot'); + + // Get L2 orderbook data using the new utility function + const redisL2 = await fetchL2FromRedis( + fetchFromRedis, + selectMostRecentBySlot, + marketType, + marketIndex + ); + + let l2Formatted: L2OrderBook; + if (redisL2) { + l2Formatted = convertRawL2ToBN(redisL2); + } else { + l2Formatted = { + bids: [], + asks: [], + }; + } + + const oracleData = isSpot + ? driftClient.getOracleDataForSpotMarket(marketIndex) + : driftClient.getOracleDataForPerpMarket(marketIndex); + + // Get oracle price + const oraclePrice = new BN(oracleData?.price || 0).mul(PRICE_PRECISION); + + const spreadInfo = COMMON_MATH.calculateSpreadBidAskMark( + l2Formatted, + oraclePrice + ); + + const markPrice = spreadInfo?.markPrice ?? oraclePrice; + + // If we have L2 data, calculate estimated prices + if (l2Formatted.bids?.length > 0 || l2Formatted.asks?.length > 0) { + try { + const basePrecision = !isSpot + ? BASE_PRECISION + : process.env.ENV === 'mainnet-beta' + ? MainnetSpotMarkets[marketIndex].precision + : DevnetSpotMarkets[marketIndex].precision; + + const priceEstimate = calculateEstimatedEntryPriceWithL2( + assetType, + amount, + direction, + basePrecision, + l2Formatted as L2OrderBook + ); + + return { + oraclePrice, + bestPrice: priceEstimate.bestPrice, + entryPrice: priceEstimate.entryPrice, + worstPrice: priceEstimate.worstPrice, + markPrice, + priceImpact: priceEstimate.priceImpact, + }; + } catch (error) { + // If calculation fails, fallback to oracle prices + console.warn('Price calculation failed, using oracle fallback:', error); + } + } + + // Fallback to oracle prices if no L2 data or calculation fails + return { + oraclePrice, + bestPrice: oraclePrice, + entryPrice: oraclePrice, + worstPrice: oraclePrice, + markPrice, + priceImpact: ZERO, + }; +}; + +/** + * Maps AuctionParamArgs to the format expected by deriveMarketOrderParams + * @param params - AuctionParamArgs from the API request + * @param driftClient - DriftClient instance (optional, for price calculation) + * @param fetchFromRedis - Redis fetch function (optional, for price calculation) + * @param selectMostRecentBySlot - Slot selection function (optional, for price calculation) + * @returns Object formatted for deriveMarketOrderParams function or error response + */ +export const mapToMarketOrderParams = async ( + params: AuctionParamArgs, + driftClient?: DriftClient, + fetchFromRedis?: ( + key: string, + selectionCriteria: (responses: any) => any + ) => Promise, + selectMostRecentBySlot?: (responses: any[]) => any +): Promise<{ + success: boolean; + data?: { + marketOrderParams: any; + estimatedPrices: any; + }; + error?: string; +}> => { + // Convert marketType string to MarketType enum + const marketType = + params.marketType.toLowerCase() === 'spot' + ? MarketType.SPOT + : MarketType.PERP; + + // Convert direction string to PositionDirection enum + const direction = + params.direction === 'long' + ? PositionDirection.LONG + : PositionDirection.SHORT; + + // Convert amount string to BN based on assetType + const amount = + params.assetType === 'base' + ? stringToBN(params.amount).mul(BASE_PRECISION) + : stringToBN(params.amount).mul(QUOTE_PRECISION); + + // Convert additionalEndPriceBuffer string to BN with PRICE_PRECISION (1e6) if provided + const additionalEndPriceBuffer = params.additionalEndPriceBuffer + ? stringToBN(params.additionalEndPriceBuffer).mul(PRICE_PRECISION) + : undefined; + + // Calculate estimated prices and handle slippage tolerance calculation + let estimatedPrices; + let processedSlippageTolerance = params.slippageTolerance; + + if (driftClient && fetchFromRedis && selectMostRecentBySlot) { + // Get L2 orderbook data using the utility function + const redisL2 = await fetchL2FromRedis( + fetchFromRedis, + selectMostRecentBySlot, + marketType, + params.marketIndex + ); + + // Calculate estimated prices using the fetched L2 data + estimatedPrices = await getEstimatedPricesWithL2( + driftClient, + marketType, + params.marketIndex, + direction, + amount, + params.assetType, + redisL2 + ); + + // Handle dynamic slippage tolerance calculation if needed + if (params.slippageTolerance === undefined) { + // Convert raw L2 to formatted L2 for slippage calculation + let l2Formatted: L2OrderBook; + if (redisL2) { + l2Formatted = convertRawL2ToBN(redisL2); + } else { + l2Formatted = { + bids: [], + asks: [], + }; + } + + processedSlippageTolerance = calculateDynamicSlippage( + params.marketIndex, + params.marketType, + driftClient, + l2Formatted + ); + } + } else { + return { + success: false, + error: 'Cannot create valid auction parameters: could not fetch prices', + }; + } + + // Calculate baseAmount based on assetType + let baseAmount: BN; + if (params.assetType === 'base') { + // If assetType is base, use the amount directly + baseAmount = amount; + } else { + // If assetType is quote, convert quote amount to base amount using entry price + // baseAmount = (quoteAmount * QUOTE_PRECISION * BASE_PRECISION) / entryPrice + baseAmount = amount.mul(BASE_PRECISION).div(estimatedPrices.entryPrice); + } + + return { + success: true, + data: { + marketOrderParams: { + marketType, + marketIndex: params.marketIndex, + direction, + maxLeverageSelected: false, + maxLeverageOrderSize: ZERO, + baseAmount, + reduceOnly: params.reduceOnly ?? false, + allowInfSlippage: params.allowInfSlippage ?? false, + oraclePrice: estimatedPrices.oraclePrice, + bestPrice: estimatedPrices.bestPrice, + entryPrice: estimatedPrices.entryPrice, + worstPrice: estimatedPrices.worstPrice, + markPrice: estimatedPrices.markPrice, + auctionDuration: params.auctionDuration, + auctionStartPriceOffset: params.auctionStartPriceOffset as number, + auctionEndPriceOffset: params.auctionEndPriceOffset, + auctionStartPriceOffsetFrom: params.auctionStartPriceOffsetFrom as any, + auctionEndPriceOffsetFrom: params.auctionEndPriceOffsetFrom, + slippageTolerance: processedSlippageTolerance, + isOracleOrder: params.isOracleOrder, + additionalEndPriceBuffer, + forceUpToSlippage: true, + userOrderId: params.userOrderId, + }, + estimatedPrices, + }, + }; +}; + +/** + * Format auction parameters for API response + * @param auctionParams - Raw auction parameters from deriveMarketOrderParams + * @returns Formatted auction parameters with BNs as strings and enums as readable strings + */ +export const formatAuctionParamsForResponse = (auctionParams: any) => { + const formatted = { ...auctionParams }; + + // we don't use this field anymore, TODO to remove from ui + delete formatted.constrainedBySlippage; + + // Convert all properties + Object.keys(formatted).forEach((key) => { + const value = formatted[key]; + + // Check if it's a BN using BN.isBN() + if (BN.isBN(value)) { + formatted[key] = value.toString(); + } + // Check if it's an enum (has nested object structure like {oracle: {}}) + else if ( + value && + typeof value === 'object' && + Object.keys(value).length === 1 + ) { + try { + formatted[key] = ENUM_UTILS.toStr(value); + } catch (e) { + // If ENUM_UTILS.toStr fails, keep original value + formatted[key] = value; + } + } + }); + + return formatted; +}; + +/** + * Fetch L2 orderbook data from Redis + * @param fetchFromRedis - Redis fetch function + * @param selectMostRecentBySlot - Slot selection function + * @param marketType - MarketType enum (spot or perp) + * @param marketIndex - Market index number + * @param includeIndicative - Whether to include indicative orders (optional) + * @returns Promise - Raw L2 data from Redis or null if not found + */ +export const fetchL2FromRedis = async ( + fetchFromRedis: ( + key: string, + selectionCriteria: (responses: any) => any + ) => Promise, + selectMostRecentBySlot: (responses: any[]) => any, + marketType: MarketType, + marketIndex: number, + includeIndicative?: boolean +): Promise => { + const isSpot = isVariant(marketType, 'spot'); + const marketTypeStr = isSpot ? 'spot' : 'perp'; + const indicativeSuffix = includeIndicative ? '_indicative' : ''; + + return await fetchFromRedis( + `last_update_orderbook_${marketTypeStr}_${marketIndex}${indicativeSuffix}`, + selectMostRecentBySlot + ); +}; + +/** + * Calculate dynamic slippage tolerance using L2 data + * @param direction - Position direction ('long' or 'short') + * @param marketIndex - Market index number + * @param marketType - Market type ('spot' or 'perp') + * @param driftClient - DriftClient instance for oracle data + * @param l2Formatted - Already formatted L2OrderBook data + * @returns Dynamic slippage tolerance as a number + */ +export const calculateDynamicSlippage = ( + marketIndex: number, + marketType: string, + driftClient: DriftClient, + l2Formatted: L2OrderBook +): number => { + // Determine if this is a major market (PERP with marketIndex 0, 1, or 2) + const isPerp = marketType.toLowerCase() === 'perp'; + const isMajor = isPerp && marketIndex < 3; + + const baseSlippage = isMajor + ? parseFloat(process.env.DYNAMIC_BASE_SLIPPAGE_MAJOR || '0') // 0% default + : parseFloat(process.env.DYNAMIC_BASE_SLIPPAGE_NON_MAJOR || '0.5'); // 0.5% default + + // Calculate spread using L2 data + let spreadBaseSlippage = 0.0005; // 0.05% fallback spread + try { + // Get oracle data + const oracleData = isPerp + ? driftClient.getOracleDataForPerpMarket(marketIndex) + : driftClient.getOracleDataForSpotMarket(marketIndex); + + // Get oracle price + const oraclePrice = new BN(oracleData?.price || 0).mul(PRICE_PRECISION); + + // Calculate actual spread + const spreadInfo = COMMON_MATH.calculateSpreadBidAskMark( + l2Formatted, + oraclePrice + ); + + const spreadPctNum = BigNum.from( + spreadInfo.spreadPct, + PERCENTAGE_PRECISION_EXP + )?.toNum(); + + if (spreadInfo?.spreadPct) { + spreadBaseSlippage = spreadPctNum / 2; + } + } catch (error) { + console.warn('Failed to calculate spread, using fallback:', error); + } + + let dynamicSlippage = baseSlippage + spreadBaseSlippage; + + // Apply multiplier from env var + const multiplier = isMajor + ? parseFloat(process.env.DYNAMIC_SLIPPAGE_MULTIPLIER_MAJOR || '1.02') + : parseFloat(process.env.DYNAMIC_SLIPPAGE_MULTIPLIER_NON_MAJOR || '1.5'); + dynamicSlippage = dynamicSlippage * multiplier; + + // Enforce minimum and maximum limits from env vars + const minSlippage = parseFloat(process.env.DYNAMIC_SLIPPAGE_MIN || '0.05'); // 0.05% minimum + const maxSlippage = parseFloat(process.env.DYNAMIC_SLIPPAGE_MAX || '5'); // 5% maximum + + return Math.min(Math.max(dynamicSlippage, minSlippage), maxSlippage); +}; + +/** + * Get L2 orderbook data and calculate estimated prices using pre-fetched L2 data + * @param driftClient - DriftClient instance + * @param marketType - MarketType enum + * @param marketIndex - Market index number + * @param direction - Position direction + * @param amount - Amount as BN (could be base or quote amount) + * @param assetType - Whether amount is 'base' or 'quote' + * @param redisL2 - Pre-fetched L2 data from Redis + * @returns Price data object with oracle, best, entry, worst, and mark prices + */ +export const getEstimatedPricesWithL2 = async ( + driftClient: DriftClient, + marketType: MarketType, + marketIndex: number, + direction: PositionDirection, + amount: BN, + assetType: AssetType, + redisL2: any +): Promise<{ + oraclePrice: BN; + bestPrice: BN; + entryPrice: BN; + worstPrice: BN; + markPrice: BN; + priceImpact: BN; +}> => { + const isSpot = isVariant(marketType, 'spot'); + + let l2Formatted: L2OrderBook; + if (redisL2) { + l2Formatted = convertRawL2ToBN(redisL2); + } else { + l2Formatted = { + bids: [], + asks: [], + }; + } + + const oracleData = isSpot + ? driftClient.getOracleDataForSpotMarket(marketIndex) + : driftClient.getOracleDataForPerpMarket(marketIndex); + + // Get oracle price + const oraclePrice = oracleData.price ?? ZERO; + + const spreadInfo = COMMON_MATH.calculateSpreadBidAskMark( + l2Formatted, + oraclePrice + ); + + const markPrice = spreadInfo?.markPrice ?? oraclePrice; + + // If we have L2 data, calculate estimated prices + if (l2Formatted.bids?.length > 0 || l2Formatted.asks?.length > 0) { + try { + const basePrecision = !isSpot + ? BASE_PRECISION + : process.env.ENV === 'mainnet-beta' + ? MainnetSpotMarkets[marketIndex].precision + : DevnetSpotMarkets[marketIndex].precision; + + const priceEstimate = calculateEstimatedEntryPriceWithL2( + assetType, + amount, + direction, + basePrecision, + l2Formatted as L2OrderBook + ); + + return { + oraclePrice, + bestPrice: priceEstimate.bestPrice, + entryPrice: priceEstimate.entryPrice, + worstPrice: priceEstimate.worstPrice, + markPrice, + priceImpact: priceEstimate.priceImpact, + }; + } catch (error) { + // If calculation fails, fallback to oracle prices + console.warn('Price calculation failed, using oracle fallback:', error); + } + } + + // Fallback to oracle prices if no L2 data or calculation fails + return { + oraclePrice, + bestPrice: oraclePrice, + entryPrice: oraclePrice, + worstPrice: oraclePrice, + markPrice, + priceImpact: ZERO, + }; +}; diff --git a/yarn.lock b/yarn.lock index 674eed1..4e80d03 100644 --- a/yarn.lock +++ b/yarn.lock @@ -453,6 +453,15 @@ dependencies: "@babel/highlight" "^7.10.4" +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.27.1.tgz#200f715e66d52a23b221a9435534a91cc13ad5be" + integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg== + dependencies: + "@babel/helper-validator-identifier" "^7.27.1" + js-tokens "^4.0.0" + picocolors "^1.1.1" + "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.23.5", "@babel/code-frame@^7.24.2": version "7.24.2" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.2.tgz#718b4b19841809a58b29b68cde80bc5e1aa6d9ae" @@ -466,6 +475,11 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.24.4.tgz#6f102372e9094f25d908ca0d34fc74c74606059a" integrity sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ== +"@babel/compat-data@^7.27.2": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.28.0.tgz#9fc6fd58c2a6a15243cd13983224968392070790" + integrity sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw== + "@babel/core@^7.11.6", "@babel/core@^7.12.3": version "7.24.5" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.24.5.tgz#15ab5b98e101972d171aeef92ac70d8d6718f06a" @@ -487,6 +501,27 @@ json5 "^2.2.3" semver "^6.3.1" +"@babel/core@^7.23.9": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.0.tgz#55dad808d5bf3445a108eefc88ea3fdf034749a4" + integrity sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.27.1" + "@babel/generator" "^7.28.0" + "@babel/helper-compilation-targets" "^7.27.2" + "@babel/helper-module-transforms" "^7.27.3" + "@babel/helpers" "^7.27.6" + "@babel/parser" "^7.28.0" + "@babel/template" "^7.27.2" + "@babel/traverse" "^7.28.0" + "@babel/types" "^7.28.0" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + "@babel/generator@^7.24.5", "@babel/generator@^7.7.2": version "7.24.5" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.24.5.tgz#e5afc068f932f05616b66713e28d0f04e99daeb3" @@ -497,6 +532,17 @@ "@jridgewell/trace-mapping" "^0.3.25" jsesc "^2.5.1" +"@babel/generator@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.0.tgz#9cc2f7bd6eb054d77dc66c2664148a0c5118acd2" + integrity sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg== + dependencies: + "@babel/parser" "^7.28.0" + "@babel/types" "^7.28.0" + "@jridgewell/gen-mapping" "^0.3.12" + "@jridgewell/trace-mapping" "^0.3.28" + jsesc "^3.0.2" + "@babel/helper-compilation-targets@^7.23.6": version "7.23.6" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz#4d79069b16cbcf1461289eccfbbd81501ae39991" @@ -508,6 +554,17 @@ lru-cache "^5.1.1" semver "^6.3.1" +"@babel/helper-compilation-targets@^7.27.2": + version "7.27.2" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz#46a0f6efab808d51d29ce96858dd10ce8732733d" + integrity sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ== + dependencies: + "@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" + "@babel/helper-environment-visitor@^7.22.20": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" @@ -521,6 +578,11 @@ "@babel/template" "^7.22.15" "@babel/types" "^7.23.0" +"@babel/helper-globals@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz#b9430df2aa4e17bc28665eadeae8aa1d985e6674" + integrity sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw== + "@babel/helper-hoist-variables@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" @@ -535,6 +597,14 @@ dependencies: "@babel/types" "^7.24.0" +"@babel/helper-module-imports@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz#7ef769a323e2655e126673bb6d2d6913bbead204" + integrity sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w== + dependencies: + "@babel/traverse" "^7.27.1" + "@babel/types" "^7.27.1" + "@babel/helper-module-transforms@^7.24.5": version "7.24.5" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.24.5.tgz#ea6c5e33f7b262a0ae762fd5986355c45f54a545" @@ -546,6 +616,15 @@ "@babel/helper-split-export-declaration" "^7.24.5" "@babel/helper-validator-identifier" "^7.24.5" +"@babel/helper-module-transforms@^7.27.3": + version "7.27.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz#db0bbcfba5802f9ef7870705a7ef8788508ede02" + integrity sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg== + dependencies: + "@babel/helper-module-imports" "^7.27.1" + "@babel/helper-validator-identifier" "^7.27.1" + "@babel/traverse" "^7.27.3" + "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.24.0", "@babel/helper-plugin-utils@^7.8.0": version "7.24.5" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.5.tgz#a924607dd254a65695e5bd209b98b902b3b2f11a" @@ -570,6 +649,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz#f99c36d3593db9540705d0739a1f10b5e20c696e" integrity sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ== +"@babel/helper-string-parser@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687" + integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== + "@babel/helper-validator-identifier@^7.18.6": version "7.19.1" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" @@ -580,11 +664,21 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz#918b1a7fa23056603506370089bd990d8720db62" integrity sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA== +"@babel/helper-validator-identifier@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8" + integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow== + "@babel/helper-validator-option@^7.23.5": version "7.23.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== +"@babel/helper-validator-option@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz#fa52f5b1e7db1ab049445b421c4471303897702f" + integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg== + "@babel/helpers@^7.24.5": version "7.24.5" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.24.5.tgz#fedeb87eeafa62b621160402181ad8585a22a40a" @@ -594,6 +688,14 @@ "@babel/traverse" "^7.24.5" "@babel/types" "^7.24.5" +"@babel/helpers@^7.27.6": + version "7.27.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.27.6.tgz#6456fed15b2cb669d2d1fabe84b66b34991d812c" + integrity sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug== + dependencies: + "@babel/template" "^7.27.2" + "@babel/types" "^7.27.6" + "@babel/highlight@^7.10.4": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" @@ -613,6 +715,13 @@ js-tokens "^4.0.0" picocolors "^1.0.0" +"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.27.2", "@babel/parser@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.0.tgz#979829fbab51a29e13901e5a80713dbcb840825e" + integrity sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g== + dependencies: + "@babel/types" "^7.28.0" + "@babel/parser@^7.14.7", "@babel/parser@^7.24.0", "@babel/parser@^7.24.5": version "7.24.5" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.5.tgz#4a4d5ab4315579e5398a82dcf636ca80c3392790" @@ -746,6 +855,15 @@ "@babel/parser" "^7.24.0" "@babel/types" "^7.24.0" +"@babel/template@^7.27.2", "@babel/template@^7.3.3": + version "7.27.2" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.27.2.tgz#fa78ceed3c4e7b63ebf6cb39e5852fca45f6809d" + integrity sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw== + dependencies: + "@babel/code-frame" "^7.27.1" + "@babel/parser" "^7.27.2" + "@babel/types" "^7.27.1" + "@babel/traverse@^7.24.5": version "7.24.5" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.5.tgz#972aa0bc45f16983bf64aa1f877b2dd0eea7e6f8" @@ -762,6 +880,27 @@ debug "^4.3.1" globals "^11.1.0" +"@babel/traverse@^7.27.1", "@babel/traverse@^7.27.3", "@babel/traverse@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.0.tgz#518aa113359b062042379e333db18380b537e34b" + integrity sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg== + dependencies: + "@babel/code-frame" "^7.27.1" + "@babel/generator" "^7.28.0" + "@babel/helper-globals" "^7.28.0" + "@babel/parser" "^7.28.0" + "@babel/template" "^7.27.2" + "@babel/types" "^7.28.0" + debug "^4.3.1" + +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.27.1", "@babel/types@^7.27.6", "@babel/types@^7.28.0": + version "7.28.1" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.1.tgz#2aaf3c10b31ba03a77ac84f52b3912a0edef4cf9" + integrity sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ== + dependencies: + "@babel/helper-string-parser" "^7.27.1" + "@babel/helper-validator-identifier" "^7.27.1" + "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.24.0", "@babel/types@^7.24.5", "@babel/types@^7.3.3": version "7.24.5" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.5.tgz#7661930afc638a5383eb0c4aee59b74f38db84d7" @@ -771,6 +910,11 @@ "@babel/helper-validator-identifier" "^7.24.5" to-fast-properties "^2.0.0" +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + "@colors/colors@1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" @@ -859,8 +1003,8 @@ enabled "2.0.x" kuler "^2.0.0" -"@drift-labs/sdk@file:./drift-common/protocol/sdk", "@drift-labs/sdk@file:drift-common/protocol/sdk": - version "2.123.0-beta.0" +"@drift-labs/sdk@2.126.0-beta.11", "@drift-labs/sdk@file:drift-common/protocol/sdk": + version "2.126.0-beta.11" dependencies: "@coral-xyz/anchor" "0.29.0" "@coral-xyz/anchor-30" "npm:@coral-xyz/anchor@0.30.1" @@ -891,7 +1035,7 @@ "@drift/common@file:./drift-common/common-ts": version "1.0.0" dependencies: - "@drift-labs/sdk" "file:../Library/Caches/Yarn/v6/npm-@drift-common-1.0.0-7a36f885-90b7-4c71-b92f-9112bfdc6aee-1750120546913/node_modules/@drift/protocol/sdk" + "@drift-labs/sdk" "file:../../../Library/Caches/Yarn/v6/npm-@drift-common-1.0.0-ec50fb48-a8f0-4afe-ab64-240fcabb7e43-1752529047869/node_modules/@drift/protocol/sdk" "@jest/globals" "29.3.1" "@slack/web-api" "6.4.0" "@solana/spl-token" "0.3.8" @@ -1221,12 +1365,58 @@ js-yaml "^3.13.1" resolve-from "^5.0.0" -"@istanbuljs/schema@^0.1.2": +"@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3": version "0.1.3" resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/environment@^29.3.1": +"@jest/console@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.7.0.tgz#cd4822dbdb84529265c5a2bdb529a3c9cc950ffc" + integrity sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + slash "^3.0.0" + +"@jest/core@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.7.0.tgz#b6cccc239f30ff36609658c5a5e2291757ce448f" + integrity sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg== + dependencies: + "@jest/console" "^29.7.0" + "@jest/reporters" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + ci-info "^3.2.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^29.7.0" + jest-config "^29.7.0" + jest-haste-map "^29.7.0" + jest-message-util "^29.7.0" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-resolve-dependencies "^29.7.0" + jest-runner "^29.7.0" + jest-runtime "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + jest-watcher "^29.7.0" + micromatch "^4.0.4" + pretty-format "^29.7.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^29.3.1", "@jest/environment@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.7.0.tgz#24d61f54ff1f786f3cd4073b4b94416383baf2a7" integrity sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw== @@ -1243,7 +1433,7 @@ dependencies: jest-get-type "^29.6.3" -"@jest/expect@^29.3.1": +"@jest/expect@^29.3.1", "@jest/expect@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.7.0.tgz#76a3edb0cb753b70dfbfe23283510d3d45432bf2" integrity sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ== @@ -1273,6 +1463,46 @@ "@jest/types" "^29.3.1" jest-mock "^29.3.1" +"@jest/globals@^29.3.1", "@jest/globals@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.7.0.tgz#8d9290f9ec47ff772607fa864ca1d5a2efae1d4d" + integrity sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/expect" "^29.7.0" + "@jest/types" "^29.6.3" + jest-mock "^29.7.0" + +"@jest/reporters@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.7.0.tgz#04b262ecb3b8faa83b0b3d321623972393e8f4c7" + integrity sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@jridgewell/trace-mapping" "^0.3.18" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^6.0.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + jest-worker "^29.7.0" + slash "^3.0.0" + string-length "^4.0.1" + strip-ansi "^6.0.0" + v8-to-istanbul "^9.0.1" + "@jest/schemas@^29.6.3": version "29.6.3" resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" @@ -1280,6 +1510,35 @@ dependencies: "@sinclair/typebox" "^0.27.8" +"@jest/source-map@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.6.3.tgz#d90ba772095cf37a34a5eb9413f1b562a08554c4" + integrity sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw== + dependencies: + "@jridgewell/trace-mapping" "^0.3.18" + callsites "^3.0.0" + graceful-fs "^4.2.9" + +"@jest/test-result@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.7.0.tgz#8db9a80aa1a097bb2262572686734baed9b1657c" + integrity sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA== + dependencies: + "@jest/console" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-sequencer@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz#6cef977ce1d39834a3aea887a1726628a6f072ce" + integrity sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw== + dependencies: + "@jest/test-result" "^29.7.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + slash "^3.0.0" + "@jest/transform@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.7.0.tgz#df2dd9c346c7d7768b8a06639994640c642e284c" @@ -1313,6 +1572,14 @@ "@types/yargs" "^17.0.8" chalk "^4.0.0" +"@jridgewell/gen-mapping@^0.3.12": + version "0.3.12" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz#2234ce26c62889f03db3d7fea43c1932ab3e927b" + integrity sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + "@jridgewell/trace-mapping" "^0.3.24" + "@jridgewell/gen-mapping@^0.3.5": version "0.3.5" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" @@ -1347,6 +1614,11 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== +"@jridgewell/sourcemap-codec@^1.5.0": + version "1.5.4" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz#7358043433b2e5da569aa02cbc4c121da3af27d7" + integrity sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw== + "@jridgewell/trace-mapping@0.3.9": version "0.3.9" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" @@ -1355,6 +1627,14 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.28": + version "0.3.29" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz#a58d31eaadaf92c6695680b2e1d464a9b8fbf7fc" + integrity sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": version "0.3.25" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" @@ -3214,6 +3494,39 @@ resolved "https://registry.yarnpkg.com/@types/aws-lambda/-/aws-lambda-8.10.81.tgz#6d405269aad82e05a348687631aa9a587cdbe158" integrity sha512-C1rFKGVZ8KwqhwBOYlpoybTSRtxu2433ea6JaO3amc6ubEe08yQoFsPa9aU9YqvX7ppeZ25CnCtC4AH9mhtxsQ== +"@types/babel__core@^7.1.14": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" + integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== + dependencies: + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.27.0" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.27.0.tgz#b5819294c51179957afaec341442f9341e4108a9" + integrity sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" + integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.7.tgz#968cdc2366ec3da159f61166428ee40f370e56c2" + integrity sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng== + dependencies: + "@babel/types" "^7.20.7" + "@types/bluebird@*": version "3.5.38" resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.5.38.tgz#7a671e66750ccd21c9fc9d264d0e1e5330bc9908" @@ -3370,7 +3683,7 @@ dependencies: "@types/node" "*" -"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.6" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== @@ -3389,6 +3702,14 @@ dependencies: "@types/istanbul-lib-report" "*" +"@types/jest@^29.4.0": + version "29.5.14" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.14.tgz#2b910912fa1d6856cadcd0c1f95af7df1d6049e5" + integrity sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ== + dependencies: + expect "^29.0.0" + pretty-format "^29.0.0" + "@types/json-schema@^7.0.7": version "7.0.11" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" @@ -3797,6 +4118,13 @@ ansi-colors@^4.1.1: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== +ansi-escapes@^4.2.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" @@ -3952,6 +4280,19 @@ axios@^1.8.3, axios@^1.9.0: form-data "^4.0.0" proxy-from-env "^1.1.0" +babel-jest@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" + integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== + dependencies: + "@jest/transform" "^29.7.0" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^29.6.3" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + babel-plugin-istanbul@^6.1.1: version "6.1.1" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" @@ -3963,6 +4304,16 @@ babel-plugin-istanbul@^6.1.1: istanbul-lib-instrument "^5.0.4" test-exclude "^6.0.0" +babel-plugin-jest-hoist@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz#aadbe943464182a8922c3c927c3067ff40d24626" + integrity sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.1.14" + "@types/babel__traverse" "^7.0.6" + babel-preset-current-node-syntax@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" @@ -3981,6 +4332,14 @@ babel-preset-current-node-syntax@^1.0.0: "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-top-level-await" "^7.8.3" +babel-preset-jest@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz#fa05fa510e7d493896d7b0dd2033601c840f171c" + integrity sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA== + dependencies: + babel-plugin-jest-hoist "^29.6.3" + babel-preset-current-node-syntax "^1.0.0" + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" @@ -4138,6 +4497,23 @@ browserslist@^4.22.2: node-releases "^2.0.14" update-browserslist-db "^1.0.13" +browserslist@^4.24.0: + version "4.25.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.25.1.tgz#ba9e8e6f298a1d86f829c9b975e07948967bb111" + integrity sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw== + dependencies: + caniuse-lite "^1.0.30001726" + electron-to-chromium "^1.5.173" + node-releases "^2.0.19" + update-browserslist-db "^1.1.3" + +bs-logger@^0.2.6: + version "0.2.6" + resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" + integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== + dependencies: + fast-json-stable-stringify "2.x" + bs58@^4.0.0, bs58@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" @@ -4173,6 +4549,11 @@ bson@*: dependencies: buffer "^5.6.0" +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + buffer-layout@^1.2.0, buffer-layout@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/buffer-layout/-/buffer-layout-1.2.2.tgz#b9814e7c7235783085f9ca4966a0cfff112259d5" @@ -4237,7 +4618,7 @@ camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -camelcase@^6.0.0, camelcase@^6.2.1, camelcase@^6.3.0: +camelcase@^6.0.0, camelcase@^6.2.0, camelcase@^6.2.1, camelcase@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== @@ -4247,6 +4628,11 @@ caniuse-lite@^1.0.30001587: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001618.tgz#fad74fa006aef0f01e8e5c0a5540c74d8d36ec6f" integrity sha512-p407+D1tIkDvsEAPS22lJxLQQaG8OTBEqo0KhzfABGk0TU4juBNDSfH0hyAp/HRyx+M8L17z/ltyhxh27FTfQg== +caniuse-lite@^1.0.30001726: + version "1.0.30001727" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz#22e9706422ad37aa50556af8c10e40e2d93a8b85" + integrity sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q== + cerializr@3.1.4: version "3.1.4" resolved "https://registry.yarnpkg.com/cerializr/-/cerializr-3.1.4.tgz#e26dcedbd1e715ec57f54ca4d383e3abe43fac6b" @@ -4264,7 +4650,7 @@ chalk@^2.0.0, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0, chalk@^4.1.0: +chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -4282,6 +4668,11 @@ chalk@^5.4.1: resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.4.1.tgz#1b48bf0963ec158dce2aacf69c093ae2dd2092d8" integrity sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w== +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + chokidar@3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" @@ -4302,6 +4693,11 @@ ci-info@^3.2.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== +cjs-module-lexer@^1.0.0: + version "1.4.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz#0f79731eb8cfe1ec72acd4066efac9d61991b00d" + integrity sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q== + cliui@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" @@ -4330,6 +4726,16 @@ cluster-key-slot@1.1.2, cluster-key-slot@^1.1.0: resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac" integrity sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA== +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== + +collect-v8-coverage@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" + integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== + color-convert@^1.9.0, color-convert@^1.9.3: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -4475,6 +4881,19 @@ cors@^2.8.5: object-assign "^4" vary "^1" +create-jest@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/create-jest/-/create-jest-29.7.0.tgz#a355c5b3cb1e1af02ba177fe7afd7feee49a5320" + integrity sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q== + dependencies: + "@jest/types" "^29.6.3" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-config "^29.7.0" + jest-util "^29.7.0" + prompts "^2.0.1" + create-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" @@ -4496,6 +4915,15 @@ cross-spawn@^7.0.2: shebang-command "^2.0.0" which "^2.0.1" +cross-spawn@^7.0.3: + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + crypto-hash@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/crypto-hash/-/crypto-hash-1.3.0.tgz#b402cb08f4529e9f4f09346c3e275942f845e247" @@ -4525,6 +4953,11 @@ decimal.js@^10.4.3: resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== +dedent@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.6.0.tgz#79d52d6389b1ffa67d2bcef59ba51847a9d503b2" + integrity sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA== + deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" @@ -4578,6 +5011,11 @@ destroy@1.2.0: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + diff-sequences@^29.6.3: version "29.6.3" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" @@ -4640,11 +5078,28 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== +ejs@^3.1.10: + version "3.1.10" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b" + integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA== + dependencies: + jake "^10.8.5" + electron-to-chromium@^1.4.668: version "1.4.768" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.768.tgz#3795bd000ccb8978be1af2d06320b2dac810a372" integrity sha512-z2U3QcvNuxdkk33YV7R1bVMNq7fL23vq3WfO5BHcqrm4TnDGReouBfYKLEFh5umoK1XACjEwp8mmnhXk2EJigw== +electron-to-chromium@^1.5.173: + version "1.5.183" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.183.tgz#38c2e16910569b6c595bd16d1d39d1218bf0ffb6" + integrity sha512-vCrDBYjQCAEefWGjlK3EpoSKfKbT10pR4XXPdn65q7snuNOZnthoVpBfZPykmDapOKfoD+MMIPG8ZjKyyc9oHA== + +emittery@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" + integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -4674,6 +5129,13 @@ enquirer@^2.3.5: dependencies: ansi-colors "^4.1.1" +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + es6-object-assign@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/es6-object-assign/-/es6-object-assign-1.1.0.tgz#c2c3582656247c39ea107cb1e6652b6f9f24523c" @@ -4731,6 +5193,11 @@ escalade@^3.1.2: resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== +escalade@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -4916,7 +5383,27 @@ eventsource@^3.0.5: dependencies: eventsource-parser "^3.0.1" -expect@^29.7.0: +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== + +expect@^29.0.0, expect@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== @@ -4995,7 +5482,7 @@ fast-glob@^3.2.9: merge2 "^1.3.0" micromatch "^4.0.4" -fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -5090,6 +5577,13 @@ file-uri-to-path@1.0.0: resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== +filelist@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" + integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== + dependencies: + minimatch "^5.0.1" + fill-range@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" @@ -5137,7 +5631,7 @@ find-up@5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" -find-up@^4.1.0: +find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== @@ -5245,6 +5739,11 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" @@ -5279,6 +5778,11 @@ get-package-type@^0.1.0: resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -5397,11 +5901,23 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +hasown@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + he@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + http-errors@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" @@ -5413,6 +5929,11 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + humanize-ms@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" @@ -5460,6 +5981,14 @@ import-fresh@^3.0.0, import-fresh@^3.2.1: parent-module "^1.0.0" resolve-from "^4.0.0" +import-local@^3.0.2: + version "3.2.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.2.0.tgz#c3d5c745798c02a6f8b897726aba5100186ee260" + integrity sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -5506,6 +6035,11 @@ is-arguments@^1.0.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + is-arrayish@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" @@ -5523,6 +6057,13 @@ is-callable@^1.1.3: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== +is-core-module@^2.16.0: + version "2.16.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4" + integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== + dependencies: + hasown "^2.0.2" + is-core-module@^2.9.0: version "2.11.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" @@ -5545,6 +6086,11 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + is-generator-function@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" @@ -5618,7 +6164,7 @@ isomorphic-ws@^5.0.0: resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== -istanbul-lib-coverage@^3.2.0: +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== @@ -5634,6 +6180,53 @@ istanbul-lib-instrument@^5.0.4: istanbul-lib-coverage "^3.2.0" semver "^6.3.0" +istanbul-lib-instrument@^6.0.0: + version "6.0.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz#fa15401df6c15874bcb2105f773325d78c666765" + integrity sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q== + dependencies: + "@babel/core" "^7.23.9" + "@babel/parser" "^7.23.9" + "@istanbuljs/schema" "^0.1.3" + istanbul-lib-coverage "^3.2.0" + semver "^7.5.4" + +istanbul-lib-report@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" + integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^4.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.1.3: + version "3.1.7" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.7.tgz#daed12b9e1dca518e15c056e1e537e741280fa0b" + integrity sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jake@^10.8.5: + version "10.9.2" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.2.tgz#6ae487e6a69afec3a5e167628996b59f35ae2b7f" + integrity sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA== + dependencies: + async "^3.2.3" + chalk "^4.0.2" + filelist "^1.0.4" + minimatch "^3.1.2" + jayson@^3.4.4: version "3.7.0" resolved "https://registry.yarnpkg.com/jayson/-/jayson-3.7.0.tgz#b735b12d06d348639ae8230d7a1e2916cb078f25" @@ -5689,6 +6282,86 @@ jayson@^4.1.0: uuid "^8.3.2" ws "^7.4.5" +jest-changed-files@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a" + integrity sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w== + dependencies: + execa "^5.0.0" + jest-util "^29.7.0" + p-limit "^3.1.0" + +jest-circus@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.7.0.tgz#b6817a45fcc835d8b16d5962d0c026473ee3668a" + integrity sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/expect" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^1.0.0" + is-generator-fn "^2.0.0" + jest-each "^29.7.0" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-runtime "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + p-limit "^3.1.0" + pretty-format "^29.7.0" + pure-rand "^6.0.0" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-cli@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.7.0.tgz#5592c940798e0cae677eec169264f2d839a37995" + integrity sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg== + dependencies: + "@jest/core" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" + chalk "^4.0.0" + create-jest "^29.7.0" + exit "^0.1.2" + import-local "^3.0.2" + jest-config "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + yargs "^17.3.1" + +jest-config@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.7.0.tgz#bcbda8806dbcc01b1e316a46bb74085a84b0245f" + integrity sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ== + dependencies: + "@babel/core" "^7.11.6" + "@jest/test-sequencer" "^29.7.0" + "@jest/types" "^29.6.3" + babel-jest "^29.7.0" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-circus "^29.7.0" + jest-environment-node "^29.7.0" + jest-get-type "^29.6.3" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-runner "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^29.7.0" + slash "^3.0.0" + strip-json-comments "^3.1.1" + jest-diff@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" @@ -5699,6 +6372,36 @@ jest-diff@^29.7.0: jest-get-type "^29.6.3" pretty-format "^29.7.0" +jest-docblock@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.7.0.tgz#8fddb6adc3cdc955c93e2a87f61cfd350d5d119a" + integrity sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g== + dependencies: + detect-newline "^3.0.0" + +jest-each@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.7.0.tgz#162a9b3f2328bdd991beaabffbb74745e56577d1" + integrity sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ== + dependencies: + "@jest/types" "^29.6.3" + chalk "^4.0.0" + jest-get-type "^29.6.3" + jest-util "^29.7.0" + pretty-format "^29.7.0" + +jest-environment-node@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.7.0.tgz#0b93e111dda8ec120bc8300e6d1fb9576e164376" + integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/fake-timers" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + jest-mock "^29.7.0" + jest-util "^29.7.0" + jest-get-type@^29.6.3: version "29.6.3" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" @@ -5723,6 +6426,14 @@ jest-haste-map@^29.7.0: optionalDependencies: fsevents "^2.3.2" +jest-leak-detector@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz#5b7ec0dadfdfec0ca383dc9aa016d36b5ea4c728" + integrity sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw== + dependencies: + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + jest-matcher-utils@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12" @@ -5757,11 +6468,94 @@ jest-mock@^29.3.1, jest-mock@^29.7.0: "@types/node" "*" jest-util "^29.7.0" +jest-pnp-resolver@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" + integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== + jest-regex-util@^29.6.3: version "29.6.3" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.6.3.tgz#4a556d9c776af68e1c5f48194f4d0327d24e8a52" integrity sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg== +jest-resolve-dependencies@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz#1b04f2c095f37fc776ff40803dc92921b1e88428" + integrity sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA== + dependencies: + jest-regex-util "^29.6.3" + jest-snapshot "^29.7.0" + +jest-resolve@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.7.0.tgz#64d6a8992dd26f635ab0c01e5eef4399c6bcbc30" + integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA== + dependencies: + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + jest-pnp-resolver "^1.2.2" + jest-util "^29.7.0" + jest-validate "^29.7.0" + resolve "^1.20.0" + resolve.exports "^2.0.0" + slash "^3.0.0" + +jest-runner@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.7.0.tgz#809af072d408a53dcfd2e849a4c976d3132f718e" + integrity sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ== + dependencies: + "@jest/console" "^29.7.0" + "@jest/environment" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.13.1" + graceful-fs "^4.2.9" + jest-docblock "^29.7.0" + jest-environment-node "^29.7.0" + jest-haste-map "^29.7.0" + jest-leak-detector "^29.7.0" + jest-message-util "^29.7.0" + jest-resolve "^29.7.0" + jest-runtime "^29.7.0" + jest-util "^29.7.0" + jest-watcher "^29.7.0" + jest-worker "^29.7.0" + p-limit "^3.1.0" + source-map-support "0.5.13" + +jest-runtime@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.7.0.tgz#efecb3141cf7d3767a3a0cc8f7c9990587d3d817" + integrity sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/fake-timers" "^29.7.0" + "@jest/globals" "^29.7.0" + "@jest/source-map" "^29.6.3" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + jest-message-util "^29.7.0" + jest-mock "^29.7.0" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + slash "^3.0.0" + strip-bom "^4.0.0" + jest-snapshot@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.7.0.tgz#c2c574c3f51865da1bb329036778a69bf88a6be5" @@ -5800,6 +6594,32 @@ jest-util@^29.7.0: graceful-fs "^4.2.9" picomatch "^2.2.3" +jest-validate@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c" + integrity sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw== + dependencies: + "@jest/types" "^29.6.3" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^29.6.3" + leven "^3.1.0" + pretty-format "^29.7.0" + +jest-watcher@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.7.0.tgz#7810d30d619c3a62093223ce6bb359ca1b28a2f2" + integrity sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g== + dependencies: + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.13.1" + jest-util "^29.7.0" + string-length "^4.0.1" + jest-worker@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a" @@ -5810,6 +6630,16 @@ jest-worker@^29.7.0: merge-stream "^2.0.0" supports-color "^8.0.0" +jest@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-29.7.0.tgz#994676fc24177f088f1c5e3737f5697204ff2613" + integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw== + dependencies: + "@jest/core" "^29.7.0" + "@jest/types" "^29.6.3" + import-local "^3.0.2" + jest-cli "^29.7.0" + jito-ts@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/jito-ts/-/jito-ts-3.0.1.tgz#24126389896e042c26d303c4e802064b249ed27e" @@ -5870,6 +6700,16 @@ jsesc@^2.5.1: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== +jsesc@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d" + integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -5905,11 +6745,21 @@ k6@^0.0.0: resolved "https://registry.yarnpkg.com/k6/-/k6-0.0.0.tgz#8c923200be0a68c578e8f5a32be96b1d8065cc3b" integrity sha512-GAQSWayS2+LjbH5bkRi+pMPYyP1JSp7o+4j58ANZ762N/RH/SdlAT3CHHztnn8s/xgg8kYNM24Gd2IPo9b5W+g== +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + kuler@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + levn@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" @@ -5928,6 +6778,11 @@ light-my-request@^4.2.0: process-warning "^1.0.0" set-cookie-parser "^2.4.1" +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + localstorage-memory@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/localstorage-memory/-/localstorage-memory-1.0.3.tgz#566b37968fe0c4d76ba36a6da564fa613945ca72" @@ -5962,6 +6817,11 @@ lodash.isarguments@^3.1.0: resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" integrity sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg== +lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== + lodash.merge@4.6.2, lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" @@ -6034,7 +6894,14 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -make-error@^1.1.1: +make-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" + integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== + dependencies: + semver "^7.5.3" + +make-error@^1.1.1, make-error@^1.3.6: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== @@ -6096,6 +6963,11 @@ mime@1.6.0: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + minimatch@5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" @@ -6103,13 +6975,20 @@ minimatch@5.0.1: dependencies: brace-expansion "^2.0.1" -minimatch@^3.0.4, minimatch@^3.1.1: +minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" +minimatch@^5.0.1: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + mocha@10.2.0: version "10.2.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" @@ -6239,6 +7118,11 @@ node-releases@^2.0.14: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== +node-releases@^2.0.19: + version "2.0.19" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314" + integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw== + normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" @@ -6249,6 +7133,13 @@ notepack.io@~2.2.0: resolved "https://registry.yarnpkg.com/notepack.io/-/notepack.io-2.2.0.tgz#d7ea71d1cb90094f88c6f3c8d84277c2d0cd101c" integrity sha512-9b5w3t5VSH6ZPosoYnyDONnUTF8o0UkBw7JLA6eBlYJWyGT1Q3vQa8Hmuj1/X6RYvHjjygBDgw6fJhe0JEojfw== +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + object-assign@^4: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -6310,6 +7201,13 @@ one-time@^1.0.0: dependencies: fn.name "1.x.x" +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + optionator@^0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" @@ -6334,7 +7232,7 @@ p-limit@^2.2.0: dependencies: p-try "^2.0.0" -p-limit@^3.0.2: +p-limit@^3.0.2, p-limit@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== @@ -6395,6 +7293,16 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" @@ -6410,7 +7318,7 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== -path-key@^3.1.0: +path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== @@ -6456,6 +7364,11 @@ picocolors@^1.0.0, picocolors@^1.0.1: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== +picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== + picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" @@ -6514,6 +7427,13 @@ pirates@^4.0.4: resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + postgres-array@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" @@ -6558,7 +7478,7 @@ prettier@^2.5.1: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== -pretty-format@^29.7.0: +pretty-format@^29.0.0, pretty-format@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== @@ -6585,6 +7505,14 @@ prom-client@^15.0.0: "@opentelemetry/api" "^1.4.0" tdigest "^0.1.1" +prompts@^2.0.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + protobufjs@^7.2.4: version "7.2.5" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.5.tgz#45d5c57387a6d29a17aab6846dcc283f9b8e7f2d" @@ -6657,6 +7585,11 @@ punycode@^2.1.0: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +pure-rand@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.1.0.tgz#d173cf23258231976ccbdb05247c9787957604f2" + integrity sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA== + qs@6.11.0: version "6.11.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" @@ -6804,6 +7737,13 @@ require-in-the-middle@^5.0.3: module-details-from-path "^1.0.3" resolve "^1.22.1" +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" @@ -6814,6 +7754,20 @@ resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== +resolve.exports@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.3.tgz#41955e6f1b4013b7586f873749a635dea07ebe3f" + integrity sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A== + +resolve@^1.20.0: + version "1.22.10" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39" + integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w== + dependencies: + is-core-module "^2.16.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + resolve@^1.22.1: version "1.22.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" @@ -6956,6 +7910,11 @@ semver@^7.5.3: resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.2.tgz#1e3b34759f896e8f14d6134732ce798aeb0c6e13" integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w== +semver@^7.5.4, semver@^7.7.2: + version "7.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58" + integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== + send@0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" @@ -7028,7 +7987,7 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" -signal-exit@^3.0.7: +signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== @@ -7040,6 +7999,11 @@ simple-swizzle@^0.2.2: dependencies: is-arrayish "^0.3.1" +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -7132,6 +8096,19 @@ sonic-boom@^2.2.1: dependencies: atomic-sleep "^1.0.0" +source-map-support@0.5.13: + version "0.5.13" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + split2@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/split2/-/split2-4.1.0.tgz#101907a24370f85bb782f08adaabe4e281ecf809" @@ -7182,6 +8159,14 @@ strict-event-emitter-types@2.0.0: resolved "https://registry.yarnpkg.com/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz#05e15549cb4da1694478a53543e4e2f4abcf277f" integrity sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA== +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== + dependencies: + char-regex "^1.0.2" + strip-ansi "^6.0.0" + string-similarity@^4.0.1: version "4.0.4" resolved "https://registry.yarnpkg.com/string-similarity/-/string-similarity-4.0.4.tgz#42d01ab0b34660ea8a018da8f56a3309bb8b2a5b" @@ -7210,6 +8195,16 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" @@ -7380,6 +8375,21 @@ triple-beam@^1.3.0: resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9" integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== +ts-jest@^29.1.0: + version "29.4.0" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.4.0.tgz#bef0ee98d94c83670af7462a1617bf2367a83740" + integrity sha512-d423TJMnJGu80/eSgfQ5w/R+0zFJvdtTxwtF9KzFFunOpSeD+79lHJQIiAhluJoyGRbvj9NZJsl9WjCUo0ND7Q== + dependencies: + bs-logger "^0.2.6" + ejs "^3.1.10" + fast-json-stable-stringify "^2.1.0" + json5 "^2.2.3" + lodash.memoize "^4.1.2" + make-error "^1.3.6" + semver "^7.7.2" + type-fest "^4.41.0" + yargs-parser "^21.1.1" + ts-node@^10.9.1: version "10.9.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" @@ -7453,6 +8463,16 @@ type-fest@^0.20.2: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-fest@^4.41.0: + version "4.41.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.41.0.tgz#6ae1c8e5731273c2bf1f58ad39cbae2c91a46c58" + integrity sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA== + type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -7499,6 +8519,14 @@ update-browserslist-db@^1.0.13: escalade "^3.1.2" picocolors "^1.0.1" +update-browserslist-db@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420" + integrity sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw== + dependencies: + escalade "^3.2.0" + picocolors "^1.1.1" + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -7554,6 +8582,15 @@ v8-compile-cache@^2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== +v8-to-istanbul@^9.0.1: + version "9.3.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz#b9572abfa62bd556c16d75fdebc1a411d5ff3175" + integrity sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.12" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^2.0.0" + vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -7773,7 +8810,7 @@ yargs@16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" -yargs@17.7.2, yargs@^17.7.2: +yargs@17.7.2, yargs@^17.3.1, yargs@^17.7.2: version "17.7.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==