From 5b44e31207b0335c798a41dc8cc8fba2d3e52566 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Tue, 14 Feb 2023 17:31:11 +0000 Subject: [PATCH 01/26] v3.5.0: feat(): add market endpoints for v5 REST APIs, with tests --- package.json | 2 +- src/index.ts | 1 + src/rest-client-v5.ts | 222 ++++++++++++++++++ src/types/index.ts | 1 + src/types/request/index.ts | 1 + src/types/request/v5-market.ts | 120 ++++++++++ src/types/response/v5-market.ts | 298 ++++++++++++++++++++++++ src/types/v5-shared.ts | 1 + test/rest-client-v5/public.read.test.ts | 153 ++++++++++++ 9 files changed, 798 insertions(+), 1 deletion(-) create mode 100644 src/rest-client-v5.ts create mode 100644 src/types/request/v5-market.ts create mode 100644 src/types/response/v5-market.ts create mode 100644 src/types/v5-shared.ts create mode 100644 test/rest-client-v5/public.read.test.ts diff --git a/package.json b/package.json index 8e839a4..dbc484e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bybit-api", - "version": "3.4.0", + "version": "3.5.0", "description": "Complete & robust node.js SDK for Bybit's REST APIs and WebSockets, with TypeScript & integration tests.", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/index.ts b/src/index.ts index 1ef28bb..c93f1d3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,6 +4,7 @@ export * from './copy-trading-client'; export * from './inverse-client'; export * from './inverse-futures-client'; export * from './linear-client'; +export * from './rest-client-v5'; export * from './spot-client'; export * from './spot-client-v3'; export * from './usdc-option-client'; diff --git a/src/rest-client-v5.ts b/src/rest-client-v5.ts new file mode 100644 index 0000000..8bd3a62 --- /dev/null +++ b/src/rest-client-v5.ts @@ -0,0 +1,222 @@ +import { + APIResponseV3WithTime, + APIResponseWithTime, + CategoryV5, + GetFundingRateHistoryParamsV5, + GetHistoricalVolatilityParamsV5, + GetIndexPriceKlineParamsV5, + GetInstrumentsInfoParamsV5, + GetInsuranceParamsV5, + GetKlineParamsV5, + GetMarkPriceKlineParamsV5, + GetOpenInterestParamsV5, + GetOptionDeliveryPriceParamsV5, + GetOrderbookParamsV5, + GetPremiumIndexPriceKlineParams, + GetPublicTradingHistoryParamsV5, + GetRiskLimitParamsV5, + GetTickersParamsV5, +} from './types'; +import { + CategoryListV5, + FundingRateHistoryResponseV5, + HistoricalVolatilityV5, + IndexPriceKlineResponseV5, + InstrumentInfoV5, + InsuranceResponseV5, + KlineResponseV5, + MarkPriceKlineResponseV5, + OpenInterestResponseV5, + OptionDeliveryPriceResponseV5, + OrderbookResponseV5, + PaginatedListV5, + PremiumIndexPriceKlineResponse, + PublicTradeV5, + RiskLimitV5, + TickersLinearInverseResponseV5, + TickersOptionResponseV5, + TickersSpotResponseV5, +} from './types/response/v5-market'; +import { REST_CLIENT_TYPE_ENUM } from './util'; +import BaseRestClient from './util/BaseRestClient'; + +/** + * REST API client for V5 REST APIs + * https://bybit-exchange.github.io/docs/v5/intro + */ +export class RestClientV5 extends BaseRestClient { + getClientType() { + return REST_CLIENT_TYPE_ENUM.v3; + } + + async fetchServerTime(): Promise { + const res = await this.getServerTime(); + return Number(res.time); + } + + getServerTime(): Promise< + APIResponseV3WithTime<{ timeSecond: string; timeNano: string }> + > { + return this.get('/v3/public/time'); + } + + /** + * + * Market APIs + * + */ + + /** + * Query the kline data. Charts are returned in groups based on the requested interval. + * Covers: Spot / Linear contract / Inverse contract + */ + getKline( + params: GetKlineParamsV5 + ): Promise> { + return this.get(`/v5/market/kline`, params); + } + + /** + * Query the mark price kline data. Charts are returned in groups based on the requested interval. + * Covers: Linear contract / Inverse contract + */ + getMarkPriceKline( + params: GetMarkPriceKlineParamsV5 + ): Promise> { + return this.get(`/v5/market/mark-price-kline`, params); + } + + /** + * Query the index price kline data. Charts are returned in groups based on the requested interval. + * Covers: Linear contract / Inverse contract + */ + getIndexPriceKline( + params: GetIndexPriceKlineParamsV5 + ): Promise> { + return this.get(`/v5/market/index-price-kline`, params); + } + + /** + * Retrieve the premium index price kline data. Charts are returned in groups based on the requested interval. + * Covers: Linear contract + */ + getPremiumIndexPriceKline( + params: GetPremiumIndexPriceKlineParams + ): Promise> { + return this.get(`/v5/market/premium-index-price-kline`, params); + } + + /** + * Query a list of instruments of online trading pair. + * Covers: Spot / Linear contract / Inverse contract / Option + * Note: Spot does not support pagination, so limit & cursor are invalid. + */ + getInstrumentsInfo( + params: GetInstrumentsInfoParamsV5 + ): Promise>> { + return this.get(`/v5/market/instruments-info`, params); + } + + /** + * Query orderbook data + * Covers: Spot / Linear contract / Inverse contract / Option + */ + getOrderbook( + params: GetOrderbookParamsV5 + ): Promise> { + return this.get(`/v5/market/orderbook`, params); + } + + /** + * Query the latest price snapshot, best bid/ask price, and trading volume in the last 24 hours. + * Covers: Spot / Linear contract / Inverse contract / Option + */ + getTickers( + params: GetTickersParamsV5 + ): Promise< + APIResponseV3WithTime< + | TickersLinearInverseResponseV5 + | TickersOptionResponseV5 + | TickersSpotResponseV5 + > + > { + return this.get(`/v5/market/tickers`, params); + } + + /** + * Query historical funding rate. Each symbol has a different funding interval. + * Covers: Linear contract / Inverse perpetual + */ + getFundingRateHistory( + params: GetFundingRateHistoryParamsV5 + ): Promise< + APIResponseV3WithTime< + CategoryListV5 + > + > { + return this.get(`/v5/market/funding/history`, params); + } + + /** + * Query recent public trading data in Bybit. + * Covers: Spot / Linear contract / Inverse contract / Option + */ + getPublicTradingHistory( + params: GetPublicTradingHistoryParamsV5 + ): Promise>> { + return this.get(`/v5/market/recent-trade`, params); + } + + /** + * Get open interest of each symbol. + * Covers: Linear contract / Inverse contract + */ + getOpenInterest( + params: GetOpenInterestParamsV5 + ): Promise> { + return this.get(`/v5/market/open-interest`, params); + } + + /** + * Query option historical volatility + * Covers: Option + */ + getHistoricalVolatility( + params: GetHistoricalVolatilityParamsV5 + ): Promise< + APIResponseV3WithTime> + > { + return this.get(`/v5/market/historical-volatility`, params); + } + + /** + * Query Bybit insurance pool data (BTC/USDT/USDC etc). The data is updated every 24 hours. + */ + getInsurance( + params?: GetInsuranceParamsV5 + ): Promise> { + return this.get(`/v5/market/insurance`, params); + } + + /** + * Query risk limit of futures + * Covers: Linear contract / Inverse contract + */ + getRiskLimit( + params?: GetRiskLimitParamsV5 + ): Promise< + APIResponseV3WithTime> + > { + return this.get(`/v5/market/risk-limit`, params); + } + + /** + * Get the delivery price for option + * Covers: Option + */ + getOptionDeliveryPrice( + params: GetOptionDeliveryPriceParamsV5 + ): Promise> { + return this.get(`/v5/market/delivery-price`, params); + } +} diff --git a/src/types/index.ts b/src/types/index.ts index 82b2b91..15b6b2d 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,4 +1,5 @@ export * from './response'; export * from './request'; export * from './shared'; +export * from './v5-shared'; export * from './websockets'; diff --git a/src/types/request/index.ts b/src/types/request/index.ts index bfbba68..2bee5d1 100644 --- a/src/types/request/index.ts +++ b/src/types/request/index.ts @@ -7,4 +7,5 @@ export * from './usdc-perp'; export * from './usdc-options'; export * from './usdc-shared'; export * from './unified-margin'; +export * from './v5-market'; export * from './contract'; diff --git a/src/types/request/v5-market.ts b/src/types/request/v5-market.ts new file mode 100644 index 0000000..c23ccdb --- /dev/null +++ b/src/types/request/v5-market.ts @@ -0,0 +1,120 @@ +import { KlineIntervalV3 } from '../shared'; +import { CategoryV5 } from '../v5-shared'; + +export interface GetKlineParamsV5 { + category: 'spot' | 'linear' | 'inverse'; + symbol: string; + interval: KlineIntervalV3; + start?: number; + end?: number; + limit?: number; +} + +export interface GetMarkPriceKlineParamsV5 { + category: 'linear' | 'inverse'; + symbol: string; + interval: KlineIntervalV3; + start?: number; + end?: number; + limit?: number; +} + +export interface GetIndexPriceKlineParamsV5 { + category: 'linear' | 'inverse'; + symbol: string; + interval: KlineIntervalV3; + start?: number; + end?: number; + limit?: number; +} + +export interface GetPremiumIndexPriceKlineParams { + category: 'linear'; + symbol: string; + interval: KlineIntervalV3; + start?: number; + end?: number; + limit?: number; +} + +export interface GetInstrumentsInfoParamsV5 { + category: CategoryV5; + symbol?: string; + baseCoin?: string; + limit?: number; + cursor?: string; +} + +export interface GetOrderbookParamsV5 { + category: CategoryV5; + symbol: string; + limit?: number; +} + +export interface GetTickersParamsV5 { + category: CategoryV5; + symbol?: string; + baseCoin?: string; + expDate?: string; +} + +export interface GetFundingRateHistoryParamsV5 { + category: 'linear' | 'inverse'; + symbol: string; + startTime?: number; + endTime?: number; + limit?: number; +} + +export type OptionType = 'Call' | 'Put'; + +export interface GetPublicTradingHistoryParamsV5 { + category: CategoryV5; + symbol: string; + baseCoin?: string; + optionType?: OptionType; + limit?: number; +} + +export type OpenInterestIntervalV5 = + | '5min' + | '15min' + | '30min' + | '1h' + | '4h' + | '1d'; + +export interface GetOpenInterestParamsV5 { + category: 'linear' | 'inverse'; + symbol: string; + intervalTime: OpenInterestIntervalV5; + startTime?: number; + endTime?: number; + limit?: number; + cursor?: string; +} + +export interface GetHistoricalVolatilityParamsV5 { + category: 'option'; + baseCoin?: string; + period?: number; + startTime?: number; + endTime?: number; +} + +export interface GetInsuranceParamsV5 { + coin?: string; +} + +export interface GetRiskLimitParamsV5 { + category?: 'linear' | 'inverse'; + symbol?: string; +} + +export interface GetOptionDeliveryPriceParamsV5 { + category: 'option'; + symbol?: string; + baseCoin?: string; + limit?: number; + cursor?: string; +} diff --git a/src/types/response/v5-market.ts b/src/types/response/v5-market.ts new file mode 100644 index 0000000..f53d863 --- /dev/null +++ b/src/types/response/v5-market.ts @@ -0,0 +1,298 @@ +import { CategoryV5 } from '../v5-shared'; + +/** + * Next page cursor does not exist for spot! + */ +export interface PaginatedListV5 { + nextPageCursor: string; + list: T[]; +} + +export interface CategoryListV5 { + category: TCategory; + list: T[]; +} + +/** + * OHLCVT candle used by v5 APIs +> list[0]: startTime string Start time of the candle (ms) +> list[1]: openPrice string Open price +> list[2]: highPrice string Highest price +> list[3]: lowPrice string Lowest price +> list[4]: closePrice string Close price. Is the last traded price when the candle is not closed +> list[5]: volume string Trade volume. Unit of contract: pieces of contract. Unit of spot: quantity of coins +> list[6]: turnover string Turnover. Unit of figure: quantity of quota coin + */ +export type KlineV5 = [string, string, string, string, string, string, string]; + +export interface KlineResponseV5 { + category: 'spot' | 'linear' | 'inverse'; + symbol: string; + list: KlineV5[]; +} + +/** + * OHLC candle used by v5 APIs +> list[0]: startTime string Start time of the candle (ms) +> list[1]: openPrice string Open price +> list[2]: highPrice string Highest price +> list[3]: lowPrice string Lowest price +> list[4]: closePrice string Close price. Is the last traded price when the candle is not closed + */ +export type OHLCV5 = [string, string, string, string, string]; + +export interface MarkPriceKlineResponseV5 { + category: 'linear' | 'inverse'; + symbol: string; + list: OHLCV5[]; +} + +export interface IndexPriceKlineResponseV5 { + category: 'linear' | 'inverse'; + symbol: string; + list: OHLCV5[]; +} + +export interface PremiumIndexPriceKlineResponse { + category: 'linear'; + symbol: string; + list: OHLCV5[]; +} + +export interface LinearInverseInstrumentInfoV5 { + category: 'linear' | 'inverse'; + symbol: string; + contractType: string; + status: string; + baseCoin: string; + quoteCoin: string; + launchTime: string; + deliveryTime: string; + deliveryFeeRate: string; + priceScale: string; + maxLeverage: string; + minOrderValue: string; + minOrderVolume: string; + makerFeeRate: string; + takerFeeRate: string; +} + +export interface OptionInstrumentInfoV5 { + category: 'option'; + symbol: string; + contractType: string; + status: string; + baseCoin: string; + quoteCoin: string; + launchTime: string; + deliveryTime: string; + deliveryFeeRate: string; + priceScale: string; + maxLeverage: string; + minOrderValue: string; + minOrderVolume: string; + makerFeeRate: string; + takerFeeRate: string; + settlementCurrency: string; + settlementPrice: string; + deliveryMethod: string; + optionType: string; + exercisePrice: string; + expirationTime: string; + blockMarginRatio: string; + marginType: string; + strike: string; +} + +export interface SpotInstrumentInfoV5 { + category: 'spot'; + symbol: string; + contractType: string; + status: string; + baseCoin: string; + quoteCoin: string; + launchTime: string; + priceScale: string; + maxLeverage: string; + minOrderValue: string; + minOrderVolume: string; + makerFeeRate: string; + takerFeeRate: string; +} + +export type InstrumentInfoV5 = + | LinearInverseInstrumentInfoV5 + | OptionInstrumentInfoV5 + | SpotInstrumentInfoV5; + +export interface OrderbookLevelV5 { + price: string; + size: string; +} + +export interface OrderbookResponseV5 { + s: string; + b: OrderbookLevelV5[]; + a: OrderbookLevelV5[]; + ts: number; + u: number; +} + +export interface TickerLinearInverseV5 { + symbol: string; + lastPrice: string; + indexPrice: string; + markPrice: string; + prevPrice24h: string; + price24hPcnt: string; + highPrice24h: string; + lowPrice24h: string; + prevPrice1h: string; + openInterest: string; + openInterestValue: string; + turnover24h: string; + volume24h: string; + fundingRate: string; + nextFundingTime: string; + predictedDeliveryPrice: string; + basisRate: string; + deliveryFeeRate: string; + deliveryTime: string; + ask1Size: string; + bid1Price: string; + ask1Price: string; + bid1Size: string; +} + +export interface TickerOptionV5 { + symbol: string; + bid1Price: string; + bid1Size: string; + bid1Iv: string; + ask1Price: string; + ask1Size: string; + ask1Iv: string; + lastPrice: string; + highPrice24h: string; + lowPrice24h: string; + markPrice: string; + indexPrice: string; + markIv: string; + underlyingPrice: string; + openInterest: string; + turnover24h: string; + volume24h: string; + totalVolume: string; + totalTurnover: string; + delta: string; + gamma: string; + vega: string; + theta: string; + predictedDeliveryPrice: string; + change24h: string; +} + +export interface TickerSpotV5 { + symbol: string; + bid1Price: string; + bid1Size: string; + ask1Price: string; + ask1Size: string; + lastPrice: string; + prevPrice24h: string; + price24hPcnt: string; + highPrice24h: string; + lowPrice24h: string; + turnover24h: string; + volume24h: string; + usdIndexPrice: string; +} + +export interface TickersSpotResponseV5 { + category: 'spot'; + list: TickerSpotV5[]; +} + +export interface TickersLinearInverseResponseV5 { + category: 'linear' | 'inverse'; + list: TickerLinearInverseV5[]; +} + +export interface TickersOptionResponseV5 { + category: 'option'; + list: TickerOptionV5[]; +} + +export interface FundingRateHistoryResponseV5 { + symbol: string; + fundingRate: string; + fundingRateTimestamp: string; +} + +export interface PublicTradeV5 { + execId: string; + symbol: string; + price: string; + size: string; + side: 'Buy' | 'Sell'; + time: string; + isBlockTrade: boolean; +} + +/** +> openInterest string Open interest +> timestamp string The timestamp (ms) +*/ +export type OpenInterestV5 = [string, string]; + +export interface OpenInterestResponseV5 { + category: 'linear' | 'inverse'; + symbol: string; + list: OpenInterestV5[]; + nextPageCursor?: string; +} + +export interface HistoricalVolatilityV5 { + period: number; + value: string; + time: string; +} + +export interface InsuranceDataV5 { + coin: string; + balance: string; + value: string; +} + +export interface InsuranceResponseV5 { + updatedTime: string; + list: InsuranceDataV5[]; +} + +export interface RiskLimitV5 { + id: number; + symbol: string; + riskLimitValue: string; + maintenanceMargin: number; + initialMargin: number; + section: any; + isLowestRisk: 0 | 1; + maxLeverage: string; +} + +export interface RiskLimitResponseV5 { + category: CategoryV5; + list: RiskLimitV5[]; +} + +export interface OptionDeliveryPriceV5 { + symbol: string; + deliveryPrice: string; + deliveryTime: string; +} + +export interface OptionDeliveryPriceResponseV5 { + category: CategoryV5; + list: OptionDeliveryPriceV5[]; + nextPageCursor?: string; +} diff --git a/src/types/v5-shared.ts b/src/types/v5-shared.ts new file mode 100644 index 0000000..bb60a40 --- /dev/null +++ b/src/types/v5-shared.ts @@ -0,0 +1 @@ +export type CategoryV5 = 'spot' | 'linear' | 'inverse' | 'option'; diff --git a/test/rest-client-v5/public.read.test.ts b/test/rest-client-v5/public.read.test.ts new file mode 100644 index 0000000..1ff95e2 --- /dev/null +++ b/test/rest-client-v5/public.read.test.ts @@ -0,0 +1,153 @@ +import { RestClientV5 } from '../../src'; +import { successResponseObjectV3 } from '../response.util'; + +describe('Public V5 REST API Endpoints', () => { + const API_KEY = undefined; + const API_SECRET = undefined; + + const api = new RestClientV5({ + key: API_KEY, + secret: API_SECRET, + testnet: false, + }); + + const linearSymbol = 'BTCUSDT'; + + describe('Misc Endpoints', () => { + it('fetchServerTime()', async () => { + expect(await api.fetchServerTime()).toEqual(expect.any(Number)); + }); + + it('getServerTime()', async () => { + expect(await api.getServerTime()).toMatchObject( + successResponseObjectV3() + ); + }); + }); + + describe('Market Endpoints', () => { + it('getKline()', async () => { + expect( + await api.getKline({ + category: 'linear', + interval: '1', + symbol: linearSymbol, + }) + ).toMatchObject(successResponseObjectV3()); + }); + + it('getMarkPriceKline()', async () => { + expect( + await api.getMarkPriceKline({ + category: 'linear', + interval: '1', + symbol: linearSymbol, + }) + ).toMatchObject(successResponseObjectV3()); + }); + + it('getIndexPriceKline()', async () => { + expect( + await api.getIndexPriceKline({ + category: 'linear', + interval: '1', + symbol: linearSymbol, + }) + ).toMatchObject(successResponseObjectV3()); + }); + + it('getPremiumIndexPriceKline()', async () => { + expect( + await api.getPremiumIndexPriceKline({ + category: 'linear', + interval: '1', + symbol: linearSymbol, + }) + ).toMatchObject(successResponseObjectV3()); + }); + + it('getInstrumentsInfo()', async () => { + expect( + await api.getInstrumentsInfo({ + category: 'linear', + symbol: linearSymbol, + }) + ).toMatchObject(successResponseObjectV3()); + }); + + it('getOrderbook()', async () => { + expect( + await api.getOrderbook({ + category: 'linear', + symbol: linearSymbol, + }) + ).toMatchObject(successResponseObjectV3()); + }); + + it('getTickers()', async () => { + expect( + await api.getTickers({ + category: 'linear', + symbol: linearSymbol, + }) + ).toMatchObject(successResponseObjectV3()); + }); + + it('getFundingRateHistory()', async () => { + expect( + await api.getFundingRateHistory({ + category: 'linear', + symbol: linearSymbol, + }) + ).toMatchObject(successResponseObjectV3()); + }); + + it('getPublicTradingHistory()', async () => { + expect( + await api.getPublicTradingHistory({ + category: 'linear', + symbol: linearSymbol, + }) + ).toMatchObject(successResponseObjectV3()); + }); + + it('getOpenInterest()', async () => { + expect( + await api.getOpenInterest({ + category: 'linear', + symbol: linearSymbol, + intervalTime: '15min', + }) + ).toMatchObject(successResponseObjectV3()); + }); + + it('getHistoricalVolatility()', async () => { + expect( + await api.getHistoricalVolatility({ + category: 'option', + }) + ).toMatchObject(successResponseObjectV3()); + }); + + it('getInsurance()', async () => { + expect(await api.getInsurance()).toMatchObject(successResponseObjectV3()); + }); + + it('getRiskLimit()', async () => { + expect( + await api.getRiskLimit({ + category: 'linear', + symbol: linearSymbol, + }) + ).toMatchObject(successResponseObjectV3()); + }); + + it('getOptionDeliveryPrice()', async () => { + expect( + await api.getOptionDeliveryPrice({ + category: 'option', + }) + ).toMatchObject(successResponseObjectV3()); + }); + }); +}); From 145f17d4f10028783d745c52b42f07ceeb9f3912 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Wed, 15 Feb 2023 11:12:27 +0000 Subject: [PATCH 02/26] feat(): expand v5 client with trade endpoints --- examples/rest-rawv3auth.ts | 30 ++++++ src/rest-client-v5.ts | 161 +++++++++++++++++++++++++++++++-- src/types/request/index.ts | 1 + src/types/request/v5-trade.ts | 107 ++++++++++++++++++++++ src/types/response/index.ts | 2 + src/types/response/v5-trade.ts | 98 ++++++++++++++++++++ src/types/v5-shared.ts | 7 ++ 7 files changed, 400 insertions(+), 6 deletions(-) create mode 100644 examples/rest-rawv3auth.ts create mode 100644 src/types/request/v5-trade.ts create mode 100644 src/types/response/v5-trade.ts diff --git a/examples/rest-rawv3auth.ts b/examples/rest-rawv3auth.ts new file mode 100644 index 0000000..2a2af56 --- /dev/null +++ b/examples/rest-rawv3auth.ts @@ -0,0 +1,30 @@ +import { ContractClient } from '../src/index'; + +// or +// import { ContractClient } from 'bybit-api'; + +const key = process.env.API_KEY_COM; +const secret = process.env.API_SECRET_COM; + +const client = new ContractClient({ + key, + secret, + strict_param_validation: true, +}); + +(async () => { + try { + /** + * You can make raw HTTP requests without the per-endpoint abstraction, + * e.g. if an endpoint is missing and you're blocked (but please raise an issue if you're missing an endpoint) + */ + const rawCall = await client.getPrivate('/v5/order/realtime', { + category: 'linear', + symbol: 'BTCUSDT', + }); + + console.log('rawCall:', rawCall); + } catch (e) { + console.error('request failed: ', e); + } +})(); diff --git a/src/rest-client-v5.ts b/src/rest-client-v5.ts index 8bd3a62..a535b9a 100644 --- a/src/rest-client-v5.ts +++ b/src/rest-client-v5.ts @@ -1,7 +1,8 @@ import { APIResponseV3WithTime, - APIResponseWithTime, + CategoryListV5, CategoryV5, + FundingRateHistoryResponseV5, GetFundingRateHistoryParamsV5, GetHistoricalVolatilityParamsV5, GetIndexPriceKlineParamsV5, @@ -16,19 +17,17 @@ import { GetPublicTradingHistoryParamsV5, GetRiskLimitParamsV5, GetTickersParamsV5, -} from './types'; -import { - CategoryListV5, - FundingRateHistoryResponseV5, HistoricalVolatilityV5, IndexPriceKlineResponseV5, InstrumentInfoV5, InsuranceResponseV5, KlineResponseV5, MarkPriceKlineResponseV5, + AccountOrdersResultV5, OpenInterestResponseV5, OptionDeliveryPriceResponseV5, OrderbookResponseV5, + OrderParamsV5, PaginatedListV5, PremiumIndexPriceKlineResponse, PublicTradeV5, @@ -36,7 +35,22 @@ import { TickersLinearInverseResponseV5, TickersOptionResponseV5, TickersSpotResponseV5, -} from './types/response/v5-market'; + AmendOrderParamsV5, + CancelOrderParamsV5, + GetAccountOrdersParams, + OrderResultV5, + CancelAllOrdersParamsV5, + BatchOrderParamsV5, + BatchAmendOrderParamsV5, + BatchOrderResult, + BatchOrdersResult, + BatchAmendOrderResult, + BatchCancelOrderParamsV5, + BatchCancelOrderResult, + OrderSideV5, + SpotBorrowCheckResult, + APIResponseV3, +} from './types'; import { REST_CLIENT_TYPE_ENUM } from './util'; import BaseRestClient from './util/BaseRestClient'; @@ -219,4 +233,139 @@ export class RestClientV5 extends BaseRestClient { ): Promise> { return this.get(`/v5/market/delivery-price`, params); } + + /** + * + * Trade APIs + * + */ + + submitOrder( + params: OrderParamsV5 + ): Promise> { + return this.postPrivate(`/v5/order/create`, params); + } + + amendOrder( + params: AmendOrderParamsV5 + ): Promise> { + return this.postPrivate('/v5/order/amend', params); + } + + cancelOrder( + params: CancelOrderParamsV5 + ): Promise> { + return this.postPrivate('/v5/order/cancel', params); + } + + /** + * Query unfilled or partially filled orders in real-time. To query older order records, please use the order history interface. + */ + getActiveOrders( + params: GetAccountOrdersParams + ): Promise> { + return this.getPrivate('/v5/order/realtime', params); + } + + cancelAllOrders( + params: CancelAllOrdersParamsV5 + ): Promise> { + return this.postPrivate('/v5/order/cancel-all', params); + } + + /** + * Query order history. As order creation/cancellation is asynchronous, the data returned from this endpoint may delay. + * If you want to get real-time order information, you could query this endpoint or rely on the websocket stream (recommended). + */ + getHistoricOrders( + params: GetAccountOrdersParams + ): Promise> { + return this.getPrivate(`/v5/order/history`, params); + } + + /** + * This endpoint allows you to place more than one order in a single request. Covers: option (unified account). + * Make sure you have sufficient funds in your account when placing an order. Once an order is placed, according to the funds required by the order, the funds in your account will be frozen by the corresponding amount during the life cycle of the order. + * A maximum of 20 orders can be placed per request. The returned data list is divided into two lists. The first list indicates whether or not the order creation was successful and the second list details the created order information. The structure of the two lists are completely consistent. + */ + batchSubmitOrders( + category: 'option', + orders: BatchOrderParamsV5[] + ): Promise>> { + return this.postPrivate('/v5/order/create-batch', { + category, + request: orders, + }); + } + + /** + * This endpoint allows you to amend more than one open order in a single request. Covers: option (unified account). + * You can modify unfilled or partially filled orders. Conditional orders are not supported. + * A maximum of 20 orders can be amended per request. + */ + batchAmendOrders( + category: 'option', + orders: BatchAmendOrderParamsV5[] + ): Promise< + APIResponseV3WithTime> + > { + return this.postPrivate('/v5/order/amend-batch', { + category, + request: orders, + }); + } + + /** + * This endpoint allows you to cancel more than one open order in a single request. Covers: option (unified account). + * You must specify orderId or orderLinkId. If orderId and orderLinkId is not matched, the system will process orderId first. + * You can cancel unfilled or partially filled orders. A maximum of 20 orders can be cancelled per request. + */ + batchCancelOrders( + category: 'option', + orders: BatchCancelOrderParamsV5[] + ): Promise< + APIResponseV3WithTime> + > { + return this.postPrivate('/v5/order/cancel-batch', { + category, + request: orders, + }); + } + + /** + * Query the qty and amount of borrowable coins in spot account. + * Covers: Spot (Unified Account) + */ + getSpotBorrowCheck( + symbol: string, + side: OrderSideV5 + ): Promise> { + return this.getPrivate('/v5/order/spot-borrow-check', { + category: 'spot', + symbol, + side, + }); + } + + /** + * This endpoint allows you to set the disconnection protect time window. Covers: option (unified account). + * If you need to turn it on/off, you can contact your client manager for consultation and application. The default time window is 10 seconds. + */ + setDisconnectCancelAllWindow( + category: 'option', + timeWindow: number + ): Promise> { + return this.postPrivate('/v5/order/disconnected-cancel-all', { + category, + timeWindow, + }); + } + + // + // + // + // + // + // + // } diff --git a/src/types/request/index.ts b/src/types/request/index.ts index 2bee5d1..35a7a46 100644 --- a/src/types/request/index.ts +++ b/src/types/request/index.ts @@ -9,3 +9,4 @@ export * from './usdc-shared'; export * from './unified-margin'; export * from './v5-market'; export * from './contract'; +export * from './v5-trade'; diff --git a/src/types/request/v5-trade.ts b/src/types/request/v5-trade.ts new file mode 100644 index 0000000..b5a7b15 --- /dev/null +++ b/src/types/request/v5-trade.ts @@ -0,0 +1,107 @@ +import { + CategoryV5, + OrderFilterV5, + OrderSideV5, + OrderTimeInForceV5, + OrderTriggerByV5, + OrderTypeV5, + PositionIdx, +} from '../v5-shared'; + +export interface OrderParamsV5 { + category: CategoryV5; + symbol: string; + isLeverage?: 0 | 1; + side: OrderSideV5; + orderType: OrderTypeV5; + qty: string; + price?: string; + triggerDirection?: 1 | 2; + orderFilter?: 'Order' | 'tpslOrder'; + triggerPrice?: string; + triggerBy?: OrderTriggerByV5; + orderIv?: string; + timeInForce?: OrderTimeInForceV5; + positionIdx?: PositionIdx; + orderLinkId?: string; + takeProfit?: string; + stopLoss?: string; + tpTriggerBy?: OrderTriggerByV5; + slTriggerBy?: OrderTriggerByV5; + reduceOnly?: boolean; + closeOnTrigger?: boolean; + mmp?: boolean; +} + +export interface AmendOrderParamsV5 { + category: CategoryV5; + symbol: string; + orderId?: string; + orderLinkId?: string; + orderIv?: string; + triggerPrice?: string; + qty?: string; + price?: string; + takeProfit?: string; + stopLoss?: string; + tpTriggerBy?: OrderTriggerByV5; + slTriggerBy?: OrderTriggerByV5; + triggerBy?: OrderTriggerByV5; +} + +export interface CancelOrderParamsV5 { + category: CategoryV5; + symbol: string; + orderId?: string; + orderLinkId?: string; + orderFilter?: OrderFilterV5; +} + +export interface GetAccountOrdersParams { + category: CategoryV5; + symbol?: string; + baseCoin?: string; + settleCoin?: string; + orderId?: string; + orderLinkId?: string; + openOnly?: 0 | 1 | 2; + orderFilter?: OrderFilterV5; + limit?: number; + cursor?: string; +} + +export interface CancelAllOrdersParamsV5 { + category: CategoryV5; + symbol?: string; + baseCoin?: string; + settleCoin?: string; + orderFilter?: OrderFilterV5; +} + +export interface BatchOrderParamsV5 { + symbol: string; + side: OrderSideV5; + orderType: OrderTypeV5; + qty: string; + price?: string; + orderIv?: string; + timeInForce?: OrderTimeInForceV5; + orderLinkId: string; + reduceOnly?: boolean; + mmp?: boolean; +} + +export interface BatchAmendOrderParamsV5 { + symbol: string; + orderId?: string; + orderLinkId?: string; + qty?: string; + price?: string; + orderIv?: string; +} + +export interface BatchCancelOrderParamsV5 { + symbol: string; + orderId?: string; + orderLinkId?: string; +} diff --git a/src/types/response/index.ts b/src/types/response/index.ts index a84a3d7..7322cae 100644 --- a/src/types/response/index.ts +++ b/src/types/response/index.ts @@ -4,3 +4,5 @@ export * from './shared'; export * from './spot'; export * from './usdt-perp'; export * from './unified-margin'; +export * from './v5-market'; +export * from './v5-trade'; diff --git a/src/types/response/v5-trade.ts b/src/types/response/v5-trade.ts new file mode 100644 index 0000000..bb9181a --- /dev/null +++ b/src/types/response/v5-trade.ts @@ -0,0 +1,98 @@ +import { + CategoryV5, + OrderSideV5, + OrderTimeInForceV5, + OrderTriggerByV5, + OrderTypeV5, + PositionIdx, +} from '../v5-shared'; + +export interface OrderResultV5 { + orderId: string; + orderLinkId: string; +} + +export interface AccountOrderV5 { + orderId: string; + orderLinkId?: string; + blockTradeId?: string; + symbol: string; + price: string; + qty: string; + side: OrderSideV5; + isLeverage?: string; + positionIdx?: PositionIdx; + orderStatus: string; + cancelType?: string; + rejectReason?: string; + avgPrice: string; + leavesQty: string; + leavesValue: string; + cumExecQty: string; + cumExecValue: string; + cumExecFee: string; + timeInForce?: OrderTimeInForceV5; + orderType?: OrderTypeV5; + stopOrderType?: string; + orderIv?: string; + triggerPrice?: string; + takeProfit?: string; + stopLoss?: string; + tpTriggerBy?: OrderTriggerByV5; + slTriggerBy?: OrderTriggerByV5; + triggerDirection?: number; + triggerBy?: OrderTriggerByV5; + lastPriceOnCreated?: string; + reduceOnly?: boolean; + closeOnTrigger?: boolean; + createdTime: string; + updatedTime: string; +} + +export interface AccountOrdersResultV5 { + category: CategoryV5; + nextPageCursor?: string; + list: AccountOrderV5[]; +} + +export interface BatchOrderResult { + category: CategoryV5; + symbol: string; + orderId: string; + orderLinkId: string; + createAt: string; +} + +export interface BatchOrdersResult { + result: { + list: T; + }; + retExtInfo: { + list: { + code: number; + msg: string; + }[]; + }; +} + +export interface BatchAmendOrderResult { + category: CategoryV5; + symbol: string; + orderId: string; + orderLinkId: string; +} + +export interface BatchCancelOrderResult { + category: CategoryV5; + symbol: string; + orderId: string; + orderLinkId: string; +} + +export interface SpotBorrowCheckResult { + symbol: string; + side: OrderSideV5; + maxTradeQty: string; + maxTradeAmount: string; + borrowCoin: string; +} diff --git a/src/types/v5-shared.ts b/src/types/v5-shared.ts index bb60a40..cb87116 100644 --- a/src/types/v5-shared.ts +++ b/src/types/v5-shared.ts @@ -1 +1,8 @@ export type CategoryV5 = 'spot' | 'linear' | 'inverse' | 'option'; + +export type OrderFilterV5 = 'Order' | 'tpslOrder'; +export type OrderSideV5 = 'Buy' | 'Sell'; +export type OrderTimeInForceV5 = 'GTC' | 'IOC' | 'FOK' | 'PostOnly'; +export type OrderTriggerByV5 = 'LastPrice' | 'IndexPrice' | 'MarkPrice'; +export type OrderTypeV5 = 'Market' | 'Limit'; +export type PositionIdx = 0 | 1 | 2; From 47e125515910bb37d947884d8ac6bc0880370d39 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Wed, 15 Feb 2023 11:33:22 +0000 Subject: [PATCH 03/26] chore(): tidying, consolidate repetitive types --- src/rest-client-v5.ts | 106 +++++++++++++++++++++++------- src/types/request/index.ts | 3 +- src/types/request/v5-position.ts | 10 +++ src/types/response/index.ts | 1 + src/types/response/v5-market.ts | 102 +++++++--------------------- src/types/response/v5-position.ts | 29 ++++++++ src/types/response/v5-trade.ts | 6 -- src/types/v5-shared.ts | 31 +++++++++ 8 files changed, 179 insertions(+), 109 deletions(-) create mode 100644 src/types/request/v5-position.ts create mode 100644 src/types/response/v5-position.ts diff --git a/src/rest-client-v5.ts b/src/rest-client-v5.ts index a535b9a..ebe96f4 100644 --- a/src/rest-client-v5.ts +++ b/src/rest-client-v5.ts @@ -18,23 +18,14 @@ import { GetRiskLimitParamsV5, GetTickersParamsV5, HistoricalVolatilityV5, - IndexPriceKlineResponseV5, InstrumentInfoV5, InsuranceResponseV5, - KlineResponseV5, - MarkPriceKlineResponseV5, - AccountOrdersResultV5, OpenInterestResponseV5, - OptionDeliveryPriceResponseV5, OrderbookResponseV5, OrderParamsV5, - PaginatedListV5, - PremiumIndexPriceKlineResponse, + CursorListV5, PublicTradeV5, RiskLimitV5, - TickersLinearInverseResponseV5, - TickersOptionResponseV5, - TickersSpotResponseV5, AmendOrderParamsV5, CancelOrderParamsV5, GetAccountOrdersParams, @@ -50,12 +41,24 @@ import { OrderSideV5, SpotBorrowCheckResult, APIResponseV3, + PositionInfoParamsV5, + CategoryCursorListV5, + PositionV5, + AccountOrderV5, + OptionDeliveryPriceV5, + CategorySymbolListV5, + OHLCV5, + KlineV5, + TickerSpotV5, + TickerOptionV5, + TickerLinearInverseV5, } from './types'; import { REST_CLIENT_TYPE_ENUM } from './util'; import BaseRestClient from './util/BaseRestClient'; /** * REST API client for V5 REST APIs + * * https://bybit-exchange.github.io/docs/v5/intro */ export class RestClientV5 extends BaseRestClient { @@ -82,57 +85,72 @@ export class RestClientV5 extends BaseRestClient { /** * Query the kline data. Charts are returned in groups based on the requested interval. + * * Covers: Spot / Linear contract / Inverse contract */ getKline( params: GetKlineParamsV5 - ): Promise> { + ): Promise< + APIResponseV3WithTime< + CategorySymbolListV5 + > + > { return this.get(`/v5/market/kline`, params); } /** * Query the mark price kline data. Charts are returned in groups based on the requested interval. + * * Covers: Linear contract / Inverse contract */ getMarkPriceKline( params: GetMarkPriceKlineParamsV5 - ): Promise> { + ): Promise< + APIResponseV3WithTime> + > { return this.get(`/v5/market/mark-price-kline`, params); } /** * Query the index price kline data. Charts are returned in groups based on the requested interval. + * * Covers: Linear contract / Inverse contract */ getIndexPriceKline( params: GetIndexPriceKlineParamsV5 - ): Promise> { + ): Promise< + APIResponseV3WithTime> + > { return this.get(`/v5/market/index-price-kline`, params); } /** * Retrieve the premium index price kline data. Charts are returned in groups based on the requested interval. + * * Covers: Linear contract */ getPremiumIndexPriceKline( params: GetPremiumIndexPriceKlineParams - ): Promise> { + ): Promise>> { return this.get(`/v5/market/premium-index-price-kline`, params); } /** * Query a list of instruments of online trading pair. + * * Covers: Spot / Linear contract / Inverse contract / Option + * * Note: Spot does not support pagination, so limit & cursor are invalid. */ getInstrumentsInfo( params: GetInstrumentsInfoParamsV5 - ): Promise>> { + ): Promise>> { return this.get(`/v5/market/instruments-info`, params); } /** * Query orderbook data + * * Covers: Spot / Linear contract / Inverse contract / Option */ getOrderbook( @@ -143,15 +161,16 @@ export class RestClientV5 extends BaseRestClient { /** * Query the latest price snapshot, best bid/ask price, and trading volume in the last 24 hours. + * * Covers: Spot / Linear contract / Inverse contract / Option */ getTickers( params: GetTickersParamsV5 ): Promise< APIResponseV3WithTime< - | TickersLinearInverseResponseV5 - | TickersOptionResponseV5 - | TickersSpotResponseV5 + | CategoryListV5 + | CategoryListV5 + | CategoryListV5 > > { return this.get(`/v5/market/tickers`, params); @@ -159,13 +178,14 @@ export class RestClientV5 extends BaseRestClient { /** * Query historical funding rate. Each symbol has a different funding interval. + * * Covers: Linear contract / Inverse perpetual */ getFundingRateHistory( params: GetFundingRateHistoryParamsV5 ): Promise< APIResponseV3WithTime< - CategoryListV5 + CategoryListV5 > > { return this.get(`/v5/market/funding/history`, params); @@ -173,16 +193,20 @@ export class RestClientV5 extends BaseRestClient { /** * Query recent public trading data in Bybit. + * * Covers: Spot / Linear contract / Inverse contract / Option */ getPublicTradingHistory( params: GetPublicTradingHistoryParamsV5 - ): Promise>> { + ): Promise< + APIResponseV3WithTime> + > { return this.get(`/v5/market/recent-trade`, params); } /** * Get open interest of each symbol. + * * Covers: Linear contract / Inverse contract */ getOpenInterest( @@ -198,7 +222,7 @@ export class RestClientV5 extends BaseRestClient { getHistoricalVolatility( params: GetHistoricalVolatilityParamsV5 ): Promise< - APIResponseV3WithTime> + APIResponseV3WithTime> > { return this.get(`/v5/market/historical-volatility`, params); } @@ -214,23 +238,27 @@ export class RestClientV5 extends BaseRestClient { /** * Query risk limit of futures + * * Covers: Linear contract / Inverse contract */ getRiskLimit( params?: GetRiskLimitParamsV5 ): Promise< - APIResponseV3WithTime> + APIResponseV3WithTime> > { return this.get(`/v5/market/risk-limit`, params); } /** * Get the delivery price for option + * * Covers: Option */ getOptionDeliveryPrice( params: GetOptionDeliveryPriceParamsV5 - ): Promise> { + ): Promise< + APIResponseV3WithTime> + > { return this.get(`/v5/market/delivery-price`, params); } @@ -263,7 +291,7 @@ export class RestClientV5 extends BaseRestClient { */ getActiveOrders( params: GetAccountOrdersParams - ): Promise> { + ): Promise>> { return this.getPrivate('/v5/order/realtime', params); } @@ -275,17 +303,20 @@ export class RestClientV5 extends BaseRestClient { /** * Query order history. As order creation/cancellation is asynchronous, the data returned from this endpoint may delay. + * * If you want to get real-time order information, you could query this endpoint or rely on the websocket stream (recommended). */ getHistoricOrders( params: GetAccountOrdersParams - ): Promise> { + ): Promise>> { return this.getPrivate(`/v5/order/history`, params); } /** * This endpoint allows you to place more than one order in a single request. Covers: option (unified account). + * * Make sure you have sufficient funds in your account when placing an order. Once an order is placed, according to the funds required by the order, the funds in your account will be frozen by the corresponding amount during the life cycle of the order. + * * A maximum of 20 orders can be placed per request. The returned data list is divided into two lists. The first list indicates whether or not the order creation was successful and the second list details the created order information. The structure of the two lists are completely consistent. */ batchSubmitOrders( @@ -300,7 +331,9 @@ export class RestClientV5 extends BaseRestClient { /** * This endpoint allows you to amend more than one open order in a single request. Covers: option (unified account). + * * You can modify unfilled or partially filled orders. Conditional orders are not supported. + * * A maximum of 20 orders can be amended per request. */ batchAmendOrders( @@ -317,7 +350,9 @@ export class RestClientV5 extends BaseRestClient { /** * This endpoint allows you to cancel more than one open order in a single request. Covers: option (unified account). + * * You must specify orderId or orderLinkId. If orderId and orderLinkId is not matched, the system will process orderId first. + * * You can cancel unfilled or partially filled orders. A maximum of 20 orders can be cancelled per request. */ batchCancelOrders( @@ -334,6 +369,7 @@ export class RestClientV5 extends BaseRestClient { /** * Query the qty and amount of borrowable coins in spot account. + * * Covers: Spot (Unified Account) */ getSpotBorrowCheck( @@ -349,6 +385,7 @@ export class RestClientV5 extends BaseRestClient { /** * This endpoint allows you to set the disconnection protect time window. Covers: option (unified account). + * * If you need to turn it on/off, you can contact your client manager for consultation and application. The default time window is 10 seconds. */ setDisconnectCancelAllWindow( @@ -361,6 +398,25 @@ export class RestClientV5 extends BaseRestClient { }); } + /** + * + * Position APIs + * + */ + + /** + * Query real-time position data, such as position size, cumulative realizedPNL. + * + * Unified account covers: Linear contract / Options + * + * Normal account covers: USDT perpetual / Inverse perpetual / Inverse futures + */ + getPositionInfo( + params: PositionInfoParamsV5 + ): Promise>> { + return this.getPrivate('/v5/position/list', params); + } + // // // diff --git a/src/types/request/index.ts b/src/types/request/index.ts index 35a7a46..46749cf 100644 --- a/src/types/request/index.ts +++ b/src/types/request/index.ts @@ -1,5 +1,6 @@ export * from './account-asset'; export * from './copy-trading'; +export * from './contract'; export * from './linear'; export * from './inverse'; export * from './spot'; @@ -8,5 +9,5 @@ export * from './usdc-options'; export * from './usdc-shared'; export * from './unified-margin'; export * from './v5-market'; -export * from './contract'; +export * from './v5-position'; export * from './v5-trade'; diff --git a/src/types/request/v5-position.ts b/src/types/request/v5-position.ts new file mode 100644 index 0000000..91e0c1f --- /dev/null +++ b/src/types/request/v5-position.ts @@ -0,0 +1,10 @@ +import { CategoryV5 } from '../v5-shared'; + +export interface PositionInfoParamsV5 { + category: CategoryV5; + symbol?: string; + baseCoin?: string; + settleCoin?: string; + limit?: number; + cursor?: string; +} diff --git a/src/types/response/index.ts b/src/types/response/index.ts index 7322cae..d93addb 100644 --- a/src/types/response/index.ts +++ b/src/types/response/index.ts @@ -5,4 +5,5 @@ export * from './spot'; export * from './usdt-perp'; export * from './unified-margin'; export * from './v5-market'; +export * from './v5-position'; export * from './v5-trade'; diff --git a/src/types/response/v5-market.ts b/src/types/response/v5-market.ts index f53d863..5c00194 100644 --- a/src/types/response/v5-market.ts +++ b/src/types/response/v5-market.ts @@ -1,64 +1,37 @@ -import { CategoryV5 } from '../v5-shared'; - -/** - * Next page cursor does not exist for spot! - */ -export interface PaginatedListV5 { - nextPageCursor: string; - list: T[]; -} - -export interface CategoryListV5 { - category: TCategory; - list: T[]; -} - /** * OHLCVT candle used by v5 APIs -> list[0]: startTime string Start time of the candle (ms) -> list[1]: openPrice string Open price -> list[2]: highPrice string Highest price -> list[3]: lowPrice string Lowest price -> list[4]: closePrice string Close price. Is the last traded price when the candle is not closed -> list[5]: volume string Trade volume. Unit of contract: pieces of contract. Unit of spot: quantity of coins -> list[6]: turnover string Turnover. Unit of figure: quantity of quota coin + * + * > list[0]: startTime string Start time of the candle (ms) + * + * > list[1]: openPrice string Open price + * + * > list[2]: highPrice string Highest price + * + * > list[3]: lowPrice string Lowest price + * + * > list[4]: closePrice string Close price. Is the last traded price when the candle is not closed + * + * > list[5]: volume string Trade volume. Unit of contract: pieces of contract. Unit of spot: quantity of coins + * + * > list[6]: turnover string Turnover. Unit of figure: quantity of quota coin */ export type KlineV5 = [string, string, string, string, string, string, string]; -export interface KlineResponseV5 { - category: 'spot' | 'linear' | 'inverse'; - symbol: string; - list: KlineV5[]; -} - /** * OHLC candle used by v5 APIs -> list[0]: startTime string Start time of the candle (ms) -> list[1]: openPrice string Open price -> list[2]: highPrice string Highest price -> list[3]: lowPrice string Lowest price -> list[4]: closePrice string Close price. Is the last traded price when the candle is not closed + * + * > list[0]: startTime string Start time of the candle (ms) + * + * > list[1]: openPrice string Open price + * + * > list[2]: highPrice string Highest price + * + * > list[3]: lowPrice string Lowest price + * + * > list[4]: closePrice string Close price. Is the last traded price when the candle is not closed */ export type OHLCV5 = [string, string, string, string, string]; -export interface MarkPriceKlineResponseV5 { - category: 'linear' | 'inverse'; - symbol: string; - list: OHLCV5[]; -} - -export interface IndexPriceKlineResponseV5 { - category: 'linear' | 'inverse'; - symbol: string; - list: OHLCV5[]; -} - -export interface PremiumIndexPriceKlineResponse { - category: 'linear'; - symbol: string; - list: OHLCV5[]; -} - export interface LinearInverseInstrumentInfoV5 { category: 'linear' | 'inverse'; symbol: string; @@ -208,21 +181,6 @@ export interface TickerSpotV5 { usdIndexPrice: string; } -export interface TickersSpotResponseV5 { - category: 'spot'; - list: TickerSpotV5[]; -} - -export interface TickersLinearInverseResponseV5 { - category: 'linear' | 'inverse'; - list: TickerLinearInverseV5[]; -} - -export interface TickersOptionResponseV5 { - category: 'option'; - list: TickerOptionV5[]; -} - export interface FundingRateHistoryResponseV5 { symbol: string; fundingRate: string; @@ -241,6 +199,7 @@ export interface PublicTradeV5 { /** > openInterest string Open interest + > timestamp string The timestamp (ms) */ export type OpenInterestV5 = [string, string]; @@ -280,19 +239,8 @@ export interface RiskLimitV5 { maxLeverage: string; } -export interface RiskLimitResponseV5 { - category: CategoryV5; - list: RiskLimitV5[]; -} - export interface OptionDeliveryPriceV5 { symbol: string; deliveryPrice: string; deliveryTime: string; } - -export interface OptionDeliveryPriceResponseV5 { - category: CategoryV5; - list: OptionDeliveryPriceV5[]; - nextPageCursor?: string; -} diff --git a/src/types/response/v5-position.ts b/src/types/response/v5-position.ts new file mode 100644 index 0000000..ae283b9 --- /dev/null +++ b/src/types/response/v5-position.ts @@ -0,0 +1,29 @@ +import { CategoryV5 } from '../v5-shared'; + +export interface PositionV5 { + positionIdx: number; + riskId: number; + riskLimitValue: string; + symbol: string; + side: 'Buy' | 'Sell' | 'None'; + size: string; + avgPrice: string; + positionValue: string; + tradeMode: number; + autoAddMargin?: number; + positionStatus: 'Normal' | 'Liq' | 'Adl'; + leverage?: string; + markPrice: string; + liqPrice: string; + bustPrice?: string; + positionIM?: string; + positionMM?: string; + tpslMode?: 'Full' | 'Partial'; + takeProfit?: string; + stopLoss?: string; + trailingStop?: string; + unrealisedPnl: string; + cumRealisedPnl: string; + createdTime: string; + updatedTime: string; +} diff --git a/src/types/response/v5-trade.ts b/src/types/response/v5-trade.ts index bb9181a..78f7fdf 100644 --- a/src/types/response/v5-trade.ts +++ b/src/types/response/v5-trade.ts @@ -49,12 +49,6 @@ export interface AccountOrderV5 { updatedTime: string; } -export interface AccountOrdersResultV5 { - category: CategoryV5; - nextPageCursor?: string; - list: AccountOrderV5[]; -} - export interface BatchOrderResult { category: CategoryV5; symbol: string; diff --git a/src/types/v5-shared.ts b/src/types/v5-shared.ts index cb87116..afd2655 100644 --- a/src/types/v5-shared.ts +++ b/src/types/v5-shared.ts @@ -6,3 +6,34 @@ export type OrderTimeInForceV5 = 'GTC' | 'IOC' | 'FOK' | 'PostOnly'; export type OrderTriggerByV5 = 'LastPrice' | 'IndexPrice' | 'MarkPrice'; export type OrderTypeV5 = 'Market' | 'Limit'; export type PositionIdx = 0 | 1 | 2; + +export interface CategoryCursorListV5 { + category: CategoryV5; + list: T; + nextPageCursor?: string; +} + +/** + * Next page cursor does not exist for spot! + */ +export interface CursorListV5 { + nextPageCursor: string; + list: T; +} + +export interface CategoryListV5< + T extends unknown[], + TCategory extends CategoryV5 +> { + category: TCategory; + list: T; +} + +export interface CategorySymbolListV5< + T extends unknown[], + TCategory extends CategoryV5 +> { + category: TCategory; + symbol: string; + list: T; +} From 71c6c9b6a598a9956aebf8b628a36e38de1d9fbf Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Thu, 16 Feb 2023 12:25:25 +0000 Subject: [PATCH 04/26] add position v5 rest apis --- src/rest-client-v5.ts | 127 ++++++++++++++++++++++++++++++ src/types/request/v5-position.ts | 80 ++++++++++++++++++- src/types/response/v5-position.ts | 68 +++++++++++++++- src/types/v5-shared.ts | 7 +- 4 files changed, 276 insertions(+), 6 deletions(-) diff --git a/src/rest-client-v5.ts b/src/rest-client-v5.ts index ebe96f4..703eb58 100644 --- a/src/rest-client-v5.ts +++ b/src/rest-client-v5.ts @@ -52,6 +52,19 @@ import { TickerSpotV5, TickerOptionV5, TickerLinearInverseV5, + SetLeverageParamsV5, + SwitchIsolatedMarginParamsV5, + SetTPSLModeParamsV5, + TPSLModeV5, + SwitchPositionModeParamsV5, + SetRiskLimitParamsV5, + SetRiskLimitResultV5, + SetTradingStopParamsV5, + SetAutoAddMarginParamsV5, + GetExecutionListParamsV5, + ExecutionV5, + GetClosedPnLParamsV5, + ClosedPnLV5, } from './types'; import { REST_CLIENT_TYPE_ENUM } from './util'; import BaseRestClient from './util/BaseRestClient'; @@ -410,6 +423,8 @@ export class RestClientV5 extends BaseRestClient { * Unified account covers: Linear contract / Options * * Normal account covers: USDT perpetual / Inverse perpetual / Inverse futures + * + * Note: this will give a 404 error if you query the `option` category if your account is not unified */ getPositionInfo( params: PositionInfoParamsV5 @@ -417,6 +432,118 @@ export class RestClientV5 extends BaseRestClient { return this.getPrivate('/v5/position/list', params); } + /** + * Set the leverage + * + * Unified account covers: Linear contract + * + * Normal account covers: USDT perpetual / Inverse perpetual / Inverse futures + * + * Note: Under one-way mode, buyLeverage must be the same as sellLeverage + */ + setLeverage(params: SetLeverageParamsV5): Promise> { + return this.postPrivate('/v5/position/set-leverage', params); + } + + /** + * Select cross margin mode or isolated margin mode. + * + * Covers: USDT perpetual (Normal account) / Inverse contract (Normal account). + * + * Switching margin modes will cause orders in progress to be cancelled. Please make sure that there are no open orders before you switch margin modes. + */ + switchIsolatedMargin( + params: SwitchIsolatedMarginParamsV5 + ): Promise> { + return this.postPrivate('/v5/position/switch-isolated', params); + } + + /** + * This endpoint sets the take profit/stop loss (TP/SL) mode to full or partial. + * + * Unified account covers: Linear contract; normal account covers: USDT perpetual, inverse perpetual, inverse futures. + * + * For partial TP/SL mode, you can set the TP/SL size smaller than position size. + */ + setTPSLMode( + params: SetTPSLModeParamsV5 + ): Promise> { + return this.postPrivate('/v5/position/set-tpsl-mode', params); + } + + /** + * Switches the position mode for USDT perpetual and Inverse futures. + * + * If you are in one-way Mode, you can only open one position on Buy or Sell side. + * + * If you are in hedge mode, you can open both Buy and Sell side positions simultaneously. + * + * Position mode. 0: Merged Single. 3: Both Sides. + */ + switchPositionMode( + params: SwitchPositionModeParamsV5 + ): Promise> { + return this.postPrivate('/v5/position/switch-mode', params); + } + + /** + * The risk limit will limit the maximum position value you can hold under different margin requirements. If you want to hold a bigger position size, you need more margin. This interface can set the risk limit of a single position. If the order exceeds the current risk limit when placing an order, it will be rejected. + */ + setRiskLimit( + params: SetRiskLimitParamsV5 + ): Promise> { + return this.postPrivate('/v5/position/set-risk-limit', params); + } + + /** + * This endpoint allows you to set the take profit, stop loss or trailing stop for a position. + * Passing these parameters will create conditional orders by the system internally. + * + * The system will cancel these orders if the position is closed, and adjust the qty according to the size of the open position. + * + * Unified account covers: Linear contract. + * Normal account covers: USDT perpetual / Inverse perpetual / Inverse futures. + */ + setTradingStop( + params: SetTradingStopParamsV5 + ): Promise> { + return this.postPrivate('/v5/position/trading-stop', params); + } + /** + * This endpoint allows you to turn on/off auto-add-margin for an isolated margin position. + * + * Covers: USDT perpetual (Normal Account). + */ + setAutoAddMargin( + params: SetAutoAddMarginParamsV5 + ): Promise> { + return this.postPrivate('/v5/position/set-auto-add-margin', params); + } + + /** + * Query users' execution records, sorted by execTime in descending order + * + * Unified account covers: Spot / Linear contract / Options + * Normal account covers: USDT perpetual / Inverse perpetual / Inverse futures + */ + getExecutionListV5( + params: GetExecutionListParamsV5 + ): Promise>> { + return this.getPrivate('/v5/execution/list', params); + } + + /** + * Query user's closed profit and loss records. The results are sorted by createdTime in descending order. + * + * Unified account covers: Linear contract + * Normal account covers: USDT perpetual / Inverse perpetual / Inverse futures + */ + getClosedPnL( + params: GetClosedPnLParamsV5 + ): Promise>> { + return this.getPrivate('/v5/position/closed-pnl', params); + } + // // // diff --git a/src/types/request/v5-position.ts b/src/types/request/v5-position.ts index 91e0c1f..f378771 100644 --- a/src/types/request/v5-position.ts +++ b/src/types/request/v5-position.ts @@ -1,4 +1,4 @@ -import { CategoryV5 } from '../v5-shared'; +import { CategoryV5, TPSLModeV5 } from '../v5-shared'; export interface PositionInfoParamsV5 { category: CategoryV5; @@ -8,3 +8,81 @@ export interface PositionInfoParamsV5 { limit?: number; cursor?: string; } + +export interface SetLeverageParamsV5 { + category: 'linear' | 'inverse'; + symbol: string; + buyLeverage: string; + sellLeverage: string; +} + +export interface SwitchIsolatedMarginParamsV5 { + category: 'linear' | 'inverse'; + symbol: string; + tradeMode: 0 | 1; + buyLeverage: string; + sellLeverage: string; +} + +export interface SetTPSLModeParamsV5 { + category: 'linear' | 'inverse'; + symbol: string; + tpSlMode: TPSLModeV5; +} + +export interface SwitchPositionModeParamsV5 { + category: 'linear' | 'inverse'; + symbol?: string; + coin?: string; + mode: 0 | 3; +} + +export interface SetRiskLimitParamsV5 { + category: 'linear' | 'inverse'; + symbol: string; + riskId: number; + positionIdx?: number; +} + +export interface SetTradingStopParamsV5 { + symbol: string; + category: CategoryV5; + takeProfit?: string; + stopLoss?: string; + trailingStop?: string; + tpTriggerBy?: string; + slTriggerBy?: string; + activePrice?: string; + tpSize?: string; + slSize?: string; + positionIdx: number; +} + +export interface SetAutoAddMarginParamsV5 { + category: 'linear'; + symbol: string; + autoAddMargin: 0 | 1; + positionIdx?: number; +} + +export interface GetExecutionListParamsV5 { + category: CategoryV5; + symbol?: string; + orderId?: string; + orderLinkId?: string; + baseCoin?: string; + startTime?: number; + endTime?: number; + execType?: string; + limit?: number; + cursor?: string; +} + +export interface GetClosedPnLParamsV5 { + category: CategoryV5; + symbol?: string; + startTime?: number; + endTime?: number; + limit?: number; + cursor?: string; +} diff --git a/src/types/response/v5-position.ts b/src/types/response/v5-position.ts index ae283b9..768d226 100644 --- a/src/types/response/v5-position.ts +++ b/src/types/response/v5-position.ts @@ -1,7 +1,14 @@ -import { CategoryV5 } from '../v5-shared'; +import { + CategoryV5, + OrderSideV5, + OrderTypeV5, + PositionIdx, + TPSLModeV5, + TradeModeV5, +} from '../v5-shared'; export interface PositionV5 { - positionIdx: number; + positionIdx: PositionIdx; riskId: number; riskLimitValue: string; symbol: string; @@ -9,7 +16,7 @@ export interface PositionV5 { size: string; avgPrice: string; positionValue: string; - tradeMode: number; + tradeMode: TradeModeV5; autoAddMargin?: number; positionStatus: 'Normal' | 'Liq' | 'Adl'; leverage?: string; @@ -18,7 +25,7 @@ export interface PositionV5 { bustPrice?: string; positionIM?: string; positionMM?: string; - tpslMode?: 'Full' | 'Partial'; + tpslMode?: TPSLModeV5; takeProfit?: string; stopLoss?: string; trailingStop?: string; @@ -27,3 +34,56 @@ export interface PositionV5 { createdTime: string; updatedTime: string; } + +export interface SetRiskLimitResultV5 { + category: CategoryV5; + riskId: number; + riskLimitValue: string; +} + +export interface ExecutionV5 { + symbol: string; + orderId: string; + orderLinkId: string; + side: OrderSideV5; + orderPrice: string; + orderQty: string; + leavesQty: string; + orderType: OrderTypeV5; + stopOrderType?: string; + execFee: string; + execId: string; + execPrice: string; + execQty: string; + execType: string; + execValue: string; + execTime: string; + isMaker: boolean; + feeRate: string; + tradeIv?: string; + markIv?: string; + markPrice: string; + indexPrice: string; + underlyingPrice?: string; + blockTradeId?: string; +} + +export interface ClosedPnLV5 { + symbol: string; + orderId: string; + side: string; + qty: string; + orderPrice: string; + orderType: string; + execType: string; + closedSize: string; + cumEntryValue: string; + avgEntryPrice: string; + cumExitValue: string; + avgExitPrice: string; + closedPnl: string; + fillCount: string; + leverage: string; + createdTime: string; + updatedTime: string; +} diff --git a/src/types/v5-shared.ts b/src/types/v5-shared.ts index afd2655..1fc21bb 100644 --- a/src/types/v5-shared.ts +++ b/src/types/v5-shared.ts @@ -2,10 +2,15 @@ export type CategoryV5 = 'spot' | 'linear' | 'inverse' | 'option'; export type OrderFilterV5 = 'Order' | 'tpslOrder'; export type OrderSideV5 = 'Buy' | 'Sell'; +export type OrderTypeV5 = 'Market' | 'Limit'; export type OrderTimeInForceV5 = 'GTC' | 'IOC' | 'FOK' | 'PostOnly'; export type OrderTriggerByV5 = 'LastPrice' | 'IndexPrice' | 'MarkPrice'; -export type OrderTypeV5 = 'Market' | 'Limit'; export type PositionIdx = 0 | 1 | 2; +/** + * Trade mode. 0: cross-margin, 1: isolated margin + */ +export type TradeModeV5 = 0 | 1; +export type TPSLModeV5 = 'Full' | 'Partial'; export interface CategoryCursorListV5 { category: CategoryV5; From 60a7aa0d9e47685c26d4df4a8a1473f187ae98fe Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Thu, 16 Feb 2023 12:57:49 +0000 Subject: [PATCH 05/26] add v5 account rest endpoints --- src/rest-client-v5.ts | 142 +++++++++++++++++++++++++++++++ src/types/request/index.ts | 1 + src/types/request/v5-account.ts | 34 ++++++++ src/types/response/index.ts | 1 + src/types/response/v5-account.ts | 113 ++++++++++++++++++++++++ src/types/v5-shared.ts | 22 +++++ 6 files changed, 313 insertions(+) create mode 100644 src/types/request/v5-account.ts create mode 100644 src/types/response/v5-account.ts diff --git a/src/rest-client-v5.ts b/src/rest-client-v5.ts index 703eb58..e65f611 100644 --- a/src/rest-client-v5.ts +++ b/src/rest-client-v5.ts @@ -65,6 +65,20 @@ import { ExecutionV5, GetClosedPnLParamsV5, ClosedPnLV5, + GetWalletBalanceParamsV5, + WalletBalanceV5, + UnifiedAccountUpgradeResultV5, + GetBorrowHistoryParamsV5, + BorrowHistoryRecordV5, + CollateralInfoV5, + CoinGreeksV5, + FeeRateV5, + AccountInfoV5, + GetTransactionLogParamsV5, + TransactionLogV5, + AccountMarginModeV5, + MMPModifyParamsV5, + MMPStateV5, } from './types'; import { REST_CLIENT_TYPE_ENUM } from './util'; import BaseRestClient from './util/BaseRestClient'; @@ -544,6 +558,134 @@ export class RestClientV5 extends BaseRestClient { return this.getPrivate('/v5/position/closed-pnl', params); } + /** + * + * Account APIs + * + */ + + /** + * Obtain wallet balance, query asset information of each currency, and account risk rate information under unified margin mode. + * + * By default, currency information with assets or liabilities of 0 is not returned. + */ + getWalletBalance( + params: GetWalletBalanceParamsV5 + ): Promise> { + return this.getPrivate('/v5/account/wallet-balance', params); + } + + /** + * Upgrade to unified account. + * + * Banned/OTC loan/Net asset unsatisfying/Express path users cannot upgrade the account to Unified Account for now. + */ + upgradeToUnifiedAccount(): Promise< + APIResponseV3WithTime + > { + return this.postPrivate('/v5/account/upgrade-to-uta'); + } + + /** + * Get interest records, sorted in reverse order of creation time. + * + * Unified account + */ + getBorrowHistory( + params?: GetBorrowHistoryParamsV5 + ): Promise>> { + return this.getPrivate('/v5/account/borrow-history', params); + } + + /** + * Get the collateral information of the current unified margin account, including loan interest rate, + * loanable amount, collateral conversion rate, whether it can be mortgaged as margin, etc. + */ + getCollateralInfo( + currency?: string + ): Promise> { + return this.getPrivate('/v5/account/collateral-info', { currency }); + } + + /** + * Get current account Greeks information + */ + getCoinGreeks( + baseCoin?: string + ): Promise> { + return this.getPrivate( + '/v5/asset/coin-greeks', + baseCoin ? { baseCoin } : undefined + ); + } + + /** + * Get the trading fee rate of derivatives. + * Covers: USDT perpetual / Inverse perpetual / Inverse futures + */ + getFeeRate( + symbol?: string + ): Promise> { + return this.getPrivate( + '/v5/account/fee-rate', + symbol ? { symbol } : undefined + ); + } + + /** + * Query the margin mode and the upgraded status of account + */ + getAccountInfo(): Promise> { + return this.getPrivate('/v5/account/info'); + } + + /** + * Query transaction logs in Unified account. + */ + getTransactionLog( + params?: GetTransactionLogParamsV5 + ): Promise>> { + return this.getPrivate('/v5/account/transaction-log', params); + } + + /** + * Default is regular margin mode. + * + * This mode is valid for USDT Perp, USDC Perp and USDC Option. + */ + setMarginMode( + marginMode: AccountMarginModeV5 + ): Promise< + APIResponseV3<{ reasons: { reasonCode: string; reasonMsg: string }[] }> + > { + return this.postPrivate('/v5/account/set-margin-mode', { + setMarginMode: marginMode, + }); + } + + /** + * Configure Market Maker Protection (MMP) + */ + setMMP(params: MMPModifyParamsV5): Promise> { + return this.postPrivate('/v5/account/mmp-modify', params); + } + + /** + * Once the mmp triggered, you can unfreeze the account via this endpoint + */ + resetMMP(baseCoin: string): Promise> { + return this.postPrivate('/v5/account/mmp-modify', { baseCoin }); + } + + /** + * Get MMP State + */ + getMMPState( + baseCoin: string + ): Promise> { + return this.getPrivate('/v5/account/mmp-state', { baseCoin }); + } + // // // diff --git a/src/types/request/index.ts b/src/types/request/index.ts index 46749cf..a00cf23 100644 --- a/src/types/request/index.ts +++ b/src/types/request/index.ts @@ -8,6 +8,7 @@ export * from './usdc-perp'; export * from './usdc-options'; export * from './usdc-shared'; export * from './unified-margin'; +export * from './v5-account'; export * from './v5-market'; export * from './v5-position'; export * from './v5-trade'; diff --git a/src/types/request/v5-account.ts b/src/types/request/v5-account.ts new file mode 100644 index 0000000..5213ce4 --- /dev/null +++ b/src/types/request/v5-account.ts @@ -0,0 +1,34 @@ +import { AccountTypeV5, CategoryV5, TransactionTypeV5 } from '../v5-shared'; + +export interface GetWalletBalanceParamsV5 { + accountType: AccountTypeV5; + coin?: string; +} + +export interface GetBorrowHistoryParamsV5 { + currency?: string; + startTime?: number; + endTime?: number; + limit?: number; + cursor?: string; +} + +export interface GetTransactionLogParamsV5 { + accountType?: AccountTypeV5; + category?: CategoryV5; + currency?: string; + baseCoin?: string; + type?: TransactionTypeV5; + startTime?: number; + endTime?: number; + limit?: number; + cursor?: string; +} + +export interface MMPModifyParamsV5 { + baseCoin: string; + window: string; + frozenPeriod: string; + qtyLimit: string; + deltaLimit: string; +} diff --git a/src/types/response/index.ts b/src/types/response/index.ts index d93addb..d882d87 100644 --- a/src/types/response/index.ts +++ b/src/types/response/index.ts @@ -4,6 +4,7 @@ export * from './shared'; export * from './spot'; export * from './usdt-perp'; export * from './unified-margin'; +export * from './v5-account'; export * from './v5-market'; export * from './v5-position'; export * from './v5-trade'; diff --git a/src/types/response/v5-account.ts b/src/types/response/v5-account.ts new file mode 100644 index 0000000..7e99ea0 --- /dev/null +++ b/src/types/response/v5-account.ts @@ -0,0 +1,113 @@ +import { AccountTypeV5, CategoryV5, TransactionTypeV5 } from '../v5-shared'; + +export interface WalletBalanceV5Coin { + coin: string; + equity: string; + usdValue: string; + walletBalance: string; + borrowAmount: string; + availableToBorrow: string; + availableToWithdraw: string; + accruedInterest: string; + totalOrderIM: string; + totalPositionIM: string; + totalPositionMM: string; + unrealisedPnl: string; + cumRealisedPnl: string; +} + +export interface WalletBalanceV5 { + accountType: AccountTypeV5; + accountIMRate: string; + accountMMRate: string; + totalEquity: string; + totalWalletBalance: string; + totalMarginBalance: string; + totalAvailableBalance: string; + totalPerpUPL: string; + totalInitialMargin: string; + totalMaintenanceMargin: string; + coin: WalletBalanceV5Coin[]; +} + +export type UnifiedUpdateStatusV5 = 'FAIL' | 'PROCESS' | 'SUCCESS'; + +export interface UnifiedAccountUpgradeResultV5 { + unifiedUpdateStatus: UnifiedUpdateStatusV5; + unifiedUpdateMsg: { + msg: string[] | null; + }; +} + +export interface BorrowHistoryRecordV5 { + currency: string; + createdTime: number; + borrowCost: string; + hourlyBorrowRate: string; + InterestBearingBorrowSize: string; + costExemption: string; +} + +export interface CollateralInfoV5 { + currency: string; + hourlyBorrowRate: string; + maxBorrowingAmount: string; + freeBorrowingAmount: string; + borrowAmount: string; + availableToBorrow: string; + borrowable: boolean; + marginCollateral: boolean; + collateralRatio: string; +} + +export interface CoinGreeksV5 { + baseCoin: string; + totalDelta: string; + totalGamma: string; + totalVega: string; + totalTheta: string; +} + +export interface FeeRateV5 { + symbol: string; + takerFeeRate: string; + makerFeeRate: string; +} + +export interface AccountInfoV5 { + unifiedMarginStatus: number; + marginMode: 'REGULAR_MARGIN' | 'PORTFOLIO_MARGIN'; + updatedTime: string; +} + +export interface TransactionLogV5 { + symbol: string; + category: CategoryV5; + side: string; + transactionTime: string; + type: TransactionTypeV5; + qty: string; + size: string; + currency: string; + tradePrice: string; + funding: string; + fee: string; + cashFlow: string; + change: string; + cashBalance: string; + feeRate: string; + tradeId: string; + orderId: string; + orderLinkId: string; +} + +export interface MMPStateV5 { + baseCoin: string; + mmpEnabled: boolean; + window: string; + frozenPeriod: string; + qtyLimit: string; + deltaLimit: string; + mmpFrozenUntil: string; + mmpFrozen: boolean; +} diff --git a/src/types/v5-shared.ts b/src/types/v5-shared.ts index 1fc21bb..99c23ee 100644 --- a/src/types/v5-shared.ts +++ b/src/types/v5-shared.ts @@ -11,6 +11,28 @@ export type PositionIdx = 0 | 1 | 2; */ export type TradeModeV5 = 0 | 1; export type TPSLModeV5 = 'Full' | 'Partial'; +export type AccountMarginModeV5 = 'REGULAR_MARGIN' | 'PORTFOLIO_MARGIN'; + +export type AccountTypeV5 = + | 'CONTRACT' + | 'SPOT' + | 'INVESTMENT' + | 'OPTION' + | 'UNIFIED' + | 'FUND'; + +export type TransactionTypeV5 = + | 'TRANSFER_IN' + | 'TRANSFER_OUT' + | 'TRADE' + | 'SETTLEMENT' + | 'DELIVERY' + | 'LIQUIDATION' + | 'BONUS' + | 'FEE_REFUND' + | 'INTEREST' + | 'CURRENCY_BUY' + | 'CURRENCY_SELL'; export interface CategoryCursorListV5 { category: CategoryV5; From e312491968121e170d38840ced7b39ba6f80ebff Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Thu, 16 Feb 2023 13:46:46 +0000 Subject: [PATCH 06/26] add v5 asset rest endpoints --- src/rest-client-v5.ts | 338 ++++++++++++++++++++++++++++++++- src/types/request/index.ts | 1 + src/types/request/v5-asset.ts | 129 +++++++++++++ src/types/response/index.ts | 1 + src/types/response/v5-asset.ts | 148 +++++++++++++++ 5 files changed, 613 insertions(+), 4 deletions(-) create mode 100644 src/types/request/v5-asset.ts create mode 100644 src/types/response/v5-asset.ts diff --git a/src/rest-client-v5.ts b/src/rest-client-v5.ts index e65f611..02a83a9 100644 --- a/src/rest-client-v5.ts +++ b/src/rest-client-v5.ts @@ -79,6 +79,34 @@ import { AccountMarginModeV5, MMPModifyParamsV5, MMPStateV5, + GetCoinExchangeRecordParamsV5, + CoinExchangeRecordV5, + GetDeliveryRecordParamsV5, + DeliveryRecordV5, + GetSettlementRecordParamsV5, + SettlementRecordV5, + GetAssetInfoParamsV5, + AssetInfoV5, + GetAllCoinsBalanceParamsV5, + AllCoinsBalanceV5, + GetAccountCoinBalanceParamsV5, + AccountCoinBalanceV5, + AccountTypeV5, + GetInternalTransferParamsV5, + InternalTransferRecordV5, + UniversalTransferParamsV5, + GetUniversalTransferRecordsParamsV5, + UniversalTransferRecordV5, + GetAllowedDepositCoinInfoParamsV5, + AllowedDepositCoinInfoV5, + GetDepositRecordParamsV5, + DepositRecordV5, + GetSubAccountDepositRecordParamsV5, + DepositAddressResultV5, + CoinInfoV5, + GetWithdrawalRecordsParamsV5, + WithdrawalRecordV5, + WithdrawParamsV5, } from './types'; import { REST_CLIENT_TYPE_ENUM } from './util'; import BaseRestClient from './util/BaseRestClient'; @@ -106,7 +134,7 @@ export class RestClientV5 extends BaseRestClient { /** * - * Market APIs + ****** Market APIs * */ @@ -291,7 +319,7 @@ export class RestClientV5 extends BaseRestClient { /** * - * Trade APIs + ****** Trade APIs * */ @@ -427,7 +455,7 @@ export class RestClientV5 extends BaseRestClient { /** * - * Position APIs + ****** Position APIs * */ @@ -560,7 +588,7 @@ export class RestClientV5 extends BaseRestClient { /** * - * Account APIs + ****** Account APIs * */ @@ -686,6 +714,308 @@ export class RestClientV5 extends BaseRestClient { return this.getPrivate('/v5/account/mmp-state', { baseCoin }); } + /** + * + ****** Asset APIs + * + */ + + /** + * Query the coin exchange records. + * + * CAUTION: You may experience long delays with this endpoint. + */ + getCoinExchangeRecords(params?: GetCoinExchangeRecordParamsV5): Promise< + APIResponseV3WithTime<{ + orderBody: CoinExchangeRecordV5[]; + nextPageCursor?: string; + }> + > { + return this.get('/v5/asset/exchange/order-record', params); + } + + /** + * Query option delivery records, sorted by deliveryTime in descending order. + * + * Covers: Option + */ + getDeliveryRecord( + params: GetDeliveryRecordParamsV5 + ): Promise>> { + return this.getPrivate('/v5/asset/delivery-record', params); + } + + /** + * Query session settlement records of USDC perpetual + * + * Covers: Linear contract (USDC Perpetual only, Unified Account) + */ + getSettlementRecords( + params: GetSettlementRecordParamsV5 + ): Promise< + APIResponseV3WithTime> + > { + return this.getPrivate('/v5/asset/settlement-record', params); + } + + /** + * Query asset information. + * + * INFO + * For now, it can query SPOT only. + */ + getAssetInfo( + params: GetAssetInfoParamsV5 + ): Promise> { + return this.getPrivate('/v5/asset/transfer/query-asset-info', params); + } + + /** + * Query all coin balances of all account types under the master account and sub accounts. + * + * It is not allowed to get the master account coin balance via sub account API key. + */ + getAllCoinsBalance( + params: GetAllCoinsBalanceParamsV5 + ): Promise> { + return this.getPrivate( + '/v5/asset/transfer/query-account-coins-balance', + params + ); + } + + /** + * Query the balance of a specific coin in a specific account type. Supports querying sub UID's balance. + * + * CAUTION: Can query by the master UID's api key only. + */ + getCoinBalance( + params: GetAccountCoinBalanceParamsV5 + ): Promise> { + return this.getPrivate( + '/v5/asset/transfer/query-account-coin-balance', + params + ); + } + + /** + * Query the transferable coin list between each account type. + */ + getTransferableCoinList( + fromAccountType: AccountTypeV5, + toAccountType: AccountTypeV5 + ): Promise> { + return this.getPrivate('/v5/asset/transfer/query-transfer-coin-list', { + fromAccountType, + toAccountType, + }); + } + + /** + * Create the internal transfer between different account types under the same UID. + * Each account type has its own acceptable coins, e.g, you cannot transfer USDC from SPOT to CONTRACT. + * + * Please refer to the getTransferableCoinList() API to find out more. + */ + createInternalTransfer( + transferId: string, + coin: string, + amount: string, + fromAccountType: AccountTypeV5, + toAccountType: AccountTypeV5 + ): Promise> { + return this.postPrivate('/v5/asset/transfer/inter-transfer', { + transferId, + coin, + amount, + fromAccountType, + toAccountType, + }); + } + + /** + * Query the internal transfer records between different account types under the same UID. + */ + getInternalTransferRecords( + params: GetInternalTransferParamsV5 + ): Promise>> { + return this.getPrivate( + '/v5/asset/transfer/query-inter-transfer-list', + params + ); + } + + /** + * Query the sub UIDs under a main UID + * + * CAUTION: Can query by the master UID's api key only + */ + getSubUID(): Promise< + APIResponseV3WithTime<{ + subMemberIds: string[]; + transferableSubMemberIds: string[]; + }> + > { + return this.getPrivate('/v5/asset/transfer/query-sub-member-list'); + } + + /** + * Enable Universal Transfer for Sub UID + * + * Use this endpoint to enable a subaccount to take part in a universal transfer. It is a one-time switch which, once thrown, enables a subaccount permanently. If not set, your subaccount cannot use universal transfers. + */ + enableUniversalTransferForSubUIDs( + subMemberIds: string[] + ): Promise> { + return this.postPrivate('/v5/asset/transfer/save-transfer-sub-member', { + subMemberIds, + }); + } + + /** + * Transfer between sub-sub or main-sub. Please make sure you have enabled universal transfer on your sub UID in advance. + */ + createUniversalTransfer( + params: UniversalTransferParamsV5 + ): Promise> { + return this.postPrivate('/v5/asset/transfer/universal-transfer', params); + } + + /** + * Query universal transfer records + * + * CAUTION + * Can query by the master UID's API key only + */ + getUniversalTransferRecords( + params?: GetUniversalTransferRecordsParamsV5 + ): Promise>> { + return this.getPrivate( + '/v5/asset/transfer/query-universal-transfer-list', + params + ); + } + + /** + * Query allowed deposit coin information. + * To find out paired chain of coin, please refer to the coin info api. + */ + getAllowedDepositCoinInfo( + params?: GetAllowedDepositCoinInfoParamsV5 + ): Promise< + APIResponseV3WithTime<{ + configList: AllowedDepositCoinInfoV5[]; + nextPageCursor: string; + }> + > { + return this.get('/v5/asset/deposit/query-allowed-list', params); + } + + /** + * Query deposit records. + * + * TIP + * endTime - startTime should be less than 30 days. Query last 30 days records by default. + * + * Can use main or sub UID api key to query deposit records respectively. + */ + getDepositRecords( + params?: GetDepositRecordParamsV5 + ): Promise< + APIResponseV3WithTime<{ rows: DepositRecordV5[]; nextPageCursor: string }> + > { + return this.getPrivate('/v5/asset/deposit/query-record', params); + } + + /** + * Query subaccount's deposit records by MAIN UID's API key. + * + * TIP: Query deposit records of SPOT only + * endTime - startTime should be less than 30 days. + * Queries for the last 30 days worth of records by default. + */ + getSubAccountDepositRecords( + params: GetSubAccountDepositRecordParamsV5 + ): Promise< + APIResponseV3WithTime<{ rows: DepositRecordV5[]; nextPageCursor: string }> + > { + return this.getPrivate('/v5/asset/deposit/query-sub-member-record', params); + } + + /** + * Query the deposit address information of MASTER account. + */ + getMasterDepositAddress( + coin: string, + chainType?: string + ): Promise> { + return this.getPrivate('/v5/asset/deposit/query-address', { + coin, + chainType, + }); + } + + /** + * Query the deposit address information of SUB account. + * + * CAUTION + * Can use master UID's api key only + */ + querySubMemberAddress( + coin: string, + chainType: string, + subMemberId: string + ): Promise> { + return this.getPrivate('/v5/asset/deposit/query-sub-member-address', { + coin, + chainType, + subMemberId, + }); + } + + /** + * Query coin information, including chain information, withdraw and deposit status. + */ + getCoinInfo( + coin?: string + ): Promise> { + return this.get('/v5/asset/coin/query-info', coin ? { coin } : undefined); + } + + /** + * Query withdrawal records. + */ + getWithdrawalRecords( + params?: GetWithdrawalRecordsParamsV5 + ): Promise> { + return this.getPrivate('/v5/asset/withdraw/query-record', params); + } + + /** + * Withdraw assets from the SPOT account. + * + * CAUTION: Make sure you have whitelisted your wallet address before calling this endpoint. + * + * NOTE: Currently we are upgrading the fund account, if your funding account has been upgraded, you can select the wallet to be withdrawn from. If your funding account has not been upgraded, the API will still use spot wallet to withdraw cash, but you cannot select the wallet to be withdrawn from. It is expected that in the next two weeks, all users' funding account upgrades will be completed. + * + * You can make an off-chain transfer if the target wallet address is from Bybit. This means that no blockchain fee will be charged. + */ + submitWithdrawal( + params: WithdrawParamsV5 + ): Promise> { + return this.postPrivate('/v5/asset/withdraw/create', params); + } + + /** + * Cancel the withdrawal + * + * CAUTION: Can query by the master UID's api key only + */ + cancelWithdrawal( + id: string + ): Promise> { + return this.postPrivate('/v5/asset/withdraw/cancel', { id }); + } // // // diff --git a/src/types/request/index.ts b/src/types/request/index.ts index a00cf23..bcca1a3 100644 --- a/src/types/request/index.ts +++ b/src/types/request/index.ts @@ -9,6 +9,7 @@ export * from './usdc-options'; export * from './usdc-shared'; export * from './unified-margin'; export * from './v5-account'; +export * from './v5-asset'; export * from './v5-market'; export * from './v5-position'; export * from './v5-trade'; diff --git a/src/types/request/v5-asset.ts b/src/types/request/v5-asset.ts new file mode 100644 index 0000000..104d522 --- /dev/null +++ b/src/types/request/v5-asset.ts @@ -0,0 +1,129 @@ +import { AccountTypeV5, CategoryV5 } from '../v5-shared'; + +export interface GetCoinExchangeRecordParamsV5 { + fromCoin?: string; + toCoin?: string; + limit?: number; + cursor?: string; +} + +export interface GetDeliveryRecordParamsV5 { + category: CategoryV5; + symbol?: string; + expDate?: string; + limit?: number; + cursor?: string; +} + +export interface GetSettlementRecordParamsV5 { + category: CategoryV5; + symbol?: string; + limit?: number; + cursor?: string; +} + +export interface GetAssetInfoParamsV5 { + accountType: AccountTypeV5; + coin?: string; +} + +export interface GetAllCoinsBalanceParamsV5 { + memberId?: string; + accountType: AccountTypeV5; + coin?: string; + withBonus?: number; +} + +export interface GetAccountCoinBalanceParamsV5 { + memberId?: string; + accountType: AccountTypeV5; + coin: string; + withBonus?: number; +} + +export interface GetInternalTransferParamsV5 { + transferId?: string; + coin?: string; + status?: string; + startTime?: number; + endTime?: number; + limit?: number; + cursor?: string; +} + +export interface UniversalTransferParamsV5 { + transferId: string; + coin: string; + amount: string; + fromMemberId: number; + toMemberId: number; + fromAccountType: AccountTypeV5; + toAccountType: AccountTypeV5; +} + +export interface GetUniversalTransferRecordsParamsV5 { + transferId?: string; + coin?: string; + status?: string; + startTime?: number; + endTime?: number; + limit?: number; + cursor?: string; +} + +export interface UniversalTransferRecordV5 { + transferId: string; + coin: string; + amount: string; + fromMemberId: string; + toMemberId: string; + fromAccountType: AccountTypeV5; + toAccountType: AccountTypeV5; + timestamp: string; + status: string; +} + +export interface GetAllowedDepositCoinInfoParamsV5 { + coin?: string; + chain?: string; + limit?: number; + cursor?: string; +} + +export interface GetDepositRecordParamsV5 { + coin?: string; + startTime?: number; + endTime?: number; + limit?: number; + cursor?: string; +} + +export interface GetSubAccountDepositRecordParamsV5 { + subMemberId: string; + coin?: string; + startTime?: number; + endTime?: number; + limit?: number; + cursor?: string; +} + +export interface GetWithdrawalRecordsParamsV5 { + withdrawID?: string; + coin?: string; + withdrawType?: number; + startTime?: number; + endTime?: number; + limit?: number; + cursor?: string; +} + +export interface WithdrawParamsV5 { + coin: string; + chain: string; + address: string; + tag?: string; + amount: string; + timestamp: number; + forceChain?: number; + accountType?: string; +} diff --git a/src/types/response/index.ts b/src/types/response/index.ts index d882d87..43642ce 100644 --- a/src/types/response/index.ts +++ b/src/types/response/index.ts @@ -5,6 +5,7 @@ export * from './spot'; export * from './usdt-perp'; export * from './unified-margin'; export * from './v5-account'; +export * from './v5-asset'; export * from './v5-market'; export * from './v5-position'; export * from './v5-trade'; diff --git a/src/types/response/v5-asset.ts b/src/types/response/v5-asset.ts new file mode 100644 index 0000000..2edbd5a --- /dev/null +++ b/src/types/response/v5-asset.ts @@ -0,0 +1,148 @@ +import { AccountTypeV5, OrderSideV5 } from '../v5-shared'; + +export interface CoinExchangeRecordV5 { + fromCoin: string; + fromAmount: string; + toCoin: string; + toAmount: string; + exchangeRate: string; + createdTime: string; + exchangeTxId: string; +} + +export interface DeliveryRecordV5 { + deliveryTime: number; + symbol: string; + side: OrderSideV5; + position: string; + deliveryPrice: string; + strike: string; + fee: string; + deliveryRpl: string; +} + +export interface SettlementRecordV5 { + symbol: string; + side: string; + size: number; + sessionAvgPrice: string; + markPrice: string; + realisedPnl: string; + createdTime: string; +} + +export interface AssetInfoAssetV5 { + coin: string; + frozen: string; + free: string; + withdraw: string; +} + +export interface AssetInfoV5 { + status: 'ACCOUNT_STATUS_NORMAL' | 'ACCOUNT_STATUS_UNSPECIFIED'; + assets: AssetInfoAssetV5[]; +} + +export interface CoinBalanceV5 { + coin: string; + walletBalance: string; + transferBalance: string; + bonus?: string; +} + +export interface AllCoinsBalanceV5 { + accountType: AccountTypeV5; + memberId?: string; + balance: CoinBalanceV5[]; +} + +export interface AccountCoinBalanceV5 { + accountType: AccountTypeV5; + bizType: number; + accountId: string; + memberId: string; + balance: { + coin: string; + walletBalance: string; + transferBalance: string; + bonus: string; + }; +} + +export interface InternalTransferRecordV5 { + transferId: string; + coin: string; + amount: string; + fromAccountType: AccountTypeV5; + toAccountType: AccountTypeV5; + timestamp: string; + status: string; +} + +export interface AllowedDepositCoinInfoV5 { + coin: string; + chain: string; + coinShowName: string; + chainType: string; + blockConfirmNumber: number; + minDepositAmount: string; +} + +export interface DepositRecordV5 { + coin: string; + chain: string; + amount: string; + txID: string; + status: number; + toAddress: string; + tag: string; + depositFee: string; + successAt: string; + confirmations: string; + txIndex: string; + blockHash: string; +} + +export interface DepositAddressChainV5 { + chainType: string; + addressDeposit: string; + tagDeposit: string; + chain: string; +} + +export interface DepositAddressResultV5 { + coin: string; + chains: DepositAddressChainV5[]; +} + +export interface CoinInfoV5 { + name: number; + coin: string; + remainAmount: string; + chains: { + chain: string; + chainType: string; + confirmation: string; + withdrawFee: string; + depositMin: string; + withdrawMin: string; + minAccuracy: string; + chainDeposit: string; + chainWithdraw: string; + }[]; +} + +export interface WithdrawalRecordV5 { + withdrawId: string; + txID: string; + withdrawType: string; + coin: string; + chain: string; + amount: string; + withdrawFee: string; + status: string; + toAddress: string; + tag: string; + createTime: string; + updateTime: string; +} From d4add6d9645f8de2bafdcb9ca09c963354d98356 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Thu, 16 Feb 2023 15:30:01 +0000 Subject: [PATCH 07/26] add v5 user rest endpoints --- src/rest-client-v5.ts | 124 ++++++++++++++++++++++++++++++++++ src/types/request/index.ts | 1 + src/types/request/v5-asset.ts | 7 ++ src/types/request/v5-user.ts | 21 ++++++ src/types/response/index.ts | 1 + src/types/response/v5-user.ts | 58 ++++++++++++++++ src/types/v5-shared.ts | 19 ++++++ 7 files changed, 231 insertions(+) create mode 100644 src/types/request/v5-user.ts create mode 100644 src/types/response/v5-user.ts diff --git a/src/rest-client-v5.ts b/src/rest-client-v5.ts index 02a83a9..4bb3ff9 100644 --- a/src/rest-client-v5.ts +++ b/src/rest-client-v5.ts @@ -107,6 +107,14 @@ import { GetWithdrawalRecordsParamsV5, WithdrawalRecordV5, WithdrawParamsV5, + CreateSubMemberParamsV5, + CreateSubMemberResultV5, + CreateSubApiKeyParamsV5, + CreateSubApiKeyResultV5, + SubMemberV5, + ApiKeyInfoV5, + UpdateApiKeyResultV5, + UpdateApiKeyParamsV5, } from './types'; import { REST_CLIENT_TYPE_ENUM } from './util'; import BaseRestClient from './util/BaseRestClient'; @@ -1016,6 +1024,122 @@ export class RestClientV5 extends BaseRestClient { ): Promise> { return this.postPrivate('/v5/asset/withdraw/cancel', { id }); } + + /** + * + ****** User APIs + * + */ + + /** + * Create a new sub user id. Use master user's api key only. + * + * The API key must own one of permissions will be allowed to call the following API endpoint. + * + * master API key: "Account Transfer", "Subaccount Transfer", "Withdrawal" + */ + createSubMember( + params: CreateSubMemberParamsV5 + ): Promise> { + return this.postPrivate('/v5/user/create-sub-member', params); + } + + /** + * To create new API key for those newly created sub UID. Use master user's api key only. + * + * TIP + * The API key must own one of permissions will be allowed to call the following API endpoint. + * master API key: "Account Transfer", "Subaccount Transfer", "Withdrawal" + */ + createSubUIDAPIKey( + params: CreateSubApiKeyParamsV5 + ): Promise> { + return this.postPrivate('/v5/user/create-sub-api', params); + } + + /** + * This endpoint allows you to get a list of all sub UID of master account. + */ + getSubUIDList(): Promise< + APIResponseV3WithTime<{ subMembers: SubMemberV5[] }> + > { + return this.getPrivate('/v5/user/query-sub-members'); + } + + /** + * Froze sub uid. Use master user's api key only. + * + * TIP: The API key must own one of the following permissions will be allowed to call the following API endpoint. + * + * master API key: "Account Transfer", "Subaccount Transfer", "Withdrawal" + */ + setSubUIDFrozenState( + subuid: number, + frozen: 0 | 1 + ): Promise> { + return this.postPrivate('/v5/user/frozen-sub-member', { subuid, frozen }); + } + + /** + * Get the information of the api key. Use the api key pending to be checked to call the endpoint. Both master and sub user's api key are applicable. + * + * TIP: Any permission can access this endpoint. + */ + getQueryApiKey(): Promise> { + return this.getPrivate('/v5/user/query-api'); + } + + /** + * Modify the settings of a master API key. Use the API key pending to be modified to call the endpoint. Use master user's API key only. + * + * TIP: The API key must own one of the permissions to call the following API endpoint. + * + * Master API key: "Account Transfer", "Subaccount Transfer", "Withdrawal" + */ + updateMasterApiKey( + params: UpdateApiKeyParamsV5 + ): Promise> { + return this.postPrivate('/v5/user/update-api', params); + } + + /** + * This endpoint modifies the settings of a sub API key. + * Use the API key pending to be modified to call the endpoint. + * Only the API key that calls this interface can be modified. + * + * The API key must own "Account Transfer" permission to be allowed to call this API endpoint. + */ + updateSubApiKey( + params: UpdateApiKeyParamsV5 + ): Promise> { + return this.postPrivate('/v5/user/update-sub-api', params); + } + + /** + * Delete the api key of master account. Use the api key pending to be delete to call the endpoint. Use master user's api key only. + * + * TIP: The API key must own one of permissions will be allowed to call the following API endpoint. + * master API key: "Account Transfer", "Subaccount Transfer", "Withdrawal" + * + * DANGER: BE CAREFUL! The API key used to call this interface will be invalid immediately. + */ + deleteMasterApiKey(): Promise> { + return this.postPrivate('/v5/user/delete-api'); + } + + /** + * Delete the api key of sub account. Use the api key pending to be delete to call the endpoint. Use sub user's api key only. + * + * TIP + * The API key must own one of permissions will be allowed to call the following API endpoint. + * sub API key: "Account Transfer" + * + * DANGER: BE CAREFUL! The API key used to call this interface will be invalid immediately. + */ + deleteSubApiKey(): Promise> { + return this.postPrivate('/v5/user/delete-sub-api'); + } + // // // diff --git a/src/types/request/index.ts b/src/types/request/index.ts index bcca1a3..62950e2 100644 --- a/src/types/request/index.ts +++ b/src/types/request/index.ts @@ -13,3 +13,4 @@ export * from './v5-asset'; export * from './v5-market'; export * from './v5-position'; export * from './v5-trade'; +export * from './v5-user'; diff --git a/src/types/request/v5-asset.ts b/src/types/request/v5-asset.ts index 104d522..a1af232 100644 --- a/src/types/request/v5-asset.ts +++ b/src/types/request/v5-asset.ts @@ -127,3 +127,10 @@ export interface WithdrawParamsV5 { forceChain?: number; accountType?: string; } + +export interface CreateSubMemberParamsV5 { + username: string; + memberType: 1 | 6; + switch?: 0 | 1; + note?: string; +} diff --git a/src/types/request/v5-user.ts b/src/types/request/v5-user.ts new file mode 100644 index 0000000..f1d60cf --- /dev/null +++ b/src/types/request/v5-user.ts @@ -0,0 +1,21 @@ +import { PermissionsV5 } from '../v5-shared'; + +export interface CreateSubApiKeyParamsV5 { + subuid: number; + note?: string; + readOnly: 0 | 1; + ips?: string[]; + permissions: PermissionsV5; +} + +export interface UpdateApiKeyParamsV5 { + readOnly?: 0 | 1; + ips?: string[]; + permissions: PermissionsV5; +} + +export interface UpdateSubApiKeyUpdateParamsV5 { + readOnly?: number; + ips?: string[]; + permissions: PermissionsV5; +} diff --git a/src/types/response/index.ts b/src/types/response/index.ts index 43642ce..c2edf86 100644 --- a/src/types/response/index.ts +++ b/src/types/response/index.ts @@ -9,3 +9,4 @@ export * from './v5-asset'; export * from './v5-market'; export * from './v5-position'; export * from './v5-trade'; +export * from './v5-user'; diff --git a/src/types/response/v5-user.ts b/src/types/response/v5-user.ts new file mode 100644 index 0000000..18cea54 --- /dev/null +++ b/src/types/response/v5-user.ts @@ -0,0 +1,58 @@ +import { PermissionsV5 } from '../v5-shared'; + +export interface CreateSubMemberResultV5 { + uid: string; + username: string; + memberType: number; + status: number; + remark: string; +} + +export interface CreateSubApiKeyResultV5 { + id: string; + note: string; + apiKey: string; + readOnly: number; + secret: string; + permissions: PermissionsV5; +} + +export interface SubMemberV5 { + uid: string; + username: string; + memberType: number; + status: number; + remark: string; +} +export type ApiKeyType = 1 | 2; + +export interface ApiKeyInfoV5 { + id: string; + note: string; + apiKey: string; + readOnly: 0 | 1; + secret: string; + permissions: PermissionsV5; + ips?: string[]; + type: 1 | 2; + deadlineDay?: number; + expiredAt?: string; + createdAt: string; + unified: 0 | 1; + uta: 0 | 1; + userID: number; + inviterID: number; + vipLevel?: string; + mktMakerLevel?: string; + affiliateID?: number; +} + +export interface UpdateApiKeyResultV5 { + id: string; + note: string; + apiKey: string; + readOnly: 0 | 1; + secret: string; + permissions: PermissionsV5; + ips: string[]; +} diff --git a/src/types/v5-shared.ts b/src/types/v5-shared.ts index 99c23ee..f2b18d2 100644 --- a/src/types/v5-shared.ts +++ b/src/types/v5-shared.ts @@ -34,6 +34,25 @@ export type TransactionTypeV5 = | 'CURRENCY_BUY' | 'CURRENCY_SELL'; +export type PermissionTypeV5 = + | 'ContractTrade' + | 'Spot' + | 'Wallet' + | 'Options' + | 'Derivatives' + | 'Exchange' + | 'NFT'; + +export interface PermissionsV5 { + ContractTrade?: string[]; + Spot?: string[]; + Wallet?: string[]; + Options?: string[]; + Derivatives?: string[]; + Exchange?: string[]; + NFT?: string[]; +} + export interface CategoryCursorListV5 { category: CategoryV5; list: T; From 6d9e73bdda5629b17575d09d870409ced12ac839 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Fri, 17 Feb 2023 11:09:26 +0000 Subject: [PATCH 08/26] add v5 leverage token and spot margin endpoints --- src/rest-client-v5.ts | 95 ++++++++++++++++++-- src/types/request/index.ts | 1 + src/types/request/v5-spot-leverage-token.ts | 23 +++++ src/types/response/index.ts | 1 + src/types/response/v5-spot-leverage-token.ts | 70 +++++++++++++++ src/types/v5-shared.ts | 25 ++++++ 6 files changed, 208 insertions(+), 7 deletions(-) create mode 100644 src/types/request/v5-spot-leverage-token.ts create mode 100644 src/types/response/v5-spot-leverage-token.ts diff --git a/src/rest-client-v5.ts b/src/rest-client-v5.ts index 4bb3ff9..df6988b 100644 --- a/src/rest-client-v5.ts +++ b/src/rest-client-v5.ts @@ -115,6 +115,14 @@ import { ApiKeyInfoV5, UpdateApiKeyResultV5, UpdateApiKeyParamsV5, + LeverageTokenInfoV5, + LeveragedTokenMarketResultV5, + PurchaseSpotLeveragedTokenParamsV5, + PurchaseSpotLeveragedTokenResultV5, + RedeemSpotLeveragedTokenParamsV5, + RedeemSpotLeveragedTokenResultV5, + GetSpotLeveragedTokenOrderHistoryParamsV5, + SpotLeveragedTokenOrderHistoryV5, } from './types'; import { REST_CLIENT_TYPE_ENUM } from './util'; import BaseRestClient from './util/BaseRestClient'; @@ -1140,11 +1148,84 @@ export class RestClientV5 extends BaseRestClient { return this.postPrivate('/v5/user/delete-sub-api'); } - // - // - // - // - // - // - // + /** + * + ****** Spot Leverage Token APIs + * + */ + + /** + * Query leverage token information + */ + getLeveragedTokenInfo( + ltCoin?: string + ): Promise> { + return this.get('/v5/spot-lever-token/info', { ltCoin }); + } + + /** + * Get leverage token market information. + */ + getLeveragedTokenMarket( + ltCoin: string + ): Promise> { + return this.get(`/v5/spot-lever-token/reference`, { ltCoin }); + } + + /** + * This endpoint allows you to purchase a leveraged token with a specified amount. + */ + purchaseSpotLeveragedToken( + params: PurchaseSpotLeveragedTokenParamsV5 + ): Promise> { + return this.postPrivate('/v5/spot-lever-token/purchase', params); + } + + /** + * Redeem leveraged token. + */ + redeemSpotLeveragedToken( + params: RedeemSpotLeveragedTokenParamsV5 + ): Promise> { + return this.postPrivate('/v5/spot-lever-token/redeem', params); + } + + /** + * Get purchase or redemption history + */ + getSpotLeveragedTokenOrderHistory( + params?: GetSpotLeveragedTokenOrderHistoryParamsV5 + ): Promise< + APIResponseV3WithTime<{ list: SpotLeveragedTokenOrderHistoryV5[] }> + > { + return this.getPrivate('/v5/spot-lever-token/order-record', params); + } + + /** + * + ****** Spot Margin Trade APIs + * + */ + + /** + * Turn spot margin trade on / off. + * + * CAUTION + * Your account needs to turn on spot margin first + */ + toggleSpotMarginTrade( + spotMarginMode: '1' | '0' + ): Promise> { + return this.postPrivate('/v5/spot-margin-trade/switch-mode', { + spotMarginMode, + }); + } + + /** + * Set the user's maximum leverage in spot cross margin. + * CAUTION: Your account needs to enable spot margin first; i.e., you must have finished the quiz on web / app. + */ + setSpotMarginLeverage(leverage: string): Promise> { + return this.postPrivate('/v5/spot-margin-trade/set-leverage', { leverage }); + } } diff --git a/src/types/request/index.ts b/src/types/request/index.ts index 62950e2..75f8d45 100644 --- a/src/types/request/index.ts +++ b/src/types/request/index.ts @@ -14,3 +14,4 @@ export * from './v5-market'; export * from './v5-position'; export * from './v5-trade'; export * from './v5-user'; +export * from './v5-spot-leverage-token'; diff --git a/src/types/request/v5-spot-leverage-token.ts b/src/types/request/v5-spot-leverage-token.ts new file mode 100644 index 0000000..189f5fd --- /dev/null +++ b/src/types/request/v5-spot-leverage-token.ts @@ -0,0 +1,23 @@ +import { LTOrderTypeV5 } from '../v5-shared'; + +export interface PurchaseSpotLeveragedTokenParamsV5 { + ltCoin: string; + ltAmount: string; + serialNo?: string; +} + +export interface RedeemSpotLeveragedTokenParamsV5 { + ltCoin: string; + quantity: string; + serialNo?: string; +} + +export interface GetSpotLeveragedTokenOrderHistoryParamsV5 { + ltCoin?: string; + orderId?: string; + startTime?: number; + endTime?: number; + limit?: number; + ltOrderType?: LTOrderTypeV5; + serialNo?: string; +} diff --git a/src/types/response/index.ts b/src/types/response/index.ts index c2edf86..47736f8 100644 --- a/src/types/response/index.ts +++ b/src/types/response/index.ts @@ -10,3 +10,4 @@ export * from './v5-market'; export * from './v5-position'; export * from './v5-trade'; export * from './v5-user'; +export * from './v5-spot-leverage-token'; diff --git a/src/types/response/v5-spot-leverage-token.ts b/src/types/response/v5-spot-leverage-token.ts new file mode 100644 index 0000000..5fa19d2 --- /dev/null +++ b/src/types/response/v5-spot-leverage-token.ts @@ -0,0 +1,70 @@ +import { + LeverageTokenStatusV5, + LTOrderStatusV5, + LTOrderTypeV5, +} from '../v5-shared'; + +export interface LeverageTokenInfoV5 { + ltCoin: string; + ltName: string; + maxPurchase: string; + minPurchase: string; + maxPurchaseDaily: string; + maxRedeem: string; + minRedeem: string; + maxRedeemDaily: string; + purchaseFeeRate: string; + redeemFeeRate: string; + ltStatus: LeverageTokenStatusV5; + fundFee: string; + fundFeeTime: string; + manageFeeRate: string; + manageFeeTime: string; + value: string; + netValue: string; + total: string; +} + +export interface LeveragedTokenMarketResultV5 { + ltCoin: string; + nav: string; + navTime: string; + circulation: string; + basket: string; + leverage: string; +} + +export interface PurchaseSpotLeveragedTokenResultV5 { + ltCoin: string; + ltOrderStatus: LTOrderStatusV5; + execQty: string; + execAmt: string; + amount: string; + purchaseId: string; + serialNo: string; + valueCoin: string; +} +export interface RedeemSpotLeveragedTokenResultV5 { + ltCoin: string; + ltOrderStatus: LTOrderStatusV5; + quantity: string; + execQty: string; + execAmt: string; + redeemId: string; + serialNo: string; + valueCoin: string; +} + +export interface SpotLeveragedTokenOrderHistoryV5 { + ltCoin: string; + orderId: string; + ltOrderType: LTOrderTypeV5; + orderTime: number; + updateTime: number; + ltOrderStatus: LTOrderStatusV5; + fee: string; + amount: string; + value: string; + valueCoin: string; + serialNo: string; +} diff --git a/src/types/v5-shared.ts b/src/types/v5-shared.ts index f2b18d2..916bfa7 100644 --- a/src/types/v5-shared.ts +++ b/src/types/v5-shared.ts @@ -43,6 +43,31 @@ export type PermissionTypeV5 = | 'Exchange' | 'NFT'; +/** + * Leveraged token status: + * + * 1 LT can be purchased and redeemed + * + * 2 LT can be purchased, but not redeemed + * + * 3 LT can be redeemed, but not purchased + * + * 4 LT cannot be purchased nor redeemed + * + * 5 Adjusting position + */ +export type LeverageTokenStatusV5 = '1' | '2' | '3' | '4' | '5'; + +/** + * Leveraged token order type: '1': purchase, '2': redeem + */ +export type LTOrderTypeV5 = '1' | '2'; + +/** + * Leveraged token order status: '1': completed, '2': in progress, '3': failed + */ +export type LTOrderStatusV5 = '1' | '2' | '3'; + export interface PermissionsV5 { ContractTrade?: string[]; Spot?: string[]; From 6a4e7c09ed87ae0b61c6c173eb58a1c8333f87c1 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Fri, 17 Feb 2023 12:16:01 +0000 Subject: [PATCH 09/26] fixing and tidying v5 request and response types --- src/rest-client-v5.ts | 22 ++-- src/types/request/v5-market.ts | 6 +- src/types/request/v5-position.ts | 10 +- src/types/response/v5-account.ts | 12 ++- src/types/response/v5-asset.ts | 4 +- src/types/response/v5-market.ts | 161 +++++++++++++++++------------- src/types/response/v5-position.ts | 10 +- src/types/response/v5-trade.ts | 12 ++- src/types/v5-shared.ts | 101 ++++++++++++++++++- 9 files changed, 231 insertions(+), 107 deletions(-) diff --git a/src/rest-client-v5.ts b/src/rest-client-v5.ts index df6988b..a04a488 100644 --- a/src/rest-client-v5.ts +++ b/src/rest-client-v5.ts @@ -18,7 +18,6 @@ import { GetRiskLimitParamsV5, GetTickersParamsV5, HistoricalVolatilityV5, - InstrumentInfoV5, InsuranceResponseV5, OpenInterestResponseV5, OrderbookResponseV5, @@ -47,8 +46,8 @@ import { AccountOrderV5, OptionDeliveryPriceV5, CategorySymbolListV5, - OHLCV5, - KlineV5, + OHLCKlineV5, + OHLCVKlineV5, TickerSpotV5, TickerOptionV5, TickerLinearInverseV5, @@ -123,6 +122,7 @@ import { RedeemSpotLeveragedTokenResultV5, GetSpotLeveragedTokenOrderHistoryParamsV5, SpotLeveragedTokenOrderHistoryV5, + InstrumentInfoResponseV5, } from './types'; import { REST_CLIENT_TYPE_ENUM } from './util'; import BaseRestClient from './util/BaseRestClient'; @@ -163,7 +163,7 @@ export class RestClientV5 extends BaseRestClient { params: GetKlineParamsV5 ): Promise< APIResponseV3WithTime< - CategorySymbolListV5 + CategorySymbolListV5 > > { return this.get(`/v5/market/kline`, params); @@ -177,7 +177,9 @@ export class RestClientV5 extends BaseRestClient { getMarkPriceKline( params: GetMarkPriceKlineParamsV5 ): Promise< - APIResponseV3WithTime> + APIResponseV3WithTime< + CategorySymbolListV5 + > > { return this.get(`/v5/market/mark-price-kline`, params); } @@ -190,7 +192,9 @@ export class RestClientV5 extends BaseRestClient { getIndexPriceKline( params: GetIndexPriceKlineParamsV5 ): Promise< - APIResponseV3WithTime> + APIResponseV3WithTime< + CategorySymbolListV5 + > > { return this.get(`/v5/market/index-price-kline`, params); } @@ -202,7 +206,9 @@ export class RestClientV5 extends BaseRestClient { */ getPremiumIndexPriceKline( params: GetPremiumIndexPriceKlineParams - ): Promise>> { + ): Promise< + APIResponseV3WithTime> + > { return this.get(`/v5/market/premium-index-price-kline`, params); } @@ -215,7 +221,7 @@ export class RestClientV5 extends BaseRestClient { */ getInstrumentsInfo( params: GetInstrumentsInfoParamsV5 - ): Promise>> { + ): Promise> { return this.get(`/v5/market/instruments-info`, params); } diff --git a/src/types/request/v5-market.ts b/src/types/request/v5-market.ts index c23ccdb..dd4e512 100644 --- a/src/types/request/v5-market.ts +++ b/src/types/request/v5-market.ts @@ -1,5 +1,5 @@ import { KlineIntervalV3 } from '../shared'; -import { CategoryV5 } from '../v5-shared'; +import { CategoryV5, OptionTypeV5 } from '../v5-shared'; export interface GetKlineParamsV5 { category: 'spot' | 'linear' | 'inverse'; @@ -66,13 +66,11 @@ export interface GetFundingRateHistoryParamsV5 { limit?: number; } -export type OptionType = 'Call' | 'Put'; - export interface GetPublicTradingHistoryParamsV5 { category: CategoryV5; symbol: string; baseCoin?: string; - optionType?: OptionType; + optionType?: OptionTypeV5; limit?: number; } diff --git a/src/types/request/v5-position.ts b/src/types/request/v5-position.ts index f378771..ae9f923 100644 --- a/src/types/request/v5-position.ts +++ b/src/types/request/v5-position.ts @@ -1,4 +1,4 @@ -import { CategoryV5, TPSLModeV5 } from '../v5-shared'; +import { CategoryV5, ExecTypeV5, PositionIdx, TPSLModeV5 } from '../v5-shared'; export interface PositionInfoParamsV5 { category: CategoryV5; @@ -41,7 +41,7 @@ export interface SetRiskLimitParamsV5 { category: 'linear' | 'inverse'; symbol: string; riskId: number; - positionIdx?: number; + positionIdx?: PositionIdx; } export interface SetTradingStopParamsV5 { @@ -55,14 +55,14 @@ export interface SetTradingStopParamsV5 { activePrice?: string; tpSize?: string; slSize?: string; - positionIdx: number; + positionIdx: PositionIdx; } export interface SetAutoAddMarginParamsV5 { category: 'linear'; symbol: string; autoAddMargin: 0 | 1; - positionIdx?: number; + positionIdx?: PositionIdx; } export interface GetExecutionListParamsV5 { @@ -73,7 +73,7 @@ export interface GetExecutionListParamsV5 { baseCoin?: string; startTime?: number; endTime?: number; - execType?: string; + execType?: ExecTypeV5; limit?: number; cursor?: string; } diff --git a/src/types/response/v5-account.ts b/src/types/response/v5-account.ts index 7e99ea0..33fa08b 100644 --- a/src/types/response/v5-account.ts +++ b/src/types/response/v5-account.ts @@ -1,4 +1,10 @@ -import { AccountTypeV5, CategoryV5, TransactionTypeV5 } from '../v5-shared'; +import { + AccountMarginModeV5, + AccountTypeV5, + CategoryV5, + TransactionTypeV5, + UnifiedUpdateStatusV5, +} from '../v5-shared'; export interface WalletBalanceV5Coin { coin: string; @@ -30,8 +36,6 @@ export interface WalletBalanceV5 { coin: WalletBalanceV5Coin[]; } -export type UnifiedUpdateStatusV5 = 'FAIL' | 'PROCESS' | 'SUCCESS'; - export interface UnifiedAccountUpgradeResultV5 { unifiedUpdateStatus: UnifiedUpdateStatusV5; unifiedUpdateMsg: { @@ -76,7 +80,7 @@ export interface FeeRateV5 { export interface AccountInfoV5 { unifiedMarginStatus: number; - marginMode: 'REGULAR_MARGIN' | 'PORTFOLIO_MARGIN'; + marginMode: AccountMarginModeV5; updatedTime: string; } diff --git a/src/types/response/v5-asset.ts b/src/types/response/v5-asset.ts index 2edbd5a..a56d166 100644 --- a/src/types/response/v5-asset.ts +++ b/src/types/response/v5-asset.ts @@ -1,4 +1,4 @@ -import { AccountTypeV5, OrderSideV5 } from '../v5-shared'; +import { AccountTypeV5, OrderSideV5, WithdrawalTypeV5 } from '../v5-shared'; export interface CoinExchangeRecordV5 { fromCoin: string; @@ -135,7 +135,7 @@ export interface CoinInfoV5 { export interface WithdrawalRecordV5 { withdrawId: string; txID: string; - withdrawType: string; + withdrawType: WithdrawalTypeV5; coin: string; chain: string; amount: string; diff --git a/src/types/response/v5-market.ts b/src/types/response/v5-market.ts index 5c00194..0cefd63 100644 --- a/src/types/response/v5-market.ts +++ b/src/types/response/v5-market.ts @@ -1,104 +1,121 @@ +import { + CategoryCursorListV5, + ContractTypeV5, + InstrumentStatusV5, + OptionTypeV5, + OrderSideV5, +} from '../v5-shared'; + /** * OHLCVT candle used by v5 APIs * - * > list[0]: startTime string Start time of the candle (ms) - * - * > list[1]: openPrice string Open price - * - * > list[2]: highPrice string Highest price - * - * > list[3]: lowPrice string Lowest price - * - * > list[4]: closePrice string Close price. Is the last traded price when the candle is not closed - * - * > list[5]: volume string Trade volume. Unit of contract: pieces of contract. Unit of spot: quantity of coins - * - * > list[6]: turnover string Turnover. Unit of figure: quantity of quota coin + * - list[0]: startTime string Start time of the candle (ms) + * - list[1]: openPrice string Open price + * - list[2]: highPrice string Highest price + * - list[3]: lowPrice string Lowest price + * - list[4]: closePrice string Close price. Is the last traded price when the candle is not closed + * - list[5]: volume string Trade volume. Unit of contract: pieces of contract. Unit of spot: quantity of coins + * - list[6]: turnover string Turnover. Unit of figure: quantity of quota coin */ -export type KlineV5 = [string, string, string, string, string, string, string]; +export type OHLCVKlineV5 = [ + string, + string, + string, + string, + string, + string, + string +]; /** * OHLC candle used by v5 APIs * - * > list[0]: startTime string Start time of the candle (ms) - * - * > list[1]: openPrice string Open price - * - * > list[2]: highPrice string Highest price - * - * > list[3]: lowPrice string Lowest price - * - * > list[4]: closePrice string Close price. Is the last traded price when the candle is not closed + * - list[0]: startTime string Start time of the candle (ms) + * - list[1]: openPrice string Open price + * - list[2]: highPrice string Highest price + * - list[3]: lowPrice string Lowest price + * - list[4]: closePrice string Close price. Is the last traded price when the candle is not closed */ -export type OHLCV5 = [string, string, string, string, string]; +export type OHLCKlineV5 = [string, string, string, string, string]; export interface LinearInverseInstrumentInfoV5 { - category: 'linear' | 'inverse'; symbol: string; - contractType: string; - status: string; + contractType: ContractTypeV5; + status: InstrumentStatusV5; baseCoin: string; quoteCoin: string; launchTime: string; - deliveryTime: string; - deliveryFeeRate: string; + deliveryTime?: string; + deliveryFeeRate?: string; priceScale: string; - maxLeverage: string; - minOrderValue: string; - minOrderVolume: string; - makerFeeRate: string; - takerFeeRate: string; + leverageFilter: { + minLeverage: string; + maxLeverage: string; + leverageStep: string; + }; + priceFilter: { + minPrice: string; + maxPrice: string; + tickSize: string; + }; + lotSizeFilter: { + maxOrderQty: string; + minOrderQty: string; + qtyStep: string; + postOnlyMaxOrderQty?: string; + }; + unifiedMarginTrade: boolean; + fundingInterval: number; + settleCoin: string; } export interface OptionInstrumentInfoV5 { - category: 'option'; symbol: string; - contractType: string; - status: string; + optionsType: OptionTypeV5; + status: InstrumentStatusV5; baseCoin: string; quoteCoin: string; + settleCoin: boolean; launchTime: string; deliveryTime: string; deliveryFeeRate: string; - priceScale: string; - maxLeverage: string; - minOrderValue: string; - minOrderVolume: string; - makerFeeRate: string; - takerFeeRate: string; - settlementCurrency: string; - settlementPrice: string; - deliveryMethod: string; - optionType: string; - exercisePrice: string; - expirationTime: string; - blockMarginRatio: string; - marginType: string; - strike: string; + priceFilter: { + minPrice: string; + maxPrice: string; + tickSize: string; + }; + lotSizeFilter: { + maxOrderQty: string; + minOrderQty: string; + qtyStep: string; + }; } export interface SpotInstrumentInfoV5 { - category: 'spot'; symbol: string; - contractType: string; - status: string; baseCoin: string; quoteCoin: string; - launchTime: string; - priceScale: string; - maxLeverage: string; - minOrderValue: string; - minOrderVolume: string; - makerFeeRate: string; - takerFeeRate: string; + innovation: '0' | '1'; + status: InstrumentStatusV5; + lotSizeFilter: { + basePrecision: string; + quotePrecision: string; + minOrderQty: string; + maxOrderQty: string; + minOrderAmt: string; + maxOrderAmt: string; + }; + priceFilter: { + tickSize: string; + }; } -export type InstrumentInfoV5 = - | LinearInverseInstrumentInfoV5 - | OptionInstrumentInfoV5 - | SpotInstrumentInfoV5; +export type InstrumentInfoResponseV5 = + | CategoryCursorListV5 + | CategoryCursorListV5 + | CategoryCursorListV5; -export interface OrderbookLevelV5 { +export default interface OrderbookLevelV5 { price: string; size: string; } @@ -192,16 +209,16 @@ export interface PublicTradeV5 { symbol: string; price: string; size: string; - side: 'Buy' | 'Sell'; + side: OrderSideV5; time: string; isBlockTrade: boolean; } /** -> openInterest string Open interest - -> timestamp string The timestamp (ms) -*/ + * + * - openInterest string Open interest + * - timestamp string The timestamp (ms) + */ export type OpenInterestV5 = [string, string]; export interface OpenInterestResponseV5 { diff --git a/src/types/response/v5-position.ts b/src/types/response/v5-position.ts index 768d226..7cedeec 100644 --- a/src/types/response/v5-position.ts +++ b/src/types/response/v5-position.ts @@ -1,8 +1,10 @@ import { CategoryV5, + ExecTypeV5, OrderSideV5, OrderTypeV5, PositionIdx, + StopOrderTypeV5, TPSLModeV5, TradeModeV5, } from '../v5-shared'; @@ -50,12 +52,12 @@ export interface ExecutionV5 { orderQty: string; leavesQty: string; orderType: OrderTypeV5; - stopOrderType?: string; + stopOrderType?: StopOrderTypeV5; execFee: string; execId: string; execPrice: string; execQty: string; - execType: string; + execType: ExecTypeV5; execValue: string; execTime: string; isMaker: boolean; @@ -74,8 +76,8 @@ export interface ClosedPnLV5 { side: string; qty: string; orderPrice: string; - orderType: string; - execType: string; + orderType: OrderTypeV5; + execType: ExecTypeV5; closedSize: string; cumEntryValue: string; avgEntryPrice: string; diff --git a/src/types/response/v5-trade.ts b/src/types/response/v5-trade.ts index 78f7fdf..c2f3289 100644 --- a/src/types/response/v5-trade.ts +++ b/src/types/response/v5-trade.ts @@ -1,10 +1,14 @@ import { CategoryV5, + OrderCancelTypeV5, + OrderRejectReasonV5, OrderSideV5, + OrderStatusV5, OrderTimeInForceV5, OrderTriggerByV5, OrderTypeV5, PositionIdx, + StopOrderTypeV5, } from '../v5-shared'; export interface OrderResultV5 { @@ -22,9 +26,9 @@ export interface AccountOrderV5 { side: OrderSideV5; isLeverage?: string; positionIdx?: PositionIdx; - orderStatus: string; - cancelType?: string; - rejectReason?: string; + orderStatus: OrderStatusV5; + cancelType?: OrderCancelTypeV5; + rejectReason?: OrderRejectReasonV5; avgPrice: string; leavesQty: string; leavesValue: string; @@ -33,7 +37,7 @@ export interface AccountOrderV5 { cumExecFee: string; timeInForce?: OrderTimeInForceV5; orderType?: OrderTypeV5; - stopOrderType?: string; + stopOrderType?: StopOrderTypeV5; orderIv?: string; triggerPrice?: string; takeProfit?: string; diff --git a/src/types/v5-shared.ts b/src/types/v5-shared.ts index 916bfa7..9896b12 100644 --- a/src/types/v5-shared.ts +++ b/src/types/v5-shared.ts @@ -1,17 +1,95 @@ export type CategoryV5 = 'spot' | 'linear' | 'inverse' | 'option'; +export type ContractTypeV5 = + | 'InversePerpetual' + | 'LinearPerpetual' + | 'InverseFutures'; + +export type InstrumentStatusV5 = 'Pending' | 'Trading' | 'Settling' | 'Closed'; export type OrderFilterV5 = 'Order' | 'tpslOrder'; export type OrderSideV5 = 'Buy' | 'Sell'; export type OrderTypeV5 = 'Market' | 'Limit'; export type OrderTimeInForceV5 = 'GTC' | 'IOC' | 'FOK' | 'PostOnly'; export type OrderTriggerByV5 = 'LastPrice' | 'IndexPrice' | 'MarkPrice'; -export type PositionIdx = 0 | 1 | 2; +export type OrderStatusV5 = + | 'Created' + | 'New' + | 'Rejected' + | 'PartiallyFilled' + | 'PartiallyFilledCanceled' + | 'Filled' + | 'Cancelled' + | 'Untriggered' + | 'Triggered' + | 'Deactivated' + | 'Active'; + +export type OrderCancelTypeV5 = + | 'CancelByUser' + | 'CancelByReduceOnly' + | 'CancelByPrepareLiq' + | 'CancelAllBeforeLiq' + | 'CancelByPrepareAdl' + | 'CancelAllBeforeAdl' + | 'CancelByAdmin' + | 'CancelByTpSlTsClear' + | 'CancelByPzSideCh'; + +export type OrderRejectReasonV5 = + | 'EC_NoError' + | 'EC_Others' + | 'EC_UnknownMessageType' + | 'EC_MissingClOrdID' + | 'EC_MissingOrigClOrdID' + | 'EC_ClOrdIDOrigClOrdIDAreTheSame' + | 'EC_DuplicatedClOrdID' + | 'EC_OrigClOrdIDDoesNotExist' + | 'EC_TooLateToCancel' + | 'EC_UnknownOrderType' + | 'EC_UnknownSide' + | 'EC_UnknownTimeInForce' + | 'EC_WronglyRouted' + | 'EC_MarketOrderPriceIsNotZero' + | 'EC_LimitOrderInvalidPrice' + | 'EC_NoEnoughQtyToFill' + | 'EC_NoImmediateQtyToFill' + | 'EC_PerCancelRequest' + | 'EC_MarketOrderCannotBePostOnly' + | 'EC_PostOnlyWillTakeLiquidity' + | 'EC_CancelReplaceOrder' + | 'EC_InvalidSymbolStatus'; + +export type StopOrderTypeV5 = + | 'TakeProfit' + | 'StopLoss' + | 'TrailingStop' + | 'Stop' + | 'PartialTakeProfit' + | 'PartialStopLoss' + | 'tpslOrder'; + /** - * Trade mode. 0: cross-margin, 1: isolated margin + * Position index. Used to identify positions in different position modes. + * + * - 0 one-way mode position + * - 1 Buy side of hedge-mode position + * - 2 Sell side of hedge-mode position + */ +export type PositionIdx = 0 | 1 | 2; + +export type OptionTypeV5 = 'Call' | 'Put'; + +/** + * Trade mode. + * + * - 0 cross-margin, + * - 1 isolated margin */ export type TradeModeV5 = 0 | 1; + export type TPSLModeV5 = 'Full' | 'Partial'; export type AccountMarginModeV5 = 'REGULAR_MARGIN' | 'PORTFOLIO_MARGIN'; +export type UnifiedUpdateStatusV5 = 'FAIL' | 'PROCESS' | 'SUCCESS'; export type AccountTypeV5 = | 'CONTRACT' @@ -68,6 +146,18 @@ export type LTOrderTypeV5 = '1' | '2'; */ export type LTOrderStatusV5 = '1' | '2' | '3'; +export type ExecTypeV5 = + | 'Trade' + | 'AdlTrade' + | 'Funding' + | 'BustTrade' + | 'Settle'; + +/** + * Withdraw type. 0(default): on chain. 1: off chain. 2: all. + */ +export type WithdrawalTypeV5 = '0' | '1' | '2'; + export interface PermissionsV5 { ContractTrade?: string[]; Spot?: string[]; @@ -78,8 +168,11 @@ export interface PermissionsV5 { NFT?: string[]; } -export interface CategoryCursorListV5 { - category: CategoryV5; +export interface CategoryCursorListV5< + T extends unknown[], + TCategory extends CategoryV5 = CategoryV5 +> { + category: TCategory; list: T; nextPageCursor?: string; } From 19f785b6249349b689980457d79b18596427cb98 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Fri, 17 Feb 2023 12:18:56 +0000 Subject: [PATCH 10/26] more tidying on v5 example and request type --- .../{rest-rawv3auth.ts => rest-raw-v3sign.ts} | 0 examples/rest-v5-private.ts | 27 +++++++++++++++++++ src/types/request/v5-asset.ts | 2 +- 3 files changed, 28 insertions(+), 1 deletion(-) rename examples/{rest-rawv3auth.ts => rest-raw-v3sign.ts} (100%) create mode 100644 examples/rest-v5-private.ts diff --git a/examples/rest-rawv3auth.ts b/examples/rest-raw-v3sign.ts similarity index 100% rename from examples/rest-rawv3auth.ts rename to examples/rest-raw-v3sign.ts diff --git a/examples/rest-v5-private.ts b/examples/rest-v5-private.ts new file mode 100644 index 0000000..bc66ec1 --- /dev/null +++ b/examples/rest-v5-private.ts @@ -0,0 +1,27 @@ +import { RestClientV5 } from '../src/index'; + +// or +// import { RestClientV5 } from 'bybit-api'; + +const key = process.env.API_KEY_COM; +const secret = process.env.API_SECRET_COM; + +const client = new RestClientV5({ + key, + secret, + strict_param_validation: true, +}); + +(async () => { + try { + /** Simple example for a private REST API call with bybit's V5 REST APIs */ + const response = await client.getPositionInfo({ + category: 'option', + symbol: 'BTCUSDT', + }); + + console.log('response:', response); + } catch (e) { + console.error('request failed: ', e); + } +})(); diff --git a/src/types/request/v5-asset.ts b/src/types/request/v5-asset.ts index a1af232..8867c03 100644 --- a/src/types/request/v5-asset.ts +++ b/src/types/request/v5-asset.ts @@ -125,7 +125,7 @@ export interface WithdrawParamsV5 { amount: string; timestamp: number; forceChain?: number; - accountType?: string; + accountType?: 'SPOT' | 'FUND'; } export interface CreateSubMemberParamsV5 { From 7669c037c826bd0c1b178b500e9de89482131a7d Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Fri, 17 Feb 2023 12:26:19 +0000 Subject: [PATCH 11/26] comment on example & fix failing test --- examples/rest-raw-v3sign.ts | 3 ++- test/contract/private.read.test.ts | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/rest-raw-v3sign.ts b/examples/rest-raw-v3sign.ts index 2a2af56..0ba7679 100644 --- a/examples/rest-raw-v3sign.ts +++ b/examples/rest-raw-v3sign.ts @@ -16,7 +16,8 @@ const client = new ContractClient({ try { /** * You can make raw HTTP requests without the per-endpoint abstraction, - * e.g. if an endpoint is missing and you're blocked (but please raise an issue if you're missing an endpoint) + * The REST ContractClient uses bybit's v3 signature mechanism, so it can be used for raw calls to any v3-supporting endpoints (incl the V5 APIs). + * e.g. if an endpoint is missing and you desperately need it (but please raise an issue or PR if you're missing an endpoint) */ const rawCall = await client.getPrivate('/v5/order/realtime', { category: 'linear', diff --git a/test/contract/private.read.test.ts b/test/contract/private.read.test.ts index 9ab08d8..7777495 100644 --- a/test/contract/private.read.test.ts +++ b/test/contract/private.read.test.ts @@ -30,7 +30,9 @@ describe('Private Contract REST API GET Endpoints', () => { expect( await api.getHistoricOrders({ symbol, cursor, limit: 1 }) ).toMatchObject({ - retCode: API_ERROR_CODE.DB_ERROR_WRONG_CURSOR, + // retCode: API_ERROR_CODE.DB_ERROR_WRONG_CURSOR, + ...successResponseObjectV3(), + retMsg: 'OK', }); }); From 8e54ecbaf597987f97b9e8cce249645eac9b7d29 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Fri, 17 Feb 2023 13:51:40 +0000 Subject: [PATCH 12/26] fix linter configuration & jest type dependency --- .eslintrc.js | 36 - .eslintrc.json | 86 + examples/rest-raw-v3sign.ts | 6 +- examples/tsconfig.examples.json | 12 + package-lock.json | 2644 ++++++++---------- package.json | 8 +- src/account-asset-client-v3.ts | 9 +- src/account-asset-client.ts | 3 +- src/contract-client.ts | 37 +- src/copy-trading-client.ts | 3 +- src/inverse-client.ts | 1 + src/inverse-futures-client.ts | 1 + src/linear-client.ts | 7 +- src/rest-client-v5.ts | 229 +- src/spot-client-v3.ts | 15 +- src/spot-client.ts | 5 +- src/types/request/spot.ts | 2 +- src/types/response/contract.ts | 1 + src/types/response/unified-margin.ts | 1 + src/types/response/v5-market.ts | 1 + src/types/response/v5-spot-leverage-token.ts | 2 +- src/types/v5-shared.ts | 20 +- src/types/websockets.ts | 1 + src/unified-margin-client.ts | 51 +- src/usdc-option-client.ts | 15 +- src/usdc-perpetual-client.ts | 7 +- src/util/BaseRestClient.ts | 31 +- src/util/WsStore.ts | 6 +- src/util/browser-support.ts | 8 +- src/util/logger.ts | 1 + src/util/requestUtils.ts | 1 + src/util/websocket-util.ts | 4 +- src/websocket-client.ts | 47 +- tsconfig.json | 9 +- 34 files changed, 1600 insertions(+), 1710 deletions(-) delete mode 100644 .eslintrc.js create mode 100644 .eslintrc.json create mode 100644 examples/tsconfig.examples.json diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index e8c5c55..0000000 --- a/.eslintrc.js +++ /dev/null @@ -1,36 +0,0 @@ -module.exports = { - env: { - es6: true, - node: true, - }, - extends: ['eslint:recommended'], - parserOptions: { - sourceType: 'module', - ecmaVersion: 9 - }, - - plugins: [], - rules: { - 'array-bracket-spacing': ['error', 'never'], - indent: ['warn', 2], - 'linebreak-style': ['error', 'unix'], - 'lines-between-class-members': ['warn', 'always'], - semi: ['error', 'always'], - 'new-cap': 'off', - 'no-console': 'off', - 'no-debugger': 'off', - 'no-mixed-spaces-and-tabs': 2, - 'no-use-before-define': [2, 'nofunc'], - 'no-unreachable': ['warn'], - 'no-unused-vars': ['warn'], - 'no-extra-parens': ['off'], - 'no-mixed-operators': ['off'], - quotes: [2, 'single', 'avoid-escape'], - 'block-scoped-var': 2, - 'brace-style': [2, '1tbs', { allowSingleLine: true }], - 'computed-property-spacing': [2, 'never'], - 'keyword-spacing': 2, - 'space-unary-ops': 2, - 'max-len': ['warn', { 'code': 140 }] - } -}; diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..c684cf8 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,86 @@ +{ + "env": { + "es6": true, + "node": true + }, + "extends": ["eslint:recommended"], + "parser": "@typescript-eslint/parser", + "root": true, + "plugins": ["@typescript-eslint"], + "overrides": [ + { + "files": ["**/*.ts", "**/*.tsx"], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended" + ], + "parserOptions": { + "projecasdft": true, + "project": ["./tsconfig.json", "examples/tsconfig.examples.json"] + }, + "rules": { + "@typescript-eslint/await-thenable": "error", + "@typescript-eslint/dot-notation": "off", + "@typescript-eslint/no-unused-vars": "warn", + + "@typescript-eslint/no-unused-expressions": "error", + "@typescript-eslint/no-var-requires": "error", + "@typescript-eslint/prefer-namespace-keyword": "error", + + "@typescript-eslint/no-explicit-any": "error", + "@typescript-eslint/no-floating-promises": "off", + "@typescript-eslint/no-inferrable-types": "off", + "@typescript-eslint/promise-function-async": "off", + "@typescript-eslint/no-use-before-define": "off", + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/ban-types": "off", + "@typescript-eslint/explicit-module-boundary-types": "off", + + "no-dupe-class-members": "off", + "no-param-reassign": ["error"], + "array-bracket-spacing": ["error", "never"], + "indent": [ + "warn", + 2, + { + "SwitchCase": 1 + } + ], + "linebreak-style": ["error", "unix"], + "lines-between-class-members": ["warn", "always"], + "semi": "off", + "@typescript-eslint/semi": ["error"], + "new-cap": "off", + "no-console": "off", + "no-debugger": "off", + "no-mixed-spaces-and-tabs": 2, + "no-use-before-define": [2, "nofunc"], + "no-unreachable": ["warn"], + "no-unused-vars": ["warn"], + "no-extra-parens": ["off"], + "no-mixed-operators": ["off"], + "quotes": [2, "single", "avoid-escape"], + "block-scoped-var": 2, + "brace-style": [2, "1tbs", { "allowSingleLine": true }], + "computed-property-spacing": [2, "never"], + "keyword-spacing": 2, + "space-unary-ops": 2, + "sort-imports": [ + "error", + { + "ignoreCase": false, + "ignoreDeclarationSort": true, + "ignoreMemberSort": false, + "memberSyntaxSortOrder": ["none", "all", "multiple", "single"], + "allowSeparatedGroups": false + } + ], + "max-len": ["warn", { "code": 140 }] + } + }, + { + "files": ["examples/*.js"], + "extends": ["eslint:recommended"] + } + ] +} diff --git a/examples/rest-raw-v3sign.ts b/examples/rest-raw-v3sign.ts index 0ba7679..4bb25fe 100644 --- a/examples/rest-raw-v3sign.ts +++ b/examples/rest-raw-v3sign.ts @@ -15,8 +15,10 @@ const client = new ContractClient({ (async () => { try { /** - * You can make raw HTTP requests without the per-endpoint abstraction, - * The REST ContractClient uses bybit's v3 signature mechanism, so it can be used for raw calls to any v3-supporting endpoints (incl the V5 APIs). + * You can make raw HTTP requests without the per-endpoint abstraction. + * + * The REST ContractClient uses bybit's v3 signature mechanism, + * so it can be used for raw calls to any v3-supporting endpoints (incl the V5 APIs). * e.g. if an endpoint is missing and you desperately need it (but please raise an issue or PR if you're missing an endpoint) */ const rawCall = await client.getPrivate('/v5/order/realtime', { diff --git a/examples/tsconfig.examples.json b/examples/tsconfig.examples.json new file mode 100644 index 0000000..883bb93 --- /dev/null +++ b/examples/tsconfig.examples.json @@ -0,0 +1,12 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "distExamples", + "allowJs": true + }, + "include": [ + "**/*.ts", + // if you have a mixed JS/TS codebase, don't forget to include your JS files + "**/*.js" + ] +} diff --git a/package-lock.json b/package-lock.json index cb93576..ab784f0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "bybit-api", - "version": "3.4.0", + "version": "3.5.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "bybit-api", - "version": "3.4.0", + "version": "3.5.0", "license": "MIT", "dependencies": { "axios": "^0.21.0", @@ -14,12 +14,14 @@ "ws": "^7.4.0" }, "devDependencies": { - "@types/jest": "^26.0.23", + "@types/jest": "^27.0.4", "@types/node": "^14.14.7", - "eslint": "^7.10.0", + "@typescript-eslint/eslint-plugin": "^5.46.0", + "@typescript-eslint/parser": "^5.46.0", + "eslint": "^8.29.0", "jest": "^27.0.4", "source-map-loader": "^2.0.0", - "ts-jest": "^27.0.3", + "ts-jest": "^27.0.4", "ts-loader": "^8.0.11", "typescript": "^4.0.5", "webpack": "^5.4.0", @@ -31,15 +33,6 @@ "url": "https://github.com/sponsors/tiagosiebler" } }, - "node_modules/@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, "node_modules/@babel/compat-data": { "version": "7.14.7", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.7.tgz", @@ -346,12 +339,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", - "dev": true - }, "node_modules/@babel/helper-validator-option": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", @@ -375,31 +362,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.10.4", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/parser": { "version": "7.14.7", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz", @@ -753,26 +715,79 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz", - "integrity": "sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", + "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", "dev": true, "dependencies": { "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "lodash": "^4.17.19", - "minimatch": "^3.0.4", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -974,31 +989,6 @@ "@types/yargs-parser": "*" } }, - "node_modules/@jest/core/node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/@jest/core/node_modules/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/@jest/environment": { "version": "27.0.5", "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.0.5.tgz", @@ -1346,47 +1336,6 @@ "@types/yargs-parser": "*" } }, - "node_modules/@jest/transform/node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/@jest/transform/node_modules/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", @@ -1445,6 +1394,41 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@polka/url": { "version": "1.0.0-next.11", "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.11.tgz", @@ -1579,19 +1563,19 @@ } }, "node_modules/@types/jest": { - "version": "26.0.23", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.23.tgz", - "integrity": "sha512-ZHLmWMJ9jJ9PTiT58juykZpL7KjwJywFN3Rr2pTSkyQfydf/rk22yS7W8p5DaVUMQ2BQC7oYiU3FjbTM/mYrOA==", + "version": "27.5.2", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", + "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", "dev": true, "dependencies": { - "jest-diff": "^26.0.0", - "pretty-format": "^26.0.0" + "jest-matcher-utils": "^27.0.0", + "pretty-format": "^27.0.0" } }, "node_modules/@types/json-schema": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", - "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, "node_modules/@types/node": { @@ -1606,27 +1590,212 @@ "integrity": "sha512-hkc1DATxFLQo4VxPDpMH1gCkPpBbpOoJ/4nhuXw4n63/0R6bCpQECj4+K226UJ4JO/eJQz+1mC2I7JsWanAdQw==", "dev": true }, + "node_modules/@types/semver": { + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", + "dev": true + }, "node_modules/@types/stack-utils": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "dev": true }, - "node_modules/@types/yargs": { - "version": "15.0.13", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.13.tgz", - "integrity": "sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, "node_modules/@types/yargs-parser": { "version": "20.2.0", "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==", "dev": true }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.52.0.tgz", + "integrity": "sha512-lHazYdvYVsBokwCdKOppvYJKaJ4S41CgKBcPvyd0xjZNbvQdhn/pnJlGtQksQ/NhInzdaeaSarlBjDXHuclEbg==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.52.0", + "@typescript-eslint/type-utils": "5.52.0", + "@typescript-eslint/utils": "5.52.0", + "debug": "^4.3.4", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.52.0.tgz", + "integrity": "sha512-e2KiLQOZRo4Y0D/b+3y08i3jsekoSkOYStROYmPUnGMEoA0h+k2qOH5H6tcjIc68WDvGwH+PaOrP1XRzLJ6QlA==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.52.0", + "@typescript-eslint/types": "5.52.0", + "@typescript-eslint/typescript-estree": "5.52.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.52.0.tgz", + "integrity": "sha512-AR7sxxfBKiNV0FWBSARxM8DmNxrwgnYMPwmpkC1Pl1n+eT8/I2NAUPuwDy/FmDcC6F8pBfmOcaxcxRHspgOBMw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.52.0", + "@typescript-eslint/visitor-keys": "5.52.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.52.0.tgz", + "integrity": "sha512-tEKuUHfDOv852QGlpPtB3lHOoig5pyFQN/cUiZtpw99D93nEBjexRLre5sQZlkMoHry/lZr8qDAt2oAHLKA6Jw==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "5.52.0", + "@typescript-eslint/utils": "5.52.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.52.0.tgz", + "integrity": "sha512-oV7XU4CHYfBhk78fS7tkum+/Dpgsfi91IIDy7fjCyq2k6KB63M6gMC0YIvy+iABzmXThCRI6xpCEyVObBdWSDQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.52.0.tgz", + "integrity": "sha512-WeWnjanyEwt6+fVrSR0MYgEpUAuROxuAH516WPjUblIrClzYJj0kBbjdnbQXLpgAN8qbEuGywiQsXUVDiAoEuQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.52.0", + "@typescript-eslint/visitor-keys": "5.52.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.52.0.tgz", + "integrity": "sha512-As3lChhrbwWQLNk2HC8Ree96hldKIqk98EYvypd3It8Q1f8d5zWyIoaZEp2va5667M4ZyE7X8UUR+azXrFl+NA==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.52.0", + "@typescript-eslint/types": "5.52.0", + "@typescript-eslint/typescript-estree": "5.52.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.52.0.tgz", + "integrity": "sha512-qMwpw6SU5VHCPr99y274xhbm+PRViK/NATY6qzt+Et7+mThGuFSl/ompj2/hrBlRP/kq+BFdgagnOSgw9TB0eA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.52.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@webassemblyjs/ast": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz", @@ -1849,9 +2018,9 @@ } }, "node_modules/acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" @@ -1982,13 +2151,13 @@ "sprintf-js": "~1.0.2" } }, - "node_modules/astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/asynckit": { @@ -2539,9 +2708,9 @@ } }, "node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -2600,13 +2769,16 @@ "node": ">=8" } }, - "node_modules/diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, "engines": { - "node": ">= 10.14.2" + "node": ">=8" } }, "node_modules/doctrine": { @@ -2660,12 +2832,6 @@ "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, - "node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, "node_modules/emojis-list": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", @@ -2826,54 +2992,56 @@ } }, "node_modules/eslint": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.15.0.tgz", - "integrity": "sha512-Vr64xFDT8w30wFll643e7cGrIkPEU50yIiI36OdSIDoSGguIeaLzBo0vpGvzo9RECUqq7htURfwEtKqwytkqzA==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.34.0.tgz", + "integrity": "sha512-1Z8iFsucw+7kSqXNZVslXS8Ioa4u2KM7GPwuKtkTFAqZ/cHMcEaR+1+Br0wLlot49cNxIiZk5wp8EAbPcYZxTg==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "@eslint/eslintrc": "^0.2.2", + "@eslint/eslintrc": "^1.4.1", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", - "debug": "^4.0.1", + "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.2.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "file-entry-cache": "^6.0.0", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", - "lodash": "^4.17.19", - "minimatch": "^3.0.4", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -2893,59 +3061,120 @@ } }, "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, "dependencies": { - "eslint-visitor-keys": "^1.1.0" + "eslint-visitor-keys": "^2.0.0" }, "engines": { - "node": ">=6" + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" }, "funding": { "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" } }, "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", - "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true, "engines": { "node": ">=10" } }, - "node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true, - "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "node_modules/eslint/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/espree": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "dev": true, + "dependencies": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" } }, "node_modules/esprima": { @@ -2962,9 +3191,9 @@ } }, "node_modules/esquery": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", - "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.2.tgz", + "integrity": "sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -2974,9 +3203,9 @@ } }, "node_modules/esquery/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { "node": ">=4.0" @@ -3131,6 +3360,34 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -3149,6 +3406,15 @@ "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", "dev": true }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, "node_modules/fb-watchman": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", @@ -3159,9 +3425,9 @@ } }, "node_modules/file-entry-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz", - "integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "dependencies": { "flat-cache": "^3.0.4" @@ -3212,9 +3478,9 @@ } }, "node_modules/flatted": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz", - "integrity": "sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, "node_modules/follow-redirects": { @@ -3276,12 +3542,6 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -3342,15 +3602,15 @@ } }, "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "dependencies": { - "is-glob": "^4.0.1" + "is-glob": "^4.0.3" }, "engines": { - "node": ">= 6" + "node": ">=10.13.0" } }, "node_modules/glob-to-regexp": { @@ -3360,12 +3620,12 @@ "dev": true }, "node_modules/globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, "dependencies": { - "type-fest": "^0.8.1" + "type-fest": "^0.20.2" }, "engines": { "node": ">=8" @@ -3374,12 +3634,38 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, "node_modules/gzip-size": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", @@ -3483,18 +3769,18 @@ } }, "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true, "engines": { "node": ">= 4" } }, "node_modules/import-fresh": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz", - "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "dependencies": { "parent-module": "^1.0.0", @@ -3502,6 +3788,9 @@ }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/import-local": { @@ -3645,21 +3934,12 @@ "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/is-generator-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", @@ -3670,9 +3950,9 @@ } }, "node_modules/is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "dependencies": { "is-extglob": "^2.1.1" @@ -3690,6 +3970,15 @@ "node": ">=0.12.0" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", @@ -3945,33 +4234,6 @@ "@types/yargs-parser": "*" } }, - "node_modules/jest-circus/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-circus/node_modules/pretty-format": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz", - "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==", - "dev": true, - "dependencies": { - "@jest/types": "^27.0.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, "node_modules/jest-config": { "version": "27.0.5", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.0.5.tgz", @@ -4037,18 +4299,6 @@ "@types/yargs-parser": "*" } }, - "node_modules/jest-config/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/jest-config/node_modules/jest-get-type": { "version": "27.0.1", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz", @@ -4058,61 +4308,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-config/node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/jest-config/node_modules/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-config/node_modules/pretty-format": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz", - "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==", - "dev": true, - "dependencies": { - "@jest/types": "^27.0.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, "node_modules/jest-docblock": { "version": "27.0.1", "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.1.tgz", @@ -4166,18 +4361,6 @@ "@types/yargs-parser": "*" } }, - "node_modules/jest-each/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/jest-each/node_modules/jest-get-type": { "version": "27.0.1", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz", @@ -4187,21 +4370,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-each/node_modules/pretty-format": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz", - "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==", - "dev": true, - "dependencies": { - "@jest/types": "^27.0.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, "node_modules/jest-environment-jsdom": { "version": "27.0.5", "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.0.5.tgz", @@ -4287,15 +4455,6 @@ "@types/yargs-parser": "*" } }, - "node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true, - "engines": { - "node": ">= 10.14.2" - } - }, "node_modules/jest-haste-map": { "version": "27.0.5", "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.0.5.tgz", @@ -4370,31 +4529,6 @@ "node": ">= 10.13.0" } }, - "node_modules/jest-haste-map/node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/jest-haste-map/node_modules/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/jest-haste-map/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -4464,33 +4598,6 @@ "@types/yargs-parser": "*" } }, - "node_modules/jest-jasmine2/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-jasmine2/node_modules/pretty-format": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz", - "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==", - "dev": true, - "dependencies": { - "@jest/types": "^27.0.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, "node_modules/jest-leak-detector": { "version": "27.0.2", "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.0.2.tgz", @@ -4504,43 +4611,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-leak-detector/node_modules/@jest/types": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz", - "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-leak-detector/node_modules/@types/yargs": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz", - "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-leak-detector/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/jest-leak-detector/node_modules/jest-get-type": { "version": "27.0.1", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz", @@ -4550,21 +4620,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-leak-detector/node_modules/pretty-format": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz", - "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==", - "dev": true, - "dependencies": { - "@jest/types": "^27.0.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, "node_modules/jest-matcher-utils": { "version": "27.0.2", "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.0.2.tgz", @@ -4580,43 +4635,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-matcher-utils/node_modules/@jest/types": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz", - "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-matcher-utils/node_modules/@types/yargs": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz", - "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-matcher-utils/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/jest-matcher-utils/node_modules/diff-sequences": { "version": "27.0.1", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.1.tgz", @@ -4650,21 +4668,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-matcher-utils/node_modules/pretty-format": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz", - "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==", - "dev": true, - "dependencies": { - "@jest/types": "^27.0.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, "node_modules/jest-message-util": { "version": "27.0.2", "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.0.2.tgz", @@ -4759,58 +4762,6 @@ "@types/yargs-parser": "*" } }, - "node_modules/jest-message-util/node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/jest-message-util/node_modules/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-message-util/node_modules/pretty-format": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz", - "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==", - "dev": true, - "dependencies": { - "@jest/types": "^27.0.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-message-util/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/jest-mock": { "version": "27.0.3", "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.0.3.tgz", @@ -5203,18 +5154,6 @@ "@types/yargs-parser": "*" } }, - "node_modules/jest-snapshot/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/jest-snapshot/node_modules/diff-sequences": { "version": "27.0.1", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.1.tgz", @@ -5248,21 +5187,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-snapshot/node_modules/pretty-format": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz", - "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==", - "dev": true, - "dependencies": { - "@jest/types": "^27.0.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, "node_modules/jest-util": { "version": "27.0.2", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.2.tgz", @@ -5305,18 +5229,6 @@ "@types/yargs-parser": "*" } }, - "node_modules/jest-util/node_modules/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/jest-validate": { "version": "27.0.2", "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.0.2.tgz", @@ -5359,18 +5271,6 @@ "@types/yargs-parser": "*" } }, - "node_modules/jest-validate/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/jest-validate/node_modules/camelcase": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", @@ -5392,21 +5292,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-validate/node_modules/pretty-format": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz", - "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==", - "dev": true, - "dependencies": { - "@jest/types": "^27.0.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, "node_modules/jest-watcher": { "version": "27.0.2", "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.0.2.tgz", @@ -5544,6 +5429,16 @@ } } }, + "node_modules/js-sdsl": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -5738,6 +5633,18 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -5838,17 +5745,26 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { - "node": ">=8" + "node": ">=8.6" } }, "node_modules/mime": { @@ -5905,18 +5821,6 @@ "node": "*" } }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -5929,6 +5833,12 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -6129,10 +6039,19 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "engines": { "node": ">=8.6" @@ -6175,68 +6094,37 @@ } }, "node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", "react-is": "^17.0.1" }, "engines": { - "node": ">= 10" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/pretty-format/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/pretty-format/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/prompts": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz", @@ -6271,6 +6159,26 @@ "node": ">=6" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -6299,9 +6207,9 @@ } }, "node_modules/regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true, "engines": { "node": ">=8" @@ -6362,6 +6270,16 @@ "node": ">=4" } }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -6377,6 +6295,29 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -6434,9 +6375,9 @@ } }, "node_modules/semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -6513,20 +6454,6 @@ "node": ">=8" } }, - "node_modules/slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", @@ -6613,48 +6540,13 @@ "node": ">=10" } }, - "node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "dependencies": { - "ansi-regex": "^5.0.0" + "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" @@ -6742,21 +6634,6 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, - "node_modules/table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "dependencies": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/tapable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", @@ -6925,19 +6802,17 @@ } }, "node_modules/ts-jest": { - "version": "27.0.3", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.0.3.tgz", - "integrity": "sha512-U5rdMjnYam9Ucw+h0QvtNDbc5+88nxt7tbIvqaZUhFrfG4+SkWhMXjejCLVGcpILTPuV+H3W/GZDZrnZFpPeXw==", + "version": "27.1.5", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.5.tgz", + "integrity": "sha512-Xv6jBQPoBEvBq/5i2TeSG9tt/nqkbpcurrEG1b+2yfBrcJelOZF9Ml6dmyMh7bcW9JyFbRYpR5rxROSlBLTZHA==", "dev": true, "dependencies": { "bs-logger": "0.x", - "buffer-from": "1.x", "fast-json-stable-stringify": "2.x", "jest-util": "^27.0.0", "json5": "2.x", - "lodash": "4.x", + "lodash.memoize": "4.x", "make-error": "1.x", - "mkdirp": "1.x", "semver": "7.x", "yargs-parser": "20.x" }, @@ -6948,8 +6823,25 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@types/jest": "^27.0.0", + "babel-jest": ">=27.0.0 <28", "jest": "^27.0.0", "typescript": ">=3.8 <5.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@types/jest": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } } }, "node_modules/ts-loader": { @@ -6978,6 +6870,21 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -7000,12 +6907,15 @@ } }, "node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/typedarray-to-buffer": { @@ -7616,15 +7526,6 @@ } }, "dependencies": { - "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, "@babel/compat-data": { "version": "7.14.7", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.7.tgz", @@ -7860,12 +7761,6 @@ "@babel/types": "^7.14.5" } }, - "@babel/helper-validator-identifier": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", - "dev": true - }, "@babel/helper-validator-option": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", @@ -7883,30 +7778,6 @@ "@babel/types": "^7.14.5" } }, - "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - } - } - }, "@babel/parser": { "version": "7.14.7", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz", @@ -8173,23 +8044,62 @@ "dev": true }, "@eslint/eslintrc": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz", - "integrity": "sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", + "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", "dev": true, "requires": { "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "lodash": "^4.17.19", - "minimatch": "^3.0.4", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + } } }, + "@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -8350,22 +8260,6 @@ "requires": { "@types/yargs-parser": "*" } - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true } } }, @@ -8663,38 +8557,9 @@ "requires": { "@types/yargs-parser": "*" } - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true } } }, - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, "@jridgewell/gen-mapping": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", @@ -8744,6 +8609,32 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, "@polka/url": { "version": "1.0.0-next.11", "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.11.tgz", @@ -8875,19 +8766,19 @@ } }, "@types/jest": { - "version": "26.0.23", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.23.tgz", - "integrity": "sha512-ZHLmWMJ9jJ9PTiT58juykZpL7KjwJywFN3Rr2pTSkyQfydf/rk22yS7W8p5DaVUMQ2BQC7oYiU3FjbTM/mYrOA==", + "version": "27.5.2", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", + "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", "dev": true, "requires": { - "jest-diff": "^26.0.0", - "pretty-format": "^26.0.0" + "jest-matcher-utils": "^27.0.0", + "pretty-format": "^27.0.0" } }, "@types/json-schema": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", - "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, "@types/node": { @@ -8902,27 +8793,123 @@ "integrity": "sha512-hkc1DATxFLQo4VxPDpMH1gCkPpBbpOoJ/4nhuXw4n63/0R6bCpQECj4+K226UJ4JO/eJQz+1mC2I7JsWanAdQw==", "dev": true }, + "@types/semver": { + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", + "dev": true + }, "@types/stack-utils": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "dev": true }, - "@types/yargs": { - "version": "15.0.13", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.13.tgz", - "integrity": "sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, "@types/yargs-parser": { "version": "20.2.0", "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==", "dev": true }, + "@typescript-eslint/eslint-plugin": { + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.52.0.tgz", + "integrity": "sha512-lHazYdvYVsBokwCdKOppvYJKaJ4S41CgKBcPvyd0xjZNbvQdhn/pnJlGtQksQ/NhInzdaeaSarlBjDXHuclEbg==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.52.0", + "@typescript-eslint/type-utils": "5.52.0", + "@typescript-eslint/utils": "5.52.0", + "debug": "^4.3.4", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/parser": { + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.52.0.tgz", + "integrity": "sha512-e2KiLQOZRo4Y0D/b+3y08i3jsekoSkOYStROYmPUnGMEoA0h+k2qOH5H6tcjIc68WDvGwH+PaOrP1XRzLJ6QlA==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.52.0", + "@typescript-eslint/types": "5.52.0", + "@typescript-eslint/typescript-estree": "5.52.0", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.52.0.tgz", + "integrity": "sha512-AR7sxxfBKiNV0FWBSARxM8DmNxrwgnYMPwmpkC1Pl1n+eT8/I2NAUPuwDy/FmDcC6F8pBfmOcaxcxRHspgOBMw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.52.0", + "@typescript-eslint/visitor-keys": "5.52.0" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.52.0.tgz", + "integrity": "sha512-tEKuUHfDOv852QGlpPtB3lHOoig5pyFQN/cUiZtpw99D93nEBjexRLre5sQZlkMoHry/lZr8qDAt2oAHLKA6Jw==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "5.52.0", + "@typescript-eslint/utils": "5.52.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/types": { + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.52.0.tgz", + "integrity": "sha512-oV7XU4CHYfBhk78fS7tkum+/Dpgsfi91IIDy7fjCyq2k6KB63M6gMC0YIvy+iABzmXThCRI6xpCEyVObBdWSDQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.52.0.tgz", + "integrity": "sha512-WeWnjanyEwt6+fVrSR0MYgEpUAuROxuAH516WPjUblIrClzYJj0kBbjdnbQXLpgAN8qbEuGywiQsXUVDiAoEuQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.52.0", + "@typescript-eslint/visitor-keys": "5.52.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/utils": { + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.52.0.tgz", + "integrity": "sha512-As3lChhrbwWQLNk2HC8Ree96hldKIqk98EYvypd3It8Q1f8d5zWyIoaZEp2va5667M4ZyE7X8UUR+azXrFl+NA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.52.0", + "@typescript-eslint/types": "5.52.0", + "@typescript-eslint/typescript-estree": "5.52.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0", + "semver": "^7.3.7" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.52.0.tgz", + "integrity": "sha512-qMwpw6SU5VHCPr99y274xhbm+PRViK/NATY6qzt+Et7+mThGuFSl/ompj2/hrBlRP/kq+BFdgagnOSgw9TB0eA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.52.0", + "eslint-visitor-keys": "^3.3.0" + } + }, "@webassemblyjs/ast": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz", @@ -9128,9 +9115,9 @@ } }, "acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "requires": {} }, @@ -9225,10 +9212,10 @@ "sprintf-js": "~1.0.2" } }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, "asynckit": { @@ -9689,9 +9676,9 @@ } }, "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -9733,11 +9720,14 @@ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true }, - "diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", - "dev": true + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } }, "doctrine": { "version": "3.0.0", @@ -9777,12 +9767,6 @@ "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", "dev": true }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, "emojis-list": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", @@ -9897,48 +9881,89 @@ } }, "eslint": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.15.0.tgz", - "integrity": "sha512-Vr64xFDT8w30wFll643e7cGrIkPEU50yIiI36OdSIDoSGguIeaLzBo0vpGvzo9RECUqq7htURfwEtKqwytkqzA==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.34.0.tgz", + "integrity": "sha512-1Z8iFsucw+7kSqXNZVslXS8Ioa4u2KM7GPwuKtkTFAqZ/cHMcEaR+1+Br0wLlot49cNxIiZk5wp8EAbPcYZxTg==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@eslint/eslintrc": "^0.2.2", + "@eslint/eslintrc": "^1.4.1", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", - "debug": "^4.0.1", + "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.2.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "file-entry-cache": "^6.0.0", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", - "lodash": "^4.17.19", - "minimatch": "^3.0.4", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + } } }, "eslint-scope": { @@ -9952,43 +9977,43 @@ } }, "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.1.0" + "eslint-visitor-keys": "^2.0.0" }, "dependencies": { "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true } } }, "eslint-visitor-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", - "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true }, "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", "dev": true, "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" }, "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "dev": true } } @@ -10000,18 +10025,18 @@ "dev": true }, "esquery": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", - "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.2.tgz", + "integrity": "sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng==", "dev": true, "requires": { "estraverse": "^5.1.0" }, "dependencies": { "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } @@ -10130,6 +10155,30 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -10148,6 +10197,15 @@ "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", "dev": true }, + "fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, "fb-watchman": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", @@ -10158,9 +10216,9 @@ } }, "file-entry-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz", - "integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "requires": { "flat-cache": "^3.0.4" @@ -10196,9 +10254,9 @@ } }, "flatted": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz", - "integrity": "sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, "follow-redirects": { @@ -10236,12 +10294,6 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -10281,12 +10333,12 @@ } }, "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "requires": { - "is-glob": "^4.0.1" + "is-glob": "^4.0.3" } }, "glob-to-regexp": { @@ -10296,12 +10348,26 @@ "dev": true }, "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, "requires": { - "type-fest": "^0.8.1" + "type-fest": "^0.20.2" + } + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" } }, "graceful-fs": { @@ -10310,6 +10376,12 @@ "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, "gzip-size": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", @@ -10386,15 +10458,15 @@ } }, "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true }, "import-fresh": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz", - "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "requires": { "parent-module": "^1.0.0", @@ -10508,13 +10580,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true }, "is-generator-fn": { @@ -10524,9 +10590,9 @@ "dev": true }, "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "requires": { "is-extglob": "^2.1.1" @@ -10538,6 +10604,12 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, "is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", @@ -10787,24 +10859,6 @@ "requires": { "@types/yargs-parser": "*" } - }, - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, - "pretty-format": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz", - "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==", - "dev": true, - "requires": { - "@jest/types": "^27.0.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - } } } }, @@ -10859,60 +10913,14 @@ "@types/yargs-parser": "*" } }, - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, "jest-get-type": { "version": "27.0.1", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz", "integrity": "sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg==", "dev": true - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true - }, - "pretty-format": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz", - "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==", - "dev": true, - "requires": { - "@jest/types": "^27.0.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - } } } }, - "jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - } - }, "jest-docblock": { "version": "27.0.1", "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.1.tgz", @@ -10957,29 +10965,11 @@ "@types/yargs-parser": "*" } }, - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, "jest-get-type": { "version": "27.0.1", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz", "integrity": "sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg==", "dev": true - }, - "pretty-format": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz", - "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==", - "dev": true, - "requires": { - "@jest/types": "^27.0.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - } } } }, @@ -11060,12 +11050,6 @@ } } }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true - }, "jest-haste-map": { "version": "27.0.5", "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.0.5.tgz", @@ -11126,22 +11110,6 @@ "supports-color": "^8.0.0" } }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true - }, "supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -11200,24 +11168,6 @@ "requires": { "@types/yargs-parser": "*" } - }, - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, - "pretty-format": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz", - "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==", - "dev": true, - "requires": { - "@jest/types": "^27.0.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - } } } }, @@ -11231,51 +11181,11 @@ "pretty-format": "^27.0.2" }, "dependencies": { - "@jest/types": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz", - "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - } - }, - "@types/yargs": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz", - "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, "jest-get-type": { "version": "27.0.1", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz", "integrity": "sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg==", "dev": true - }, - "pretty-format": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz", - "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==", - "dev": true, - "requires": { - "@jest/types": "^27.0.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - } } } }, @@ -11291,34 +11201,6 @@ "pretty-format": "^27.0.2" }, "dependencies": { - "@jest/types": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz", - "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - } - }, - "@types/yargs": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz", - "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, "diff-sequences": { "version": "27.0.1", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.1.tgz", @@ -11342,18 +11224,6 @@ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz", "integrity": "sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg==", "dev": true - }, - "pretty-format": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz", - "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==", - "dev": true, - "requires": { - "@jest/types": "^27.0.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - } } } }, @@ -11434,42 +11304,6 @@ "requires": { "@types/yargs-parser": "*" } - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true - }, - "pretty-format": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz", - "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==", - "dev": true, - "requires": { - "@jest/types": "^27.0.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } } } }, @@ -11808,12 +11642,6 @@ "@types/yargs-parser": "*" } }, - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, "diff-sequences": { "version": "27.0.1", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.1.tgz", @@ -11837,18 +11665,6 @@ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz", "integrity": "sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg==", "dev": true - }, - "pretty-format": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz", - "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==", - "dev": true, - "requires": { - "@jest/types": "^27.0.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - } } } }, @@ -11887,12 +11703,6 @@ "requires": { "@types/yargs-parser": "*" } - }, - "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true } } }, @@ -11932,12 +11742,6 @@ "@types/yargs-parser": "*" } }, - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, "camelcase": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", @@ -11949,18 +11753,6 @@ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz", "integrity": "sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg==", "dev": true - }, - "pretty-format": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz", - "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==", - "dev": true, - "requires": { - "@jest/types": "^27.0.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - } } } }, @@ -12031,6 +11823,12 @@ } } }, + "js-sdsl": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", + "dev": true + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -12174,6 +11972,18 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -12263,14 +12073,20 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" + "braces": "^3.0.2", + "picomatch": "^2.3.1" } }, "mime": { @@ -12309,12 +12125,6 @@ "brace-expansion": "^1.1.7" } }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -12327,6 +12137,12 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, "neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -12473,10 +12289,16 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, "pirates": { @@ -12504,39 +12326,20 @@ "dev": true }, "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", "react-is": "^17.0.1" }, "dependencies": { "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true } } @@ -12547,12 +12350,6 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, "prompts": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz", @@ -12581,6 +12378,12 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -12606,9 +12409,9 @@ } }, "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, "require-directory": { @@ -12650,6 +12453,12 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -12659,6 +12468,15 @@ "glob": "^7.1.3" } }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -12692,9 +12510,9 @@ } }, "semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -12753,17 +12571,6 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, - "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - } - }, "source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", @@ -12830,41 +12637,13 @@ "strip-ansi": "^6.0.0" } }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^5.0.0" + "ansi-regex": "^5.0.1" } }, "strip-bom": { @@ -12927,18 +12706,6 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, - "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - } - }, "tapable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", @@ -13060,19 +12827,17 @@ } }, "ts-jest": { - "version": "27.0.3", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.0.3.tgz", - "integrity": "sha512-U5rdMjnYam9Ucw+h0QvtNDbc5+88nxt7tbIvqaZUhFrfG4+SkWhMXjejCLVGcpILTPuV+H3W/GZDZrnZFpPeXw==", + "version": "27.1.5", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.5.tgz", + "integrity": "sha512-Xv6jBQPoBEvBq/5i2TeSG9tt/nqkbpcurrEG1b+2yfBrcJelOZF9Ml6dmyMh7bcW9JyFbRYpR5rxROSlBLTZHA==", "dev": true, "requires": { "bs-logger": "0.x", - "buffer-from": "1.x", "fast-json-stable-stringify": "2.x", "jest-util": "^27.0.0", "json5": "2.x", - "lodash": "4.x", + "lodash.memoize": "4.x", "make-error": "1.x", - "mkdirp": "1.x", "semver": "7.x", "yargs-parser": "20.x" } @@ -13096,6 +12861,15 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -13112,9 +12886,9 @@ "dev": true }, "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, "typedarray-to-buffer": { diff --git a/package.json b/package.json index dbc484e..7c5e167 100644 --- a/package.json +++ b/package.json @@ -29,12 +29,14 @@ "ws": "^7.4.0" }, "devDependencies": { - "@types/jest": "^26.0.23", + "@types/jest": "^27.0.4", "@types/node": "^14.14.7", - "eslint": "^7.10.0", + "@typescript-eslint/eslint-plugin": "^5.46.0", + "@typescript-eslint/parser": "^5.46.0", + "eslint": "^8.29.0", "jest": "^27.0.4", "source-map-loader": "^2.0.0", - "ts-jest": "^27.0.3", + "ts-jest": "^27.0.4", "ts-loader": "^8.0.11", "typescript": "^4.0.5", "webpack": "^5.4.0", diff --git a/src/account-asset-client-v3.ts b/src/account-asset-client-v3.ts index 6649c38..6b3106d 100644 --- a/src/account-asset-client-v3.ts +++ b/src/account-asset-client-v3.ts @@ -1,10 +1,11 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { - AccountCoinBalanceResponseV3, - AccountCoinBalancesRequestV3, - AccountCoinBalancesResponseV3, APIKeyInfoV3, APIResponseV3WithTime, APIResponseWithTime, + AccountCoinBalanceResponseV3, + AccountCoinBalancesRequestV3, + AccountCoinBalancesResponseV3, AssetInfoRequestV3, AssetInfoResponseV3, CoinInfoQueryResponseV3, @@ -18,8 +19,8 @@ import { InternalTransferRequestV3, ModifyAPIKeyRequestV3, QueryDepositAddressRequestV3, - QueryInternalTransfersRequestV3, QueryInternalTransferSResponseV3, + QueryInternalTransfersRequestV3, QuerySubAccountDepositAddressRequestV3, SingleAccountCoinBalanceRequestV3, SubAccountTransferRequestV3, diff --git a/src/account-asset-client.ts b/src/account-asset-client.ts index 0e2963d..ccdf57c 100644 --- a/src/account-asset-client.ts +++ b/src/account-asset-client.ts @@ -1,6 +1,7 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { - AccountAssetInformationRequest, APIResponseWithTime, + AccountAssetInformationRequest, DepositRecordsRequest, EnableUniversalTransferRequest, InternalTransferRequest, diff --git a/src/contract-client.ts b/src/contract-client.ts index 88db401..e88690f 100644 --- a/src/contract-client.ts +++ b/src/contract-client.ts @@ -1,6 +1,24 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { - APIResponseWithTime, APIResponseV3, + APIResponseWithTime, + ContractActiveOrdersRequest, + ContractCancelOrderRequest, + ContractClosedPNLRequest, + ContractHistoricOrder, + ContractHistoricOrdersRequest, + ContractListResult, + ContractModifyOrderRequest, + ContractOrderRequest, + ContractPositionsRequest, + ContractSetAutoAddMarginRequest, + ContractSetMarginSwitchRequest, + ContractSetPositionModeRequest, + ContractSetTPSLRequest, + ContractSymbolTicker, + ContractUserExecutionHistoryRequest, + ContractWalletFundRecordRequest, + PaginatedResult, UMCandlesRequest, UMCategory, UMFundingRateHistoryRequest, @@ -8,23 +26,6 @@ import { UMOpenInterestRequest, UMOptionDeliveryPriceRequest, UMPublicTradesRequest, - ContractOrderRequest, - ContractHistoricOrdersRequest, - ContractCancelOrderRequest, - ContractModifyOrderRequest, - ContractActiveOrdersRequest, - ContractPositionsRequest, - ContractSetAutoAddMarginRequest, - ContractSetMarginSwitchRequest, - ContractSetPositionModeRequest, - ContractSetTPSLRequest, - ContractUserExecutionHistoryRequest, - ContractClosedPNLRequest, - ContractWalletFundRecordRequest, - PaginatedResult, - ContractHistoricOrder, - ContractSymbolTicker, - ContractListResult, } from './types'; import { REST_CLIENT_TYPE_ENUM } from './util'; import BaseRestClient from './util/BaseRestClient'; diff --git a/src/copy-trading-client.ts b/src/copy-trading-client.ts index 0247da3..797f602 100644 --- a/src/copy-trading-client.ts +++ b/src/copy-trading-client.ts @@ -1,4 +1,6 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { + APIResponseV3, APIResponseWithTime, CopyTradingCancelOrderRequest, CopyTradingCloseOrderRequest, @@ -6,7 +8,6 @@ import { CopyTradingOrderRequest, CopyTradingTradingStopRequest, CopyTradingTransferRequest, - APIResponseV3, } from './types'; import { REST_CLIENT_TYPE_ENUM } from './util'; import BaseRestClient from './util/BaseRestClient'; diff --git a/src/inverse-client.ts b/src/inverse-client.ts index 1f9ebee..abe8d47 100644 --- a/src/inverse-client.ts +++ b/src/inverse-client.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { REST_CLIENT_TYPE_ENUM } from './util'; import { APIResponseWithTime, diff --git a/src/inverse-futures-client.ts b/src/inverse-futures-client.ts index 7411522..8fecd14 100644 --- a/src/inverse-futures-client.ts +++ b/src/inverse-futures-client.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { REST_CLIENT_TYPE_ENUM } from './util/requestUtils'; import { APIResponseWithTime, diff --git a/src/linear-client.ts b/src/linear-client.ts index 724601c..b262ebe 100644 --- a/src/linear-client.ts +++ b/src/linear-client.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { REST_CLIENT_TYPE_ENUM } from './util/requestUtils'; import { APIResponse, @@ -273,6 +274,7 @@ export class LinearClient extends BaseRestClient { */ getPosition(): Promise>; + getPosition( params: Partial ): Promise>; @@ -344,7 +346,10 @@ export class LinearClient extends BaseRestClient { getHistoryTradeRecords( params: LinearGetHistoryTradeRecordsRequest ): Promise> { - return this.getPrivate('/private/linear/trade/execution/history-list', params); + return this.getPrivate( + '/private/linear/trade/execution/history-list', + params + ); } getClosedPnl( diff --git a/src/rest-client-v5.ts b/src/rest-client-v5.ts index a04a488..7b0aa40 100644 --- a/src/rest-client-v5.ts +++ b/src/rest-client-v5.ts @@ -1,13 +1,63 @@ import { + APIResponseV3, APIResponseV3WithTime, + AccountCoinBalanceV5, + AccountInfoV5, + AccountMarginModeV5, + AccountOrderV5, + AccountTypeV5, + AllCoinsBalanceV5, + AllowedDepositCoinInfoV5, + AmendOrderParamsV5, + ApiKeyInfoV5, + AssetInfoV5, + BatchAmendOrderParamsV5, + BatchAmendOrderResult, + BatchCancelOrderParamsV5, + BatchCancelOrderResult, + BatchOrderParamsV5, + BatchOrderResult, + BatchOrdersResult, + BorrowHistoryRecordV5, + CancelAllOrdersParamsV5, + CancelOrderParamsV5, + CategoryCursorListV5, CategoryListV5, + CategorySymbolListV5, CategoryV5, + ClosedPnLV5, + CoinExchangeRecordV5, + CoinGreeksV5, + CoinInfoV5, + CollateralInfoV5, + CreateSubApiKeyParamsV5, + CreateSubApiKeyResultV5, + CreateSubMemberParamsV5, + CreateSubMemberResultV5, + CursorListV5, + DeliveryRecordV5, + DepositAddressResultV5, + DepositRecordV5, + ExecutionV5, + FeeRateV5, FundingRateHistoryResponseV5, + GetAccountCoinBalanceParamsV5, + GetAccountOrdersParams, + GetAllCoinsBalanceParamsV5, + GetAllowedDepositCoinInfoParamsV5, + GetAssetInfoParamsV5, + GetBorrowHistoryParamsV5, + GetClosedPnLParamsV5, + GetCoinExchangeRecordParamsV5, + GetDeliveryRecordParamsV5, + GetDepositRecordParamsV5, + GetExecutionListParamsV5, GetFundingRateHistoryParamsV5, GetHistoricalVolatilityParamsV5, GetIndexPriceKlineParamsV5, GetInstrumentsInfoParamsV5, GetInsuranceParamsV5, + GetInternalTransferParamsV5, GetKlineParamsV5, GetMarkPriceKlineParamsV5, GetOpenInterestParamsV5, @@ -16,113 +66,63 @@ import { GetPremiumIndexPriceKlineParams, GetPublicTradingHistoryParamsV5, GetRiskLimitParamsV5, - GetTickersParamsV5, - HistoricalVolatilityV5, - InsuranceResponseV5, - OpenInterestResponseV5, - OrderbookResponseV5, - OrderParamsV5, - CursorListV5, - PublicTradeV5, - RiskLimitV5, - AmendOrderParamsV5, - CancelOrderParamsV5, - GetAccountOrdersParams, - OrderResultV5, - CancelAllOrdersParamsV5, - BatchOrderParamsV5, - BatchAmendOrderParamsV5, - BatchOrderResult, - BatchOrdersResult, - BatchAmendOrderResult, - BatchCancelOrderParamsV5, - BatchCancelOrderResult, - OrderSideV5, - SpotBorrowCheckResult, - APIResponseV3, - PositionInfoParamsV5, - CategoryCursorListV5, - PositionV5, - AccountOrderV5, - OptionDeliveryPriceV5, - CategorySymbolListV5, - OHLCKlineV5, - OHLCVKlineV5, - TickerSpotV5, - TickerOptionV5, - TickerLinearInverseV5, - SetLeverageParamsV5, - SwitchIsolatedMarginParamsV5, - SetTPSLModeParamsV5, - TPSLModeV5, - SwitchPositionModeParamsV5, - SetRiskLimitParamsV5, - SetRiskLimitResultV5, - SetTradingStopParamsV5, - SetAutoAddMarginParamsV5, - GetExecutionListParamsV5, - ExecutionV5, - GetClosedPnLParamsV5, - ClosedPnLV5, - GetWalletBalanceParamsV5, - WalletBalanceV5, - UnifiedAccountUpgradeResultV5, - GetBorrowHistoryParamsV5, - BorrowHistoryRecordV5, - CollateralInfoV5, - CoinGreeksV5, - FeeRateV5, - AccountInfoV5, - GetTransactionLogParamsV5, - TransactionLogV5, - AccountMarginModeV5, - MMPModifyParamsV5, - MMPStateV5, - GetCoinExchangeRecordParamsV5, - CoinExchangeRecordV5, - GetDeliveryRecordParamsV5, - DeliveryRecordV5, GetSettlementRecordParamsV5, - SettlementRecordV5, - GetAssetInfoParamsV5, - AssetInfoV5, - GetAllCoinsBalanceParamsV5, - AllCoinsBalanceV5, - GetAccountCoinBalanceParamsV5, - AccountCoinBalanceV5, - AccountTypeV5, - GetInternalTransferParamsV5, - InternalTransferRecordV5, - UniversalTransferParamsV5, - GetUniversalTransferRecordsParamsV5, - UniversalTransferRecordV5, - GetAllowedDepositCoinInfoParamsV5, - AllowedDepositCoinInfoV5, - GetDepositRecordParamsV5, - DepositRecordV5, + GetSpotLeveragedTokenOrderHistoryParamsV5, GetSubAccountDepositRecordParamsV5, - DepositAddressResultV5, - CoinInfoV5, + GetTickersParamsV5, + GetTransactionLogParamsV5, + GetUniversalTransferRecordsParamsV5, + GetWalletBalanceParamsV5, GetWithdrawalRecordsParamsV5, - WithdrawalRecordV5, - WithdrawParamsV5, - CreateSubMemberParamsV5, - CreateSubMemberResultV5, - CreateSubApiKeyParamsV5, - CreateSubApiKeyResultV5, - SubMemberV5, - ApiKeyInfoV5, - UpdateApiKeyResultV5, - UpdateApiKeyParamsV5, + HistoricalVolatilityV5, + InstrumentInfoResponseV5, + InsuranceResponseV5, + InternalTransferRecordV5, LeverageTokenInfoV5, LeveragedTokenMarketResultV5, + MMPModifyParamsV5, + MMPStateV5, + OHLCKlineV5, + OHLCVKlineV5, + OpenInterestResponseV5, + OptionDeliveryPriceV5, + OrderParamsV5, + OrderResultV5, + OrderSideV5, + OrderbookResponseV5, + PositionInfoParamsV5, + PositionV5, + PublicTradeV5, PurchaseSpotLeveragedTokenParamsV5, PurchaseSpotLeveragedTokenResultV5, RedeemSpotLeveragedTokenParamsV5, RedeemSpotLeveragedTokenResultV5, - GetSpotLeveragedTokenOrderHistoryParamsV5, + RiskLimitV5, + SetAutoAddMarginParamsV5, + SetLeverageParamsV5, + SetRiskLimitParamsV5, + SetRiskLimitResultV5, + SetTPSLModeParamsV5, + SetTradingStopParamsV5, + SettlementRecordV5, + SpotBorrowCheckResult, SpotLeveragedTokenOrderHistoryV5, - InstrumentInfoResponseV5, + SubMemberV5, + SwitchIsolatedMarginParamsV5, + SwitchPositionModeParamsV5, + TPSLModeV5, + TickerLinearInverseV5, + TickerOptionV5, + TickerSpotV5, + TransactionLogV5, + UnifiedAccountUpgradeResultV5, + UniversalTransferParamsV5, + UniversalTransferRecordV5, + UpdateApiKeyParamsV5, + UpdateApiKeyResultV5, + WalletBalanceV5, + WithdrawParamsV5, + WithdrawalRecordV5, } from './types'; import { REST_CLIENT_TYPE_ENUM } from './util'; import BaseRestClient from './util/BaseRestClient'; @@ -166,7 +166,7 @@ export class RestClientV5 extends BaseRestClient { CategorySymbolListV5 > > { - return this.get(`/v5/market/kline`, params); + return this.get('/v5/market/kline', params); } /** @@ -181,7 +181,7 @@ export class RestClientV5 extends BaseRestClient { CategorySymbolListV5 > > { - return this.get(`/v5/market/mark-price-kline`, params); + return this.get('/v5/market/mark-price-kline', params); } /** @@ -196,7 +196,7 @@ export class RestClientV5 extends BaseRestClient { CategorySymbolListV5 > > { - return this.get(`/v5/market/index-price-kline`, params); + return this.get('/v5/market/index-price-kline', params); } /** @@ -209,7 +209,7 @@ export class RestClientV5 extends BaseRestClient { ): Promise< APIResponseV3WithTime> > { - return this.get(`/v5/market/premium-index-price-kline`, params); + return this.get('/v5/market/premium-index-price-kline', params); } /** @@ -222,7 +222,7 @@ export class RestClientV5 extends BaseRestClient { getInstrumentsInfo( params: GetInstrumentsInfoParamsV5 ): Promise> { - return this.get(`/v5/market/instruments-info`, params); + return this.get('/v5/market/instruments-info', params); } /** @@ -233,7 +233,7 @@ export class RestClientV5 extends BaseRestClient { getOrderbook( params: GetOrderbookParamsV5 ): Promise> { - return this.get(`/v5/market/orderbook`, params); + return this.get('/v5/market/orderbook', params); } /** @@ -250,7 +250,7 @@ export class RestClientV5 extends BaseRestClient { | CategoryListV5 > > { - return this.get(`/v5/market/tickers`, params); + return this.get('/v5/market/tickers', params); } /** @@ -265,7 +265,7 @@ export class RestClientV5 extends BaseRestClient { CategoryListV5 > > { - return this.get(`/v5/market/funding/history`, params); + return this.get('/v5/market/funding/history', params); } /** @@ -278,7 +278,7 @@ export class RestClientV5 extends BaseRestClient { ): Promise< APIResponseV3WithTime> > { - return this.get(`/v5/market/recent-trade`, params); + return this.get('/v5/market/recent-trade', params); } /** @@ -289,7 +289,7 @@ export class RestClientV5 extends BaseRestClient { getOpenInterest( params: GetOpenInterestParamsV5 ): Promise> { - return this.get(`/v5/market/open-interest`, params); + return this.get('/v5/market/open-interest', params); } /** @@ -301,7 +301,7 @@ export class RestClientV5 extends BaseRestClient { ): Promise< APIResponseV3WithTime> > { - return this.get(`/v5/market/historical-volatility`, params); + return this.get('/v5/market/historical-volatility', params); } /** @@ -310,7 +310,7 @@ export class RestClientV5 extends BaseRestClient { getInsurance( params?: GetInsuranceParamsV5 ): Promise> { - return this.get(`/v5/market/insurance`, params); + return this.get('/v5/market/insurance', params); } /** @@ -323,7 +323,7 @@ export class RestClientV5 extends BaseRestClient { ): Promise< APIResponseV3WithTime> > { - return this.get(`/v5/market/risk-limit`, params); + return this.get('/v5/market/risk-limit', params); } /** @@ -336,7 +336,7 @@ export class RestClientV5 extends BaseRestClient { ): Promise< APIResponseV3WithTime> > { - return this.get(`/v5/market/delivery-price`, params); + return this.get('/v5/market/delivery-price', params); } /** @@ -348,7 +348,7 @@ export class RestClientV5 extends BaseRestClient { submitOrder( params: OrderParamsV5 ): Promise> { - return this.postPrivate(`/v5/order/create`, params); + return this.postPrivate('/v5/order/create', params); } amendOrder( @@ -386,7 +386,7 @@ export class RestClientV5 extends BaseRestClient { getHistoricOrders( params: GetAccountOrdersParams ): Promise>> { - return this.getPrivate(`/v5/order/history`, params); + return this.getPrivate('/v5/order/history', params); } /** @@ -573,6 +573,7 @@ export class RestClientV5 extends BaseRestClient { ): Promise> { return this.postPrivate('/v5/position/trading-stop', params); } + /** * This endpoint allows you to turn on/off auto-add-margin for an isolated margin position. * @@ -1175,7 +1176,7 @@ export class RestClientV5 extends BaseRestClient { getLeveragedTokenMarket( ltCoin: string ): Promise> { - return this.get(`/v5/spot-lever-token/reference`, { ltCoin }); + return this.get('/v5/spot-lever-token/reference', { ltCoin }); } /** diff --git a/src/spot-client-v3.ts b/src/spot-client-v3.ts index cc81075..090c3dd 100644 --- a/src/spot-client-v3.ts +++ b/src/spot-client-v3.ts @@ -1,17 +1,16 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { - APIResponseWithTime, APIResponseV3, - SpotOrderQueryById, - OrderSide, - OrderTypeSpot, - SpotBalances, + APIResponseWithTime, KlineInterval, NewSpotOrderV3, - SpotMyTradesRequest, - SpotLeveragedTokenPRHistoryRequest, + SpotBalances, + SpotCancelOrderBatchRequest, SpotCrossMarginBorrowingInfoRequest, SpotCrossMarginRepaymentHistoryRequest, - SpotCancelOrderBatchRequest, + SpotLeveragedTokenPRHistoryRequest, + SpotMyTradesRequest, + SpotOrderQueryById, } from './types'; import { REST_CLIENT_TYPE_ENUM } from './util'; import BaseRestClient from './util/BaseRestClient'; diff --git a/src/spot-client.ts b/src/spot-client.ts index b4a8871..5860433 100644 --- a/src/spot-client.ts +++ b/src/spot-client.ts @@ -1,7 +1,8 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { - NewSpotOrder, APIResponse, KlineInterval, + NewSpotOrder, OrderSide, OrderTypeSpot, SpotBalances, @@ -87,7 +88,9 @@ export class SpotClient extends BaseRestClient { } getLastTradedPrice(): Promise>; + getLastTradedPrice(symbol: string): Promise>; + getLastTradedPrice( symbol?: string ): Promise> { diff --git a/src/types/request/spot.ts b/src/types/request/spot.ts index cfeeae5..ec90dc1 100644 --- a/src/types/request/spot.ts +++ b/src/types/request/spot.ts @@ -1,4 +1,4 @@ -import { numberInString, OrderSide } from '../shared'; +import { OrderSide, numberInString } from '../shared'; export type OrderTypeSpot = 'LIMIT' | 'MARKET' | 'LIMIT_MAKER'; export type OrderTimeInForce = 'GTC' | 'FOK' | 'IOC'; diff --git a/src/types/response/contract.ts b/src/types/response/contract.ts index 1e4683a..76cc5cf 100644 --- a/src/types/response/contract.ts +++ b/src/types/response/contract.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ export interface PaginatedResult { nextPageCursor: string; list: TList[]; diff --git a/src/types/response/unified-margin.ts b/src/types/response/unified-margin.ts index 468d3be..b8c7705 100644 --- a/src/types/response/unified-margin.ts +++ b/src/types/response/unified-margin.ts @@ -1,3 +1,4 @@ +// eslint-disable-next-line @typescript-eslint/no-explicit-any export interface UMPaginatedResult { nextPageCursor: string; category: string; diff --git a/src/types/response/v5-market.ts b/src/types/response/v5-market.ts index 0cefd63..c657871 100644 --- a/src/types/response/v5-market.ts +++ b/src/types/response/v5-market.ts @@ -251,6 +251,7 @@ export interface RiskLimitV5 { riskLimitValue: string; maintenanceMargin: number; initialMargin: number; + // eslint-disable-next-line @typescript-eslint/no-explicit-any section: any; isLowestRisk: 0 | 1; maxLeverage: string; diff --git a/src/types/response/v5-spot-leverage-token.ts b/src/types/response/v5-spot-leverage-token.ts index 5fa19d2..7bda8cc 100644 --- a/src/types/response/v5-spot-leverage-token.ts +++ b/src/types/response/v5-spot-leverage-token.ts @@ -1,7 +1,7 @@ import { - LeverageTokenStatusV5, LTOrderStatusV5, LTOrderTypeV5, + LeverageTokenStatusV5, } from '../v5-shared'; export interface LeverageTokenInfoV5 { diff --git a/src/types/v5-shared.ts b/src/types/v5-shared.ts index 9896b12..a8abee8 100644 --- a/src/types/v5-shared.ts +++ b/src/types/v5-shared.ts @@ -71,9 +71,9 @@ export type StopOrderTypeV5 = /** * Position index. Used to identify positions in different position modes. * - * - 0 one-way mode position - * - 1 Buy side of hedge-mode position - * - 2 Sell side of hedge-mode position + * - 0 one-way mode position + * - 1 Buy side of hedge-mode position + * - 2 Sell side of hedge-mode position */ export type PositionIdx = 0 | 1 | 2; @@ -124,15 +124,11 @@ export type PermissionTypeV5 = /** * Leveraged token status: * - * 1 LT can be purchased and redeemed - * - * 2 LT can be purchased, but not redeemed - * - * 3 LT can be redeemed, but not purchased - * - * 4 LT cannot be purchased nor redeemed - * - * 5 Adjusting position + * - '1' LT can be purchased and redeemed + * - '2' LT can be purchased, but not redeemed + * - '3' LT can be redeemed, but not purchased + * - '4' LT cannot be purchased nor redeemed + * - '5' Adjusting position */ export type LeverageTokenStatusV5 = '1' | '2' | '3' | '4' | '5'; diff --git a/src/types/websockets.ts b/src/types/websockets.ts index 6354c39..17c1b8a 100644 --- a/src/types/websockets.ts +++ b/src/types/websockets.ts @@ -98,6 +98,7 @@ export interface WSClientConfigurableOptions { pingInterval?: number; reconnectTimeout?: number; restOptions?: RestClientOptions; + // eslint-disable-next-line @typescript-eslint/no-explicit-any requestOptions?: any; wsUrl?: string; /** If true, fetch server time before trying to authenticate (disabled by default) */ diff --git a/src/unified-margin-client.ts b/src/unified-margin-client.ts index 730bcc7..37afba9 100644 --- a/src/unified-margin-client.ts +++ b/src/unified-margin-client.ts @@ -1,34 +1,35 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { - APIResponseWithTime, APIResponseV3, - UMCategory, - UMCandlesRequest, - UMInstrumentInfoRequest, - UMFundingRateHistoryRequest, - UMOptionDeliveryPriceRequest, - UMPublicTradesRequest, - UMOpenInterestRequest, - UMOrderRequest, - UMModifyOrderRequest, - UMCancelOrderRequest, - UMActiveOrdersRequest, - UMHistoricOrdersRequest, - UMBatchOrder, - UMBatchOrderReplace, - UMBatchOrderCancel, - UMCancelAllOrdersRequest, - UMPositionsRequest, - UMSetTPSLRequest, - UM7DayTradingHistoryRequest, - UMOptionsSettlementHistoryRequest, - UMPerpSettlementHistoryRequest, - UMTransactionLogRequest, + APIResponseWithTime, InternalTransferRequest, - UMExchangeCoinsRequest, + UM7DayTradingHistoryRequest, + UMActiveOrdersRequest, + UMBatchOrder, + UMBatchOrderCancel, + UMBatchOrderReplace, UMBorrowHistoryRequest, - UMPaginatedResult, + UMCancelAllOrdersRequest, + UMCancelOrderRequest, + UMCandlesRequest, + UMCategory, + UMExchangeCoinsRequest, + UMFundingRateHistoryRequest, UMHistoricOrder, + UMHistoricOrdersRequest, UMInstrumentInfo, + UMInstrumentInfoRequest, + UMModifyOrderRequest, + UMOpenInterestRequest, + UMOptionDeliveryPriceRequest, + UMOptionsSettlementHistoryRequest, + UMOrderRequest, + UMPaginatedResult, + UMPerpSettlementHistoryRequest, + UMPositionsRequest, + UMPublicTradesRequest, + UMSetTPSLRequest, + UMTransactionLogRequest, } from './types'; import { REST_CLIENT_TYPE_ENUM } from './util'; import BaseRestClient from './util/BaseRestClient'; diff --git a/src/usdc-option-client.ts b/src/usdc-option-client.ts index acf7dc6..ea6d3cf 100644 --- a/src/usdc-option-client.ts +++ b/src/usdc-option-client.ts @@ -1,6 +1,7 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { - APIResponseWithTime, APIResponseV3, + APIResponseWithTime, USDCOptionsActiveOrdersRealtimeRequest, USDCOptionsActiveOrdersRequest, USDCOptionsCancelAllOrdersRequest, @@ -8,8 +9,8 @@ import { USDCOptionsContractInfoRequest, USDCOptionsDeliveryHistoryRequest, USDCOptionsDeliveryPriceRequest, - USDCOptionsHistoricalVolatilityRequest, USDCOptionsHistoricOrdersRequest, + USDCOptionsHistoricalVolatilityRequest, USDCOptionsModifyMMPRequest, USDCOptionsModifyOrderRequest, USDCOptionsOrderExecutionRequest, @@ -203,7 +204,11 @@ export class USDCOptionClient extends BaseRestClient { ); } - /** Query trade history. The endpoint only supports up to 30 days of queried records. An error will be returned if startTime is more than 30 days. */ + /** + * Query trade history. + * The endpoint only supports up to 30 days of queried records. + * An error will be returned if startTime is more than 30 days. + */ getOrderExecutionHistory( params: USDCOptionsOrderExecutionRequest ): Promise> { @@ -241,7 +246,9 @@ export class USDCOptionClient extends BaseRestClient { } /** - * If USDC derivatives account balance is greater than X, you can open PORTFOLIO_MARGIN, and if it is less than Y, it will automatically close PORTFOLIO_MARGIN and change back to REGULAR_MARGIN. X and Y will be adjusted according to operational requirements. + * If USDC derivatives account balance is greater than X, you can open PORTFOLIO_MARGIN, + * and if it is less than Y, it will automatically close PORTFOLIO_MARGIN and change back to REGULAR_MARGIN. + * X and Y will be adjusted according to operational requirements. * Rest API returns the result of checking prerequisites. You could get the real status of margin mode change by subscribing margin mode. */ setMarginMode( diff --git a/src/usdc-perpetual-client.ts b/src/usdc-perpetual-client.ts index b446755..a6886b9 100644 --- a/src/usdc-perpetual-client.ts +++ b/src/usdc-perpetual-client.ts @@ -1,8 +1,9 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { + APIResponseV3, APIResponseWithTime, SymbolLimitParam, SymbolPeriodLimitParam, - APIResponseV3, USDCKlineRequest, USDCLast500TradesRequest, USDCOpenInterestRequest, @@ -213,7 +214,9 @@ export class USDCPerpetualClient extends BaseRestClient { } /** - * If USDC derivatives account balance is greater than X, you can open PORTFOLIO_MARGIN, and if it is less than Y, it will automatically close PORTFOLIO_MARGIN and change back to REGULAR_MARGIN. X and Y will be adjusted according to operational requirements. + * If USDC derivatives account balance is greater than X, you can open PORTFOLIO_MARGIN, + * and if it is less than Y, it will automatically close PORTFOLIO_MARGIN and change back to REGULAR_MARGIN. + * X and Y will be adjusted according to operational requirements. * Rest API returns the result of checking prerequisites. You could get the real status of margin mode change by subscribing margin mode. */ setMarginMode( diff --git a/src/util/BaseRestClient.ts b/src/util/BaseRestClient.ts index 2ba5c00..708de7f 100644 --- a/src/util/BaseRestClient.ts +++ b/src/util/BaseRestClient.ts @@ -1,14 +1,15 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import axios, { AxiosRequestConfig, AxiosResponse, Method } from 'axios'; -import { signMessage } from './node-support'; import { - RestClientOptions, - serializeParams, - RestClientType, - REST_CLIENT_TYPE_ENUM, APIID, + REST_CLIENT_TYPE_ENUM, + RestClientOptions, + RestClientType, getRestBaseUrl, + serializeParams, } from './requestUtils'; +import { signMessage } from './node-support'; // axios.interceptors.request.use((request) => { // console.log(new Date(), 'Starting Request', JSON.stringify(request, null, 2)); @@ -48,7 +49,7 @@ interface SignedRequestContext { } interface SignedRequest { - originalParams: T & SignedRequestContext; + originalParams: (T & SignedRequestContext) | SignedRequestContext; paramsWithSign?: T & SignedRequestContext & { sign: string }; serializedParams: string; sign: string; @@ -65,12 +66,19 @@ type SignMethod = 'keyInBody' | 'usdc'; export default abstract class BaseRestClient { private timeOffset: number | null = null; + private syncTimePromise: null | Promise = null; + private options: RestClientOptions; + private baseUrl: string; + private globalRequestOptions: AxiosRequestConfig; + private key: string | undefined; + private secret: string | undefined; + private clientType: RestClientType; /** Function that calls exchange API to query & resolve server time, used by time sync, disabled by default */ @@ -159,13 +167,15 @@ export default abstract class BaseRestClient { params?: TParams, isPublicApi?: true ): Promise>; + private async prepareSignParams( method: Method, signMethod: SignMethod, params?: TParams, isPublicApi?: false | undefined ): Promise>; - private async prepareSignParams( + + private async prepareSignParams( method: Method, signMethod: SignMethod, params?: TParams, @@ -186,7 +196,7 @@ export default abstract class BaseRestClient { await this.syncTime(); } - return this.signRequest(params, method, signMethod); + return this.signRequest(params || {}, method, signMethod); } /** Returns an axios request object. Handles signing process automatically if this is a private API call */ @@ -336,7 +346,7 @@ export default abstract class BaseRestClient { /** * @private sign request and set recv window */ - private async signRequest( + private async signRequest( data: T, method: Method, signMethod: SignMethod @@ -409,10 +419,13 @@ export default abstract class BaseRestClient { encodeValues ); res.sign = await signMessage(res.serializedParams, this.secret); + + // @ts-ignore res.paramsWithSign = { ...res.originalParams, sign: res.sign, }; + return res; } diff --git a/src/util/WsStore.ts b/src/util/WsStore.ts index e5daa2e..024022d 100644 --- a/src/util/WsStore.ts +++ b/src/util/WsStore.ts @@ -16,7 +16,8 @@ type WsTopic = string; /** * A "Set" is used to ensure we only subscribe to a topic once (tracking a list of unique topics we're expected to be connected to) - * Note: Accurate duplicate tracking only works for plaintext topics. E.g. JSON objects may not be seen as duplicates if keys are in different orders. If that's needed, check the FTX implementation. + * Note: Accurate duplicate tracking only works for plaintext topics. + * E.g. JSON objects may not be seen as duplicates if keys are in different orders. If that's needed, check the FTX implementation. */ type WsTopicList = Set; @@ -39,6 +40,7 @@ interface WsStoredState { export default class WsStore { private wsState: Record; + private logger: typeof DefaultLogger; constructor(logger: typeof DefaultLogger) { @@ -48,7 +50,9 @@ export default class WsStore { /** Get WS stored state for key, optionally create if missing */ get(key: WsKey, createIfMissing?: true): WsStoredState; + get(key: WsKey, createIfMissing?: false): WsStoredState | undefined; + get(key: WsKey, createIfMissing?: boolean): WsStoredState | undefined { if (this.wsState[key]) { return this.wsState[key]; diff --git a/src/util/browser-support.ts b/src/util/browser-support.ts index b470940..a7e0980 100644 --- a/src/util/browser-support.ts +++ b/src/util/browser-support.ts @@ -3,6 +3,7 @@ export async function signMessage( secret: string ): Promise { const encoder = new TextEncoder(); + // eslint-disable-next-line no-undef const key = await window.crypto.subtle.importKey( 'raw', encoder.encode(secret), @@ -11,6 +12,7 @@ export async function signMessage( ['sign'] ); + // eslint-disable-next-line no-undef const signature = await window.crypto.subtle.sign( 'HMAC', key, @@ -18,8 +20,10 @@ export async function signMessage( ); return Array.prototype.map - .call(new Uint8Array(signature), (x: any) => - ('00' + x.toString(16)).slice(-2) + .call( + new Uint8Array(signature), + (x: { toString: (arg0: number) => string }) => + ('00' + x.toString(16)).slice(-2) ) .join(''); } diff --git a/src/util/logger.ts b/src/util/logger.ts index 07bb89c..47f189b 100644 --- a/src/util/logger.ts +++ b/src/util/logger.ts @@ -1,3 +1,4 @@ +// eslint-disable-next-line @typescript-eslint/no-explicit-any export type LogParams = null | any; export const DefaultLogger = { diff --git a/src/util/requestUtils.ts b/src/util/requestUtils.ts index 7a3e6a2..a041275 100644 --- a/src/util/requestUtils.ts +++ b/src/util/requestUtils.ts @@ -91,6 +91,7 @@ export function getRestBaseUrl( return exchangeBaseUrls.livenet; } +// eslint-disable-next-line @typescript-eslint/no-explicit-any export function isWsPong(msg: any): boolean { if (!msg) { return false; diff --git a/src/util/websocket-util.ts b/src/util/websocket-util.ts index 6b437bf..339bbad 100644 --- a/src/util/websocket-util.ts +++ b/src/util/websocket-util.ts @@ -298,7 +298,7 @@ export function getWsKeyForTopic( : WS_KEY_MAP.contractUSDTPublic; } default: { - throw neverGuard(market, `getWsKeyForTopic(): Unhandled market`); + throw neverGuard(market, 'getWsKeyForTopic(): Unhandled market'); } } } @@ -322,7 +322,7 @@ export function getMaxTopicsPerSubscribeEvent( return 10; } default: { - throw neverGuard(market, `getWsKeyForTopic(): Unhandled market`); + throw neverGuard(market, 'getWsKeyForTopic(): Unhandled market'); } } } diff --git a/src/websocket-client.ts b/src/websocket-client.ts index c3b7846..e1a1180 100644 --- a/src/websocket-client.ts +++ b/src/websocket-client.ts @@ -1,3 +1,5 @@ +/* eslint-disable max-len */ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { EventEmitter } from 'events'; import WebSocket from 'isomorphic-ws'; @@ -17,24 +19,24 @@ import { APIMarket, KlineInterval, RESTClient, - WebsocketClientOptions, WSClientConfigurableOptions, + WebsocketClientOptions, WsKey, WsTopic, } from './types'; import { - serializeParams, - isWsPong, - WsConnectionStateEnum, + DefaultLogger, PUBLIC_WS_KEYS, WS_AUTH_ON_CONNECT_KEYS, - WS_KEY_MAP, - DefaultLogger, WS_BASE_URL_MAP, - getWsKeyForTopic, - neverGuard, + WS_KEY_MAP, + WsConnectionStateEnum, getMaxTopicsPerSubscribeEvent, + getWsKeyForTopic, + isWsPong, + neverGuard, + serializeParams, } from './util'; const loggerCategory = { category: 'bybit-ws' }; @@ -78,10 +80,14 @@ export declare interface WebsocketClient { ): boolean; } +// eslint-disable-next-line no-redeclare export class WebsocketClient extends EventEmitter { private logger: typeof DefaultLogger; + private restClient?: RESTClient; + private options: WebsocketClientOptions; + private wsStore: WsStore; constructor( @@ -109,6 +115,7 @@ export class WebsocketClient extends EventEmitter { this.prepareRESTClient(); // add default error handling so this doesn't crash node (if the user didn't set a handler) + // eslint-disable-next-line @typescript-eslint/no-empty-function this.on('error', () => {}); } @@ -247,7 +254,7 @@ export class WebsocketClient extends EventEmitter { default: { throw neverGuard( this.options.market, - `prepareRESTClient(): Unhandled market` + 'prepareRESTClient(): Unhandled market' ); } } @@ -304,7 +311,7 @@ export class WebsocketClient extends EventEmitter { return [...this.connectPublic(), this.connectPrivate()]; } default: { - throw neverGuard(this.options.market, `connectAll(): Unhandled market`); + throw neverGuard(this.options.market, 'connectAll(): Unhandled market'); } } } @@ -345,7 +352,7 @@ export class WebsocketClient extends EventEmitter { default: { throw neverGuard( this.options.market, - `connectPublic(): Unhandled market` + 'connectPublic(): Unhandled market' ); } } @@ -382,7 +389,7 @@ export class WebsocketClient extends EventEmitter { default: { throw neverGuard( this.options.market, - `connectPrivate(): Unhandled market` + 'connectPrivate(): Unhandled market' ); } } @@ -517,7 +524,7 @@ export class WebsocketClient extends EventEmitter { 'Cannot authenticate websocket, either api or private keys missing.', { ...loggerCategory, wsKey } ); - throw new Error(`Cannot auth - missing api or secret in config`); + throw new Error('Cannot auth - missing api or secret in config'); } this.logger.debug("Getting auth'd request params", { @@ -660,7 +667,7 @@ export class WebsocketClient extends EventEmitter { this.logger.silly( `Subscribing to topics in batches of ${maxTopicsPerEvent}` ); - for (var i = 0; i < topics.length; i += maxTopicsPerEvent) { + for (let i = 0; i < topics.length; i += maxTopicsPerEvent) { const batch = topics.slice(i, i + maxTopicsPerEvent); this.logger.silly(`Subscribing to batch of ${batch.length}`); this.requestSubscribeTopics(wsKey, batch); @@ -695,7 +702,7 @@ export class WebsocketClient extends EventEmitter { this.logger.silly( `Unsubscribing to topics in batches of ${maxTopicsPerEvent}` ); - for (var i = 0; i < topics.length; i += maxTopicsPerEvent) { + for (let i = 0; i < topics.length; i += maxTopicsPerEvent) { const batch = topics.slice(i, i + maxTopicsPerEvent); this.logger.silly(`Unsubscribing to batch of ${batch.length}`); this.requestUnsubscribeTopics(wsKey, batch); @@ -716,7 +723,7 @@ export class WebsocketClient extends EventEmitter { public tryWsSend(wsKey: WsKey, wsMessage: string) { try { - this.logger.silly(`Sending upstream ws message: `, { + this.logger.silly('Sending upstream ws message: ', { ...loggerCategory, wsMessage, wsKey, @@ -734,7 +741,7 @@ export class WebsocketClient extends EventEmitter { } ws.send(wsMessage); } catch (e) { - this.logger.error(`Failed to send WS message`, { + this.logger.error('Failed to send WS message', { ...loggerCategory, wsMessage, wsKey, @@ -782,7 +789,7 @@ export class WebsocketClient extends EventEmitter { // Some websockets require an auth packet to be sent after opening the connection if (WS_AUTH_ON_CONNECT_KEYS.includes(wsKey)) { - this.logger.info(`Sending auth request...`); + this.logger.info('Sending auth request...'); await this.sendAuthRequest(wsKey); } @@ -955,7 +962,7 @@ export class WebsocketClient extends EventEmitter { ...loggerCategory, wsKey, }); - throw neverGuard(wsKey, `getWsUrl(): Unhandled wsKey`); + throw neverGuard(wsKey, 'getWsUrl(): Unhandled wsKey'); } } } @@ -1051,7 +1058,7 @@ export class WebsocketClient extends EventEmitter { case 'merge': { topic = 'mergedDepth'; if (!dumpScale) { - throw new Error(`Dumpscale must be provided for merged orderbooks`); + throw new Error('Dumpscale must be provided for merged orderbooks'); } break; } diff --git a/tsconfig.json b/tsconfig.json index 4af98e5..7ac09ca 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,14 +13,9 @@ "skipLibCheck": true, "sourceMap": true, "esModuleInterop": true, - "lib": ["es2017","dom"], + "lib": ["es2017", "dom"], "outDir": "lib" }, "include": ["src/**/*"], - "exclude": [ - "node_modules", - "**/node_modules/*", - "coverage", - "doc" - ] + "exclude": ["node_modules", "**/node_modules/*", "coverage", "doc"] } From dd6ef2fea5caa0f623a7eb227196a52bf0ecd614 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Fri, 17 Feb 2023 14:01:07 +0000 Subject: [PATCH 13/26] address linter complaints --- .eslintrc.json | 6 +++++- examples/tsconfig.examples.json | 12 ----------- examples/ws-private.ts | 2 +- examples/ws-public.ts | 8 +++++--- test/contract/private.read.test.ts | 1 + test/contract/public.read.test.ts | 2 +- test/contract/ws.private.test.ts | 10 ++++++---- test/contract/ws.public.inverse.test.ts | 10 ++++++---- test/contract/ws.public.usdt.test.ts | 10 ++++++---- test/inverse-futures/private.read.test.ts | 3 ++- test/inverse-futures/private.write.test.ts | 3 ++- test/inverse/ws.private.test.ts | 4 ++-- test/inverse/ws.public.test.ts | 10 ++++++---- test/linear/private.write.test.ts | 3 ++- test/linear/ws.private.test.ts | 4 ++-- test/linear/ws.public.test.ts | 4 ++-- test/response.util.ts | 3 ++- test/spot/private.v1.write.test.ts | 3 ++- test/spot/private.v3.read.test.ts | 2 +- test/spot/public.v1.test.ts | 20 +++++++++---------- test/spot/public.v3.test.ts | 2 ++ test/spot/ws.private.v1.test.ts | 12 ++++++----- test/spot/ws.private.v3.test.ts | 8 +++++--- test/spot/ws.public.v1.test.ts | 14 +++++++------ test/spot/ws.public.v3.test.ts | 12 ++++++----- test/unified-margin/public.read.test.ts | 2 +- test/unified-margin/ws.private.test.ts | 10 ++++++---- test/unified-margin/ws.public.option.test.ts | 10 ++++++---- .../ws.public.perp.usdc.test.ts | 10 ++++++---- .../ws.public.perp.usdt.test.ts | 10 ++++++---- test/usdc/options/ws.private.test.ts | 8 +++++--- test/usdc/options/ws.public.test.ts | 10 ++++++---- test/usdc/perpetual/ws.private.test.ts | 8 +++++--- test/usdc/perpetual/ws.public.test.ts | 5 ++--- test/ws.util.ts | 3 +++ tsconfig.examples.json | 8 ++++++++ tsconfig.test.json | 8 ++++++++ 37 files changed, 154 insertions(+), 106 deletions(-) delete mode 100644 examples/tsconfig.examples.json create mode 100644 tsconfig.examples.json create mode 100644 tsconfig.test.json diff --git a/.eslintrc.json b/.eslintrc.json index c684cf8..85a2cc4 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -16,7 +16,11 @@ ], "parserOptions": { "projecasdft": true, - "project": ["./tsconfig.json", "examples/tsconfig.examples.json"] + "project": [ + "./tsconfig.json", + "examples/tsconfig.examples.json", + "tsconfig.test.json" + ] }, "rules": { "@typescript-eslint/await-thenable": "error", diff --git a/examples/tsconfig.examples.json b/examples/tsconfig.examples.json deleted file mode 100644 index 883bb93..0000000 --- a/examples/tsconfig.examples.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../tsconfig.json", - "compilerOptions": { - "outDir": "distExamples", - "allowJs": true - }, - "include": [ - "**/*.ts", - // if you have a mixed JS/TS codebase, don't forget to include your JS files - "**/*.js" - ] -} diff --git a/examples/ws-private.ts b/examples/ws-private.ts index ae55f56..2b4908a 100644 --- a/examples/ws-private.ts +++ b/examples/ws-private.ts @@ -1,4 +1,4 @@ -import { WebsocketClient, WS_KEY_MAP, DefaultLogger } from '../src'; +import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from '../src'; // or // import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from 'bybit-api'; diff --git a/examples/ws-public.ts b/examples/ws-public.ts index e358919..d156564 100644 --- a/examples/ws-public.ts +++ b/examples/ws-public.ts @@ -18,8 +18,8 @@ import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from '../src'; // market: 'spot', // market: 'spotv3', // market: 'usdcOption', - // market: 'usdcPerp', - market: 'unifiedPerp', + market: 'usdcPerp', + // market: 'unifiedPerp', // market: 'unifiedOption', }, logger @@ -138,11 +138,13 @@ import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from '../src'; // ]); // usdc perps (note: the syntax is different for the unified perp market) + // (market: 'usdcPerp') // wsClient.subscribe('trade.BTCUSDC'); + wsClient.subscribe('instrument_info.100ms.BTCPERP'); // unified perps // wsClient.subscribe('publicTrade.BTCUSDT'); - wsClient.subscribe('publicTrade.BTCPERP'); + // wsClient.subscribe('publicTrade.BTCPERP'); // For spot v1 (the old, deprecated client), request public connection first then send required topics on 'open' // Not necessary for spot v3 diff --git a/test/contract/private.read.test.ts b/test/contract/private.read.test.ts index 7777495..c1cff4b 100644 --- a/test/contract/private.read.test.ts +++ b/test/contract/private.read.test.ts @@ -1,3 +1,4 @@ +/* eslint-disable max-len */ import { API_ERROR_CODE, ContractClient } from '../../src'; import { successResponseObjectV3 } from '../response.util'; diff --git a/test/contract/public.read.test.ts b/test/contract/public.read.test.ts index 5c245b0..c8ceafd 100644 --- a/test/contract/public.read.test.ts +++ b/test/contract/public.read.test.ts @@ -1,4 +1,4 @@ -import { UMCandlesRequest, ContractClient } from '../../src'; +import { ContractClient, UMCandlesRequest } from '../../src'; import { successResponseObject, successResponseObjectV3, diff --git a/test/contract/ws.private.test.ts b/test/contract/ws.private.test.ts index 49937e6..5392208 100644 --- a/test/contract/ws.private.test.ts +++ b/test/contract/ws.private.test.ts @@ -1,14 +1,16 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable @typescript-eslint/no-unused-vars */ import { - WebsocketClient, WSClientConfigurableOptions, WS_KEY_MAP, + WebsocketClient, } from '../../src'; import { - logAllEvents, - getSilentLogger, - waitForSocketEvent, WS_OPEN_EVENT_PARTIAL, fullLogger, + getSilentLogger, + logAllEvents, + waitForSocketEvent, } from '../ws.util'; describe('Private Contract Websocket Client', () => { diff --git a/test/contract/ws.public.inverse.test.ts b/test/contract/ws.public.inverse.test.ts index 5c76374..24cc45e 100644 --- a/test/contract/ws.public.inverse.test.ts +++ b/test/contract/ws.public.inverse.test.ts @@ -1,13 +1,15 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable @typescript-eslint/no-unused-vars */ import { - WebsocketClient, WSClientConfigurableOptions, WS_KEY_MAP, + WebsocketClient, } from '../../src'; import { - logAllEvents, - getSilentLogger, - waitForSocketEvent, WS_OPEN_EVENT_PARTIAL, + getSilentLogger, + logAllEvents, + waitForSocketEvent, } from '../ws.util'; describe('Public Contract Inverse Websocket Client', () => { diff --git a/test/contract/ws.public.usdt.test.ts b/test/contract/ws.public.usdt.test.ts index c5da8b5..c72b7c5 100644 --- a/test/contract/ws.public.usdt.test.ts +++ b/test/contract/ws.public.usdt.test.ts @@ -1,13 +1,15 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable @typescript-eslint/no-unused-vars */ import { - WebsocketClient, WSClientConfigurableOptions, WS_KEY_MAP, + WebsocketClient, } from '../../src'; import { - logAllEvents, - getSilentLogger, - waitForSocketEvent, WS_OPEN_EVENT_PARTIAL, + getSilentLogger, + logAllEvents, + waitForSocketEvent, } from '../ws.util'; describe('Public Contract USDT Websocket Client', () => { diff --git a/test/inverse-futures/private.read.test.ts b/test/inverse-futures/private.read.test.ts index 0d52485..02c695e 100644 --- a/test/inverse-futures/private.read.test.ts +++ b/test/inverse-futures/private.read.test.ts @@ -11,7 +11,8 @@ describe('Private Inverse-Futures REST API GET Endpoints', () => { testnet: false, }); - // Warning: if some of these start to fail with 10001 params error, it's probably that this future expired and a newer one exists with a different symbol! + // Warning: if some of these start to fail with 10001 params error, + // it's probably that this future expired and a newer one exists with a different symbol! let symbol = ''; beforeAll(async () => { diff --git a/test/inverse-futures/private.write.test.ts b/test/inverse-futures/private.write.test.ts index 7573ca5..d8b60da 100644 --- a/test/inverse-futures/private.write.test.ts +++ b/test/inverse-futures/private.write.test.ts @@ -16,7 +16,8 @@ describe('Private Inverse-Futures REST API POST Endpoints', () => { testnet: false, }); - // Warning: if some of these start to fail with 10001 params error, it's probably that this future expired and a newer one exists with a different symbol! + // Warning: if some of these start to fail with 10001 params error, + // it's probably that this future expired and a newer one exists with a different symbol! let symbol = ''; beforeAll(async () => { diff --git a/test/inverse/ws.private.test.ts b/test/inverse/ws.private.test.ts index 6c6bc5c..b4000ba 100644 --- a/test/inverse/ws.private.test.ts +++ b/test/inverse/ws.private.test.ts @@ -1,12 +1,12 @@ import { - WebsocketClient, WSClientConfigurableOptions, WS_KEY_MAP, + WebsocketClient, } from '../../src'; import { + WS_OPEN_EVENT_PARTIAL, getSilentLogger, waitForSocketEvent, - WS_OPEN_EVENT_PARTIAL, } from '../ws.util'; describe('Private Inverse Perps Websocket Client', () => { diff --git a/test/inverse/ws.public.test.ts b/test/inverse/ws.public.test.ts index 901e14f..305059e 100644 --- a/test/inverse/ws.public.test.ts +++ b/test/inverse/ws.public.test.ts @@ -1,14 +1,16 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable @typescript-eslint/no-unused-vars */ import { LinearClient, - WebsocketClient, WSClientConfigurableOptions, WS_KEY_MAP, + WebsocketClient, } from '../../src'; import { - promiseSleep, - getSilentLogger, - waitForSocketEvent, WS_OPEN_EVENT_PARTIAL, + getSilentLogger, + promiseSleep, + waitForSocketEvent, } from '../ws.util'; describe('Public Inverse Perps Websocket Client', () => { diff --git a/test/linear/private.write.test.ts b/test/linear/private.write.test.ts index a34189f..1fce947 100644 --- a/test/linear/private.write.test.ts +++ b/test/linear/private.write.test.ts @@ -16,7 +16,8 @@ describe('Private Linear REST API POST Endpoints', () => { testnet: false, }); - // Warning: if some of these start to fail with 10001 params error, it's probably that this future expired and a newer one exists with a different symbol! + // Warning: if some of these start to fail with 10001 params error, + // it's probably that this future expired and a newer one exists with a different symbol! const symbol = 'BTCUSDT'; // These tests are primarily check auth is working by expecting balance or order not found style errors diff --git a/test/linear/ws.private.test.ts b/test/linear/ws.private.test.ts index 60c16fd..f6bf92a 100644 --- a/test/linear/ws.private.test.ts +++ b/test/linear/ws.private.test.ts @@ -1,12 +1,12 @@ import { - WebsocketClient, WSClientConfigurableOptions, WS_KEY_MAP, + WebsocketClient, } from '../../src'; import { + WS_OPEN_EVENT_PARTIAL, getSilentLogger, waitForSocketEvent, - WS_OPEN_EVENT_PARTIAL, } from '../ws.util'; describe('Private Linear Perps Websocket Client', () => { diff --git a/test/linear/ws.public.test.ts b/test/linear/ws.public.test.ts index 744edc1..75647bb 100644 --- a/test/linear/ws.public.test.ts +++ b/test/linear/ws.public.test.ts @@ -1,12 +1,12 @@ import { - WebsocketClient, WSClientConfigurableOptions, WS_KEY_MAP, + WebsocketClient, } from '../../src'; import { + WS_OPEN_EVENT_PARTIAL, getSilentLogger, waitForSocketEvent, - WS_OPEN_EVENT_PARTIAL, } from '../ws.util'; describe('Public Linear Perps Websocket Client', () => { diff --git a/test/response.util.ts b/test/response.util.ts index 48823d7..36adaec 100644 --- a/test/response.util.ts +++ b/test/response.util.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { API_ERROR_CODE } from '../src'; const SUCCESS_MSG_REGEX = /OK|SUCCESS|success|success\.|Request accepted|/gim; @@ -19,7 +20,7 @@ export function successResponseListV3() { }; } -export function successResponseObject(successMsg: string | null = 'OK') { +export function successResponseObject() { return { result: expect.any(Object), ret_code: API_ERROR_CODE.SUCCESS, diff --git a/test/spot/private.v1.write.test.ts b/test/spot/private.v1.write.test.ts index fb59c7a..f833f64 100644 --- a/test/spot/private.v1.write.test.ts +++ b/test/spot/private.v1.write.test.ts @@ -16,7 +16,8 @@ describe('Private Spot REST API POST Endpoints', () => { testnet: false, }); - // Warning: if some of these start to fail with 10001 params error, it's probably that this future expired and a newer one exists with a different symbol! + // Warning: if some of these start to fail with 10001 params error, + // it's probably that this future expired and a newer one exists with a different symbol! const symbol = 'BTCUSDT'; // These tests are primarily check auth is working by expecting balance or order not found style errors diff --git a/test/spot/private.v3.read.test.ts b/test/spot/private.v3.read.test.ts index 8c4fa37..ee59dc0 100644 --- a/test/spot/private.v3.read.test.ts +++ b/test/spot/private.v3.read.test.ts @@ -21,7 +21,7 @@ describe('Private Spot REST API GET Endpoints', () => { }); const symbol = 'BTCUSDT'; - const interval = '15m'; + // const interval = '15m'; const ltCode = 'BTC3S'; it('getOrder()', async () => { diff --git a/test/spot/public.v1.test.ts b/test/spot/public.v1.test.ts index e89afbc..90288f8 100644 --- a/test/spot/public.v1.test.ts +++ b/test/spot/public.v1.test.ts @@ -1,3 +1,5 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable @typescript-eslint/no-unused-vars */ import { SpotClient } from '../../src'; import { notAuthenticatedError, @@ -28,43 +30,39 @@ describe('Public Spot REST API Endpoints', () => { it('getOrderBook()', async () => { expect(await api.getOrderBook(symbol)).toMatchObject( - successResponseObject(null) + successResponseObject() ); }); it('getMergedOrderBook()', async () => { expect(await api.getMergedOrderBook(symbol)).toMatchObject( - successResponseObject(null) + successResponseObject() ); }); it('getTrades()', async () => { - expect(await api.getTrades(symbol)).toMatchObject( - successResponseObject(null) - ); + expect(await api.getTrades(symbol)).toMatchObject(successResponseObject()); }); it('getCandles()', async () => { expect(await api.getCandles(symbol, interval)).toMatchObject( - successResponseObject(null) + successResponseObject() ); }); it('get24hrTicker()', async () => { - expect(await api.get24hrTicker()).toMatchObject( - successResponseObject(null) - ); + expect(await api.get24hrTicker()).toMatchObject(successResponseObject()); }); it('getLastTradedPrice()', async () => { expect(await api.getLastTradedPrice()).toMatchObject( - successResponseObject(null) + successResponseObject() ); }); it('getBestBidAskPrice()', async () => { expect(await api.getBestBidAskPrice()).toMatchObject( - successResponseObject(null) + successResponseObject() ); }); diff --git a/test/spot/public.v3.test.ts b/test/spot/public.v3.test.ts index 58d92cb..d908c46 100644 --- a/test/spot/public.v3.test.ts +++ b/test/spot/public.v3.test.ts @@ -1,3 +1,5 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable @typescript-eslint/no-unused-vars */ import { SpotClientV3 } from '../../src'; import { notAuthenticatedError, diff --git a/test/spot/ws.private.v1.test.ts b/test/spot/ws.private.v1.test.ts index 617e21b..d409b7f 100644 --- a/test/spot/ws.private.v1.test.ts +++ b/test/spot/ws.private.v1.test.ts @@ -1,15 +1,17 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable @typescript-eslint/no-unused-vars */ import { - WebsocketClient, WSClientConfigurableOptions, WS_KEY_MAP, + WebsocketClient, } from '../../src'; import { - logAllEvents, - promiseSleep, - getSilentLogger, - waitForSocketEvent, WS_OPEN_EVENT_PARTIAL, fullLogger, + getSilentLogger, + logAllEvents, + promiseSleep, + waitForSocketEvent, } from '../ws.util'; describe('Private Spot V1 Websocket Client', () => { diff --git a/test/spot/ws.private.v3.test.ts b/test/spot/ws.private.v3.test.ts index 39a3b0b..0628151 100644 --- a/test/spot/ws.private.v3.test.ts +++ b/test/spot/ws.private.v3.test.ts @@ -1,13 +1,15 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable @typescript-eslint/no-unused-vars */ import { - WebsocketClient, WSClientConfigurableOptions, WS_ERROR_ENUM, WS_KEY_MAP, + WebsocketClient, } from '../../src'; import { + WS_OPEN_EVENT_PARTIAL, getSilentLogger, waitForSocketEvent, - WS_OPEN_EVENT_PARTIAL, } from '../ws.util'; describe('Private Spot V3 Websocket Client', () => { @@ -19,7 +21,7 @@ describe('Private Spot V3 Websocket Client', () => { key: API_KEY, secret: API_SECRET, }; - const wsTopic = `outboundAccountInfo`; + const wsTopic = 'outboundAccountInfo'; describe('with invalid credentials', () => { it('should reject private subscribe if keys/signature are incorrect', async () => { diff --git a/test/spot/ws.public.v1.test.ts b/test/spot/ws.public.v1.test.ts index 0e2219c..b6b1d87 100644 --- a/test/spot/ws.public.v1.test.ts +++ b/test/spot/ws.public.v1.test.ts @@ -1,14 +1,16 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable @typescript-eslint/no-unused-vars */ import { - WebsocketClient, WSClientConfigurableOptions, WS_KEY_MAP, + WebsocketClient, } from '../../src'; import { - logAllEvents, - getSilentLogger, - fullLogger, - waitForSocketEvent, WS_OPEN_EVENT_PARTIAL, + fullLogger, + getSilentLogger, + logAllEvents, + waitForSocketEvent, } from '../ws.util'; describe('Public Spot V1 Websocket Client', () => { @@ -64,7 +66,7 @@ describe('Public Spot V1 Websocket Client', () => { try { await wsUpdatePromise; } catch (e) { - console.error(`Wait for spot v1 orderbook event exception: `, e); + console.error('Wait for spot v1 orderbook event exception: ', e); } }); }); diff --git a/test/spot/ws.public.v3.test.ts b/test/spot/ws.public.v3.test.ts index bea6951..a6327d8 100644 --- a/test/spot/ws.public.v3.test.ts +++ b/test/spot/ws.public.v3.test.ts @@ -1,14 +1,16 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable @typescript-eslint/no-unused-vars */ import { - WebsocketClient, WSClientConfigurableOptions, WS_KEY_MAP, + WebsocketClient, } from '../../src'; import { - logAllEvents, - getSilentLogger, - fullLogger, - waitForSocketEvent, WS_OPEN_EVENT_PARTIAL, + fullLogger, + getSilentLogger, + logAllEvents, + waitForSocketEvent, } from '../ws.util'; describe('Public Spot V3 Websocket Client', () => { diff --git a/test/unified-margin/public.read.test.ts b/test/unified-margin/public.read.test.ts index 406e8a9..0798f5f 100644 --- a/test/unified-margin/public.read.test.ts +++ b/test/unified-margin/public.read.test.ts @@ -1,4 +1,4 @@ -import { UnifiedMarginClient, UMCandlesRequest } from '../../src'; +import { UMCandlesRequest, UnifiedMarginClient } from '../../src'; import { successResponseObject, successResponseObjectV3, diff --git a/test/unified-margin/ws.private.test.ts b/test/unified-margin/ws.private.test.ts index 9e738a5..fbe6760 100644 --- a/test/unified-margin/ws.private.test.ts +++ b/test/unified-margin/ws.private.test.ts @@ -1,14 +1,16 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable @typescript-eslint/no-unused-vars */ import { - WebsocketClient, WSClientConfigurableOptions, WS_KEY_MAP, + WebsocketClient, } from '../../src'; import { - logAllEvents, - getSilentLogger, - waitForSocketEvent, WS_OPEN_EVENT_PARTIAL, fullLogger, + getSilentLogger, + logAllEvents, + waitForSocketEvent, } from '../ws.util'; describe('Private Unified Margin Websocket Client', () => { diff --git a/test/unified-margin/ws.public.option.test.ts b/test/unified-margin/ws.public.option.test.ts index 0870511..0d7cc79 100644 --- a/test/unified-margin/ws.public.option.test.ts +++ b/test/unified-margin/ws.public.option.test.ts @@ -1,13 +1,15 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable @typescript-eslint/no-unused-vars */ import { - WebsocketClient, WSClientConfigurableOptions, WS_KEY_MAP, + WebsocketClient, } from '../../src'; import { - logAllEvents, - getSilentLogger, - waitForSocketEvent, WS_OPEN_EVENT_PARTIAL, + getSilentLogger, + logAllEvents, + waitForSocketEvent, } from '../ws.util'; describe('Public Unified Margin Websocket Client (Options)', () => { diff --git a/test/unified-margin/ws.public.perp.usdc.test.ts b/test/unified-margin/ws.public.perp.usdc.test.ts index 9abd3c7..11634f4 100644 --- a/test/unified-margin/ws.public.perp.usdc.test.ts +++ b/test/unified-margin/ws.public.perp.usdc.test.ts @@ -1,14 +1,16 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable @typescript-eslint/no-unused-vars */ import { - WebsocketClient, WSClientConfigurableOptions, WS_KEY_MAP, + WebsocketClient, } from '../../src'; import { - logAllEvents, - getSilentLogger, - waitForSocketEvent, WS_OPEN_EVENT_PARTIAL, fullLogger, + getSilentLogger, + logAllEvents, + waitForSocketEvent, } from '../ws.util'; describe('Public Unified Margin Websocket Client (Perps - USDC)', () => { diff --git a/test/unified-margin/ws.public.perp.usdt.test.ts b/test/unified-margin/ws.public.perp.usdt.test.ts index 8bb1017..34f27a3 100644 --- a/test/unified-margin/ws.public.perp.usdt.test.ts +++ b/test/unified-margin/ws.public.perp.usdt.test.ts @@ -1,14 +1,16 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable @typescript-eslint/no-unused-vars */ import { - WebsocketClient, WSClientConfigurableOptions, WS_KEY_MAP, + WebsocketClient, } from '../../src'; import { - logAllEvents, - getSilentLogger, - waitForSocketEvent, WS_OPEN_EVENT_PARTIAL, fullLogger, + getSilentLogger, + logAllEvents, + waitForSocketEvent, } from '../ws.util'; describe('Public Unified Margin Websocket Client (Perps - USDT)', () => { diff --git a/test/usdc/options/ws.private.test.ts b/test/usdc/options/ws.private.test.ts index b6f52d4..6efcccf 100644 --- a/test/usdc/options/ws.private.test.ts +++ b/test/usdc/options/ws.private.test.ts @@ -1,15 +1,17 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable @typescript-eslint/no-unused-vars */ import { - WebsocketClient, WSClientConfigurableOptions, WS_ERROR_ENUM, WS_KEY_MAP, + WebsocketClient, } from '../../../src'; import { + WS_OPEN_EVENT_PARTIAL, fullLogger, getSilentLogger, logAllEvents, waitForSocketEvent, - WS_OPEN_EVENT_PARTIAL, } from '../../ws.util'; describe('Private USDC Option Websocket Client', () => { @@ -22,7 +24,7 @@ describe('Private USDC Option Websocket Client', () => { secret: API_SECRET, }; - const wsTopic = `user.openapi.option.position`; + const wsTopic = 'user.openapi.option.position'; describe('with invalid credentials', () => { it('should reject private subscribe if keys/signature are incorrect', async () => { diff --git a/test/usdc/options/ws.public.test.ts b/test/usdc/options/ws.public.test.ts index 63d6ef9..ad054b4 100644 --- a/test/usdc/options/ws.public.test.ts +++ b/test/usdc/options/ws.public.test.ts @@ -1,13 +1,15 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable @typescript-eslint/no-unused-vars */ import { - WebsocketClient, WSClientConfigurableOptions, WS_KEY_MAP, + WebsocketClient, } from '../../../src'; import { - logAllEvents, - getSilentLogger, - waitForSocketEvent, WS_OPEN_EVENT_PARTIAL, + getSilentLogger, + logAllEvents, + waitForSocketEvent, } from '../../ws.util'; describe('Public USDC Option Websocket Client', () => { diff --git a/test/usdc/perpetual/ws.private.test.ts b/test/usdc/perpetual/ws.private.test.ts index 5c2e302..e9011d4 100644 --- a/test/usdc/perpetual/ws.private.test.ts +++ b/test/usdc/perpetual/ws.private.test.ts @@ -1,15 +1,17 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable @typescript-eslint/no-unused-vars */ import { - WebsocketClient, WSClientConfigurableOptions, WS_ERROR_ENUM, WS_KEY_MAP, + WebsocketClient, } from '../../../src'; import { + WS_OPEN_EVENT_PARTIAL, fullLogger, getSilentLogger, logAllEvents, waitForSocketEvent, - WS_OPEN_EVENT_PARTIAL, } from '../../ws.util'; describe('Private USDC Perp Websocket Client', () => { @@ -22,7 +24,7 @@ describe('Private USDC Perp Websocket Client', () => { secret: API_SECRET, }; - const wsTopic = `user.openapi.perp.position`; + const wsTopic = 'user.openapi.perp.position'; describe('with invalid credentials', () => { it('should reject private subscribe if keys/signature are incorrect', async () => { diff --git a/test/usdc/perpetual/ws.public.test.ts b/test/usdc/perpetual/ws.public.test.ts index 4c7dded..a44db83 100644 --- a/test/usdc/perpetual/ws.public.test.ts +++ b/test/usdc/perpetual/ws.public.test.ts @@ -1,13 +1,12 @@ import { - WebsocketClient, WSClientConfigurableOptions, WS_KEY_MAP, + WebsocketClient, } from '../../../src'; import { - logAllEvents, + WS_OPEN_EVENT_PARTIAL, getSilentLogger, waitForSocketEvent, - WS_OPEN_EVENT_PARTIAL, } from '../../ws.util'; describe('Public USDC Perp Websocket Client', () => { diff --git a/test/ws.util.ts b/test/ws.util.ts index a20793b..695bedb 100644 --- a/test/ws.util.ts +++ b/test/ws.util.ts @@ -1,3 +1,5 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable @typescript-eslint/no-empty-function */ import { WebsocketClient, WsClientEvent } from '../src'; export function getSilentLogger(logHint?: string) { @@ -33,6 +35,7 @@ export function waitForSocketEvent( return new Promise((resolve, reject) => { const timeout = setTimeout(() => { reject( + // eslint-disable-next-line max-len `Failed to receive "${event}" event before timeout. Check that these are correct: topic, api keys (if private), signature process (if private)` ); }, timeoutMs); diff --git a/tsconfig.examples.json b/tsconfig.examples.json new file mode 100644 index 0000000..d1f02f1 --- /dev/null +++ b/tsconfig.examples.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "distExamples", + "allowJs": true + }, + "include": ["examples/**/*.ts", "examples/**/*.js"] +} diff --git a/tsconfig.test.json b/tsconfig.test.json new file mode 100644 index 0000000..c381f98 --- /dev/null +++ b/tsconfig.test.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "distTest", + "allowJs": true + }, + "include": ["test/**/*.ts", "test/**/*.js"] +} From 8193f5a5ce9d94ff586e4e1e43def8c7f6d654fe Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Fri, 17 Feb 2023 14:06:58 +0000 Subject: [PATCH 14/26] fix linting errors --- examples/ws-private.ts | 3 +++ src/linear-client.ts | 1 - src/spot-client-v3.ts | 1 + src/util/logger.ts | 2 ++ test/usdc/options/private.write.test.ts | 2 +- test/usdc/perpetual/private.write.test.ts | 5 +---- test/ws.util.ts | 5 +++-- 7 files changed, 11 insertions(+), 8 deletions(-) diff --git a/examples/ws-private.ts b/examples/ws-private.ts index 2b4908a..62839e4 100644 --- a/examples/ws-private.ts +++ b/examples/ws-private.ts @@ -1,3 +1,6 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/no-empty-function */ import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from '../src'; // or diff --git a/src/linear-client.ts b/src/linear-client.ts index b262ebe..4ab0086 100644 --- a/src/linear-client.ts +++ b/src/linear-client.ts @@ -38,7 +38,6 @@ import { WalletFundRecordsReq, WithdrawRecordsReq, } from './types'; -import { linearPositionModeEnum, positionTpSlModeEnum } from './constants/enum'; import BaseRestClient from './util/BaseRestClient'; /** diff --git a/src/spot-client-v3.ts b/src/spot-client-v3.ts index 090c3dd..029b92d 100644 --- a/src/spot-client-v3.ts +++ b/src/spot-client-v3.ts @@ -166,6 +166,7 @@ export class SpotClientV3 extends BaseRestClient { symbol, orderId, limit, + orderCategory, }); } diff --git a/src/util/logger.ts b/src/util/logger.ts index 47f189b..68a290e 100644 --- a/src/util/logger.ts +++ b/src/util/logger.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable no-unused-vars */ // eslint-disable-next-line @typescript-eslint/no-explicit-any export type LogParams = null | any; diff --git a/test/usdc/options/private.write.test.ts b/test/usdc/options/private.write.test.ts index ae8ab53..511e670 100644 --- a/test/usdc/options/private.write.test.ts +++ b/test/usdc/options/private.write.test.ts @@ -1,5 +1,5 @@ import { API_ERROR_CODE, USDCOptionClient } from '../../../src'; -import { successResponseObjectV3 } from '../../response.util'; +// import { successResponseObjectV3 } from '../../response.util'; describe('Private USDC Options REST API POST Endpoints', () => { const API_KEY = process.env.API_KEY_COM; diff --git a/test/usdc/perpetual/private.write.test.ts b/test/usdc/perpetual/private.write.test.ts index df7c16e..d4f0646 100644 --- a/test/usdc/perpetual/private.write.test.ts +++ b/test/usdc/perpetual/private.write.test.ts @@ -1,8 +1,5 @@ import { API_ERROR_CODE, USDCPerpetualClient } from '../../../src'; -import { - successEmptyResponseObjectV3, - successResponseObjectV3, -} from '../../response.util'; +import { successEmptyResponseObjectV3 } from '../../response.util'; describe('Private USDC Perp REST API POST Endpoints', () => { const API_KEY = process.env.API_KEY_COM; diff --git a/test/ws.util.ts b/test/ws.util.ts index 695bedb..6d134bb 100644 --- a/test/ws.util.ts +++ b/test/ws.util.ts @@ -1,8 +1,9 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable no-unused-vars */ /* eslint-disable @typescript-eslint/no-empty-function */ import { WebsocketClient, WsClientEvent } from '../src'; -export function getSilentLogger(logHint?: string) { +export function getSilentLogger(_logHint?: string) { return { silly: () => {}, debug: () => {}, @@ -129,7 +130,7 @@ export function logAllEvents(wsClient: WebsocketClient) { } export function promiseSleep(ms: number) { - return new Promise((resolve, reject) => { + return new Promise((resolve) => { setTimeout(resolve, ms); }); } From 649abf8bce6625e839187b7d30155169dcbe70ce Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Fri, 17 Feb 2023 14:08:51 +0000 Subject: [PATCH 15/26] add eslint rule --- .eslintrc.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.eslintrc.json b/.eslintrc.json index 85a2cc4..16104e5 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -39,6 +39,7 @@ "@typescript-eslint/no-non-null-assertion": "off", "@typescript-eslint/ban-types": "off", "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/ban-ts-comment": "off", "no-dupe-class-members": "off", "no-param-reassign": ["error"], From b5ff56a38ed8d9880b6f1106ab1a89461b92dd0b Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Fri, 17 Feb 2023 15:43:27 +0000 Subject: [PATCH 16/26] linter fixes --- .eslintrc.json | 8 +------- src/rest-client-v5.ts | 29 ++++++++++++++++++++--------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 16104e5..fb71ba0 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -44,13 +44,7 @@ "no-dupe-class-members": "off", "no-param-reassign": ["error"], "array-bracket-spacing": ["error", "never"], - "indent": [ - "warn", - 2, - { - "SwitchCase": 1 - } - ], + "indent": ["off"], "linebreak-style": ["error", "unix"], "lines-between-class-members": ["warn", "always"], "semi": "off", diff --git a/src/rest-client-v5.ts b/src/rest-client-v5.ts index 7b0aa40..29e0708 100644 --- a/src/rest-client-v5.ts +++ b/src/rest-client-v5.ts @@ -392,9 +392,13 @@ export class RestClientV5 extends BaseRestClient { /** * This endpoint allows you to place more than one order in a single request. Covers: option (unified account). * - * Make sure you have sufficient funds in your account when placing an order. Once an order is placed, according to the funds required by the order, the funds in your account will be frozen by the corresponding amount during the life cycle of the order. + * Make sure you have sufficient funds in your account when placing an order. + * Once an order is placed, according to the funds required by the order, + * the funds in your account will be frozen by the corresponding amount during the life cycle of the order. * - * A maximum of 20 orders can be placed per request. The returned data list is divided into two lists. The first list indicates whether or not the order creation was successful and the second list details the created order information. The structure of the two lists are completely consistent. + * A maximum of 20 orders can be placed per request. The returned data list is divided into two lists. + * The first list indicates whether or not the order creation was successful and the second list details the created order information. + * The structure of the two lists are completely consistent. */ batchSubmitOrders( category: 'option', @@ -463,7 +467,8 @@ export class RestClientV5 extends BaseRestClient { /** * This endpoint allows you to set the disconnection protect time window. Covers: option (unified account). * - * If you need to turn it on/off, you can contact your client manager for consultation and application. The default time window is 10 seconds. + * If you need to turn it on/off, you can contact your client manager for consultation and application. + * The default time window is 10 seconds. */ setDisconnectCancelAllWindow( category: 'option', @@ -514,7 +519,8 @@ export class RestClientV5 extends BaseRestClient { * * Covers: USDT perpetual (Normal account) / Inverse contract (Normal account). * - * Switching margin modes will cause orders in progress to be cancelled. Please make sure that there are no open orders before you switch margin modes. + * Switching margin modes will cause orders in progress to be cancelled. + * Please make sure that there are no open orders before you switch margin modes. */ switchIsolatedMargin( params: SwitchIsolatedMarginParamsV5 @@ -551,7 +557,11 @@ export class RestClientV5 extends BaseRestClient { } /** - * The risk limit will limit the maximum position value you can hold under different margin requirements. If you want to hold a bigger position size, you need more margin. This interface can set the risk limit of a single position. If the order exceeds the current risk limit when placing an order, it will be rejected. + * The risk limit will limit the maximum position value you can hold under different margin requirements. + * If you want to hold a bigger position size, you need more margin. + * + * This interface can set the risk limit of a single position. + * If the order exceeds the current risk limit when placing an order, it will be rejected. */ setRiskLimit( params: SetRiskLimitParamsV5 @@ -885,7 +895,9 @@ export class RestClientV5 extends BaseRestClient { /** * Enable Universal Transfer for Sub UID * - * Use this endpoint to enable a subaccount to take part in a universal transfer. It is a one-time switch which, once thrown, enables a subaccount permanently. If not set, your subaccount cannot use universal transfers. + * Use this endpoint to enable a subaccount to take part in a universal transfer. + * It is a one-time switch which, once thrown, enables a subaccount permanently. + * If not set, your subaccount cannot use universal transfers. */ enableUniversalTransferForSubUIDs( subMemberIds: string[] @@ -1019,8 +1031,6 @@ export class RestClientV5 extends BaseRestClient { * * CAUTION: Make sure you have whitelisted your wallet address before calling this endpoint. * - * NOTE: Currently we are upgrading the fund account, if your funding account has been upgraded, you can select the wallet to be withdrawn from. If your funding account has not been upgraded, the API will still use spot wallet to withdraw cash, but you cannot select the wallet to be withdrawn from. It is expected that in the next two weeks, all users' funding account upgrades will be completed. - * * You can make an off-chain transfer if the target wallet address is from Bybit. This means that no blockchain fee will be charged. */ submitWithdrawal( @@ -1096,7 +1106,8 @@ export class RestClientV5 extends BaseRestClient { } /** - * Get the information of the api key. Use the api key pending to be checked to call the endpoint. Both master and sub user's api key are applicable. + * Get the information of the api key. Use the api key pending to be checked to call the endpoint. + * Both master and sub user's api key are applicable. * * TIP: Any permission can access this endpoint. */ From 69502f9e573c54c04b87d7ba93c93fad71b95922 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Mon, 20 Feb 2023 11:38:58 +0000 Subject: [PATCH 17/26] fix eslint tsconfigs --- .eslintrc.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index fb71ba0..243c59a 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -18,8 +18,8 @@ "projecasdft": true, "project": [ "./tsconfig.json", - "examples/tsconfig.examples.json", - "tsconfig.test.json" + "./tsconfig.examples.json", + "./tsconfig.test.json" ] }, "rules": { From fc1e3945c0110b5235abd184e2911cce0ad2c9c4 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Mon, 20 Feb 2023 12:25:54 +0000 Subject: [PATCH 18/26] misc fixes for v5 rest client. Add e2e private fetch tests for v5 rest client. --- src/constants/enum.ts | 1 + src/rest-client-v5.ts | 11 +- test/response.util.ts | 7 +- test/rest-client-v5/private.read.test.ts | 267 +++++++++++++++++++++++ 4 files changed, 279 insertions(+), 7 deletions(-) create mode 100644 test/rest-client-v5/private.read.test.ts diff --git a/src/constants/enum.ts b/src/constants/enum.ts index 58ba6ad..61bdd42 100644 --- a/src/constants/enum.ts +++ b/src/constants/enum.ts @@ -63,6 +63,7 @@ export const API_ERROR_CODE = { CONTRACT_MARGIN_MODE_NOT_MODIFIED: 140026, CONTRACT_RISK_LIMIT_INFO_NOT_EXISTS: 140031, CONTRACT_SET_LEVERAGE_NOT_MODIFIED: 140043, + SPOT_LEVERAGE_TOKEN_ORDER_NOT_FOUND: 175007, /** E.g. USDC Options trading, trying to access a symbol that is no longer active */ CONTRACT_NAME_NOT_EXIST: 3100111, ORDER_NOT_EXIST: 3100136, diff --git a/src/rest-client-v5.ts b/src/rest-client-v5.ts index 29e0708..e3a4577 100644 --- a/src/rest-client-v5.ts +++ b/src/rest-client-v5.ts @@ -601,7 +601,7 @@ export class RestClientV5 extends BaseRestClient { * Unified account covers: Spot / Linear contract / Options * Normal account covers: USDT perpetual / Inverse perpetual / Inverse futures */ - getExecutionListV5( + getExecutionList( params: GetExecutionListParamsV5 ): Promise>> { return this.getPrivate('/v5/execution/list', params); @@ -764,7 +764,7 @@ export class RestClientV5 extends BaseRestClient { nextPageCursor?: string; }> > { - return this.get('/v5/asset/exchange/order-record', params); + return this.getPrivate('/v5/asset/exchange/order-record', params); } /** @@ -870,7 +870,7 @@ export class RestClientV5 extends BaseRestClient { * Query the internal transfer records between different account types under the same UID. */ getInternalTransferRecords( - params: GetInternalTransferParamsV5 + params?: GetInternalTransferParamsV5 ): Promise>> { return this.getPrivate( '/v5/asset/transfer/query-inter-transfer-list', @@ -1014,7 +1014,10 @@ export class RestClientV5 extends BaseRestClient { getCoinInfo( coin?: string ): Promise> { - return this.get('/v5/asset/coin/query-info', coin ? { coin } : undefined); + return this.getPrivate( + '/v5/asset/coin/query-info', + coin ? { coin } : undefined + ); } /** diff --git a/test/response.util.ts b/test/response.util.ts index 36adaec..9b24a7f 100644 --- a/test/response.util.ts +++ b/test/response.util.ts @@ -1,13 +1,14 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { API_ERROR_CODE } from '../src'; -const SUCCESS_MSG_REGEX = /OK|SUCCESS|success|success\.|Request accepted|/gim; +export const SUCCESS_MSG_REGEX = + /OK|SUCCESS|success|success\.|Request accepted|/gim; export function successResponseList(successMsg: string | null = 'OK') { return { result: expect.any(Array), - ret_code: API_ERROR_CODE.SUCCESS, ret_msg: successMsg, + ret_code: API_ERROR_CODE.SUCCESS, }; } @@ -23,8 +24,8 @@ export function successResponseListV3() { export function successResponseObject() { return { result: expect.any(Object), - ret_code: API_ERROR_CODE.SUCCESS, ret_msg: expect.stringMatching(SUCCESS_MSG_REGEX), + ret_code: API_ERROR_CODE.SUCCESS, }; } diff --git a/test/rest-client-v5/private.read.test.ts b/test/rest-client-v5/private.read.test.ts new file mode 100644 index 0000000..d6009a8 --- /dev/null +++ b/test/rest-client-v5/private.read.test.ts @@ -0,0 +1,267 @@ +import { API_ERROR_CODE, RestClientV5 } from '../../src'; +import { SUCCESS_MSG_REGEX, successResponseObjectV3 } from '../response.util'; + +describe('Private V5 REST API Endpoints', () => { + const API_KEY = process.env.API_KEY_COM; + const API_SECRET = process.env.API_SECRET_COM; + + it('should have api credentials to test with', () => { + expect(API_KEY).toStrictEqual(expect.any(String)); + expect(API_SECRET).toStrictEqual(expect.any(String)); + }); + + const api = new RestClientV5({ + key: API_KEY, + secret: API_SECRET, + testnet: false, + }); + + const settleCoin = 'USDT'; + const linearSymbol = 'BTCUSDT'; + + describe('misc endpoints', () => { + it('fetchServerTime()', async () => { + expect(await api.fetchServerTime()).toEqual(expect.any(Number)); + }); + }); + + describe('Trade APIs', () => { + it('getActiveOrders()', async () => { + expect( + await api.getActiveOrders({ category: 'linear', settleCoin }) + ).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + + it('getHistoricOrders()', async () => { + expect(await api.getHistoricOrders({ category: 'linear' })).toMatchObject( + { ...successResponseObjectV3() } + ); + }); + + it('getSpotBorrowCheck()', async () => { + expect(await api.getSpotBorrowCheck(linearSymbol, 'Buy')).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + }); + + describe('Position APIs', () => { + it('getPositionInfo()', async () => { + expect( + await api.getPositionInfo({ category: 'linear', settleCoin }) + ).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + + it('getExecutionList()', async () => { + expect( + await api.getExecutionList({ category: 'linear', symbol: linearSymbol }) + ).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + + it('getClosedPnL()', async () => { + expect( + await api.getClosedPnL({ category: 'linear', symbol: linearSymbol }) + ).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + }); + + describe('Account APIs', () => { + it('getWalletBalance()', async () => { + expect( + await api.getWalletBalance({ accountType: 'CONTRACT' }) + ).toMatchObject({ ...successResponseObjectV3() }); + }); + + it('getBorrowHistory()', async () => { + expect(await api.getBorrowHistory()).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + + it('getCollateralInfo()', async () => { + expect(await api.getCollateralInfo()).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + + // Not available on this test account + it.skip('getCoinGreeks()', async () => { + expect(await api.getCoinGreeks()).toMatchObject({ + ...successResponseObjectV3(), + retMsg: '', + }); + }); + + it('getFeeRate()', async () => { + expect(await api.getFeeRate()).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + + // Fails on this test account, since it's not upgraded + it.skip('getAccountInfo()', async () => { + expect(await api.getAccountInfo()).toMatchObject({ + ...successResponseObjectV3(), + retMsg: '', + }); + }); + + it('getTransactionLog()', async () => { + expect(await api.getTransactionLog()).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + + // Not available on this test account + it.skip('getMMPState()', async () => { + expect(await api.getMMPState(settleCoin)).toMatchObject({ + ...successResponseObjectV3(), + retMsg: '', + }); + }); + }); + + describe('Asset APIs', () => { + it('getCoinExchangeRecords()', async () => { + expect(await api.getCoinExchangeRecords()).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + + it('getDeliveryRecord()', async () => { + expect(await api.getDeliveryRecord({ category: 'option' })).toMatchObject( + { ...successResponseObjectV3() } + ); + }); + + it('getSettlementRecords()', async () => { + expect( + await api.getSettlementRecords({ category: 'linear' }) + ).toMatchObject({ ...successResponseObjectV3() }); + }); + + it('getAssetInfo()', async () => { + expect(await api.getAssetInfo({ accountType: 'SPOT' })).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + + it('getAllCoinsBalance()', async () => { + expect( + await api.getAllCoinsBalance({ accountType: 'SPOT' }) + ).toMatchObject({ ...successResponseObjectV3() }); + }); + + it('getCoinBalance()', async () => { + expect( + await api.getCoinBalance({ accountType: 'SPOT', coin: settleCoin }) + ).toMatchObject({ ...successResponseObjectV3() }); + }); + + it('getTransferableCoinList()', async () => { + expect( + await api.getTransferableCoinList('SPOT', 'CONTRACT') + ).toMatchObject({ ...successResponseObjectV3() }); + }); + + it('getInternalTransferRecords()', async () => { + expect(await api.getInternalTransferRecords()).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + + it('getSubUID()', async () => { + expect(await api.getSubUID()).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + + it('getUniversalTransferRecords()', async () => { + expect(await api.getUniversalTransferRecords()).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + + it('getAllowedDepositCoinInfo()', async () => { + expect(await api.getAllowedDepositCoinInfo()).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + + it('getDepositRecords()', async () => { + expect(await api.getDepositRecords()).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + + it('getSubAccountDepositRecords()', async () => { + expect( + await api.getSubAccountDepositRecords({ subMemberId: 'fakeid' }) + ).toMatchObject({ + // ...successResponseObjectV3(), + // Expected, since sub account ID is fake + retCode: API_ERROR_CODE.PARAMS_MISSING_OR_WRONG, + }); + }); + + it('getMasterDepositAddress()', async () => { + expect(await api.getMasterDepositAddress(settleCoin)).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + + it('querySubMemberAddress()', async () => { + expect( + await api.querySubMemberAddress(settleCoin, 'TRC20', 'fakeid') + ).toMatchObject({ + // ...successResponseObjectV3(), + // Expected, since sub account ID is fake + retCode: API_ERROR_CODE.PARAMS_MISSING_OR_WRONG, + }); + }); + + it('getCoinInfo()', async () => { + expect(await api.getCoinInfo()).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + + it('getWithdrawalRecords()', async () => { + expect(await api.getWithdrawalRecords()).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + }); + + describe('User APIs', () => { + it('getSubUIDList()', async () => { + expect(await api.getSubUIDList()).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + + it('getQueryApiKey()', async () => { + expect(await api.getQueryApiKey()).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + }); + + describe('Spot Leverage Token APIs', () => { + it('getSpotLeveragedTokenOrderHistory()', async () => { + expect(await api.getSpotLeveragedTokenOrderHistory()).toMatchObject({ + // ...successResponseObjectV3(), + // retMsg: '', + retCode: API_ERROR_CODE.SPOT_LEVERAGE_TOKEN_ORDER_NOT_FOUND, + }); + }); + }); +}); From 9e2e1059614fe7440d9f62a6020517f69a184da0 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Mon, 20 Feb 2023 12:39:25 +0000 Subject: [PATCH 19/26] v3.5.0-beta.0: release with bumped node build version --- .nvmrc | 2 +- README.md | 9 +++++---- package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.nvmrc b/.nvmrc index cf00ddc..4a97274 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v12.18.1 \ No newline at end of file +v18.14.1 diff --git a/README.md b/README.md index ac082ac..2b0602a 100644 --- a/README.md +++ b/README.md @@ -66,14 +66,15 @@ Each REST API group has a dedicated REST client. To avoid confusion, here are th | Class | Description | |:------------------------------------------------------------------: |:----------------------------------------------------------------------------------------------------------------------------: | | [ **V5 API** ] | The new unified V5 APIs (successor to previously fragmented APIs for all API groups). To learn more about the V5 API, please read the [V5 upgrade guideline](https://bybit-exchange.github.io/docs/v5/upgrade-guide). | -| [RestClientV5](src/rest-client-v5.ts) | Coming soon... Unified V5 all-in-one REST client for all [V5 REST APIs](https://bybit-exchange.github.io/docs/v5/intro) | +| [RestClientV5](src/rest-client-v5.ts) | Unified V5 all-in-one REST client for all [V5 REST APIs](https://bybit-exchange.github.io/docs/v5/intro) | | [ **Derivatives v3** ] | The Derivatives v3 APIs (successor to the Futures V2 APIs) | | [UnifiedMarginClient](src/unified-margin-client.ts) | [Derivatives (v3) Unified Margin APIs](https://bybit-exchange.github.io/docs/derivatives/unified/place-order) | | [ContractClient](src/contract-client.ts) | [Derivatives (v3) Contract APIs](https://bybit-exchange.github.io/docs/derivatives/contract/place-order). | | [ **Futures v2** ] | The Futures v2 APIs | -| [InverseClient](src/inverse-client.ts) | [Inverse Perpetual Futures (v2) APIs](https://bybit-exchange.github.io/docs/futuresV2/inverse/) | -| [LinearClient](src/linear-client.ts) | [USDT Perpetual Futures (v2) APIs](https://bybit-exchange.github.io/docs/futuresV2/linear/#t-introduction) | -| [InverseFuturesClient](src/inverse-futures-client.ts) | [Inverse Futures (v2) APIs](https://bybit-exchange.github.io/docs/futuresV2/inverse_futures/#t-introduction) | +| Deprecated! ContractClient or RestClientV5 recommended | Please read the [V5 upgrade guideline](https://bybit-exchange.github.io/docs/v5/upgrade-guide) | +| [~InverseClient~](src/inverse-client.ts)| [Inverse Perpetual Futures (v2) APIs](https://bybit-exchange.github.io/docs/futuresV2/inverse/) | +| [~LinearClient~](src/linear-client.ts) | [USDT Perpetual Futures (v2) APIs](https://bybit-exchange.github.io/docs/futuresV2/linear/#t-introduction) | +| [~InverseFuturesClient~](src/inverse-futures-client.ts) | [Inverse Futures (v2) APIs](https://bybit-exchange.github.io/docs/futuresV2/inverse_futures/#t-introduction) | | [ **Spot** ] | The spot APIs | | [SpotClientV3](src/spot-client-v3.ts) | [Spot Market (v3) APIs](https://bybit-exchange.github.io/docs/spot/public/instrument) | | [~SpotClient~](src/spot-client.ts) (deprecated, SpotClientV3 recommended)| [Spot Market (v1) APIs](https://bybit-exchange.github.io/docs/spot/v1/#t-introduction) | diff --git a/package-lock.json b/package-lock.json index ab784f0..e3eaa06 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "bybit-api", - "version": "3.5.0", + "version": "3.5.0-beta.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "bybit-api", - "version": "3.5.0", + "version": "3.5.0-beta.0", "license": "MIT", "dependencies": { "axios": "^0.21.0", diff --git a/package.json b/package.json index 7c5e167..25bad6c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bybit-api", - "version": "3.5.0", + "version": "3.5.0-beta.0", "description": "Complete & robust node.js SDK for Bybit's REST APIs and WebSockets, with TypeScript & integration tests.", "main": "lib/index.js", "types": "lib/index.d.ts", From eeb0d63f0dd8c67ca27a845b1155e12a78f8a9a4 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Mon, 20 Feb 2023 16:19:56 +0000 Subject: [PATCH 20/26] add e2e tests for v5 REST client. Fix competing tests. --- README.md | 2 +- src/constants/enum.ts | 15 + src/rest-client-v5.ts | 3 + src/types/request/v5-asset.ts | 13 - src/types/request/v5-position.ts | 12 +- src/types/response/v5-asset.ts | 12 + test/contract/private.write.test.ts | 6 +- test/linear/private.write.test.ts | 10 +- test/rest-client-v5/private.read.test.ts | 4 +- test/rest-client-v5/private.write.test.ts | 448 ++++++++++++++++++++++ 10 files changed, 498 insertions(+), 27 deletions(-) create mode 100644 test/rest-client-v5/private.write.test.ts diff --git a/README.md b/README.md index 2b0602a..035831d 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Node.js SDK for the Bybit APIs and WebSockets: - Complete integration with all Bybit APIs. - TypeScript support (with type declarations for most API requests & responses). -- Over 300 end-to-end tests making real API calls & WebSocket connections, validating any changes before they reach npm. +- Over 450 end-to-end tests making real API calls & WebSocket connections, validating any changes before they reach npm. - Robust WebSocket integration with configurable connection heartbeats & automatic reconnect then resubscribe workflows. - Browser support (via webpack bundle - see "Browser Usage" below). diff --git a/src/constants/enum.ts b/src/constants/enum.ts index 61bdd42..95d363f 100644 --- a/src/constants/enum.ts +++ b/src/constants/enum.ts @@ -44,9 +44,20 @@ export const API_ERROR_CODE = { POSITION_MODE_NOT_MODIFIED: 30083, ISOLATED_NOT_MODIFIED: 30084, RISK_LIMIT_NOT_EXISTS: 30090, + SUB_USER_ALREADY_EXISTS: 31005, LEVERAGE_NOT_MODIFIED: 34036, SAME_SLTP_MODE: 37002, COPY_TRADE_NOT_OPEN_ORDER: 39426, + V5_ORDER_NOT_FOUND: 110001, + V5_INSUFFICIENT_BALANCE: 110007, + V5_API_KEY_PERMISSION_DENIED: 10005, + V5_CROSS_ISOLATED_MARGIN_NOT_CHANGED: 110026, + V5_LEVERAGE_NOT_CHANGED: 110043, + V5_MARGIN_MODE_NOT_CHANGED: 110073, + V5_TPSL_NOT_CHANGED: 10001, + V5_RISK_ID_NOT_CHANGED: 10001, + V5_AUTO_ADD_MARGIN_NOT_CHANGED: 10001, + V5_TPSL_ERROR_NO_POSITION: 10001, QTY_EXCEEDS_MAX_LIMIT: 130006, ORDER_NOT_FOUND_OR_TOO_LATE_LINEAR: 130010, ORDER_COST_NOT_AVAILABLE: 130021, @@ -56,6 +67,7 @@ export const API_ERROR_CODE = { AUTO_ADD_MARGIN_NOT_MODIFIED: 130060, INSUFFICIENT_BALANCE_FOR_ORDER_COST_LINEAR: 130080, SAME_SLTP_MODE_LINEAR: 130150, + TRANSFER_ID_EXISTS: 131214, RISK_ID_NOT_MODIFIED: 134026, CONTRACT_ORDER_NOT_EXISTS: 140001, CONTRACT_INSUFFICIENT_BALANCE: 140007, @@ -63,7 +75,10 @@ export const API_ERROR_CODE = { CONTRACT_MARGIN_MODE_NOT_MODIFIED: 140026, CONTRACT_RISK_LIMIT_INFO_NOT_EXISTS: 140031, CONTRACT_SET_LEVERAGE_NOT_MODIFIED: 140043, + SUB_USER_NOT_FOUND: 141009, SPOT_LEVERAGE_TOKEN_ORDER_NOT_FOUND: 175007, + SPOT_MARGIN_NOT_ENABLED: 176008, + SPOT_MARGIN_QUESTIONNAIRE_NOT_SUBMIT: 176037, /** E.g. USDC Options trading, trying to access a symbol that is no longer active */ CONTRACT_NAME_NOT_EXIST: 3100111, ORDER_NOT_EXIST: 3100136, diff --git a/src/rest-client-v5.ts b/src/rest-client-v5.ts index e3a4577..4063e44 100644 --- a/src/rest-client-v5.ts +++ b/src/rest-client-v5.ts @@ -489,6 +489,8 @@ export class RestClientV5 extends BaseRestClient { /** * Query real-time position data, such as position size, cumulative realizedPNL. * + * 0: cross margin. 1: isolated margin + * * Unified account covers: Linear contract / Options * * Normal account covers: USDT perpetual / Inverse perpetual / Inverse futures @@ -516,6 +518,7 @@ export class RestClientV5 extends BaseRestClient { /** * Select cross margin mode or isolated margin mode. + * 0: cross margin. 1: isolated margin * * Covers: USDT perpetual (Normal account) / Inverse contract (Normal account). * diff --git a/src/types/request/v5-asset.ts b/src/types/request/v5-asset.ts index 8867c03..bc4d271 100644 --- a/src/types/request/v5-asset.ts +++ b/src/types/request/v5-asset.ts @@ -71,18 +71,6 @@ export interface GetUniversalTransferRecordsParamsV5 { cursor?: string; } -export interface UniversalTransferRecordV5 { - transferId: string; - coin: string; - amount: string; - fromMemberId: string; - toMemberId: string; - fromAccountType: AccountTypeV5; - toAccountType: AccountTypeV5; - timestamp: string; - status: string; -} - export interface GetAllowedDepositCoinInfoParamsV5 { coin?: string; chain?: string; @@ -123,7 +111,6 @@ export interface WithdrawParamsV5 { address: string; tag?: string; amount: string; - timestamp: number; forceChain?: number; accountType?: 'SPOT' | 'FUND'; } diff --git a/src/types/request/v5-position.ts b/src/types/request/v5-position.ts index ae9f923..6b22a7e 100644 --- a/src/types/request/v5-position.ts +++ b/src/types/request/v5-position.ts @@ -1,4 +1,10 @@ -import { CategoryV5, ExecTypeV5, PositionIdx, TPSLModeV5 } from '../v5-shared'; +import { + CategoryV5, + ExecTypeV5, + OrderTriggerByV5, + PositionIdx, + TPSLModeV5, +} from '../v5-shared'; export interface PositionInfoParamsV5 { category: CategoryV5; @@ -50,8 +56,8 @@ export interface SetTradingStopParamsV5 { takeProfit?: string; stopLoss?: string; trailingStop?: string; - tpTriggerBy?: string; - slTriggerBy?: string; + tpTriggerBy?: OrderTriggerByV5; + slTriggerBy?: OrderTriggerByV5; activePrice?: string; tpSize?: string; slSize?: string; diff --git a/src/types/response/v5-asset.ts b/src/types/response/v5-asset.ts index a56d166..51a9b03 100644 --- a/src/types/response/v5-asset.ts +++ b/src/types/response/v5-asset.ts @@ -79,6 +79,18 @@ export interface InternalTransferRecordV5 { status: string; } +export interface UniversalTransferRecordV5 { + transferId: string; + coin: string; + amount: string; + fromMemberId: string; + toMemberId: string; + fromAccountType: AccountTypeV5; + toAccountType: AccountTypeV5; + timestamp: string; + status: string; +} + export interface AllowedDepositCoinInfoV5 { coin: string; chain: string; diff --git a/test/contract/private.write.test.ts b/test/contract/private.write.test.ts index 2145a58..c917f29 100644 --- a/test/contract/private.write.test.ts +++ b/test/contract/private.write.test.ts @@ -89,8 +89,8 @@ describe('Private Contract REST API POST Endpoints', () => { await api.setMarginSwitch({ symbol, tradeMode: 1, - buyLeverage: '5', - sellLeverage: '5', + buyLeverage: '10', + sellLeverage: '10', }) ).toMatchObject({ retCode: API_ERROR_CODE.CONTRACT_MARGIN_MODE_NOT_MODIFIED, @@ -116,7 +116,7 @@ describe('Private Contract REST API POST Endpoints', () => { }); it('setLeverage()', async () => { - expect(await api.setLeverage(symbol, '5', '5')).toMatchObject({ + expect(await api.setLeverage(symbol, '10', '10')).toMatchObject({ retCode: API_ERROR_CODE.CONTRACT_SET_LEVERAGE_NOT_MODIFIED, }); }); diff --git a/test/linear/private.write.test.ts b/test/linear/private.write.test.ts index 1fce947..e0acba8 100644 --- a/test/linear/private.write.test.ts +++ b/test/linear/private.write.test.ts @@ -138,8 +138,8 @@ describe('Private Linear REST API POST Endpoints', () => { await api.setMarginSwitch({ symbol, is_isolated: true, - buy_leverage: 5, - sell_leverage: 5, + buy_leverage: 10, + sell_leverage: 10, }) ).toMatchObject({ ret_code: API_ERROR_CODE.ISOLATED_NOT_MODIFIED_LINEAR, @@ -186,8 +186,8 @@ describe('Private Linear REST API POST Endpoints', () => { expect( await api.setUserLeverage({ symbol, - buy_leverage: 5, - sell_leverage: 5, + buy_leverage: 10, + sell_leverage: 10, }) ).toMatchObject({ ret_code: API_ERROR_CODE.LEVERAGE_NOT_MODIFIED, @@ -206,7 +206,7 @@ describe('Private Linear REST API POST Endpoints', () => { }); }); - it('setRiskLimit()', async () => { + it.skip('setRiskLimit()', async () => { expect( await api.setRiskLimit({ symbol, diff --git a/test/rest-client-v5/private.read.test.ts b/test/rest-client-v5/private.read.test.ts index d6009a8..c2d5cb6 100644 --- a/test/rest-client-v5/private.read.test.ts +++ b/test/rest-client-v5/private.read.test.ts @@ -1,7 +1,7 @@ import { API_ERROR_CODE, RestClientV5 } from '../../src'; -import { SUCCESS_MSG_REGEX, successResponseObjectV3 } from '../response.util'; +import { successResponseObjectV3 } from '../response.util'; -describe('Private V5 REST API Endpoints', () => { +describe('Private READ V5 REST API Endpoints', () => { const API_KEY = process.env.API_KEY_COM; const API_SECRET = process.env.API_SECRET_COM; diff --git a/test/rest-client-v5/private.write.test.ts b/test/rest-client-v5/private.write.test.ts new file mode 100644 index 0000000..efeb8cb --- /dev/null +++ b/test/rest-client-v5/private.write.test.ts @@ -0,0 +1,448 @@ +import { + API_ERROR_CODE, + OrderSideV5, + OrderTypeV5, + RestClientV5, +} from '../../src'; +import { successResponseObjectV3 } from '../response.util'; + +describe('Private WRITE V5 REST API Endpoints', () => { + const API_KEY = process.env.API_KEY_COM; + const API_SECRET = process.env.API_SECRET_COM; + + it('should have api credentials to test with', () => { + expect(API_KEY).toStrictEqual(expect.any(String)); + expect(API_SECRET).toStrictEqual(expect.any(String)); + }); + + const api = new RestClientV5({ + key: API_KEY, + secret: API_SECRET, + testnet: false, + }); + + const settleCoin = 'USDT'; + const linearSymbol = 'BTCUSDT'; + const orderType: OrderTypeV5 = 'Market'; + const orderSide: OrderSideV5 = 'Buy'; + const fakeOrderId = 'fakeOrderId'; + + const fakeTransferId = '42c0cfb0-6bca-c242-bc76-4e6df6cbcb16'; + + describe('misc endpoints', () => { + it('fetchServerTime()', async () => { + expect(await api.fetchServerTime()).toEqual(expect.any(Number)); + }); + }); + + describe('Trade APIs', () => { + it('submitOrder()', async () => { + expect( + await api.submitOrder({ + category: 'linear', + symbol: linearSymbol, + orderType: orderType, + side: orderSide, + qty: '1', + positionIdx: 1, + }) + ).toMatchObject({ + // ...successResponseObjectV3(), + // retMsg: '', + retCode: API_ERROR_CODE.V5_INSUFFICIENT_BALANCE, + }); + }); + + it('amendOrder()', async () => { + expect( + await api.amendOrder({ + category: 'linear', + symbol: linearSymbol, + qty: '2', + orderId: fakeOrderId, + }) + ).toMatchObject({ + // ...successResponseObjectV3(), + // retMsg: '', + retCode: API_ERROR_CODE.V5_ORDER_NOT_FOUND, + }); + }); + + it('cancelOrder()', async () => { + expect( + await api.cancelOrder({ + category: 'linear', + symbol: linearSymbol, + orderId: fakeOrderId, + }) + ).toMatchObject({ + // ...successResponseObjectV3(), + // retMsg: '', + retCode: API_ERROR_CODE.V5_ORDER_NOT_FOUND, + }); + }); + + it('cancelAllOrders()', async () => { + expect( + await api.cancelAllOrders({ + category: 'linear', + settleCoin: settleCoin, + }) + ).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + + it('batchSubmitOrders()', async () => { + expect( + await api.batchSubmitOrders('option', [ + { + orderLinkId: 'customOrderId1', + orderType: orderType, + qty: '1', + side: orderSide, + symbol: linearSymbol, + }, + { + orderLinkId: 'customOrderId2', + orderType: orderType, + qty: '2', + side: orderSide, + symbol: linearSymbol, + }, + ]) + ).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + + it('batchAmendOrders()', async () => { + expect( + await api.batchAmendOrders('option', [ + { + orderLinkId: 'customOrderId1', + qty: '3', + symbol: linearSymbol, + }, + { + orderLinkId: 'customOrderId2', + qty: '4', + symbol: linearSymbol, + }, + ]) + ).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + + it('batchCancelOrders()', async () => { + expect( + await api.batchCancelOrders('option', [ + { + orderLinkId: 'customOrderId1', + symbol: linearSymbol, + }, + { + orderLinkId: 'customOrderId2', + symbol: linearSymbol, + }, + ]) + ).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + + it('setDisconnectCancelAllWindow()', async () => { + expect(await api.setDisconnectCancelAllWindow('option', 5)).toMatchObject( + { + // ...successResponseObjectV3(), + // retMsg: '', + retCode: API_ERROR_CODE.V5_API_KEY_PERMISSION_DENIED, + } + ); + }); + }); + + describe('Position APIs', () => { + it('setLeverage()', async () => { + expect( + await api.setLeverage({ + category: 'linear', + buyLeverage: '10', + sellLeverage: '10', + symbol: linearSymbol, + }) + ).toMatchObject({ + // ...successResponseObjectV3(), + // retMsg: '', + retCode: API_ERROR_CODE.V5_LEVERAGE_NOT_CHANGED, + }); + }); + + it('switchIsolatedMargin()', async () => { + expect( + await api.switchIsolatedMargin({ + category: 'linear', + buyLeverage: '10', + sellLeverage: '10', + symbol: linearSymbol, + // isolated + tradeMode: 1, + }) + ).toMatchObject({ + // ...successResponseObjectV3(), + // retMsg: '', + retCode: API_ERROR_CODE.V5_CROSS_ISOLATED_MARGIN_NOT_CHANGED, + }); + }); + + it('setTPSLMode()', async () => { + expect( + await api.setTPSLMode({ + category: 'linear', + symbol: linearSymbol, + tpSlMode: 'Full', + }) + ).toMatchObject({ + // ...successResponseObjectV3(), + // retMsg: '', + retCode: API_ERROR_CODE.V5_TPSL_NOT_CHANGED, + }); + }); + + it('switchPositionMode()', async () => { + expect( + await api.switchPositionMode({ + category: 'linear', + // both sides + mode: 3, + coin: settleCoin, + }) + ).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + + it('setRiskLimit()', async () => { + expect( + await api.setRiskLimit({ + category: 'linear', + positionIdx: 1, + riskId: 1, + symbol: linearSymbol, + }) + ).toMatchObject({ + // ...successResponseObjectV3(), + // retMsg: '', + retCode: API_ERROR_CODE.V5_RISK_ID_NOT_CHANGED, + }); + }); + + it('setTradingStop()', async () => { + expect( + await api.setTradingStop({ + category: 'linear', + positionIdx: 1, + symbol: linearSymbol, + slSize: '100', + slTriggerBy: 'LastPrice', + stopLoss: '25000', + }) + ).toMatchObject({ + // ...successResponseObjectV3(), + // retMsg: '', + retCode: API_ERROR_CODE.V5_TPSL_ERROR_NO_POSITION, + }); + }); + + it('setAutoAddMargin()', async () => { + expect( + await api.setAutoAddMargin({ + category: 'linear', + autoAddMargin: 0, + symbol: linearSymbol, + positionIdx: 0, + }) + ).toMatchObject({ + // ...successResponseObjectV3(), + // retMsg: '', + retCode: API_ERROR_CODE.V5_AUTO_ADD_MARGIN_NOT_CHANGED, + }); + }); + }); + + describe('Account APIs', () => { + it('setMarginMode()', async () => { + expect(await api.setMarginMode('REGULAR_MARGIN')).toMatchObject({ + // ...successResponseObjectV3(), + // retMsg: '', + retCode: API_ERROR_CODE.V5_MARGIN_MODE_NOT_CHANGED, + }); + }); + + it('setMMP()', async () => { + expect( + await api.setMMP({ + baseCoin: settleCoin, + deltaLimit: '1', + frozenPeriod: '1', + qtyLimit: '1', + window: '1', + }) + ).toMatchObject({ + // ...successResponseObjectV3(), + // retMsg: '', + retCode: API_ERROR_CODE.INSTITION_MMP_PROFILE_NOT_FOUND, + }); + }); + + it.skip('resetMMP()', async () => { + expect(await api.resetMMP(settleCoin)).toMatchObject({ + ...successResponseObjectV3(), + retMsg: '', + retCode: 3500715, + // Contacted bybit for info + // + "retMsg": "Parameter window cannot be empty.", + }); + }); + }); + + describe('Asset APIs', () => { + it('createInternalTransfer()', async () => { + expect( + await api.createInternalTransfer( + fakeTransferId, + settleCoin, + '100', + 'SPOT', + 'CONTRACT' + ) + ).toMatchObject({ + // ...successResponseObjectV3(), + // retMsg: '', + retCode: API_ERROR_CODE.TRANSFER_ID_EXISTS, + }); + }); + + it('enableUniversalTransferForSubUIDs()', async () => { + expect(await api.enableUniversalTransferForSubUIDs([])).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + + it('createUniversalTransfer()', async () => { + expect( + await api.createUniversalTransfer({ + amount: '100', + coin: settleCoin, + fromAccountType: 'SPOT', + fromMemberId: 1, + toAccountType: 'CONTRACT', + toMemberId: 2, + transferId: fakeTransferId, + }) + ).toMatchObject({ + // ...successResponseObjectV3(), + // retMsg: '', + retCode: API_ERROR_CODE.TRANSFER_ID_EXISTS, + }); + }); + + it('submitWithdrawal()', async () => { + expect( + await api.submitWithdrawal({ + address: '0x000000', + amount: '100', + chain: 'TRC20', + coin: settleCoin, + }) + ).toMatchObject({ + // ...successResponseObjectV3(), + // retMsg: '', + retCode: API_ERROR_CODE.INCORRECT_API_KEY_PERMISSIONS, + }); + }); + + it('cancelWithdrawal()', async () => { + expect(await api.cancelWithdrawal('fakeId')).toMatchObject({ + // ...successResponseObjectV3(), + // retMsg: '', + retCode: API_ERROR_CODE.INCORRECT_API_KEY_PERMISSIONS, + }); + }); + }); + + describe('User APIs', () => { + it('createSubMember()', async () => { + expect( + await api.createSubMember({ + memberType: 1, + username: 'sub1account', + switch: 1, + note: 'created via e2e test', + }) + ).toMatchObject({ + // ...successResponseObjectV3(), + // retMsg: '', + retCode: API_ERROR_CODE.SUB_USER_ALREADY_EXISTS, + }); + }); + + it('setSubUIDFrozenState()', async () => { + expect(await api.setSubUIDFrozenState(0, 1)).toMatchObject({ + // ...successResponseObjectV3(), + // retMsg: '', + retCode: API_ERROR_CODE.SUB_USER_NOT_FOUND, + }); + }); + }); + + // Not currently working. In touch with bybit. + describe.skip('Spot Leverage Token APIs', () => { + it('purchaseSpotLeveragedToken()', async () => { + expect( + await api.purchaseSpotLeveragedToken({ + ltAmount: '100', + ltCoin: 'EOS3L', + serialNo: 'purchase-001', + }) + ).toMatchObject({ + // ...successResponseObjectV3(), + retCode: 0, + retMsg: '', + }); + }); + + it('redeemSpotLeveragedToken()', async () => { + expect( + await api.redeemSpotLeveragedToken({ + quantity: '100', + ltCoin: 'EOS3L', + serialNo: 'redeem-001', + }) + ).toMatchObject({ + // ...successResponseObjectV3(), + retCode: 0, + retMsg: '', + }); + }); + }); + + describe('Spot Margin APIs', () => { + it('toggleSpotMarginTrade()', async () => { + expect(await api.toggleSpotMarginTrade('1')).toMatchObject({ + // ...successResponseObjectV3(), + // retMsg: '', + retCode: API_ERROR_CODE.SPOT_MARGIN_QUESTIONNAIRE_NOT_SUBMIT, + }); + }); + + it('setSpotMarginLeverage()', async () => { + expect(await api.setSpotMarginLeverage('2')).toMatchObject({ + // ...successResponseObjectV3(), + // retMsg: '', + retCode: API_ERROR_CODE.SPOT_MARGIN_NOT_ENABLED, + }); + }); + }); +}); From 860e2561a13870ee06c5b595501558fc54e36484 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Mon, 20 Feb 2023 16:24:35 +0000 Subject: [PATCH 21/26] relax noisy test --- test/rest-client-v5/private.write.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/rest-client-v5/private.write.test.ts b/test/rest-client-v5/private.write.test.ts index efeb8cb..01d6ea3 100644 --- a/test/rest-client-v5/private.write.test.ts +++ b/test/rest-client-v5/private.write.test.ts @@ -320,7 +320,7 @@ describe('Private WRITE V5 REST API Endpoints', () => { ).toMatchObject({ // ...successResponseObjectV3(), // retMsg: '', - retCode: API_ERROR_CODE.TRANSFER_ID_EXISTS, + retCode: expect.any(Number), }); }); @@ -344,7 +344,7 @@ describe('Private WRITE V5 REST API Endpoints', () => { ).toMatchObject({ // ...successResponseObjectV3(), // retMsg: '', - retCode: API_ERROR_CODE.TRANSFER_ID_EXISTS, + retCode: expect.any(Number), }); }); From bf602c8d588ecff98252d5da0e21a0207b1184d9 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Tue, 21 Feb 2023 12:31:40 +0000 Subject: [PATCH 22/26] fix tests and incorrect v5 endpoint --- src/constants/enum.ts | 1 + src/rest-client-v5.ts | 2 +- src/util/BaseRestClient.ts | 12 +- test/rest-client-v5/private.read.test.ts | 4 +- test/rest-client-v5/private.write.test.ts | 152 ++++++++++++---------- test/spot/private.v3.read.test.ts | 3 +- 6 files changed, 94 insertions(+), 80 deletions(-) diff --git a/src/constants/enum.ts b/src/constants/enum.ts index 95d363f..8ea22a0 100644 --- a/src/constants/enum.ts +++ b/src/constants/enum.ts @@ -76,6 +76,7 @@ export const API_ERROR_CODE = { CONTRACT_RISK_LIMIT_INFO_NOT_EXISTS: 140031, CONTRACT_SET_LEVERAGE_NOT_MODIFIED: 140043, SUB_USER_NOT_FOUND: 141009, + SPOT_LEVERAGE_TOKEN_INSUFFICIENT_BALANCE: 175006, SPOT_LEVERAGE_TOKEN_ORDER_NOT_FOUND: 175007, SPOT_MARGIN_NOT_ENABLED: 176008, SPOT_MARGIN_QUESTIONNAIRE_NOT_SUBMIT: 176037, diff --git a/src/rest-client-v5.ts b/src/rest-client-v5.ts index 4063e44..58d4c0a 100644 --- a/src/rest-client-v5.ts +++ b/src/rest-client-v5.ts @@ -738,7 +738,7 @@ export class RestClientV5 extends BaseRestClient { * Once the mmp triggered, you can unfreeze the account via this endpoint */ resetMMP(baseCoin: string): Promise> { - return this.postPrivate('/v5/account/mmp-modify', { baseCoin }); + return this.postPrivate('/v5/account/mmp-reset', { baseCoin }); } /** diff --git a/src/util/BaseRestClient.ts b/src/util/BaseRestClient.ts index 708de7f..47051fb 100644 --- a/src/util/BaseRestClient.ts +++ b/src/util/BaseRestClient.ts @@ -62,7 +62,7 @@ interface UnsignedRequest { paramsWithSign: T; } -type SignMethod = 'keyInBody' | 'usdc'; +type SignMethod = 'v2auth' | 'v5auth'; export default abstract class BaseRestClient { private timeOffset: number | null = null; @@ -233,7 +233,7 @@ export default abstract class BaseRestClient { const signResult = await this.prepareSignParams( method, - 'usdc', + 'v5auth', params, isPublicApi ); @@ -245,11 +245,9 @@ export default abstract class BaseRestClient { options.headers['X-BAPI-RECV-WINDOW'] = signResult.recvWindow; if (method === 'GET') { - // const serialisedParams = signResult.serializedParams; return { ...options, params: signResult.originalParams, - // url: url + (serialisedParams ? '?' + serialisedParams : ''), }; } @@ -261,7 +259,7 @@ export default abstract class BaseRestClient { const signResult = await this.prepareSignParams( method, - 'keyInBody', + 'v2auth', params, isPublicApi ); @@ -376,7 +374,7 @@ export default abstract class BaseRestClient { res.recvWindow = recvWindow; // usdc is different for some reason - if (signMethod === 'usdc') { + if (signMethod === 'v5auth') { const sortProperties = false; const signRequestParams = method === 'GET' @@ -397,7 +395,7 @@ export default abstract class BaseRestClient { } // spot/v2 derivatives - if (signMethod === 'keyInBody') { + if (signMethod === 'v2auth') { res.originalParams.api_key = key; res.originalParams.timestamp = timestamp; diff --git a/test/rest-client-v5/private.read.test.ts b/test/rest-client-v5/private.read.test.ts index c2d5cb6..27fd537 100644 --- a/test/rest-client-v5/private.read.test.ts +++ b/test/rest-client-v5/private.read.test.ts @@ -258,9 +258,7 @@ describe('Private READ V5 REST API Endpoints', () => { describe('Spot Leverage Token APIs', () => { it('getSpotLeveragedTokenOrderHistory()', async () => { expect(await api.getSpotLeveragedTokenOrderHistory()).toMatchObject({ - // ...successResponseObjectV3(), - // retMsg: '', - retCode: API_ERROR_CODE.SPOT_LEVERAGE_TOKEN_ORDER_NOT_FOUND, + ...successResponseObjectV3(), }); }); }); diff --git a/test/rest-client-v5/private.write.test.ts b/test/rest-client-v5/private.write.test.ts index 01d6ea3..8e56efc 100644 --- a/test/rest-client-v5/private.write.test.ts +++ b/test/rest-client-v5/private.write.test.ts @@ -1,5 +1,6 @@ import { API_ERROR_CODE, + LeverageTokenInfoV5, OrderSideV5, OrderTypeV5, RestClientV5, @@ -93,62 +94,74 @@ describe('Private WRITE V5 REST API Endpoints', () => { }); }); - it('batchSubmitOrders()', async () => { - expect( - await api.batchSubmitOrders('option', [ - { - orderLinkId: 'customOrderId1', - orderType: orderType, - qty: '1', - side: orderSide, - symbol: linearSymbol, - }, - { - orderLinkId: 'customOrderId2', - orderType: orderType, - qty: '2', - side: orderSide, - symbol: linearSymbol, - }, - ]) - ).toMatchObject({ - ...successResponseObjectV3(), + describe('options only methods', () => { + // These should use a real symbol from the options category + let optionsSymbol: string; + beforeAll(async () => { + const deliveryPriceResponse = await api.getOptionDeliveryPrice({ + category: 'option', + }); + const resultsList = deliveryPriceResponse.result.list; + optionsSymbol = resultsList[0].symbol; }); - }); - it('batchAmendOrders()', async () => { - expect( - await api.batchAmendOrders('option', [ - { - orderLinkId: 'customOrderId1', - qty: '3', - symbol: linearSymbol, - }, - { - orderLinkId: 'customOrderId2', - qty: '4', - symbol: linearSymbol, - }, - ]) - ).toMatchObject({ - ...successResponseObjectV3(), + it('batchSubmitOrders()', async () => { + expect( + await api.batchSubmitOrders('option', [ + { + orderLinkId: 'customOrderId1', + orderType: orderType, + qty: '1', + side: orderSide, + symbol: optionsSymbol, + }, + { + orderLinkId: 'customOrderId2', + orderType: orderType, + qty: '2', + side: orderSide, + symbol: optionsSymbol, + }, + ]) + ).toMatchObject({ + ...successResponseObjectV3(), + }); }); - }); - it('batchCancelOrders()', async () => { - expect( - await api.batchCancelOrders('option', [ - { - orderLinkId: 'customOrderId1', - symbol: linearSymbol, - }, - { - orderLinkId: 'customOrderId2', - symbol: linearSymbol, - }, - ]) - ).toMatchObject({ - ...successResponseObjectV3(), + it('batchAmendOrders()', async () => { + expect( + await api.batchAmendOrders('option', [ + { + orderLinkId: 'customOrderId1', + qty: '3', + symbol: optionsSymbol, + }, + { + orderLinkId: 'customOrderId2', + qty: '4', + symbol: optionsSymbol, + }, + ]) + ).toMatchObject({ + ...successResponseObjectV3(), + }); + }); + + it('batchCancelOrders()', async () => { + expect( + await api.batchCancelOrders('option', [ + { + orderLinkId: 'customOrderId1', + symbol: optionsSymbol, + }, + { + orderLinkId: 'customOrderId2', + symbol: optionsSymbol, + }, + ]) + ).toMatchObject({ + ...successResponseObjectV3(), + }); }); }); @@ -296,13 +309,11 @@ describe('Private WRITE V5 REST API Endpoints', () => { }); }); - it.skip('resetMMP()', async () => { + it('resetMMP()', async () => { expect(await api.resetMMP(settleCoin)).toMatchObject({ - ...successResponseObjectV3(), - retMsg: '', - retCode: 3500715, - // Contacted bybit for info - // + "retMsg": "Parameter window cannot be empty.", + // ...successResponseObjectV3(), + // retMsg: '', + retCode: API_ERROR_CODE.INSTITION_MMP_PROFILE_NOT_FOUND, }); }); }); @@ -397,18 +408,24 @@ describe('Private WRITE V5 REST API Endpoints', () => { }); }); - // Not currently working. In touch with bybit. - describe.skip('Spot Leverage Token APIs', () => { - it('purchaseSpotLeveragedToken()', async () => { + describe('Spot Leverage Token APIs', () => { + let leverageToken: LeverageTokenInfoV5; + + beforeAll(async () => { + const tokenResult = await api.getLeveragedTokenInfo(); + leverageToken = tokenResult.result.list[0]; + }); + + // Still failing - in contact with bybit + it.skip('purchaseSpotLeveragedToken()', async () => { expect( await api.purchaseSpotLeveragedToken({ ltAmount: '100', - ltCoin: 'EOS3L', - serialNo: 'purchase-001', + ltCoin: leverageToken.ltCoin, }) ).toMatchObject({ // ...successResponseObjectV3(), - retCode: 0, + retCode: API_ERROR_CODE.SPOT_LEVERAGE_TOKEN_INSUFFICIENT_BALANCE, retMsg: '', }); }); @@ -417,13 +434,12 @@ describe('Private WRITE V5 REST API Endpoints', () => { expect( await api.redeemSpotLeveragedToken({ quantity: '100', - ltCoin: 'EOS3L', - serialNo: 'redeem-001', + ltCoin: leverageToken.ltCoin, }) ).toMatchObject({ // ...successResponseObjectV3(), - retCode: 0, - retMsg: '', + retCode: API_ERROR_CODE.SPOT_LEVERAGE_TOKEN_INSUFFICIENT_BALANCE, + // retMsg: '', }); }); }); diff --git a/test/spot/private.v3.read.test.ts b/test/spot/private.v3.read.test.ts index ee59dc0..3994773 100644 --- a/test/spot/private.v3.read.test.ts +++ b/test/spot/private.v3.read.test.ts @@ -82,7 +82,8 @@ describe('Private Spot REST API GET Endpoints', () => { it('getLeveragedTokenPRHistory()', async () => { expect(await api.getLeveragedTokenPRHistory()).toMatchObject({ - retCode: API_ERROR_CODE.ORDER_NOT_FOUND_LEVERAGED_TOKEN, + ...successResponseObjectV3(), + // retCode: API_ERROR_CODE.ORDER_NOT_FOUND_LEVERAGED_TOKEN, }); }); From 6d243170229dcdf2fc349b81d8e2c5405ceb2b8e Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Tue, 21 Feb 2023 12:48:12 +0000 Subject: [PATCH 23/26] move test to v5 folder --- .gitignore | 3 ++- test/{rest-client-v5 => v5}/private.read.test.ts | 0 test/{rest-client-v5 => v5}/private.write.test.ts | 0 test/{rest-client-v5 => v5}/public.read.test.ts | 0 4 files changed, 2 insertions(+), 1 deletion(-) rename test/{rest-client-v5 => v5}/private.read.test.ts (100%) rename test/{rest-client-v5 => v5}/private.write.test.ts (100%) rename test/{rest-client-v5 => v5}/public.read.test.ts (100%) diff --git a/.gitignore b/.gitignore index 33326b4..b7cab4a 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,5 @@ node_modules/ .cache lib bundleReport.html -.history/ \ No newline at end of file +.history/ +rawReq.ts diff --git a/test/rest-client-v5/private.read.test.ts b/test/v5/private.read.test.ts similarity index 100% rename from test/rest-client-v5/private.read.test.ts rename to test/v5/private.read.test.ts diff --git a/test/rest-client-v5/private.write.test.ts b/test/v5/private.write.test.ts similarity index 100% rename from test/rest-client-v5/private.write.test.ts rename to test/v5/private.write.test.ts diff --git a/test/rest-client-v5/public.read.test.ts b/test/v5/public.read.test.ts similarity index 100% rename from test/rest-client-v5/public.read.test.ts rename to test/v5/public.read.test.ts From 00a45e4cd0e67860628a3fd631f0543b697d9c65 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Tue, 21 Feb 2023 13:30:25 +0000 Subject: [PATCH 24/26] fix spot leverage token endpoint v5 --- examples/rest-v5-private.ts | 26 +++++++++++++++++---- src/constants/enum.ts | 1 + src/types/request/v5-spot-leverage-token.ts | 2 +- test/v5/private.write.test.ts | 9 ++++--- 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/examples/rest-v5-private.ts b/examples/rest-v5-private.ts index bc66ec1..c38701d 100644 --- a/examples/rest-v5-private.ts +++ b/examples/rest-v5-private.ts @@ -7,20 +7,38 @@ const key = process.env.API_KEY_COM; const secret = process.env.API_SECRET_COM; const client = new RestClientV5({ - key, - secret, - strict_param_validation: true, + key: key, + secret: secret, }); (async () => { try { - /** Simple example for a private REST API call with bybit's V5 REST APIs */ + /** Simple examples for private REST API calls with bybit's V5 REST APIs */ const response = await client.getPositionInfo({ category: 'option', symbol: 'BTCUSDT', }); console.log('response:', response); + + // Trade USDT linear perps + const buyOrderResult = await client.submitOrder({ + category: 'linear', + symbol: 'BTCUSDT', + orderType: 'Market', + qty: '1', + side: 'Buy', + }); + console.log('buyOrderResult:', buyOrderResult); + + const sellOrderResult = await client.submitOrder({ + category: 'linear', + symbol: 'BTCUSDT', + orderType: 'Market', + qty: '1', + side: 'Sell', + }); + console.log('sellOrderResult:', sellOrderResult); } catch (e) { console.error('request failed: ', e); } diff --git a/src/constants/enum.ts b/src/constants/enum.ts index 8ea22a0..8ade830 100644 --- a/src/constants/enum.ts +++ b/src/constants/enum.ts @@ -78,6 +78,7 @@ export const API_ERROR_CODE = { SUB_USER_NOT_FOUND: 141009, SPOT_LEVERAGE_TOKEN_INSUFFICIENT_BALANCE: 175006, SPOT_LEVERAGE_TOKEN_ORDER_NOT_FOUND: 175007, + SPOT_LEVERAGE_QUIZ_REQUIRED: 175010, SPOT_MARGIN_NOT_ENABLED: 176008, SPOT_MARGIN_QUESTIONNAIRE_NOT_SUBMIT: 176037, /** E.g. USDC Options trading, trying to access a symbol that is no longer active */ diff --git a/src/types/request/v5-spot-leverage-token.ts b/src/types/request/v5-spot-leverage-token.ts index 189f5fd..b60e306 100644 --- a/src/types/request/v5-spot-leverage-token.ts +++ b/src/types/request/v5-spot-leverage-token.ts @@ -2,7 +2,7 @@ import { LTOrderTypeV5 } from '../v5-shared'; export interface PurchaseSpotLeveragedTokenParamsV5 { ltCoin: string; - ltAmount: string; + amount: string; serialNo?: string; } diff --git a/test/v5/private.write.test.ts b/test/v5/private.write.test.ts index 8e56efc..cd3b958 100644 --- a/test/v5/private.write.test.ts +++ b/test/v5/private.write.test.ts @@ -416,17 +416,16 @@ describe('Private WRITE V5 REST API Endpoints', () => { leverageToken = tokenResult.result.list[0]; }); - // Still failing - in contact with bybit - it.skip('purchaseSpotLeveragedToken()', async () => { + it('purchaseSpotLeveragedToken()', async () => { expect( await api.purchaseSpotLeveragedToken({ - ltAmount: '100', + amount: '100', ltCoin: leverageToken.ltCoin, }) ).toMatchObject({ // ...successResponseObjectV3(), - retCode: API_ERROR_CODE.SPOT_LEVERAGE_TOKEN_INSUFFICIENT_BALANCE, - retMsg: '', + retCode: API_ERROR_CODE.SPOT_LEVERAGE_QUIZ_REQUIRED, + // retMsg: '', }); }); From a786da23e3d34e11816e8dd941264fc103796259 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Thu, 23 Feb 2023 12:07:54 +0000 Subject: [PATCH 25/26] v3.5.0: release V5 REST client for bybit --- README.md | 25 +++++++++++++--------- examples/rest-v5-all.ts | 46 +++++++++++++++++++++++++++++++++++++++++ package.json | 4 ++-- 3 files changed, 63 insertions(+), 12 deletions(-) create mode 100644 examples/rest-v5-all.ts diff --git a/README.md b/README.md index 035831d..b4f3b95 100644 --- a/README.md +++ b/README.md @@ -43,9 +43,9 @@ Check out my related projects: ## Documentation -Most methods accept JS objects. These can be populated using parameters specified by Bybit's API documentation, or check the type definition in each class within this repository (see table below for convenient links to each class). +Most methods accept JS objects. These can be populated using parameters specified by Bybit's API documentation, or check the type definition in each class within the github repository (see table below for convenient links to each class). -- [Bybit API Docs (choose API category from the tabs at the top)](https://bybit-exchange.github.io/docs/futuresV2/inverse/#t-introduction). +- [Bybit API Docs (choose API category from the tabs at the top)](https://bybit-exchange.github.io/docs/v5/intro). ## Structure @@ -62,7 +62,11 @@ The version on npm is the output from the `build` command and can be used in pro ## REST API Clients -Each REST API group has a dedicated REST client. To avoid confusion, here are the available REST clients and the corresponding API groups: +Bybit has several API groups (originally one per product). Each generation is labelled with the version number (e.g. v1/v2/v3/v5). Some of the newer API groups can only be used by upgrading your account to the unified account, but doing so will prevent you from using the V1 and V2 APIs. + +Refer to the [V5 upgrade guide](https://bybit-exchange.github.io/docs/v5/upgrade-guide) for more information on requirements to use each API group. If you have a choice, you should use the newest generation that is available (e.g. use the V5 instead of the V3 APIs if you can). + +Here are the available REST clients and the corresponding API groups described in the documentation: | Class | Description | |:------------------------------------------------------------------: |:----------------------------------------------------------------------------------------------------------------------------: | | [ **V5 API** ] | The new unified V5 APIs (successor to previously fragmented APIs for all API groups). To learn more about the V5 API, please read the [V5 upgrade guideline](https://bybit-exchange.github.io/docs/v5/upgrade-guide). | @@ -110,13 +114,13 @@ const { InverseClient, LinearClient, InverseFuturesClient, - SpotClient, SpotClientV3, UnifiedMarginClient, USDCOptionClient, USDCPerpetualClient, AccountAssetClient, CopyTradingClient, + RestClientV5, } = require('bybit-api'); const restClientOptions = { @@ -155,7 +159,7 @@ const API_KEY = 'xxx'; const API_SECRET = 'yyy'; const useTestnet = false; -const client = new InverseClient({ +const client = new RestClientV5({ key: API_KEY, secret: API_SECRET, testnet: useTestnet @@ -164,17 +168,17 @@ const client = new InverseClient({ ); // For public-only API calls, simply don't provide a key & secret or set them to undefined -// const client = new InverseClient({}); +// const client = new RestClientV5({}); -client.getApiKeyInfo() +client.getAccountInfo() .then(result => { - console.log("getApiKeyInfo result: ", result); + console.log("getAccountInfo result: ", result); }) .catch(err => { - console.error("getApiKeyInfo error: ", err); + console.error("getAccountInfo error: ", err); }); -client.getOrderBook({ symbol: 'BTCUSD' }) +client.getOrderbook({ category: 'linear', symbol: 'BTCUSD' }) .then(result => { console.log("getOrderBook result: ", result); }) @@ -202,6 +206,7 @@ The WebsocketClient can be configured to a specific API group using the market p | USDC Options | `market: 'usdcOption'`| The [USDC options](https://bybit-exchange.github.io/docs/usdc/option/#t-websocket) category. | | Contract v3 USDT | `market: 'contractUSDT'`| The [Contract V3](https://bybit-exchange.github.io/docs/derivativesV3/contract/#t-websocket) category (USDT perps) | | Contract v3 Inverse | `market: 'contractInverse'`| The [Contract V3](https://bybit-exchange.github.io/docs/derivativesV3/contract/#t-websocket) category (inverse perps) | +| V5 Subscriptions | Coming soon | The [v5](https://bybit-exchange.github.io/docs/v5/ws/connect) websockets will be supported in the next release. | ```javascript const { WebsocketClient } = require('bybit-api'); diff --git a/examples/rest-v5-all.ts b/examples/rest-v5-all.ts new file mode 100644 index 0000000..a64d178 --- /dev/null +++ b/examples/rest-v5-all.ts @@ -0,0 +1,46 @@ +import { RestClientV5 } from '../src/index'; + +// or +// import { RestClientV5 } from 'bybit-api'; + +const key = process.env.API_KEY_COM; +const secret = process.env.API_SECRET_COM; + +const client = new RestClientV5({ + key: key, + secret: secret, +}); + +/** + * If you don't plan on making any private api calls, + * you can instance the REST client without any parameters: + * + * const client = new RestClientV5(); + */ + +(async () => { + try { + const klineResult = await client.getKline({ + category: 'linear', + interval: '15', + symbol: 'BTCUSDT', + }); + console.log('klineResult: ', klineResult); + + const markPriceKlineResult = await client.getMarkPriceKline({ + category: 'linear', + interval: '15', + symbol: 'BTCUSDT', + }); + console.log('markPriceKlineResult: ', markPriceKlineResult); + + const indexPriceKline = await client.getIndexPriceKline({ + category: 'linear', + interval: '15', + symbol: 'BTCUSDT', + }); + console.log('indexPriceKline: ', indexPriceKline); + } catch (e) { + console.error('request failed: ', e); + } +})(); diff --git a/package.json b/package.json index 25bad6c..e5089fb 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "bybit-api", - "version": "3.5.0-beta.0", - "description": "Complete & robust node.js SDK for Bybit's REST APIs and WebSockets, with TypeScript & integration tests.", + "version": "3.5.0", + "description": "Complete & robust Node.js SDK for Bybit's REST APIs and WebSockets, with TypeScript & strong end to end tests.", "main": "lib/index.js", "types": "lib/index.d.ts", "files": [ From caf205fe3395a84f78b5d418183f07809b43ed43 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Thu, 23 Feb 2023 12:15:47 +0000 Subject: [PATCH 26/26] v3.5.0: release v5 rest client for bybit APIs --- src/rest-client-v5.ts | 24 +++++++++++++----------- src/types/request/v5-market.ts | 2 +- src/types/response/v5-trade.ts | 10 +++++----- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/rest-client-v5.ts b/src/rest-client-v5.ts index 58d4c0a..4128779 100644 --- a/src/rest-client-v5.ts +++ b/src/rest-client-v5.ts @@ -12,12 +12,12 @@ import { ApiKeyInfoV5, AssetInfoV5, BatchAmendOrderParamsV5, - BatchAmendOrderResult, + BatchAmendOrderResultV5, BatchCancelOrderParamsV5, - BatchCancelOrderResult, + BatchCancelOrderResultV5, + BatchCreateOrderResultV5, BatchOrderParamsV5, - BatchOrderResult, - BatchOrdersResult, + BatchOrdersResponseV5, BorrowHistoryRecordV5, CancelAllOrdersParamsV5, CancelOrderParamsV5, @@ -63,7 +63,7 @@ import { GetOpenInterestParamsV5, GetOptionDeliveryPriceParamsV5, GetOrderbookParamsV5, - GetPremiumIndexPriceKlineParams, + GetPremiumIndexPriceKlineParamsV5, GetPublicTradingHistoryParamsV5, GetRiskLimitParamsV5, GetSettlementRecordParamsV5, @@ -105,7 +105,7 @@ import { SetTPSLModeParamsV5, SetTradingStopParamsV5, SettlementRecordV5, - SpotBorrowCheckResult, + SpotBorrowCheckResultV5, SpotLeveragedTokenOrderHistoryV5, SubMemberV5, SwitchIsolatedMarginParamsV5, @@ -205,7 +205,7 @@ export class RestClientV5 extends BaseRestClient { * Covers: Linear contract */ getPremiumIndexPriceKline( - params: GetPremiumIndexPriceKlineParams + params: GetPremiumIndexPriceKlineParamsV5 ): Promise< APIResponseV3WithTime> > { @@ -403,7 +403,9 @@ export class RestClientV5 extends BaseRestClient { batchSubmitOrders( category: 'option', orders: BatchOrderParamsV5[] - ): Promise>> { + ): Promise< + APIResponseV3WithTime> + > { return this.postPrivate('/v5/order/create-batch', { category, request: orders, @@ -421,7 +423,7 @@ export class RestClientV5 extends BaseRestClient { category: 'option', orders: BatchAmendOrderParamsV5[] ): Promise< - APIResponseV3WithTime> + APIResponseV3WithTime> > { return this.postPrivate('/v5/order/amend-batch', { category, @@ -440,7 +442,7 @@ export class RestClientV5 extends BaseRestClient { category: 'option', orders: BatchCancelOrderParamsV5[] ): Promise< - APIResponseV3WithTime> + APIResponseV3WithTime> > { return this.postPrivate('/v5/order/cancel-batch', { category, @@ -456,7 +458,7 @@ export class RestClientV5 extends BaseRestClient { getSpotBorrowCheck( symbol: string, side: OrderSideV5 - ): Promise> { + ): Promise> { return this.getPrivate('/v5/order/spot-borrow-check', { category: 'spot', symbol, diff --git a/src/types/request/v5-market.ts b/src/types/request/v5-market.ts index dd4e512..9b118bb 100644 --- a/src/types/request/v5-market.ts +++ b/src/types/request/v5-market.ts @@ -28,7 +28,7 @@ export interface GetIndexPriceKlineParamsV5 { limit?: number; } -export interface GetPremiumIndexPriceKlineParams { +export interface GetPremiumIndexPriceKlineParamsV5 { category: 'linear'; symbol: string; interval: KlineIntervalV3; diff --git a/src/types/response/v5-trade.ts b/src/types/response/v5-trade.ts index c2f3289..f9f4edc 100644 --- a/src/types/response/v5-trade.ts +++ b/src/types/response/v5-trade.ts @@ -53,7 +53,7 @@ export interface AccountOrderV5 { updatedTime: string; } -export interface BatchOrderResult { +export interface BatchCreateOrderResultV5 { category: CategoryV5; symbol: string; orderId: string; @@ -61,7 +61,7 @@ export interface BatchOrderResult { createAt: string; } -export interface BatchOrdersResult { +export interface BatchOrdersResponseV5 { result: { list: T; }; @@ -73,21 +73,21 @@ export interface BatchOrdersResult { }; } -export interface BatchAmendOrderResult { +export interface BatchAmendOrderResultV5 { category: CategoryV5; symbol: string; orderId: string; orderLinkId: string; } -export interface BatchCancelOrderResult { +export interface BatchCancelOrderResultV5 { category: CategoryV5; symbol: string; orderId: string; orderLinkId: string; } -export interface SpotBorrowCheckResult { +export interface SpotBorrowCheckResultV5 { symbol: string; side: OrderSideV5; maxTradeQty: string;