From 0606525e9641b30eec89b0e9dde1b0b47293d1c2 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Sun, 13 Dec 2020 17:19:18 +0000 Subject: [PATCH 1/7] 1.3.0-beta.1: introduce typescript, webpack, better overall browser support, deprecate assert calls --- .github/workflows/npmpublish.yml | 1 + .gitignore | 2 + README.md | 39 +- index.js | 10 +- lib/logger.js | 9 - lib/rest-client.js | 346 --- lib/util/requestUtils.js | 21 - lib/util/requestWrapper.js | 167 -- package-lock.json | 2366 ++++++++++++++++- package.json | 57 +- src/index.ts | 3 + src/logger.ts | 22 + src/rest-client.ts | 531 ++++ src/util/requestUtils.ts | 59 + src/util/requestWrapper.ts | 193 ++ .../websocket-client.ts | 97 +- tsconfig.json | 31 + webpack/webpack.config.js | 69 + 18 files changed, 3357 insertions(+), 666 deletions(-) delete mode 100644 lib/logger.js delete mode 100644 lib/rest-client.js delete mode 100644 lib/util/requestUtils.js delete mode 100644 lib/util/requestWrapper.js create mode 100644 src/index.ts create mode 100644 src/logger.ts create mode 100644 src/rest-client.ts create mode 100644 src/util/requestUtils.ts create mode 100644 src/util/requestWrapper.ts rename lib/websocket-client.js => src/websocket-client.ts (65%) create mode 100644 tsconfig.json create mode 100644 webpack/webpack.config.js diff --git a/.github/workflows/npmpublish.yml b/.github/workflows/npmpublish.yml index 7d819fa5..39e82e73 100644 --- a/.github/workflows/npmpublish.yml +++ b/.github/workflows/npmpublish.yml @@ -41,6 +41,7 @@ jobs: registry-url: https://registry.npmjs.org/ #- run: npm ci + - run: npm run build - run: npm publish if: steps.version-updated.outputs.has-updated env: diff --git a/.gitignore b/.gitignore index c3944dd3..ff17cf3a 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,5 @@ node_modules/ .env .env.test .cache +lib +bundleReport.html diff --git a/README.md b/README.md index 68e39a97..0ac7d7ce 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,12 @@ Most methods accept JS objects. These can be populated using parameters specifie - [Bybit API Inverse Documentation](https://bybit-exchange.github.io/docs/inverse/#t-introduction). - [Bybit API Linear Documentation (not supported yet)](https://bybit-exchange.github.io/docs/linear/#t-introduction) +## Structure +This project uses typescript. Resources are stored in 3 key structures: +- [src](./src) - the whole connector written in typescript +- [lib](./lib) - the javascript version of the project (compiled from typescript). This should not be edited directly, as it will be overwritten with each release. +- [dist](./dist) - the packed bundle of the project for use in browser environments. + ### Inverse Contracts #### Rest client ```javascript @@ -31,8 +37,39 @@ const {RestClient} = require('bybit-api'); const API_KEY = 'xxx'; const PRIVATE_KEY = 'yyy'; +const useLivenet = false; + +const restInverseOptions = { + // override the max size of the request window (in ms) + recv_window?: number; + + // how often to sync time drift with bybit servers + sync_interval_ms?: number | string; + + // Default: false. Disable above sync mechanism if true. + disable_time_sync?: boolean; + + // Default: false. If true, we'll throw errors if any params are undefined + strict_param_validation?: boolean; + + // Optionally override API protocol + domain + // e.g 'https://api.bytick.com' + baseUrl?: string; + + // Default: true. whether to try and post-process request exceptions. + parse_exceptions?: boolean; +}; + +const client = new RestClient( + API_KEY, + PRIVATE_KEY, + + // optional, uses testnet by default. Set to 'true' to use livenet. + useLivenet, -const client = new RestClient(API_KEY, PRIVATE_KEY); + // restInverseOptions, + // requestLibraryOptions +); client.changeUserLeverage({leverage: 4, symbol: 'ETHUSD'}) .then(result => { diff --git a/index.js b/index.js index ce0049b3..ce417b3a 100644 --- a/index.js +++ b/index.js @@ -1,9 +1 @@ -const RestClient = require('./lib/rest-client'); -const WebsocketClient = require('./lib/websocket-client'); -const DefaultLogger = require('./lib/logger'); - -module.exports = { - RestClient, - WebsocketClient, - DefaultLogger -}; +module.exports = require('lib/index'); \ No newline at end of file diff --git a/lib/logger.js b/lib/logger.js deleted file mode 100644 index e53da595..00000000 --- a/lib/logger.js +++ /dev/null @@ -1,9 +0,0 @@ - -module.exports = { - silly: function() {console.log(arguments);}, - debug: function() {console.log(arguments);}, - notice: function() {console.log(arguments);}, - info: function() {console.info(arguments);}, - warning: function() {console.warn(arguments);}, - error: function() {console.error(arguments);}, -}; diff --git a/lib/rest-client.js b/lib/rest-client.js deleted file mode 100644 index 84b3c687..00000000 --- a/lib/rest-client.js +++ /dev/null @@ -1,346 +0,0 @@ -const assert = require('assert'); -const RequestWrapper = require('./util/requestWrapper'); - -module.exports = class RestClient { - /** - * @public Creates an instance of the inverse REST API client. - * - * @param {string} key - your API key - * @param {string} secret - your API secret - * @param {boolean} [livenet=false] - * @param {*} [options={}] options to configure REST API connectivity - * @param {*} [requestOptions={}] HTTP networking options for axios - */ - constructor(key, secret, livenet=false, options={}, requestOptions={}) { - this.request = new RequestWrapper(...arguments); - } - - async placeActiveOrder(params) { - assert(params, 'No params passed'); - assert(params.side, 'Parameter side is required'); - assert(params.symbol, 'Parameter symbol is required'); - assert(params.order_type, 'Parameter order_type is required'); - assert(params.qty, 'Parameter qty is required'); - assert(params.time_in_force, 'Parameter time_in_force is required'); - - if (params.order_type === 'Limit') assert(params.price, 'Parameter price is required for limit orders'); - - return await this.request.post('v2/private/order/create', params); - } - - async getActiveOrder(params) { - return await this.request.get('open-api/order/list', params); - } - - async cancelActiveOrder(params) { - assert(params, 'No params passed'); - assert(params.symbol, 'Parameter symbol is required'); - assert(params.order_id || params.order_link_id, 'Parameter order_id OR order_link_id is required'); - - return await this.request.post('v2/private/order/cancel', params); - } - - async cancelAllActiveOrders(params) { - assert(params, 'No params passed'); - assert(params.symbol, 'Parameter symbol is required'); - - return await this.request.post('v2/private/order/cancelAll', params); - } - - async replaceActiveOrder(params) { - assert(params, 'No params passed'); - assert(params.order_id || params.order_link_id, 'Parameter order_id OR order_link_id is required'); - assert(params.symbol, 'Parameter symbol is required'); - - return await this.request.post('v2/private/order/replace', params); - } - - /** - * @deprecated use replaceActiveOrder() - */ - async replaceActiveOrderOld(params) { - assert(params, 'No params passed'); - assert(params.order_id || params.order_link_id, 'Parameter order_id OR order_link_id is required'); - assert(params.symbol, 'Parameter symbol is required'); - - return await this.request.post('open-api/order/replace', params); - } - - async queryActiveOrder(params) { - assert(params, 'No params passed'); - assert(params.order_id || params.order_link_id, 'Parameter order_id OR order_link_id is required'); - assert(params.symbol, 'Parameter symbol is required'); - - return await this.request.get('v2/private/order', params); - } - - async placeConditionalOrder(params) { - assert(params, 'No params passed'); - assert(params.side, 'Parameter side is required'); - assert(params.symbol, 'Parameter symbol is required'); - assert(params.order_type, 'Parameter order_type is required'); - assert(params.qty, 'Parameter qty is required'); - assert(params.base_price, 'Parameter base_price is required'); - assert(params.stop_px, 'Parameter stop_px is required'); - assert(params.time_in_force, 'Parameter time_in_force is required'); - - if (params.order_type === 'Limit') assert(params.price, 'Parameter price is required for limit orders'); - - return await this.request.post('v2/private/stop-order/create', params); - } - - /** - * @deprecated use placeConditionalOrder - */ - async placeConditionalOrderOld(params) { - assert(params, 'No params passed'); - assert(params.side, 'Parameter side is required'); - assert(params.symbol, 'Parameter symbol is required'); - assert(params.order_type, 'Parameter order_type is required'); - assert(params.qty, 'Parameter qty is required'); - assert(params.time_in_force, 'Parameter time_in_force is required'); - assert(params.base_price, 'Parameter base_price is required'); - assert(params.stop_px, 'Parameter stop_px is required'); - - if (params.order_type === 'Limit') assert(params.price, 'Parameter price is required for limit orders'); - - return await this.request.post('open-api/stop-order/create', params); - } - - async getConditionalOrder(params) { - assert(params.symbol, 'Parameter symbol is required'); - return await this.request.get('v2/private/stop-order/list', params); - } - - /** - * @deprecated use placeConditionalOrder - */ - async getConditionalOrderOld(params) { - return await this.request.get('open-api/stop-order/list', params); - } - - async cancelConditionalOrder(params) { - assert(params, 'No params passed'); - assert(params.symbol, 'Parameter symbol is required'); - assert(params.stop_order_id || params.order_link_id, 'Parameter stop_order_id OR order_link_id is required'); - - return await this.request.post('v2/private/stop-order/cancel', params); - } - - /** - * @deprecated use cancelConditionalOrder - */ - async cancelConditionalOrderOld(params) { - assert(params, 'No params passed'); - assert(params.stop_order_id, 'Parameter stop_order_id is required'); - - return await this.request.post('open-api/stop-order/cancel', params); - } - - async cancelAllConditionalOrders(params) { - assert(params, 'No params passed'); - assert(params.symbol, 'Parameter symbol is required'); - - return await this.request.post('v2/private/stop-order/cancelAll', params); - } - - async replaceConditionalOrder(params) { - assert(params, 'No params passed'); - assert(params.stop_order_id || params.order_link_id, 'Parameter stop_order_id OR order_link_id is required'); - assert(params.symbol, 'Parameter symbol is required'); - - return await this.request.post('v2/private/stop-order/replace', params); - } - - /** - * @deprecated use replaceConditionalOrder - */ - async replaceConditionalOrderOld(params) { - assert(params, 'No params passed'); - assert(params.stop_order_id, 'Parameter stop_order_id is required'); - assert(params.symbol, 'Parameter symbol is required'); - - return await this.request.post('open-api/stop-order/replace', params); - } - - async queryConditionalOrder(params) { - assert(params, 'No params passed'); - assert(params.stop_order_id || params.order_link_id, 'Parameter order_id OR order_link_id is required'); - assert(params.symbol, 'Parameter symbol is required'); - - return await this.request.get('v2/private/stop-order', params); - } - - /** - * @deprecated use getPosition() instead - */ - async getUserLeverage() { - return await this.request.get('user/leverage'); - } - - async getPosition(params) { - return await this.request.get('v2/private/position/list', params); - } - - async changeUserLeverage(params) { - assert(params, 'No params passed'); - assert(params.symbol, 'Parameter symbol is required'); - - if (typeof params.leverage === 'undefined') { - throw new Error('Parameter leverage is required'); - } - - return await this.request.post('user/leverage/save', params); - } - - /** - * @deprecated use getPosition() instead - */ - async getPositions() { - return await this.request.get('position/list'); - } - - async changePositionMargin(params) { - assert(params, 'No params passed'); - assert(params.symbol, 'Parameter symbol is required'); - assert(params.margin, 'Parameter margin is required'); - - return await this.request.post('position/change-position-margin', params); - } - - async setTradingStop(params) { - assert(params, 'No params passed'); - assert(params.symbol, 'Parameter symbol is required'); - - return await this.request.post('open-api/position/trading-stop', params); - } - - async getWalletFundRecords(params) { - return await this.request.get('open-api/wallet/fund/records', params); - } - - async getWithdrawRecords(params) { - return await this.request.get('open-api/wallet/withdraw/list', params); - } - - async getAssetExchangeRecords(params) { - return await this.request.get('v2/private/exchange-order/list', params); - } - - async getWalletBalance(params) { - return await this.request.get('v2/private/wallet/balance', params); - } - - async setRiskLimit(params) { - assert(params, 'No params passed'); - assert(params.symbol, 'Parameter symbol is required'); - assert(params.risk_id, 'Parameter risk_id is required'); - - return await this.request.post('open-api/wallet/risk-limit', params); - } - - async getRiskLimitList() { - return await this.request.get('open-api/wallet/risk-limit/list'); - } - - async getLastFundingRate(params) { - assert(params, 'No params passed'); - assert(params.symbol, 'Parameter symbol is required'); - - return await this.request.get('open-api/funding/prev-funding-rate', params); - } - - async getMyLastFundingFee(params) { - assert(params, 'No params passed'); - assert(params.symbol, 'Parameter symbol is required'); - - return await this.request.get('open-api/funding/prev-funding', params); - } - - async getPredictedFunding(params) { - assert(params, 'No params passed'); - assert(params.symbol, 'Parameter symbol is required'); - - return await this.request.get('open-api/funding/predicted-funding', params); - } - - async getTradeRecords(params) { - assert(params, 'No params passed'); - assert(params.order_id || params.symbol, 'Parameter order_id OR symbol is required'); - - return await this.request.get('v2/private/execution/list', params); - } - - async getOrderBook(params) { - assert(params, 'No params passed'); - assert(params.symbol, 'Parameter symbol is required'); - - return await this.request.get('v2/public/orderBook/L2', params); - } - - async getKline(params) { - assert(params, 'No params passed'); - assert(params.symbol, 'Parameter symbol is required'); - assert(params.interval, 'Parameter interval is required'); - assert(params.from, 'Parameter from is required'); - - return await this.request.get('v2/public/kline/list', params); - } - - async getOpenInterest(params) { - assert(params, 'No params passed'); - assert(params.symbol, 'Parameter symbol is required'); - assert(params.period, 'Parameter period is required'); - - return await this.request.get('v2/public/open-interest', params); - } - - async getLatestBigDeal(params) { - assert(params, 'No params passed'); - assert(params.symbol, 'Parameter symbol is required'); - - return await this.request.get('v2/public/big-deal', params); - } - - async getLongShortRatio(params) { - assert(params, 'No params passed'); - assert(params.symbol, 'Parameter symbol is required'); - assert(params.period, 'Parameter period is required'); - - return await this.request.get('v2/public/account-ratio', params); - } - - async getLatestInformation() { - return await this.request.get('v2/public/tickers'); - } - - async getPublicTradingRecords(params) { - assert(params, 'No params passed'); - assert(params.symbol, 'Parameter symbol is required'); - - return await this.request.get('v2/public/trading-records', params); - } - - async getPublicLiquidations(params) { - assert(params, 'No params passed'); - assert(params.symbol, 'Parameter symbol is required'); - - return await this.request.get('v2/public/liq-records', params); - } - - async getServerTime() { - return await this.request.get('v2/public/time'); - } - - async getApiAnnouncements() { - return await this.request.get('v2/public/announcement'); - } - - async getSymbols() { - return await this.request.get('v2/public/symbols'); - } - - async getTimeOffset() { - return await this.request.getTimeOffset(); - } -}; diff --git a/lib/util/requestUtils.js b/lib/util/requestUtils.js deleted file mode 100644 index 1e7f348b..00000000 --- a/lib/util/requestUtils.js +++ /dev/null @@ -1,21 +0,0 @@ -const { createHmac } = require('crypto'); - -module.exports = { - signMessage(message, secret) { - return createHmac('sha256', secret) - .update(message) - .digest('hex'); - }, - serializeParams(params = {}, strict_validation = false) { - return Object.keys(params) - .sort() - .map(key => { - const value = params[key]; - if (strict_validation === true && typeof value === 'undefined') { - throw new Error('Failed to sign API request due to undefined parameter'); - } - return `${key}=${value}`; - }) - .join('&'); - } -}; diff --git a/lib/util/requestWrapper.js b/lib/util/requestWrapper.js deleted file mode 100644 index a7c0cee8..00000000 --- a/lib/util/requestWrapper.js +++ /dev/null @@ -1,167 +0,0 @@ -const assert = require('assert'); -const axios = require('axios'); - -const { signMessage, serializeParams } = require('./requestUtils'); - -const baseUrls = { - livenet: 'https://api.bybit.com', - testnet: 'https://api-testnet.bybit.com' -}; - -module.exports = class RequestUtil { - constructor(key, secret, livenet=false, options={}, requestOptions={}) { - this._timeOffset = null; - this._syncTimePromise = null; - - this.options = { - recv_window: 5000, - // how often to sync time drift with bybit servers - sync_interval_ms: 3600000, - // if true, we'll throw errors if any params are undefined - strict_param_validation: false, - ...options - }; - - this.baseUrl = baseUrls[livenet === true ? 'livenet' : 'testnet']; - if (options.baseUrl) { - this.baseUrl = options.baseUrl; - } - - this.globalRequestOptions = { - // in ms == 5 minutes by default - timeout: 1000 * 60 * 5, - // custom request options based on axios specs - see: https://github.com/axios/axios#request-config - ...requestOptions, - headers: { - 'referer': 'bybitapinode' - }, - }; - - if (key) { - assert(secret, 'Secret is required for private enpoints'); - } - - this._syncTime(); - setInterval(this._syncTime.bind(this), parseInt(this.options.sync_interval_ms)); - - this.key = key; - this.secret = secret; - } - - async get(endpoint, params) { - const result = await this._call('GET', endpoint, params); - return result; - } - - async post(endpoint, params) { - const result = await this._call('POST', endpoint, params); - return result; - } - - async getTimeOffset() { - const start = Date.now(); - const result = await this.get('v2/public/time'); - const end = Date.now(); - - return Math.ceil((result.time_now * 1000) - end + ((end - start) / 2)); - } - - async _call(method, endpoint, params) { - const publicEndpoint = endpoint.startsWith('v2/public'); - - if (!publicEndpoint) { - if (!this.key || !this.secret) { - throw new Error('Private endpoints require api and private keys set'); - } - - if (this._timeOffset === null) { - await this._syncTime(); - } - - params = this._signRequest(params); - } - - const options = { - ...this.globalRequestOptions, - url: [this.baseUrl, endpoint].join('/'), - method: method, - json: true - }; - - switch (method) { - case 'GET': - options.params = params; - break; - default: - options.data = params; - break; - } - - return axios(options).then(response => { - if (response.status == 200) { - return response.data; - } - - throw { - code: response.status, - message: response.statusText, - body: response.data, - requestOptions: options - }; - }) - .catch(e => { - if (!e.response) { - // Something happened in setting up the request that triggered an Error - if (!e.request) { - throw e.message; - } - - // request made but no response received - throw e; - } - - // The request was made and the server responded with a status code - // that falls out of the range of 2xx - throw { - code: e.response.statusCode, - message: e.response.message, - body: e.response.body, - requestOptions: options, - headers: e.response.headers - }; - }); - } - - _signRequest(data) { - const params = { - ...data, - api_key: this.key, - timestamp: Date.now() + this._timeOffset - }; - - // Optional, set to 5000 by default. Increase if timestamp/recv_window errors are seen. - if (this.options.recv_window && !params.recv_window) { - params.recv_window = this.options.recv_window; - } - - if (this.key && this.secret) { - const serializedParams = serializeParams(params, this.options.strict_param_validation); - params.sign = signMessage(serializedParams, this.secret); - } - - return params; - } - - _syncTime() { - if (this._syncTimePromise !== null) { - return this._syncTimePromise; - } - - this._syncTimePromise = this.getTimeOffset().then(offset => { - this._timeOffset = offset; - this._syncTimePromise = null; - }); - - return this._syncTimePromise; - } -}; diff --git a/package-lock.json b/package-lock.json index 27a987ca..28e70564 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "bybit-api", - "version": "1.2.1", + "version": "1.3.0-beta.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -44,9 +44,9 @@ } }, "@eslint/eslintrc": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.1.tgz", - "integrity": "sha512-XRUeBZ5zBWLYgSANMpThFddrZZkEbGHgUdt5UJjZfnlN9BGCiUBrf+nvbRupSjMvqzwnQN0qwCmOxITt1cfywA==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz", + "integrity": "sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -61,6 +61,262 @@ "strip-json-comments": "^3.1.1" } }, + "@types/eslint": { + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.6.tgz", + "integrity": "sha512-I+1sYH+NPQ3/tVqCeUSBwTE/0heyvtXqpIopUUArlBm0Kpocb8FbMa3AZ/ASKIFpN3rnEx932TTXDbt9OXsNDw==", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.0.tgz", + "integrity": "sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==", + "dev": true, + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "@types/estree": { + "version": "0.0.45", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.45.tgz", + "integrity": "sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g==", + "dev": true + }, + "@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==", + "dev": true + }, + "@types/node": { + "version": "14.14.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.11.tgz", + "integrity": "sha512-BJ97wAUuU3NUiUCp44xzUFquQEvnk1wu7q4CMEUYKJWjdkr0YWYDsm4RFtAvxYsNjLsKcrFt6RvK8r+mnzMbEQ==", + "dev": true + }, + "@webassemblyjs/ast": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", + "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "dev": true, + "requires": { + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", + "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", + "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", + "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", + "dev": true + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", + "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", + "dev": true, + "requires": { + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", + "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", + "dev": true + }, + "@webassemblyjs/helper-module-context": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", + "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", + "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", + "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", + "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", + "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", + "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", + "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/helper-wasm-section": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-opt": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", + "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", + "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", + "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wast-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", + "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/floating-point-hex-parser": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-code-frame": "1.9.0", + "@webassemblyjs/helper-fsm": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", + "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@webpack-cli/info": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.1.0.tgz", + "integrity": "sha512-uNWSdaYHc+f3LdIZNwhdhkjjLDDl3jP2+XBqAq9H8DjrJUvlOKdP8TNruy1yEaDfgpAIgbSAN7pye4FEHg9tYQ==", + "dev": true, + "requires": { + "envinfo": "^7.7.3" + } + }, + "@webpack-cli/serve": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.1.0.tgz", + "integrity": "sha512-7RfnMXCpJ/NThrhq4gYQYILB18xWyoQcBey81oIyVbmgbc6m5ZHHyFK+DyH7pLHJf0p14MxL4mTsoPAgBSTpIg==", + "dev": true + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "dev": true + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, "acorn": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", @@ -73,6 +329,12 @@ "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", "dev": true }, + "acorn-walk": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.0.0.tgz", + "integrity": "sha512-oZRad/3SMOI/pxbbmqyurIx7jHw1wZDcR9G44L8pUVFEomX/0dH89SrM1KaDXuv1NpzAXz6Op/Xu/Qd5XXzdEA==", + "dev": true + }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -85,6 +347,12 @@ "uri-js": "^4.2.2" } }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, "ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", @@ -115,6 +383,38 @@ "sprintf-js": "~1.0.2" } }, + "array-back": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.1.tgz", + "integrity": "sha512-Z/JnaVEXv+A9xabHzN43FiiiWEE7gPCRXMrVmRm00tWbjZRul1iHm7ECzlyNq1p4a4ATXz+G9FJ3GqGOkOV3fg==", + "dev": true + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, "astral-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", @@ -135,6 +435,68 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "bn.js": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz", + "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==", + "dev": true + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -145,12 +507,138 @@ "concat-map": "0.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dev": true, + "requires": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "dev": true, + "requires": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "browserslist": { + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.15.0.tgz", + "integrity": "sha512-IJ1iysdMkGmjjYeRlDU8PQejVwxvVO5QOfXH7ylW31GO6LwNRSmm/SgRXtNsEXqMLl2e+2H5eEJ7sfynF8TCaQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001164", + "colorette": "^1.2.1", + "electron-to-chromium": "^1.3.612", + "escalade": "^3.1.1", + "node-releases": "^1.1.67" + } + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, + "caniuse-lite": { + "version": "1.0.30001165", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001165.tgz", + "integrity": "sha512-8cEsSMwXfx7lWSUMA2s08z9dIgsnR5NAqjXP23stdsU3AUWkCr/rr4s4OFtHXn5XXr6+7kam3QFVoYyXNPdJPA==", + "dev": true + }, "chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -202,6 +690,25 @@ } } }, + "chrome-trace-event": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", + "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -217,12 +724,135 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, + "colorette": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", + "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", + "dev": true + }, + "command-line-usage": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.1.tgz", + "integrity": "sha512-F59pEuAR9o1SF/bD0dQBDluhpT4jJQNWUHEuVBqpDmCUo6gPjCi+m9fCWnWZVR/oG6cMTUms4h+3NPl74wGXvA==", + "dev": true, + "requires": { + "array-back": "^4.0.1", + "chalk": "^2.4.2", + "table-layout": "^1.0.1", + "typical": "^5.2.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" + } + } + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -234,36 +864,175 @@ "which": "^2.0.1" } }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" } }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "requires": { "esutils": "^2.0.2" } }, + "duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.619", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.619.tgz", + "integrity": "sha512-WFGatwtk7Fw0QcKCZzfGD72hvbcXV8kLY8aFuj0Ip0QRnOtyLYMsc+wXbSjb2w4lk1gcAeNU1/lQ20A+tvuypQ==", + "dev": true + }, + "elliptic": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", + "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", + "dev": true, + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "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", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enhanced-resolve": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz", + "integrity": "sha512-3e87LvavsdxyoCfGusJnrZ5G8SLPOFeHSNpZI/ATL9a5leXo2k0w6MKnbqhdBad9qTobSfB20Ld7UmgoNbAZkQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + } + }, "enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", @@ -273,6 +1042,33 @@ "ansi-colors": "^4.1.1" } }, + "envinfo": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.7.3.tgz", + "integrity": "sha512-46+j5QxbPWza0PB1i15nZx0xQ4I/EfQxg9J8Had3b408SV63nEtor2e+oiY63amTo9KTuh2a3XLObNwduxYwwA==", + "dev": true + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -280,13 +1076,13 @@ "dev": true }, "eslint": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.13.0.tgz", - "integrity": "sha512-uCORMuOO8tUzJmsdRtrvcGq5qposf7Rw0LwkTJkoDbOycVQtQjmnhZSuLQnozLE4TmAzlMVV45eCHmQ1OpDKUQ==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.15.0.tgz", + "integrity": "sha512-Vr64xFDT8w30wFll643e7cGrIkPEU50yIiI36OdSIDoSGguIeaLzBo0vpGvzo9RECUqq7htURfwEtKqwytkqzA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@eslint/eslintrc": "^0.2.1", + "@eslint/eslintrc": "^0.2.2", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -296,10 +1092,10 @@ "eslint-scope": "^5.1.1", "eslint-utils": "^2.1.0", "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.0", + "espree": "^7.3.1", "esquery": "^1.2.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", + "file-entry-cache": "^6.0.0", "functional-red-black-tree": "^1.0.1", "glob-parent": "^5.0.0", "globals": "^12.1.0", @@ -358,13 +1154,13 @@ "dev": true }, "espree": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz", - "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, "requires": { "acorn": "^7.4.0", - "acorn-jsx": "^5.2.0", + "acorn-jsx": "^5.3.1", "eslint-visitor-keys": "^1.3.0" }, "dependencies": { @@ -428,6 +1224,106 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, + "events": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", + "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dev": true, + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -447,29 +1343,85 @@ "dev": true }, "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz", + "integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "filesize": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz", + "integrity": "sha512-LpCHtPQ3sFx67z+uh2HnSyWSLLu5Jxo21795uRDuar/EOuYWXib5EmPaGIBuSnRqH2IODiKA2k5re/K9OnN/Yg==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "requires": { - "flat-cache": "^2.0.1" + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" } }, "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" } }, "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz", + "integrity": "sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==", "dev": true }, "follow-redirects": { @@ -477,18 +1429,45 @@ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz", "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==" }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "dev": true + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "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 }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -512,6 +1491,12 @@ "is-glob": "^4.0.1" } }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, "globals": { "version": "12.4.0", "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", @@ -521,12 +1506,110 @@ "type-fest": "^0.8.1" } }, + "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 + }, + "gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "dev": true, + "requires": { + "duplexer": "^0.1.2" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true + }, + "iconv-lite": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", + "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", @@ -543,6 +1626,64 @@ "resolve-from": "^4.0.0" } }, + "import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + } + } + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -565,6 +1706,27 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "interpret": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", + "dev": true + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true + }, + "is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -586,12 +1748,63 @@ "is-extglob": "^2.1.1" } }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, + "isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==" + }, + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -599,15 +1812,21 @@ "dev": true }, "js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" } }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -620,6 +1839,21 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -630,12 +1864,191 @@ "type-check": "~0.4.0" } }, - "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "loader-runner": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.1.0.tgz", + "integrity": "sha512-oR4lB4WvwFoC70ocraKhn5nkKSs23t57h9udUgw8o0iH8hMXeEoRuUgfcvgUwAJ1ZpRqBvcou4N2SMvM1DwMrA==", + "dev": true + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", "dev": true }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "dev": true + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "dev": true, + "requires": { + "mime-db": "1.44.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -651,15 +2064,6 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -672,6 +2076,42 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node-releases": { + "version": "1.1.67", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.67.tgz", + "integrity": "sha512-V5QF9noGFl3EymEwUYzO+3NTDpGfQB4ve6Qfnzf3UNydMhjQRVPR1DZTuvWiLzaFJYw2fmDwAfnRNEVb64hSIg==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -681,6 +2121,21 @@ "wrappy": "1" } }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true + }, "optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", @@ -695,6 +2150,30 @@ "word-wrap": "^1.2.3" } }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -704,6 +2183,31 @@ "callsites": "^3.0.0" } }, + "parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dev": true, + "requires": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -716,30 +2220,231 @@ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "pbkdf2": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", + "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "pkg-dir": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", + "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", + "dev": true, + "requires": { + "find-up": "^5.0.0" + } + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, + "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 + }, "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, + "proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "dev": true, + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "rechoir": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", + "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==", + "dev": true, + "requires": { + "resolve": "^1.9.0" + } + }, + "reduce-flatten": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", + "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==", + "dev": true + }, "regexpp": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", "dev": true }, + "resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "requires": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -747,20 +2452,139 @@ "dev": true }, "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { "glob": "^7.1.3" } }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", "dev": true }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -776,6 +2600,12 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, "slice-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", @@ -787,12 +2617,64 @@ "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", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-loader": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-1.1.3.tgz", + "integrity": "sha512-6YHeF+XzDOrT/ycFJNI53cgEsp/tHTMl37hi7uVyqFAlTXW109JazaQCkbc+jjoL2637qkH1amLi+JzrIpt5lA==", + "dev": true, + "requires": { + "abab": "^2.0.5", + "iconv-lite": "^0.6.2", + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0", + "source-map": "^0.6.1", + "whatwg-mimetype": "^2.3.0" + } + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "stream-browserify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", + "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", + "dev": true, + "requires": { + "inherits": "~2.0.4", + "readable-stream": "^3.5.0" + } + }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -821,6 +2703,15 @@ } } }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -830,6 +2721,12 @@ "ansi-regex": "^5.0.0" } }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -857,12 +2754,136 @@ "string-width": "^3.0.0" } }, + "table-layout": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.1.tgz", + "integrity": "sha512-dEquqYNJiGwY7iPfZ3wbXDI944iqanTSchrACLL2nOB+1r+h1Nzu2eH+DuPPvWvm5Ry7iAPeFlgEtP5bIp5U7Q==", + "dev": true, + "requires": { + "array-back": "^4.0.1", + "deep-extend": "~0.6.0", + "typical": "^5.2.0", + "wordwrapjs": "^4.0.0" + } + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true + }, + "terser": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.5.1.tgz", + "integrity": "sha512-6VGWZNVP2KTUcltUQJ25TtNjx/XgdDsBDKGt8nN0MpydU36LmbPPcMBd2kmtZNNGVVDLg44k7GKeHHj+4zPIBQ==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.19" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, + "terser-webpack-plugin": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.0.3.tgz", + "integrity": "sha512-zFdGk8Lh9ZJGPxxPE6jwysOlATWB8GMW8HcfGULWA/nPal+3VdATflQvSBSLQJRCmYZnfFJl6vkRTiwJGNgPiQ==", + "dev": true, + "requires": { + "jest-worker": "^26.6.1", + "p-limit": "^3.0.2", + "schema-utils": "^3.0.0", + "serialize-javascript": "^5.0.1", + "source-map": "^0.6.1", + "terser": "^5.3.8" + } + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true + }, + "ts-loader": { + "version": "8.0.11", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.0.11.tgz", + "integrity": "sha512-06X+mWA2JXoXJHYAesUUL4mHFYhnmyoCdQVMXofXF552Lzd4wNwSGg7unJpttqUP7ziaruM8d7u8LUB6I1sgzA==", + "dev": true, + "requires": { + "chalk": "^2.3.0", + "enhanced-resolve": "^4.0.0", + "loader-utils": "^1.0.2", + "micromatch": "^4.0.0", + "semver": "^6.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" + } + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -878,6 +2899,34 @@ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typescript": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.2.tgz", + "integrity": "sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ==", + "dev": true + }, + "typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, "uri-js": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", @@ -887,12 +2936,182 @@ "punycode": "^2.1.0" } }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, "v8-compile-cache": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", "dev": true }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, + "watchpack": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.0.tgz", + "integrity": "sha512-UjgD1mqjkG99+3lgG36at4wPnUXNvis2v1utwTgQ43C22c4LD71LsYMExdWXh4HZ+RmW+B0t1Vrg2GpXAkTOQw==", + "dev": true, + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, + "webpack": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.10.0.tgz", + "integrity": "sha512-P0bHAXmIz0zsNcHNLqFmLY1ZtrT+jtBr7FqpuDtA2o7GiHC+zBsfhgK7SmJ1HG7BAEb3G9JoMdSVi7mEDvG3Zg==", + "dev": true, + "requires": { + "@types/eslint-scope": "^3.7.0", + "@types/estree": "^0.0.45", + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/wasm-edit": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "acorn": "^8.0.4", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.3.1", + "eslint-scope": "^5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.4", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^4.1.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "pkg-dir": "^5.0.0", + "schema-utils": "^3.0.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.0.3", + "watchpack": "^2.0.0", + "webpack-sources": "^2.1.1" + }, + "dependencies": { + "acorn": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.4.tgz", + "integrity": "sha512-XNP0PqF1XD19ZlLKvB7cMmnZswW4C/03pRHgirB30uSJTaS3A3V1/P4sS3HPvFmjoriPCJQs+JDSbm4bL1TxGQ==", + "dev": true + }, + "enhanced-resolve": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.4.0.tgz", + "integrity": "sha512-ZmqfWURB2lConOBM1JdCVfPyMRv5RdKWktLXO6123p97ovVm2CLBgw9t5MBj3jJWA6eHyOeIws9iJQoGFR4euQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.0.0" + } + }, + "tapable": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", + "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", + "dev": true + } + } + }, + "webpack-bundle-analyzer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.2.0.tgz", + "integrity": "sha512-gmjpdL/AJeGAftSzA+bjIPiChUffjBelcH2+3woCUiRpQfuwrTJuWRyZuqegiwBAroMJp7gIwcJaGeol039zbQ==", + "dev": true, + "requires": { + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "chalk": "^4.1.0", + "commander": "^6.2.0", + "express": "^4.17.1", + "filesize": "^6.1.0", + "gzip-size": "^6.0.0", + "lodash": "^4.17.20", + "opener": "^1.5.2", + "ws": "^7.3.1" + }, + "dependencies": { + "acorn": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.4.tgz", + "integrity": "sha512-XNP0PqF1XD19ZlLKvB7cMmnZswW4C/03pRHgirB30uSJTaS3A3V1/P4sS3HPvFmjoriPCJQs+JDSbm4bL1TxGQ==", + "dev": true + }, + "commander": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.0.tgz", + "integrity": "sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==", + "dev": true + } + } + }, + "webpack-cli": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.2.0.tgz", + "integrity": "sha512-EIl3k88vaF4fSxWSgtAQR+VwicfLMTZ9amQtqS4o+TDPW9HGaEpbFBbAZ4A3ZOT5SOnMxNOzROsSTPiE8tBJPA==", + "dev": true, + "requires": { + "@webpack-cli/info": "^1.1.0", + "@webpack-cli/serve": "^1.1.0", + "colorette": "^1.2.1", + "command-line-usage": "^6.1.0", + "commander": "^6.2.0", + "enquirer": "^2.3.6", + "execa": "^4.1.0", + "import-local": "^3.0.2", + "interpret": "^2.2.0", + "leven": "^3.1.0", + "rechoir": "^0.7.0", + "v8-compile-cache": "^2.2.0", + "webpack-merge": "^4.2.2" + }, + "dependencies": { + "commander": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.0.tgz", + "integrity": "sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==", + "dev": true + } + } + }, + "webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "dev": true, + "requires": { + "lodash": "^4.17.15" + } + }, + "webpack-sources": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", + "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", + "dev": true, + "requires": { + "source-list-map": "^2.0.1", + "source-map": "^0.6.1" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -908,25 +3127,38 @@ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, + "wordwrapjs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.0.tgz", + "integrity": "sha512-Svqw723a3R34KvsMgpjFBYCgNOSdcW3mQFK4wIfhGQhtaFVOJmdYoXgi63ne3dTlWgatVcUc7t4HtQ/+bUVIzQ==", + "dev": true, + "requires": { + "reduce-flatten": "^2.0.0", + "typical": "^5.0.0" + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, "ws": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.0.tgz", - "integrity": "sha512-kyFwXuV/5ymf+IXhS6f0+eAFvydbaBW3zjpT6hUdAh/hbVjTIB5EHBGi0bPoCLSK2wcuz3BrEkB9LrYv1Nm4NQ==" + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.1.tgz", + "integrity": "sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ==" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } diff --git a/package.json b/package.json index b9059d6e..cbbba851 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,49 @@ { "name": "bybit-api", - "version": "1.2.5", + "version": "1.3.0-beta.1", "description": "A production-ready Node.js connector for the Bybit APIs and WebSockets", - "main": "index.js", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "files": [ + "lib/*", + "index.js", + "dist/*" + ], "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "echo \"Error: no test specified\" && exit 1", + "clean": "rm -rf lib dist", + "prebuild": "npm run clean", + "build": "tsc", + "pack": "webpack --config webpack/webpack.config.js", + "prepush": "npm run build", + "prepublish": "npm run build" }, "repository": { "type": "git", "url": "https://github.com/tiagosiebler/bybit-api" }, + "author": "Tiago Siebler (https://github.com/tiagosiebler)", + "contributors": [ + "Stefan Aebischer (https://pixtron.ch)" + ], + "dependencies": { + "axios": "^0.21.0", + "isomorphic-ws": "^4.0.1", + "ws": "^7.4.0" + }, + "devDependencies": { + "@types/node": "^14.14.7", + "buffer": "^6.0.2", + "crypto-browserify": "^3.12.0", + "eslint": "^7.10.0", + "source-map-loader": "^1.1.2", + "stream-browserify": "^3.0.0", + "ts-loader": "^8.0.11", + "typescript": "^4.0.5", + "webpack": "^5.4.0", + "webpack-bundle-analyzer": "^4.1.0", + "webpack-cli": "^4.2.0" + }, "keywords": [ "bybit", "api", @@ -24,20 +58,13 @@ "bitcoin", "best" ], - "author": "Tiago Siebler (https://github.com/tiagosiebler)", - "contributors": [ - "Stefan Aebischer (https://pixtron.ch)" - ], + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/tiagosiebler" + }, "license": "MIT", "bugs": { "url": "https://github.com/tiagosiebler/bybit-api/issues" }, - "homepage": "https://github.com/tiagosiebler/bybit-api#readme", - "dependencies": { - "axios": "^0.21.0", - "ws": "^7.3.1" - }, - "devDependencies": { - "eslint": "^7.10.0" - } + "homepage": "https://github.com/tiagosiebler/bybit-api#readme" } diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 00000000..ab8ec691 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,3 @@ +export * from './rest-client'; +export * from './websocket-client'; +export * from './logger'; diff --git a/src/logger.ts b/src/logger.ts new file mode 100644 index 00000000..0f5f29e9 --- /dev/null +++ b/src/logger.ts @@ -0,0 +1,22 @@ +export type LogParams = null | any; + +export const DefaultLogger = { + silly: (...params: LogParams): void => { + console.log(params); + }, + debug: (...params: LogParams): void => { + console.log(params); + }, + notice: (...params: LogParams): void => { + console.log(params); + }, + info: (...params: LogParams): void => { + console.info(params); + }, + warning: (...params: LogParams): void => { + console.error(params); + }, + error: (...params: LogParams): void => { + console.error(params); + } +}; \ No newline at end of file diff --git a/src/rest-client.ts b/src/rest-client.ts new file mode 100644 index 00000000..79b08558 --- /dev/null +++ b/src/rest-client.ts @@ -0,0 +1,531 @@ +import { AxiosRequestConfig } from 'axios'; +import { GenericAPIResponse, getBaseRESTInverseUrl, RestClientInverseOptions } from './util/requestUtils'; +import RequestWrapper from './util/requestWrapper'; + +export class RestClient { + private requestWrapper: RequestWrapper; + + /** + * @public Creates an instance of the inverse REST API client. + * + * @param {string} key - your API key + * @param {string} secret - your API secret + * @param {boolean} [useLivenet=false] + * @param {RestClientInverseOptions} [restInverseOptions={}] options to configure REST API connectivity + * @param {AxiosRequestConfig} [requestOptions={}] HTTP networking options for axios + */ + constructor( + key?: string | undefined, + secret?: string | undefined, + useLivenet?: boolean, + restInverseOptions: RestClientInverseOptions = {}, + httpOptions: AxiosRequestConfig = {} + ) { + this.requestWrapper = new RequestWrapper( + key, + secret, + getBaseRESTInverseUrl(useLivenet), + restInverseOptions, + httpOptions + ); + return this; + } + + /** + * + * Market Data Endpoints + * + */ + + getOrderBook(params: { + symbol: string; + }): GenericAPIResponse { + return this.requestWrapper.get('v2/public/orderBook/L2', params); + } + + getKline(params: { + symbol: string; + interval: string; + from: number; + limit?: number; + }): GenericAPIResponse { + return this.requestWrapper.get('v2/public/kline/list', params); + } + + /** + * @deprecated use getTickers() instead + */ + getLatestInformation(params?: { + symbol?: string; + }): GenericAPIResponse { + return this.getTickers(params); + } + + getTickers(params?: { + symbol?: string; + }): GenericAPIResponse { + return this.requestWrapper.get('v2/public/tickers', params); + } + + /** + * @deprecated use getTrades() instead + */ + getPublicTradingRecords(params: { + symbol: string; + from?: number; + limit?: number; + }): GenericAPIResponse { + return this.getTrades(params); + } + + getTrades(params: { + symbol: string; + from?: number; + limit?: number; + }): GenericAPIResponse { + return this.requestWrapper.get('v2/public/trading-records', params); + } + + getSymbols(): GenericAPIResponse { + return this.requestWrapper.get('v2/public/symbols'); + } + + /** + * @deprecated use getLiquidations() instead + */ + getPublicLiquidations(params: { + symbol: string; + from?: number; + limit?: number; + start_time?: number; + end_time?: number; + }): GenericAPIResponse { + return this.getLiquidations(params); + } + + getLiquidations(params: { + symbol: string; + from?: number; + limit?: number; + start_time?: number; + end_time?: number; + }): GenericAPIResponse { + return this.requestWrapper.get('v2/public/liq-records', params); + } + + getMarkPriceKline(params: { + symbol: string; + interval: string; + from: number; + limit?: number; + }): GenericAPIResponse { + return this.requestWrapper.get('v2/public/mark-price-kline', params); + } + + getOpenInterest(params: { + symbol: string; + period: string; + limit?: number; + }): GenericAPIResponse { + return this.requestWrapper.get('v2/public/open-interest', params); + } + + getLatestBigDeal(params: { + symbol: string; + limit?: number; + }): GenericAPIResponse { + return this.requestWrapper.get('v2/public/big-deal', params); + } + + getLongShortRatio(params: { + symbol: string; + period: string; + limit?: number; + }): GenericAPIResponse { + return this.requestWrapper.get('v2/public/account-ratio', params); + } + + /** + * + * Account Data Endpoints + * + */ + + placeActiveOrder(orderRequest: { + side: string; + symbol: string; + order_type: string; + qty: number; + price?: number; + time_in_force: string; + take_profit?: number; + stop_loss?: number; + reduce_only?: boolean; + close_on_trigger?: boolean; + order_link_id?: string; + }): GenericAPIResponse { + // if (orderRequest.order_type === 'Limit' && !orderRequest.price) { + // throw new Error('Price required for limit orders'); + // } + return this.requestWrapper.post('v2/private/order/create', orderRequest); + } + + getActiveOrderList(params: { + symbol: string; + order_status?: string; + direction?: string; + limit?: number; + cursor?: string; + }): GenericAPIResponse { + return this.requestWrapper.get('v2/private/order/list', params); + } + + /** + * @deprecated use getActiveOrderList() instead + */ + getActiveOrder(params: { + order_id?: string; + order_link_id?: string; + symbol?: string; + order?: string; + page?: number; + limit?: number; + order_status?: string; + }): GenericAPIResponse { + return this.requestWrapper.get('open-api/order/list', params); + } + + cancelActiveOrder(params: { + symbol: string; + order_id?: string; + order_link_id?: string; + }): GenericAPIResponse { + // if (!params.order_id && !params.order_link_id) { + // throw new Error('Parameter order_id OR order_link_id is required'); + // } + return this.requestWrapper.post('v2/private/order/cancel', params); + } + + cancelAllActiveOrders(params: { + symbol: string; + }): GenericAPIResponse { + return this.requestWrapper.post('v2/private/order/cancelAll', params); + } + + replaceActiveOrder(params: { + order_id?: string; + order_link_id?: string; + symbol: string; + p_r_qty?: string; + p_r_price?: string; + }): GenericAPIResponse { + // if (!params.order_id && !params.order_link_id) { + // throw new Error('Parameter order_id OR order_link_id is required'); + // } + return this.requestWrapper.post('v2/private/order/replace', params); + } + + /** + * @deprecated use replaceActiveOrder() + */ + replaceActiveOrderOld(params: any): GenericAPIResponse { + // if (!params.order_id && !params.order_link_id) { + // throw new Error('Parameter order_id OR order_link_id is required'); + // } + return this.requestWrapper.post('open-api/order/replace', params); + } + + queryActiveOrder(params: { + order_id?: string; + order_link_id?: string; + symbol: string; + }): GenericAPIResponse { + // if (!params.order_id && !params.order_link_id) { + // throw new Error('Parameter order_id OR order_link_id is required'); + // } + return this.requestWrapper.get('v2/private/order', params); + } + + placeConditionalOrder(params: { + side: string; + symbol: string; + order_type: string; + qty: string; + price?: string; + base_price: string; + stop_px: string; + time_in_force: string; + trigger_by?: string; + close_on_trigger?: boolean; + order_link_id?: string; + }): GenericAPIResponse { + // if (params.order_type === 'Limit' && !params.price) { + // throw new Error('Parameter price is required for limit orders'); + // } + return this.requestWrapper.post('v2/private/stop-order/create', params); + } + + /** + * @deprecated use placeConditionalOrder + */ + placeConditionalOrderOld(params: any): GenericAPIResponse { + // if (params.order_type === 'Limit' && !params.price) { + // throw new Error('Parameter price is required for limit orders'); + // } + return this.requestWrapper.post('open-api/stop-order/create', params); + } + + getConditionalOrder(params: { + symbol: string; + stop_order_status?: string; + direction?: string; + limit?: number; + cursor?: string; + }): GenericAPIResponse { + return this.requestWrapper.get('v2/private/stop-order/list', params); + } + + /** + * @deprecated use placeConditionalOrder + */ + getConditionalOrderOld(params: any): GenericAPIResponse { + return this.requestWrapper.get('open-api/stop-order/list', params); + } + + cancelConditionalOrder(params: { + symbol: string; + stop_order_id?: string; + order_link_id?: string; + }): GenericAPIResponse { + // if (!params.stop_order_id && !params.order_link_id) { + // throw new Error('Parameter stop_order_id OR order_link_id is required'); + // } + return this.requestWrapper.post('v2/private/stop-order/cancel', params); + } + + /** + * @deprecated use cancelConditionalOrder + */ + cancelConditionalOrderOld(params: any): GenericAPIResponse { + // if (!params.stop_order_id && !params.order_link_id) { + // throw new Error('Parameter stop_order_id OR order_link_id is required'); + // } + return this.requestWrapper.post('open-api/stop-order/cancel', params); + } + + cancelAllConditionalOrders(params: { + symbol: string; + }): GenericAPIResponse { + return this.requestWrapper.post('v2/private/stop-order/cancelAll', params); + } + + replaceConditionalOrder(params: { + stop_order_id?: string; + order_link_id?: string; + symbol: string; + p_r_qty?: number; + p_r_price?: string; + p_r_trigger_price?: string; + }): GenericAPIResponse { + // if (!params.stop_order_id && !params.order_link_id) { + // throw new Error('Parameter stop_order_id OR order_link_id is required'); + // } + return this.requestWrapper.post('v2/private/stop-order/replace', params); + } + + /** + * @deprecated use replaceConditionalOrder + */ + replaceConditionalOrderOld(params: any): GenericAPIResponse { + return this.requestWrapper.post('open-api/stop-order/replace', params); + } + + queryConditionalOrder(params: { + symbol: string; + stop_order_id?: string; + order_link_id?: string; + }): GenericAPIResponse { + // if (!params.stop_order_id && !params.order_link_id) { + // throw new Error('Parameter stop_order_id OR order_link_id is required'); + // } + return this.requestWrapper.get('v2/private/stop-order', params); + } + + /** + * @deprecated use getPosition() instead + */ + getUserLeverage(): GenericAPIResponse { + return this.requestWrapper.get('user/leverage'); + } + + getPosition(params?: { + symbol?: string; + }): GenericAPIResponse { + return this.requestWrapper.get('v2/private/position/list', params); + } + + /** + * @deprecated use getPosition() instead + */ + getPositions(): GenericAPIResponse { + return this.requestWrapper.get('position/list'); + } + + changePositionMargin(params: { + symbol: string; + margin: string; + }): GenericAPIResponse { + return this.requestWrapper.post('position/change-position-margin', params); + } + + setTradingStop(params: { + symbol: string; + take_profit?: number; + stop_loss?: number; + tp_trigger_by?: string; + sl_trigger_by?: string; + new_trailing_active?: number; + }): GenericAPIResponse { + return this.requestWrapper.post('open-api/position/trading-stop', params); + } + + setUserLeverage(params: { + symbol: string; + leverage: number; + }): GenericAPIResponse { + return this.requestWrapper.post('user/leverage/save', params); + } + + /** + * @deprecated use setUserLeverage() instead + */ + changeUserLeverage(params: any): GenericAPIResponse { + return this.setUserLeverage(params); + } + + getTradeRecords(params: { + order_id?: string; + symbol: string; + start_time?: number; + page?: number; + limit?: number; + order?: string; + }): GenericAPIResponse { + return this.requestWrapper.get('v2/private/execution/list', params); + } + + getClosedPnl(params: { + symbol: string; + start_time?: number; + end_time?: number; + exec_type?: string; + page?: number; + limit?: number; + }): GenericAPIResponse { + return this.requestWrapper.get('v2/private/trade/closed-pnl/list', params); + } + + getRiskLimitList(): GenericAPIResponse { + return this.requestWrapper.get('open-api/wallet/risk-limit/list'); + } + + setRiskLimit(params: { + symbol: string; + risk_id: string; + }): GenericAPIResponse { + return this.requestWrapper.post('open-api/wallet/risk-limit', params); + } + + getLastFundingRate(params: { + symbol: string; + }): GenericAPIResponse { + return this.requestWrapper.get('open-api/funding/prev-funding-rate', params); + } + + getMyLastFundingFee(params: { + symbol: string; + }): GenericAPIResponse { + return this.requestWrapper.get('open-api/funding/prev-funding', params); + } + + getPredictedFunding(params: { + symbol: string; + }): GenericAPIResponse { + return this.requestWrapper.get('open-api/funding/predicted-funding', params); + } + + getApiKeyInfo(): GenericAPIResponse { + return this.requestWrapper.get('open-api/api-key'); + } + + getLcpInfo(params: { + symbol: string; + }): GenericAPIResponse { + return this.requestWrapper.get('v2/private/account/lcp', params); + } + + /** + * + * Wallet Data Endpoints + * + */ + + getWalletBalance(params?: { + coin?: string; + }): GenericAPIResponse { + return this.requestWrapper.get('v2/private/wallet/balance', params); + } + + getWalletFundRecords(params?: { + start_date?: string; + end_date?: string; + currency?: string; + coin?: string; + wallet_fund_type?: string; + page?: number; + limit?: number; + }): GenericAPIResponse { + return this.requestWrapper.get('open-api/wallet/fund/records', params); + } + + getWithdrawRecords(params: { + start_date?: string; + end_date?: string; + coin?: string; + status?: string; + page?: number; + limit?: number; + }): GenericAPIResponse { + return this.requestWrapper.get('open-api/wallet/withdraw/list', params); + } + + getAssetExchangeRecords(params?: { + limit?: number; + from?: number; + direction?: string; + }): GenericAPIResponse { + return this.requestWrapper.get('v2/private/exchange-order/list', params); + } + + /** + * + * API Data Endpoints + * + */ + + getServerTime(): GenericAPIResponse { + return this.requestWrapper.get('v2/public/time'); + } + + getApiAnnouncements(): GenericAPIResponse { + return this.requestWrapper.get('v2/public/announcement'); + } + + async getTimeOffset(): Promise { + const start = Date.now(); + return this.getServerTime().then(result => { + const end = Date.now(); + return Math.ceil((result.time_now * 1000) - end + ((end - start) / 2)); + }); + } +}; diff --git a/src/util/requestUtils.ts b/src/util/requestUtils.ts new file mode 100644 index 00000000..b5f57613 --- /dev/null +++ b/src/util/requestUtils.ts @@ -0,0 +1,59 @@ +import { createHmac } from 'crypto'; + +export interface RestClientInverseOptions { + // override the max size of the request window (in ms) + recv_window?: number; + + // how often to sync time drift with bybit servers + sync_interval_ms?: number | string; + + // Default: false. Disable above sync mechanism if true. + disable_time_sync?: boolean; + + // Default: false. If true, we'll throw errors if any params are undefined + strict_param_validation?: boolean; + + // Optionally override API protocol + domain + // e.g 'https://api.bytick.com' + baseUrl?: string; + + // Default: true. whether to try and post-process request exceptions. + parse_exceptions?: boolean; +} + +export type GenericAPIResponse = Promise; + +export function signMessage(message: string, secret: string): string { + return createHmac('sha256', secret) + .update(message) + .digest('hex'); +}; + +export function serializeParams(params: object = {}, strict_validation = false): string { + return Object.keys(params) + .sort() + .map(key => { + const value = params[key]; + if (strict_validation === true && typeof value === 'undefined') { + throw new Error('Failed to sign API request due to undefined parameter'); + } + return `${key}=${value}`; + }) + .join('&'); +}; + +export function getBaseRESTInverseUrl(useLivenet?: boolean, restInverseOptions?: RestClientInverseOptions) { + const baseUrlsInverse = { + livenet: 'https://api.bybit.com', + testnet: 'https://api-testnet.bybit.com' + }; + + if (restInverseOptions?.baseUrl) { + return restInverseOptions.baseUrl; + } + + if (useLivenet === true) { + return baseUrlsInverse.livenet; + } + return baseUrlsInverse.testnet; +} \ No newline at end of file diff --git a/src/util/requestWrapper.ts b/src/util/requestWrapper.ts new file mode 100644 index 00000000..217c5ca0 --- /dev/null +++ b/src/util/requestWrapper.ts @@ -0,0 +1,193 @@ +import axios, { AxiosRequestConfig, AxiosResponse, Method } from 'axios'; + +import { signMessage, serializeParams, RestClientInverseOptions, GenericAPIResponse } from './requestUtils'; + +export default class RequestUtil { + private timeOffset: number | null; + private syncTimePromise: null | Promise; + private options: RestClientInverseOptions; + private baseUrl: string; + private globalRequestOptions: AxiosRequestConfig; + private key: string | undefined; + private secret: string | undefined; + + constructor( + key: string | undefined, + secret: string | undefined, + baseUrl: string, + options: RestClientInverseOptions = {}, + requestOptions: AxiosRequestConfig = {} + ) { + this.timeOffset = null; + this.syncTimePromise = null; + + this.options = { + recv_window: 5000, + // how often to sync time drift with bybit servers + sync_interval_ms: 3600000, + // if true, we'll throw errors if any params are undefined + strict_param_validation: false, + ...options + }; + + this.globalRequestOptions = { + // in ms == 5 minutes by default + timeout: 1000 * 60 * 5, + // custom request options based on axios specs - see: https://github.com/axios/axios#request-config + ...requestOptions, + headers: { + 'x-referer': 'bybitapinode' + }, + }; + + this.baseUrl = baseUrl; + + if (key && !secret) { + throw new Error('API Key & Secret are both required for private enpoints') + } + + if (this.options.disable_time_sync !== true) { + this.syncTime(); + setInterval(this.syncTime.bind(this), +this.options.sync_interval_ms!); + } + + this.key = key; + this.secret = secret; + } + + // TODO: type check that endpoint never starts with forward slash?? + get(endpoint: string, params?: any): GenericAPIResponse { + return this._call('GET', endpoint, params); + } + + post(endpoint: string, params?: any): GenericAPIResponse { + return this._call('POST', endpoint, params); + } + + /** + * @private Make a HTTP request to a specific endpoint. Private endpoints are automatically signed. + */ + async _call(method: Method, endpoint: string, params?: any): GenericAPIResponse { + const publicEndpoint = endpoint.startsWith('v2/public'); + + if (!publicEndpoint) { + if (!this.key || !this.secret) { + throw new Error('Private endpoints require api and private keys set'); + } + + if (this.timeOffset === null) { + await this.syncTime(); + } + + params = this.signRequest(params); + } + + const options = { + ...this.globalRequestOptions, + url: [this.baseUrl, endpoint].join('/'), + method: method, + json: true + }; + + if (method === 'GET') { + options.params = params; + } else { + options.data = params; + } + + return axios(options).then(response => { + if (response.status == 200) { + return response.data; + } + + throw response; + }).catch(this.parseException); + } + + /** + * @private generic handler to parse request exceptions + */ + parseException(e: any): unknown { + if (this.options.parse_exceptions === false) { + throw e; + } + + // Something happened in setting up the request that triggered an Error + if (!e.response) { + if (!e.request) { + throw e.message; + } + + // request made but no response received + throw e; + } + + // The request was made and the server responded with a status code + // that falls out of the range of 2xx + const response: AxiosResponse = e.response; + throw { + code: response.status, + message: response.statusText, + body: response.data, + headers: response.headers, + requestOptions: this.options + }; + } + + /** + * @private sign request and set recv window + */ + signRequest(data: any): any { + const params = { + ...data, + api_key: this.key, + timestamp: Date.now() + (this.timeOffset || 0) + }; + + // Optional, set to 5000 by default. Increase if timestamp/recv_window errors are seen. + if (this.options.recv_window && !params.recv_window) { + params.recv_window = this.options.recv_window; + } + + if (this.key && this.secret) { + const serializedParams = serializeParams(params, this.options.strict_param_validation); + params.sign = signMessage(serializedParams, this.secret); + } + + return params; + } + + /** + * @private trigger time sync and store promise + */ + syncTime(): GenericAPIResponse { + if (this.options.disable_time_sync === true) { + return Promise.resolve(false); + } + + if (this.syncTimePromise !== null) { + return this.syncTimePromise; + } + + this.syncTimePromise = this.getTimeOffset().then(offset => { + this.timeOffset = offset; + this.syncTimePromise = null; + }); + + return this.syncTimePromise; + } + + /** + * @deprecated move this somewhere else, because v2/public/time shouldn't be hardcoded here + * + * @returns {Promise} + * @memberof RequestUtil + */ + async getTimeOffset(): Promise { + const start = Date.now(); + const result = await this.get('v2/public/time'); + const end = Date.now(); + + return Math.ceil((result.time_now * 1000) - end + ((end - start) / 2)); + } +}; diff --git a/lib/websocket-client.js b/src/websocket-client.ts similarity index 65% rename from lib/websocket-client.js rename to src/websocket-client.ts index f8e9c55b..2a29dc70 100644 --- a/lib/websocket-client.js +++ b/src/websocket-client.ts @@ -1,9 +1,10 @@ -const { EventEmitter } = require('events'); -const WebSocket = require('ws'); +import { EventEmitter } from 'events'; -const defaultLogger = require('./logger'); -const RestClient = require('./rest-client'); -const { signMessage, serializeParams } = require('./util/requestUtils'); +import { DefaultLogger } from './logger'; +import { RestClient } from './rest-client'; +import { signMessage, serializeParams } from './util/requestUtils'; +// import WebSocket from 'ws'; +import WebSocket from 'isomorphic-ws'; const wsUrls = { livenet: 'wss://stream.bybit.com/realtime', @@ -16,15 +17,39 @@ const READY_STATE_CONNECTED = 2; const READY_STATE_CLOSING = 3; const READY_STATE_RECONNECTING = 4; -module.exports = class WebsocketClient extends EventEmitter { - constructor(options, logger) { +export interface WebsocketClientOptions { + key?: string; + secret?: string; + livenet?: boolean; + + pongTimeout?: number; + pingInterval?: number; + reconnectTimeout?: number; + restOptions?: any; + requestOptions?: any; + wsUrl?: string; +}; + +type Logger = typeof DefaultLogger; + +export class WebsocketClient extends EventEmitter { + private logger: Logger; + private readyState: number; + private pingInterval?: number | undefined; + private pongTimeout?: number | undefined; + private client: RestClient; + private _subscriptions: Set; + private ws: WebSocket; + private options: WebsocketClientOptions; + + constructor(options: WebsocketClientOptions, logger?: Logger) { super(); - this.logger = logger || defaultLogger; + this.logger = logger || DefaultLogger; this.readyState = READY_STATE_INITIAL; - this.pingInterval = null; - this.pongTimeout = null; + this.pingInterval = undefined; + this.pongTimeout = undefined; this.options = { livenet: false, @@ -34,7 +59,7 @@ module.exports = class WebsocketClient extends EventEmitter { ...options }; - this.client = new RestClient(null, null, this.options.livenet, this.options.restOptions, this.options.requestOptions); + this.client = new RestClient(undefined, undefined, this.options.livenet, this.options.restOptions, this.options.requestOptions); this._subscriptions = new Set(); this._connect(); @@ -78,14 +103,22 @@ module.exports = class WebsocketClient extends EventEmitter { const authParams = await this._authenticate(); const url = this._getWsUrl() + authParams; - this.ws = new WebSocket(url); + const ws = new WebSocket(url); + + // ws.onopen!(this._wsOpenHandler.bind(this)); + // ws.onmessage!(this._wsMessageHandler.bind(this)); + // ws.onerror!(this._wsOnErrorHandler.bind(this)); + // ws.onclose!(this._wsCloseHandler.bind(this)); + + ws.onopen = this._wsOpenHandler.bind(this); + ws.onmessage = this._wsMessageHandler.bind(this); + ws.onerror = this._wsOnErrorHandler.bind(this); + ws.onclose = this._wsCloseHandler.bind(this); + + this.ws = ws; - this.ws.on('open', this._wsOpenHandler.bind(this)); - this.ws.on('message', this._wsMessageHandler.bind(this)); - this.ws.on('error', this._wsOnErrorHandler.bind(this)); - this.ws.on('close', this._wsCloseHandler.bind(this)); } catch (err) { - this.logger.error('Connection failed', err); + this.logger.error('Connection failed: ', err); this._reconnect(this.options.reconnectTimeout); } } @@ -96,7 +129,7 @@ module.exports = class WebsocketClient extends EventEmitter { const timeOffset = await this.client.getTimeOffset(); - const params = { + const params: any = { api_key: this.options.key, expires: (Date.now() + timeOffset + 5000) }; @@ -105,9 +138,9 @@ module.exports = class WebsocketClient extends EventEmitter { return '?' + serializeParams(params); } else if (this.options.key || this.options.secret) { - this.logger.warning('Could not authenticate websocket, either api key or private key missing.', {category: 'bybit-ws'}); + this.logger.warning('Could not authenticate websocket, either api key or private key missing.', { category: 'bybit-ws' }); } else { - this.logger.debug('Starting public only websocket client.', {category: 'bybit-ws'}); + this.logger.debug('Starting public only websocket client.', { category: 'bybit-ws' }); } return ''; @@ -120,23 +153,25 @@ module.exports = class WebsocketClient extends EventEmitter { } setTimeout(() => { - this.logger.info('Reconnecting to server', {category: 'bybit-ws'}); + this.logger.info('Reconnecting to server', { category: 'bybit-ws' }); this._connect(); }, timeout); } _ping() { - clearTimeout(this.pongTimeout); - this.pongTimeout = null; + clearTimeout(this.pongTimeout!); + delete this.pongTimeout; - this.logger.silly('Sending ping', {category: 'bybit-ws'}); + this.logger.silly('Sending ping', { category: 'bybit-ws' }); this.ws.send(JSON.stringify({op: 'ping'})); this.pongTimeout = setTimeout(() => { - this.logger.info('Pong timeout', {category: 'bybit-ws'}); + this.logger.info('Pong timeout', { category: 'bybit-ws' }); this._teardown(); - this.ws.terminate(); + // this.ws.terminate(); + // TODO: does this work? + this.ws.close(); }, this.options.pongTimeout); } @@ -144,16 +179,16 @@ module.exports = class WebsocketClient extends EventEmitter { if (this.pingInterval) clearInterval(this.pingInterval); if (this.pongTimeout) clearTimeout(this.pongTimeout); - this.pongTimeout = null; - this.pingInterval = null; + this.pongTimeout = undefined; + this.pingInterval = undefined; } _wsOpenHandler() { if (this.readyState === READY_STATE_CONNECTING) { - this.logger.info('Websocket connected', {category: 'bybit-ws', livenet: this.options.livenet}); + this.logger.info('Websocket connected', { category: 'bybit-ws', livenet: this.options.livenet }); this.emit('open'); } else if (this.readyState === READY_STATE_RECONNECTING) { - this.logger.info('Websocket reconnected', {category: 'bybit-ws', livenet: this.options.livenet}); + this.logger.info('Websocket reconnected', { category: 'bybit-ws', livenet: this.options.livenet }); this.emit('reconnected'); } @@ -164,7 +199,7 @@ module.exports = class WebsocketClient extends EventEmitter { } _wsMessageHandler(message) { - const msg = JSON.parse(message); + const msg = JSON.parse(message && message.data || message); if ('success' in msg) { this._handleResponse(msg); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..c944cc42 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compileOnSave": true, + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "allowJs": true, + "target": "es6", + "moduleResolution": "node", + "module": "commonjs", + "outDir": "lib", + "removeComments": false, + "noEmitOnError": true, + "noImplicitAny": false, + "strictNullChecks": true, + "skipLibCheck": true, + "sourceMap": true, + "esModuleInterop": true, + "lib": ["es2017","dom"], + "baseUrl": ".", + "paths": { + "@src/*": ["src/*"] + } + }, + "include": ["src/**/*"], + "exclude": [ + "node_modules", + "**/node_modules/*", + "coverage", + "doc" + ] +} \ No newline at end of file diff --git a/webpack/webpack.config.js b/webpack/webpack.config.js new file mode 100644 index 00000000..da882d56 --- /dev/null +++ b/webpack/webpack.config.js @@ -0,0 +1,69 @@ +const webpack = require('webpack'); +const path = require('path'); +const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; + +function generateConfig(name) { + var config = { + entry: './lib/index.js', + output: { + path: path.resolve(__dirname, '../dist'), + filename: name + '.js', + sourceMapFilename: name + '.map', + library: 'bybitapi', + libraryTarget: 'umd' + }, + devtool: "source-map", + mode: 'production', + + resolve: { + // Add '.ts' and '.tsx' as resolvable extensions. + extensions: [".webpack.js", ".web.js", ".ts", ".tsx", ".js"], + fallback: { + "crypto": require.resolve("crypto-browserify"), + "buffer": require.resolve("buffer/"), + "stream": require.resolve("stream-browserify") + } + }, + + module: { + rules: [ + // All files with a '.ts' or '.tsx' extension will be handled by 'ts-loader'. + { test: /\.tsx?$/, loader: "ts-loader" }, + + // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'. + { test: /\.js$/, loader: "source-map-loader" }, + + { + test: /\.m?js$/, + exclude: /(node_modules|bower_components|samples|lib|test|coverage)/, + use: { + loader: 'babel-loader', + options: { + presets: [['@babel/preset-env', { + 'targets': { + 'node': 'current' + } + }]] + } + } + } + ] + } + }; + + config.plugins = [ + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) + }), + new BundleAnalyzerPlugin({ + defaultSizes: 'stat', + analyzerMode: 'static', + reportFilename: '../doc/bundleReport.html', + openAnalyzer: false, + }) + ]; + + return config; +}; + +module.exports = generateConfig('bybitapi'); \ No newline at end of file From a75924c0acc874b275a640bf19adfbd9f13b8d1e Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Sun, 13 Dec 2020 17:55:01 +0000 Subject: [PATCH 2/7] 1.3.0-beta.2: types cleanup and webpack trim --- package.json | 13 +++++++------ src/websocket-client.ts | 2 +- tsconfig.json | 1 - 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index cbbba851..18ca7b72 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bybit-api", - "version": "1.3.0-beta.1", + "version": "1.3.0-beta.2", "description": "A production-ready Node.js connector for the Bybit APIs and WebSockets", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -16,11 +16,8 @@ "build": "tsc", "pack": "webpack --config webpack/webpack.config.js", "prepush": "npm run build", - "prepublish": "npm run build" - }, - "repository": { - "type": "git", - "url": "https://github.com/tiagosiebler/bybit-api" + "prepublish": "npm run build", + "betapublish": "npm publish --tag beta" }, "author": "Tiago Siebler (https://github.com/tiagosiebler)", "contributors": [ @@ -63,6 +60,10 @@ "url": "https://github.com/sponsors/tiagosiebler" }, "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/tiagosiebler/bybit-api" + }, "bugs": { "url": "https://github.com/tiagosiebler/bybit-api/issues" }, diff --git a/src/websocket-client.ts b/src/websocket-client.ts index 2a29dc70..8534ee20 100644 --- a/src/websocket-client.ts +++ b/src/websocket-client.ts @@ -1,7 +1,7 @@ import { EventEmitter } from 'events'; -import { DefaultLogger } from './logger'; import { RestClient } from './rest-client'; +import { DefaultLogger } from './logger'; import { signMessage, serializeParams } from './util/requestUtils'; // import WebSocket from 'ws'; import WebSocket from 'isomorphic-ws'; diff --git a/tsconfig.json b/tsconfig.json index c944cc42..4be19e11 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,6 @@ "compileOnSave": true, "compilerOptions": { "declaration": true, - "declarationMap": true, "allowJs": true, "target": "es6", "moduleResolution": "node", From dd67eb5ef085c1fbb2730b3a58e0cfd15bc1b5e2 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Sun, 13 Dec 2020 17:58:07 +0000 Subject: [PATCH 3/7] linting --- webpack/webpack.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webpack/webpack.config.js b/webpack/webpack.config.js index da882d56..e9331115 100644 --- a/webpack/webpack.config.js +++ b/webpack/webpack.config.js @@ -64,6 +64,6 @@ function generateConfig(name) { ]; return config; -}; +} module.exports = generateConfig('bybitapi'); \ No newline at end of file From 50fc33c10c0984ce3f22d88d73ed97f302e1f796 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Sun, 13 Dec 2020 18:29:11 +0000 Subject: [PATCH 4/7] clean docs + add webpack note --- README.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 0ac7d7ce..2495348e 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,6 @@ A production-ready Node.js connector for the Bybit APIs and WebSockets. ## Installation `npm install --save bybit-api` -## Usage -Create API credentials at Bybit -- [Livenet](https://bybit.com/app/user/api-management?affiliate_id=9410&language=en-US&group_id=0&group_type=1) -- [Testnet](https://testnet.bybit.com/app/user/api-management) - ## Issues & Discussion - Issues? Check the [issues tab](https://github.com/tiagosiebler/bybit-api/issues). - Discuss & collaborate with other node devs? Join our [Node.js Algo Traders](https://t.me/nodetraders) engineering community on telegram. @@ -30,6 +25,19 @@ This project uses typescript. Resources are stored in 3 key structures: - [lib](./lib) - the javascript version of the project (compiled from typescript). This should not be edited directly, as it will be overwritten with each release. - [dist](./dist) - the packed bundle of the project for use in browser environments. +## Usage +Create API credentials at Bybit +- [Livenet](https://bybit.com/app/user/api-management?affiliate_id=9410&language=en-US&group_id=0&group_type=1) +- [Testnet](https://testnet.bybit.com/app/user/api-management) + +### Browser Usage +Build a bundle using webpack: +- `npm install` +- `npm build` +- `npm pack` + +The bundle can be found in `lib/`. Altough usage should be largely consistent, smaller differences will exist. Docs TBC. + ### Inverse Contracts #### Rest client ```javascript From 96ef6427c3d17af9df475cea33a75dd20763ee0d Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Sat, 26 Dec 2020 17:44:45 +0000 Subject: [PATCH 5/7] v1.3.0: typescript support --- package.json | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 18ca7b72..0078d6da 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,12 @@ { "name": "bybit-api", - "version": "1.3.0-beta.2", + "version": "1.3.0", "description": "A production-ready Node.js connector for the Bybit APIs and WebSockets", "main": "lib/index.js", "types": "lib/index.d.ts", "files": [ "lib/*", - "index.js", - "dist/*" + "index.js" ], "scripts": { "test": "echo \"Error: no test specified\" && exit 1", @@ -15,7 +14,6 @@ "prebuild": "npm run clean", "build": "tsc", "pack": "webpack --config webpack/webpack.config.js", - "prepush": "npm run build", "prepublish": "npm run build", "betapublish": "npm publish --tag beta" }, From 976ff20437846feda4301d5f8e5b2ae5dbad5d18 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Sat, 26 Dec 2020 17:51:15 +0000 Subject: [PATCH 6/7] cleaning & docs --- README.md | 12 ++++++------ src/websocket-client.ts | 5 ----- tsconfig.json | 8 ++++---- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 2495348e..2d75d553 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [1]: https://www.npmjs.com/package/bybit-api -A production-ready Node.js connector for the Bybit APIs and WebSockets. +A production-ready Node.js connector for the Bybit APIs and WebSockets, with TypeScript & browser support. ## Installation `npm install --save bybit-api` @@ -36,12 +36,12 @@ Build a bundle using webpack: - `npm build` - `npm pack` -The bundle can be found in `lib/`. Altough usage should be largely consistent, smaller differences will exist. Docs TBC. +The bundle can be found in `dist/`. Altough usage should be largely consistent, smaller differences will exist. Documentation is still TODO. ### Inverse Contracts #### Rest client ```javascript -const {RestClient} = require('bybit-api'); +const { RestClient } = require('bybit-api'); const API_KEY = 'xxx'; const PRIVATE_KEY = 'yyy'; @@ -88,11 +88,11 @@ client.changeUserLeverage({leverage: 4, symbol: 'ETHUSD'}) }); ``` -See inverse [rest-client.js](./lib/rest-client.js) for further information. +See inverse [rest-client.ts](./src/rest-client.ts) for further information. #### Websocket client ```javascript -const {WebsocketClient} = require('bybit-api'); +const { WebsocketClient } = require('bybit-api'); const API_KEY = 'xxx'; const PRIVATE_KEY = 'yyy'; @@ -150,7 +150,7 @@ ws.on('error', err => { console.error('ERR', err); }); ``` -See inverse [websocket-client.js](./lib/websocket-client.js) & [ws api docs](./doc/websocket-client.md) for further information. +See inverse [websocket-client.ts](./src/websocket-client.ts) for further information. ### Customise Logging Pass a custom logger which supports the log methods `silly`, `debug`, `notice`, `info`, `warning` and `error`, or override methods from the default logger as desired: diff --git a/src/websocket-client.ts b/src/websocket-client.ts index 8534ee20..8b80c80f 100644 --- a/src/websocket-client.ts +++ b/src/websocket-client.ts @@ -105,11 +105,6 @@ export class WebsocketClient extends EventEmitter { const ws = new WebSocket(url); - // ws.onopen!(this._wsOpenHandler.bind(this)); - // ws.onmessage!(this._wsMessageHandler.bind(this)); - // ws.onerror!(this._wsOnErrorHandler.bind(this)); - // ws.onclose!(this._wsCloseHandler.bind(this)); - ws.onopen = this._wsOpenHandler.bind(this); ws.onmessage = this._wsMessageHandler.bind(this); ws.onerror = this._wsOnErrorHandler.bind(this); diff --git a/tsconfig.json b/tsconfig.json index 4be19e11..02c8de22 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,21 +1,21 @@ { "compileOnSave": true, "compilerOptions": { - "declaration": true, "allowJs": true, "target": "es6", - "moduleResolution": "node", "module": "commonjs", - "outDir": "lib", + "moduleResolution": "node", + "declaration": true, + "sourceMap": true, "removeComments": false, "noEmitOnError": true, "noImplicitAny": false, "strictNullChecks": true, "skipLibCheck": true, - "sourceMap": true, "esModuleInterop": true, "lib": ["es2017","dom"], "baseUrl": ".", + "outDir": "lib", "paths": { "@src/*": ["src/*"] } From 1eeddf5545cd9a48b561ff498f09278ecad2830c Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Sat, 26 Dec 2020 17:51:57 +0000 Subject: [PATCH 7/7] deprecate REST docs --- doc/rest-client.md | 157 --------------------------------------------- 1 file changed, 157 deletions(-) delete mode 100644 doc/rest-client.md diff --git a/doc/rest-client.md b/doc/rest-client.md deleted file mode 100644 index 7d4a074a..00000000 --- a/doc/rest-client.md +++ /dev/null @@ -1,157 +0,0 @@ -# Rest API - - -## Class: RestClient -### new RestClient([key][, secret][, livenet][, options]) -- `key` {String} Bybit API Key -- `secret` {String} Bybit private key -- `livenet` {Boolean} If false (default), use testnet. -- `options` {Object} Optional settings for custom behaviour. - - `recv_window` {Number} Optional, default 5000. Increase if recv errors are seen. - - `sync_interval_ms` {Number} Optional, default 3600000. Interval at which syncTime is performed. - -If you only use the [public endpoints](#public-endpoints) you can omit key and secret. - -### Private enpoints -#### async placeActiveOrder(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-placev2active) - -#### async getActiveOrder(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-getactive) - -#### async cancelActiveOrder(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-cancelv2active) - -#### async cancelAllActiveOrders(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-cancelallactive) - -#### async replaceActiveOrder(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-replaceactive) - -#### async queryActiveOrder(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-queryactive) - -#### async placeConditionalOrder(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-placecond) - -#### async getConditionalOrder(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-getcond) - -#### async cancelConditionalOrder(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-cancelcond) - -#### async cancelAllConditionalOrders(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-cancelallcond) - -#### async replaceConditionalOrder(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-replacecond) - -#### async queryConditionalOrder(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-querycond) - -#### async getUserLeverage() -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-getleverage) - -#### async changeUserLeverage(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-changeleverage) - -#### async getPosition(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-mypositionv2) - -#### async getPositions() -*Deprecated v1 method* -[See bybit documentation](https://github.com/bybit-exchange/bybit-official-api-docs/blob/master/en/rest_api.md#positionlistget) - -#### async changePositionMargin(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-changemargin) - -#### async setTradingStop(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-tradingstop) - -#### async getWalletFundRecords(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-walletrecords) - -#### async getWithdrawRecords(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-withdrawrecords) - -#### async getAssetExchangeRecords(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-assetexchangerecords) - -#### async getWalletBalance(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-balance) - -#### async setRiskLimit(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-setrisklimit) - -#### async getRiskLimitList() -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-getrisklimit) - -#### async getLastFundingRate(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-fundingrate) - -#### async getMyLastFundingFee(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-mylastfundingfee) - -#### async getPredictedFunding(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-predictedfunding) - -#### async getTradeRecords(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-usertraderecords) - -### Public enpoints - -#### async getOrderBook(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-orderbook) - -#### async getKline(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-querykline) - -#### async getOpenInterest(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-marketopeninterest) - -#### async getLatestBigDeal(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-marketbigdeal) - -#### async getLongShortRatio(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-marketaccountratio) - -#### async getLatestInformation() -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-latestsymbolinfo) - -#### async getPublicTradingRecords(params) -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-publictradingrecords) - -#### async getServerTime() -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-servertime) - -#### async getApiAnnouncements() -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-announcement) - -#### async getSymbols() -Returns symbol information (such as tick size & min notional): -[Meeting price restrictions](https://bybit-exchange.github.io/docs/inverse/#price-price) - -[See bybit documentation](https://bybit-exchange.github.io/docs/inverse/#t-querysymbol) - -#### async getTimeOffset() - -Returns the time offset in ms to the server time retrieved by [`async getServerTime`](#async-getservertime). -If positive the time on the server is ahead of the clients time, if negative the time on the server is behind the clients time. -## Example - -```javascript -const {RestClient} = require('bybit-api'); - -const API_KEY = 'xxx'; -const PRIVATE_KEY = 'yyy'; - -const client = new RestClient(API_KEY, PRIVATE_KEY); - -client.changeUserLeverage({leverage: 4, symbol: 'ETHUSD'}) - .then(result => { - console.log(result); - }) - .catch(err => { - console.error(err); - }); -```