chore(): fix and run linter, bump node version to LTS

This commit is contained in:
Tiago Siebler
2024-12-11 16:40:54 +00:00
parent e92c083961
commit d363c51b2b
14 changed files with 330 additions and 287 deletions

View File

@@ -20,7 +20,7 @@ module.exports = {
node: true, node: true,
jest: true, jest: true,
}, },
ignorePatterns: ['.eslintrc.js'], ignorePatterns: ['.eslintrc.js', 'webpack.config.js'],
rules: { rules: {
'@typescript-eslint/interface-name-prefix': 'off', '@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off', '@typescript-eslint/explicit-function-return-type': 'off',
@@ -30,5 +30,24 @@ module.exports = {
'@typescript-eslint/ban-types': 'off', '@typescript-eslint/ban-types': 'off',
'simple-import-sort/imports': 'error', 'simple-import-sort/imports': 'error',
'simple-import-sort/exports': 'error', 'simple-import-sort/exports': 'error',
'array-bracket-spacing': ['error', 'never'],
'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,
}, },
}; };

3
.gitignore vendored
View File

@@ -26,4 +26,5 @@ tiagoSpot.ts
restClientRegex.ts restClientRegex.ts
localtest.sh localtest.sh
privaterepotracker privaterepotracker
testfile.ts testfile.ts
dist

2
.nvmrc
View File

@@ -1 +1 @@
v18.12.1 v22.11.0

File diff suppressed because it is too large Load Diff

View File

@@ -28,15 +28,6 @@ export interface WsSnapshotPositionsEvent extends WsBaseEvent<'snapshot'> {
}; };
} }
export interface WsAccountSnapshotUMCBL extends WsBaseEvent<'snapshot'> {
arg: {
instType: 'umcbl';
channel: 'account';
instId: string;
};
data: WsAccountSnapshotDataUMCBL[];
}
export interface WsAccountSnapshotDataUMCBL { export interface WsAccountSnapshotDataUMCBL {
marginCoin: string; marginCoin: string;
locked: string; locked: string;
@@ -47,13 +38,13 @@ export interface WsAccountSnapshotDataUMCBL {
usdtEquity: string; usdtEquity: string;
} }
export interface WSPositionSnapshotUMCBL extends WsBaseEvent<'snapshot'> { export interface WsAccountSnapshotUMCBL extends WsBaseEvent<'snapshot'> {
arg: { arg: {
instType: 'umcbl'; instType: 'umcbl';
channel: 'positions'; channel: 'account';
instId: string; instId: string;
}; };
data: WsPositionSnapshotDataUMCBL[]; data: WsAccountSnapshotDataUMCBL[];
} }
export interface WsPositionSnapshotDataUMCBL { export interface WsPositionSnapshotDataUMCBL {
@@ -80,3 +71,12 @@ export interface WsPositionSnapshotDataUMCBL {
uTime: string; uTime: string;
markPrice: string; markPrice: string;
} }
export interface WSPositionSnapshotUMCBL extends WsBaseEvent<'snapshot'> {
arg: {
instType: 'umcbl';
channel: 'positions';
instId: string;
};
data: WsPositionSnapshotDataUMCBL[];
}

View File

@@ -70,10 +70,15 @@ if (ENABLE_HTTP_TRACE) {
export default abstract class BaseRestClient { export default abstract class BaseRestClient {
private options: RestClientOptions; private options: RestClientOptions;
private baseUrl: string; private baseUrl: string;
private globalRequestOptions: AxiosRequestConfig; private globalRequestOptions: AxiosRequestConfig;
private apiKey: string | undefined; private apiKey: string | undefined;
private apiSecret: string | undefined; private apiSecret: string | undefined;
private apiPass: string | undefined; private apiPass: string | undefined;
/** Defines the client type (affecting how requests & signatures behave) */ /** Defines the client type (affecting how requests & signatures behave) */
@@ -292,6 +297,7 @@ export default abstract class BaseRestClient {
params?: TParams, params?: TParams,
isPublicApi?: true, isPublicApi?: true,
): Promise<UnsignedRequest<TParams>>; ): Promise<UnsignedRequest<TParams>>;
private async prepareSignParams<TParams extends object | undefined>( private async prepareSignParams<TParams extends object | undefined>(
method: Method, method: Method,
endpoint: string, endpoint: string,
@@ -299,6 +305,7 @@ export default abstract class BaseRestClient {
params?: TParams, params?: TParams,
isPublicApi?: false | undefined, isPublicApi?: false | undefined,
): Promise<SignedRequest<TParams>>; ): Promise<SignedRequest<TParams>>;
private async prepareSignParams<TParams extends object | undefined>( private async prepareSignParams<TParams extends object | undefined>(
method: Method, method: Method,
endpoint: string, endpoint: string,

View File

@@ -57,6 +57,7 @@ export abstract class BaseWebsocketClient<
private wsStore: WsStore<TWSKey, TWSTopicSubscribeEventArgs>; private wsStore: WsStore<TWSKey, TWSTopicSubscribeEventArgs>;
protected logger: typeof DefaultLogger; protected logger: typeof DefaultLogger;
protected options: WebsocketClientOptions; protected options: WebsocketClientOptions;
constructor( constructor(
@@ -87,7 +88,9 @@ export abstract class BaseWebsocketClient<
): boolean; ): boolean;
protected abstract shouldAuthOnConnect(wsKey: TWSKey): boolean; protected abstract shouldAuthOnConnect(wsKey: TWSKey): boolean;
protected abstract getWsUrl(wsKey: TWSKey): string; protected abstract getWsUrl(wsKey: TWSKey): string;
protected abstract getMaxTopicsPerSubscribeEvent( protected abstract getMaxTopicsPerSubscribeEvent(
wsKey: TWSKey, wsKey: TWSKey,
): number | null; ): number | null;
@@ -280,7 +283,7 @@ export abstract class BaseWebsocketClient<
recvWindow, recvWindow,
); );
this.logger.info(`Sending auth request...`, { this.logger.info('Sending auth request...', {
...LOGGER_CATEGORY, ...LOGGER_CATEGORY,
wsKey, wsKey,
}); });
@@ -441,7 +444,7 @@ export abstract class BaseWebsocketClient<
public tryWsSend(wsKey: TWSKey, wsMessage: string) { public tryWsSend(wsKey: TWSKey, wsMessage: string) {
try { try {
this.logger.silly(`Sending upstream ws message: `, { this.logger.silly('Sending upstream ws message: ', {
...LOGGER_CATEGORY, ...LOGGER_CATEGORY,
wsMessage, wsMessage,
wsKey, wsKey,
@@ -459,7 +462,7 @@ export abstract class BaseWebsocketClient<
} }
ws.send(wsMessage); ws.send(wsMessage);
} catch (e) { } catch (e) {
this.logger.error(`Failed to send WS message`, { this.logger.error('Failed to send WS message', {
...LOGGER_CATEGORY, ...LOGGER_CATEGORY,
wsMessage, wsMessage,
wsKey, wsKey,
@@ -552,7 +555,7 @@ export abstract class BaseWebsocketClient<
if (typeof msg === 'object') { if (typeof msg === 'object') {
if (typeof msg['code'] === 'number') { if (typeof msg['code'] === 'number') {
if (msg.event === 'login' && msg.code === 0) { if (msg.event === 'login' && msg.code === 0) {
this.logger.info(`Successfully authenticated WS client`, { this.logger.info('Successfully authenticated WS client', {
...LOGGER_CATEGORY, ...LOGGER_CATEGORY,
wsKey, wsKey,
}); });
@@ -565,7 +568,7 @@ export abstract class BaseWebsocketClient<
if (msg['event']) { if (msg['event']) {
if (msg.event === 'error') { if (msg.event === 'error') {
this.logger.error(`WS Error received`, { this.logger.error('WS Error received', {
...LOGGER_CATEGORY, ...LOGGER_CATEGORY,
wsKey, wsKey,
message: msg || 'no message', message: msg || 'no message',

View File

@@ -18,6 +18,7 @@ export default class WsStore<
> { > {
private wsState: Record<string, WsStoredState<TWSTopicSubscribeEventArgs>> = private wsState: Record<string, WsStoredState<TWSTopicSubscribeEventArgs>> =
{}; {};
private logger: typeof DefaultLogger; private logger: typeof DefaultLogger;
constructor(logger: typeof DefaultLogger) { constructor(logger: typeof DefaultLogger) {
@@ -29,10 +30,12 @@ export default class WsStore<
key: WsKey, key: WsKey,
createIfMissing?: true, createIfMissing?: true,
): WsStoredState<TWSTopicSubscribeEventArgs>; ): WsStoredState<TWSTopicSubscribeEventArgs>;
get( get(
key: WsKey, key: WsKey,
createIfMissing?: false, createIfMissing?: false,
): WsStoredState<TWSTopicSubscribeEventArgs> | undefined; ): WsStoredState<TWSTopicSubscribeEventArgs> | undefined;
get( get(
key: WsKey, key: WsKey,
createIfMissing?: boolean, createIfMissing?: boolean,

View File

@@ -78,7 +78,7 @@ export function isWsFuturesPositionsSnapshotEvent(
*/ */
export function assertMarginType(marginType: string): marginType is MarginType { export function assertMarginType(marginType: string): marginType is MarginType {
if (marginType !== 'isolated' && marginType !== 'crossed') { if (marginType !== 'isolated' && marginType !== 'crossed') {
throw new Error(`MarginType should be one of: crossed | isolated`); throw new Error('MarginType should be one of: crossed | isolated');
} }
return true; return true;
} }

View File

@@ -138,7 +138,7 @@ export function getMaxTopicsPerSubscribeEvent(wsKey: WsKey): number | null {
return 15; return 15;
} }
default: { default: {
throw neverGuard(wsKey, `getWsKeyForTopic(): Unhandled wsKey`); throw neverGuard(wsKey, 'getWsKeyForTopic(): Unhandled wsKey');
} }
} }
} }
@@ -162,7 +162,7 @@ export async function getWsAuthSignature(
}> { }> {
if (!apiKey || !apiSecret || !apiPass) { if (!apiKey || !apiSecret || !apiPass) {
throw new Error( throw new Error(
`Cannot auth - missing api key, secret or passcode in config`, 'Cannot auth - missing api key, secret or passcode in config',
); );
} }
const signatureExpiresAt = ((Date.now() + recvWindow) / 1000).toFixed(0); const signatureExpiresAt = ((Date.now() + recvWindow) / 1000).toFixed(0);

View File

@@ -36,6 +36,7 @@ export class WebsocketClientV2 extends BaseWebsocketClient<
WsTopicSubscribeEventArgsV2 WsTopicSubscribeEventArgsV2
> { > {
protected logger: typeof DefaultLogger; protected logger: typeof DefaultLogger;
protected options: WebsocketClientOptions; protected options: WebsocketClientOptions;
protected getWsKeyForTopic( protected getWsKeyForTopic(
@@ -68,7 +69,7 @@ export class WebsocketClientV2 extends BaseWebsocketClient<
case WS_KEY_MAP.spotv1: case WS_KEY_MAP.spotv1:
case WS_KEY_MAP.mixv1: { case WS_KEY_MAP.mixv1: {
throw new Error( throw new Error(
`Use the WebsocketClient instead of WebsocketClientV2 for V1 websockets`, 'Use the WebsocketClient instead of WebsocketClientV2 for V1 websockets',
); );
} }
case WS_KEY_MAP.v2Private: { case WS_KEY_MAP.v2Private: {
@@ -82,7 +83,7 @@ export class WebsocketClientV2 extends BaseWebsocketClient<
...LOGGER_CATEGORY, ...LOGGER_CATEGORY,
wsKey, wsKey,
}); });
throw neverGuard(wsKey, `getWsUrl(): Unhandled wsKey`); throw neverGuard(wsKey, 'getWsUrl(): Unhandled wsKey');
} }
} }
} }

View File

@@ -73,7 +73,9 @@ export declare interface WebsocketClient {
*/ */
export class WebsocketClient extends EventEmitter { export class WebsocketClient extends EventEmitter {
private logger: typeof DefaultLogger; private logger: typeof DefaultLogger;
private options: WebsocketClientOptions; private options: WebsocketClientOptions;
private wsStore: WsStore<WsKey, WsTopicSubscribeEventArgs>; private wsStore: WsStore<WsKey, WsTopicSubscribeEventArgs>;
constructor( constructor(
@@ -144,6 +146,7 @@ export class WebsocketClient extends EventEmitter {
} }
}); });
} }
/** /**
* Unsubscribe from topics & remove them from memory. They won't be re-subscribed to if the connection reconnects. * Unsubscribe from topics & remove them from memory. They won't be re-subscribed to if the connection reconnects.
* @param wsTopics topic or list of topics * @param wsTopics topic or list of topics
@@ -281,7 +284,7 @@ export class WebsocketClient extends EventEmitter {
recvWindow, recvWindow,
); );
this.logger.info(`Sending auth request...`, { this.logger.info('Sending auth request...', {
...LOGGER_CATEGORY, ...LOGGER_CATEGORY,
wsKey, wsKey,
}); });
@@ -442,7 +445,7 @@ export class WebsocketClient extends EventEmitter {
public tryWsSend(wsKey: WsKey, wsMessage: string) { public tryWsSend(wsKey: WsKey, wsMessage: string) {
try { try {
this.logger.silly(`Sending upstream ws message: `, { this.logger.silly('Sending upstream ws message: ', {
...LOGGER_CATEGORY, ...LOGGER_CATEGORY,
wsMessage, wsMessage,
wsKey, wsKey,
@@ -460,7 +463,7 @@ export class WebsocketClient extends EventEmitter {
} }
ws.send(wsMessage); ws.send(wsMessage);
} catch (e) { } catch (e) {
this.logger.error(`Failed to send WS message`, { this.logger.error('Failed to send WS message', {
...LOGGER_CATEGORY, ...LOGGER_CATEGORY,
wsMessage, wsMessage,
wsKey, wsKey,
@@ -553,7 +556,7 @@ export class WebsocketClient extends EventEmitter {
if (typeof msg === 'object') { if (typeof msg === 'object') {
if (typeof msg['code'] === 'number') { if (typeof msg['code'] === 'number') {
if (msg.event === 'login' && msg.code === 0) { if (msg.event === 'login' && msg.code === 0) {
this.logger.info(`Successfully authenticated WS client`, { this.logger.info('Successfully authenticated WS client', {
...LOGGER_CATEGORY, ...LOGGER_CATEGORY,
wsKey, wsKey,
}); });
@@ -566,7 +569,7 @@ export class WebsocketClient extends EventEmitter {
if (msg['event']) { if (msg['event']) {
if (msg.event === 'error') { if (msg.event === 'error') {
this.logger.error(`WS Error received`, { this.logger.error('WS Error received', {
...LOGGER_CATEGORY, ...LOGGER_CATEGORY,
wsKey, wsKey,
message: msg || 'no message', message: msg || 'no message',
@@ -648,14 +651,14 @@ export class WebsocketClient extends EventEmitter {
} }
case WS_KEY_MAP.v2Private: case WS_KEY_MAP.v2Private:
case WS_KEY_MAP.v2Public: { case WS_KEY_MAP.v2Public: {
throw new Error(`Use the WebsocketClientV2 for V2 websockets`); throw new Error('Use the WebsocketClientV2 for V2 websockets');
} }
default: { default: {
this.logger.error('getWsUrl(): Unhandled wsKey: ', { this.logger.error('getWsUrl(): Unhandled wsKey: ', {
...LOGGER_CATEGORY, ...LOGGER_CATEGORY,
wsKey, wsKey,
}); });
throw neverGuard(wsKey, `getWsUrl(): Unhandled wsKey`); throw neverGuard(wsKey, 'getWsUrl(): Unhandled wsKey');
} }
} }
} }

View File

@@ -12,6 +12,7 @@
"test/**/*.*", "test/**/*.*",
"examples/**/*.*", "examples/**/*.*",
".eslintrc.cjs", ".eslintrc.cjs",
"jest.config.ts" "jest.config.ts",
"webpack/webpack.config.ts"
] ]
} }

View File

@@ -1,6 +1,6 @@
const webpack = require('webpack');
const path = require('path'); const path = require('path');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; const BundleAnalyzerPlugin =
require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
function generateConfig(name) { function generateConfig(name) {
var config = { var config = {
@@ -10,27 +10,29 @@ function generateConfig(name) {
filename: name + '.js', filename: name + '.js',
sourceMapFilename: name + '.map', sourceMapFilename: name + '.map',
library: name, library: name,
libraryTarget: 'umd' libraryTarget: 'umd',
}, },
devtool: "source-map", devtool: 'source-map',
mode: 'production', mode: 'production',
resolve: { resolve: {
// Add '.ts' and '.tsx' as resolvable extensions. // Add '.ts' and '.tsx' as resolvable extensions.
extensions: [".webpack.js", ".web.js", ".ts", ".tsx", ".js"], extensions: ['.webpack.js', '.web.js', '.ts', '.tsx', '.js'],
alias: { alias: {
[path.resolve(__dirname, "../lib/util/node-support.js")]: [path.resolve(__dirname, '../lib/util/node-support.js')]: path.resolve(
path.resolve(__dirname, "../lib/util/browser-support.js"), __dirname,
} '../lib/util/browser-support.js',
),
},
}, },
module: { module: {
rules: [ rules: [
// All files with a '.ts' or '.tsx' extension will be handled by 'ts-loader'. // All files with a '.ts' or '.tsx' extension will be handled by 'ts-loader'.
{ test: /\.tsx?$/, loader: "ts-loader" }, { test: /\.tsx?$/, loader: 'ts-loader' },
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'. // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{ test: /\.js$/, loader: "source-map-loader" }, { test: /\.js$/, loader: 'source-map-loader' },
{ {
test: /\.m?js$/, test: /\.m?js$/,
@@ -38,28 +40,30 @@ function generateConfig(name) {
use: { use: {
loader: 'babel-loader', loader: 'babel-loader',
options: { options: {
presets: [['@babel/preset-env', { presets: [
'targets': { [
'node': 'current' '@babel/preset-env',
} {
}]] targets: {
} node: 'current',
} },
} },
] ],
} ],
},
},
},
],
},
}; };
config.plugins = [ config.plugins = [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
}),
new BundleAnalyzerPlugin({ new BundleAnalyzerPlugin({
defaultSizes: 'stat', defaultSizes: 'stat',
analyzerMode: 'static', analyzerMode: 'static',
reportFilename: '../doc/bundleReport.html', reportFilename: '../doc/bundleReport.html',
openAnalyzer: false, openAnalyzer: false,
}) }),
]; ];
return config; return config;