From 9cb22d192e92b485f5888a85441e3f340f892656 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Wed, 17 Jan 2024 11:41:36 +0000 Subject: [PATCH] v3.8.1: feat() add type guard and type for ws orderbook events --- package-lock.json | 28 ++++++++++++++-------------- package.json | 2 +- src/types/websocket.events.ts | 29 +++++++++++++++++++++++++++++ src/util/index.ts | 5 +++-- src/util/typeGuards.ts | 29 +++++++++++++++++++++++++++++ 5 files changed, 76 insertions(+), 17 deletions(-) create mode 100644 src/util/typeGuards.ts diff --git a/package-lock.json b/package-lock.json index 60c0db2f..7b89ff96 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "bybit-api", - "version": "3.8.0", + "version": "3.8.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "bybit-api", - "version": "3.8.0", + "version": "3.8.1", "license": "MIT", "dependencies": { "axios": "^0.21.0", @@ -2027,9 +2027,9 @@ "dev": true }, "node_modules/axios": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.2.tgz", - "integrity": "sha512-87otirqUw3e8CzHTMO+/9kh/FSgXt/eVDvipijwDtEuwbkySWZ9SBm6VEubmJ/kLKEoLQV/POhxXFb66bfekfg==", + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", "dependencies": { "follow-redirects": "^1.14.0" } @@ -3350,9 +3350,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", "funding": [ { "type": "individual", @@ -8885,9 +8885,9 @@ "dev": true }, "axios": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.2.tgz", - "integrity": "sha512-87otirqUw3e8CzHTMO+/9kh/FSgXt/eVDvipijwDtEuwbkySWZ9SBm6VEubmJ/kLKEoLQV/POhxXFb66bfekfg==", + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", "requires": { "follow-redirects": "^1.14.0" } @@ -9926,9 +9926,9 @@ "dev": true }, "follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==" }, "form-data": { "version": "3.0.1", diff --git a/package.json b/package.json index e5a1af9e..51c1b15b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bybit-api", - "version": "3.8.0", + "version": "3.8.1", "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", diff --git a/src/types/websocket.events.ts b/src/types/websocket.events.ts index 405d6117..b55d9643 100644 --- a/src/types/websocket.events.ts +++ b/src/types/websocket.events.ts @@ -13,6 +13,35 @@ import { } from './v5-shared'; import { WsKey } from './websockets'; +export interface WSOrderbookEventV5 { + topic: string; + /** Event timestamp */ + ts: number; + type: 'delta' | 'snapshot'; + data: { + /** Symbol */ + s: string; + /** [price, qty][] */ + b: [string, string][]; + /** [price, qty][] */ + a: [string, string][]; + /** Update ID */ + u: number; + /** + * Cross sequence + */ + seq: number; + }; + /** + * matching engine timestamp (correlated with T from public trade channel) + */ + cts: number; + /** + * Internal reference, can be used to determine if this is spot/linear/inverse/etc + */ + wsKey: WsKey; +} + export interface WSAccountOrderV5 { qty: string; price: string; diff --git a/src/util/index.ts b/src/util/index.ts index 000f8889..56491b2f 100644 --- a/src/util/index.ts +++ b/src/util/index.ts @@ -1,5 +1,6 @@ export * from './BaseRestClient'; -export * from './requestUtils'; -export * from './WsStore'; export * from './logger'; +export * from './requestUtils'; +export * from './typeGuards'; export * from './websocket-util'; +export * from './WsStore'; diff --git a/src/util/typeGuards.ts b/src/util/typeGuards.ts new file mode 100644 index 00000000..e6de0598 --- /dev/null +++ b/src/util/typeGuards.ts @@ -0,0 +1,29 @@ +/** + * Use type guards to narrow down types with minimal efforts. + */ + +import { WSOrderbookEventV5 } from '../types/websocket.events'; + +/** + * Type guard to detect a V5 orderbook event (delta & snapshots) + * + * @param event + * @returns + */ +export function isWsOrderbookEventV5( + event: unknown, +): event is WSOrderbookEventV5 { + if ( + typeof event !== 'object' || + !event || + typeof event['topic'] !== 'string' || + typeof event['type'] !== 'string' + ) { + return false; + } + + return ( + ['delta', 'snapshot'].includes(event['type']) && + event['topic'].startsWith('orderbook') + ); +}