From 28f0a7509adb33553438da1b6d4d5ee0f9877878 Mon Sep 17 00:00:00 2001 From: Zihua Li Date: Sun, 6 Feb 2022 17:31:10 +0800 Subject: [PATCH] feat: Refactor code with modern settings BREAKING CHANGE: 1. We now require Node.js v10.12.0 or newer. 2. We now only work with Redis v3.0.0 or newer. 3. `Redis` can't be called as a function anymore as it's now a class. Please change `Redis()` to `new Redis()`. Note that `Redis()` was already deprecated in the previous version. --- .eslintrc.json | 40 + .eslintrc.yml | 42 - .github/workflows/main.yml | 2 - .gitignore | 1 + .tool-versions | 1 + .travis.yml | 3 +- README.md | 2 +- benchmarks/autopipelining-single.ts | 2 +- benchmarks/dropBuffer.ts | 2 +- benchmarks/errorStack.ts | 2 +- lib/Redis.ts | 786 ++++++ lib/cluster/ClusterOptions.ts | 7 +- lib/cluster/ClusterSubscriber.ts | 7 +- lib/cluster/ConnectionPool.ts | 10 +- lib/cluster/index.ts | 57 +- lib/cluster/util.ts | 12 +- lib/connectors/AbstractConnector.ts | 2 +- lib/connectors/ConnectorConstructor.ts | 7 + lib/connectors/SentinelConnector/index.ts | 42 +- lib/connectors/SentinelConnector/types.ts | 4 +- lib/connectors/StandaloneConnector.ts | 32 +- lib/index.ts | 7 +- lib/pipeline.ts | 368 +-- lib/redis/RedisOptions.ts | 27 +- lib/redis/index.ts | 889 ------- lib/transaction.ts | 6 + lib/{commander.ts => utils/Commander.ts} | 173 +- lib/utils/applyMixin.ts | 15 + package-lock.json | 2264 ++++++++---------- package.json | 27 +- test/docker/main.sh | 2 +- test/functional/auth.ts | 2 +- test/functional/autopipelining.ts | 2 +- test/functional/cluster/disconnection.ts | 1 - test/functional/cluster/dnsLookup.ts | 4 +- test/functional/cluster/pub_sub.ts | 2 +- test/functional/cluster/tls.ts | 6 +- test/functional/commandTimeout.ts | 2 +- test/functional/connection.ts | 19 +- test/functional/disconnection.ts | 2 +- test/functional/drop_buffer_support.ts | 2 +- test/functional/duplicate.ts | 2 +- test/functional/elasticache.ts | 2 +- test/functional/fatal_error.ts | 2 +- test/functional/hgetall.ts | 2 +- test/functional/lazy_connect.ts | 2 +- test/functional/maxRetriesPerRequest.ts | 2 +- test/functional/monitor.ts | 2 +- test/functional/pipeline.ts | 2 +- test/functional/promise.ts | 26 - test/functional/pub_sub.ts | 2 +- test/functional/ready_check.ts | 4 +- test/functional/reconnect_on_error.ts | 2 +- test/functional/scan_stream.ts | 6 +- test/functional/scripting.ts | 2 +- test/functional/select.ts | 2 +- test/functional/send_command.ts | 42 +- test/functional/sentinel.ts | 2 +- test/functional/sentinel_nat.ts | 2 +- test/functional/show_friendly_error_stack.ts | 2 +- test/functional/string_numbers.ts | 2 +- test/functional/tls.ts | 28 +- test/functional/transaction.ts | 6 +- test/functional/transformer.ts | 2 +- test/functional/watch-exec.ts | 2 +- test/helpers/global.ts | 2 +- test/helpers/mock_server.ts | 5 +- test/unit/autoPipelining.ts | 14 +- test/unit/clusters/index.ts | 1 - test/unit/commander.ts | 4 +- test/unit/debug.ts | 6 +- test/unit/pipeline.ts | 4 +- test/unit/redis.ts | 6 +- tsconfig.json | 16 +- 74 files changed, 2404 insertions(+), 2685 deletions(-) create mode 100644 .eslintrc.json delete mode 100644 .eslintrc.yml create mode 100644 .tool-versions create mode 100644 lib/Redis.ts create mode 100644 lib/connectors/ConnectorConstructor.ts delete mode 100644 lib/redis/index.ts rename lib/{commander.ts => utils/Commander.ts} (62%) create mode 100644 lib/utils/applyMixin.ts delete mode 100644 test/functional/promise.ts diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 000000000..bb3c0ff08 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,40 @@ +{ + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/eslint-recommended", + "prettier" + ], + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"], + "env": { "node": true }, + "rules": { + "prefer-rest-params": 0, + "no-var": 0, + "no-prototype-builtins": 0, + "prefer-spread": 0, + "@typescript-eslint/no-var-requires": 0, + "@typescript-eslint/no-explicit-any": 0, + "@typescript-eslint/no-this-alias": 0, + "@typescript-eslint/ban-ts-ignore": 0, + "@typescript-eslint/ban-ts-comment": 0, + "@typescript-eslint/ban-types": 0, + "@typescript-eslint/no-empty-interface": 0, + "@typescript-eslint/no-empty-function": 0, + "@typescript-eslint/no-unused-vars": [ + "warn", + { + "args": "none" + } + ] + }, + "overrides": [ + { + "files": ["test/**/*"], + "env": { + "mocha": true + }, + "rules": { "prefer-const": 0 } + } + ] +} diff --git a/.eslintrc.yml b/.eslintrc.yml deleted file mode 100644 index 3dd46a1ee..000000000 --- a/.eslintrc.yml +++ /dev/null @@ -1,42 +0,0 @@ -extends: - - eslint:recommended - - plugin:@typescript-eslint/recommended - - prettier/@typescript-eslint - - prettier - -parser: "@typescript-eslint/parser" - -plugins: - - "@typescript-eslint" - -env: - node: true - es6: true - -rules: - no-console: 0 - prefer-const: 0 - prefer-rest-params: 0 - no-redeclare: 0 - no-var: 0 - no-prototype-builtins: 0 - prefer-spread: 0 - "@typescript-eslint/array-type": 0 # Removed from recommended rules in 2.x - "@typescript-eslint/no-var-requires": 0 - "@typescript-eslint/explicit-function-return-type": 0 - "@typescript-eslint/no-explicit-any": 0 - "@typescript-eslint/explicit-member-accessibility": 0 - "@typescript-eslint/no-this-alias": 0 - "@typescript-eslint/no-parameter-properties": 0 - "@typescript-eslint/no-use-before-define": 0 - "@typescript-eslint/ban-ts-ignore": 0 - "@typescript-eslint/no-empty-function": 0 - "@typescript-eslint/no-unused-vars": - - warn - - args: none - "@typescript-eslint/interface-name-prefix": 0 - -overrides: - - files: ["{test,benchmarks}/**/*"] - env: - mocha: true diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2c3803c09..a5f2c3789 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -29,8 +29,6 @@ jobs: matrix: include: # Need a new enough git version to install the npm husky module. - - NODE_VERSION: 6-stretch - - NODE_VERSION: 8-buster - NODE_VERSION: 10-buster - NODE_VERSION: 12-bullseye - NODE_VERSION: 14-bullseye diff --git a/.gitignore b/.gitignore index 101a6de39..960212a1f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ built .vscode benchmarks/fixtures/*.txt +*.rdb diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 000000000..c60c1aa7e --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +nodejs 10.12.0 diff --git a/.travis.yml b/.travis.yml index 48c9d8afb..29ba53bc0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,11 @@ language: node_js node_js: - - "6" - - "8" - "10" - "12" - "14" - "16" + - "17" services: - redis-server diff --git a/README.md b/README.md index 0236a66f5..74b3bc36b 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ A robust, performance-focused and full-featured [Redis](http://redis.io) client for [Node.js](https://nodejs.org). -Supports Redis >= 2.6.12 and (Node.js >= 6). Completely compatible with Redis 6.x. +Supports Redis >= 2.6.12 and (Node.js >= 10.12.0). Completely compatible with Redis 6.x. # Features diff --git a/benchmarks/autopipelining-single.ts b/benchmarks/autopipelining-single.ts index 698c8e9e2..8e8b4bd7b 100644 --- a/benchmarks/autopipelining-single.ts +++ b/benchmarks/autopipelining-single.ts @@ -1,7 +1,7 @@ import { cronometro } from "cronometro"; import { readFileSync } from "fs"; import { join } from "path"; -import Redis from "../lib/redis"; +import Redis from "../lib/Redis"; const iterations = parseInt(process.env.ITERATIONS || "10000", 10); const batchSize = parseInt(process.env.BATCH_SIZE || "1000", 10); diff --git a/benchmarks/dropBuffer.ts b/benchmarks/dropBuffer.ts index 9b0adb200..297cad94c 100644 --- a/benchmarks/dropBuffer.ts +++ b/benchmarks/dropBuffer.ts @@ -1,5 +1,5 @@ import { cronometro } from "cronometro"; -import Redis from "../lib/redis"; +import Redis from "../lib/Redis"; let redis; diff --git a/benchmarks/errorStack.ts b/benchmarks/errorStack.ts index 0af247340..51e017a42 100644 --- a/benchmarks/errorStack.ts +++ b/benchmarks/errorStack.ts @@ -1,5 +1,5 @@ import { cronometro } from "cronometro"; -import Redis from "../lib/redis"; +import Redis from "../lib/Redis"; let redis; diff --git a/lib/Redis.ts b/lib/Redis.ts new file mode 100644 index 000000000..e3b0938c4 --- /dev/null +++ b/lib/Redis.ts @@ -0,0 +1,786 @@ +import { EventEmitter } from "events"; +import * as commands from "redis-commands"; +import asCallback from "standard-as-callback"; +import { AbstractConnector, Command, ScanStream, SentinelConnector } from "."; +import Commander from "./utils/Commander"; +import { StandaloneConnector } from "./connectors"; +import * as eventHandler from "./redis/event_handler"; +import { + DEFAULT_REDIS_OPTIONS, + ReconnectOnError, + RedisOptions, +} from "./redis/RedisOptions"; +import { addTransactionSupport } from "./transaction"; +import { CallbackFunction, ICommandItem, NetStream } from "./types"; +import { + CONNECTION_CLOSED_ERROR_MSG, + Debug, + isInt, + parseURL, + resolveTLSProfile, +} from "./utils"; +import applyMixin from "./utils/applyMixin"; +import { defaults, noop } from "./utils/lodash"; +import Deque = require("denque"); +const debug = Debug("redis"); + +type RedisStatus = + | "wait" + | "reconnecting" + | "connecting" + | "connect" + | "ready" + | "close" + | "end"; + +class Redis extends Commander { + /** + * Default options + * + * @var defaultOptions + */ + private static defaultOptions = DEFAULT_REDIS_OPTIONS; + + /** + * Create a Redis instance + * + * @deprecated + */ + static createClient(...args: unknown[]): Redis { + // @ts-expect-error + return new Redis(...args); + } + + options: RedisOptions; + status: RedisStatus = "wait"; + commandQueue: Deque; + offlineQueue: Deque; + connectionEpoch = 0; + connector: AbstractConnector; + condition: { + select: number; + auth?: string | [string, string]; + subscriber: boolean; + }; + stream: NetStream; + manuallyClosing = false; + retryAttempts = 0; + reconnectTimeout: ReturnType | null = null; + isCluster = false; + + // Prepare autopipelines structures + private _autoPipelines = new Map(); + private _runningAutoPipelines = new Set(); + + // Prepare a cache of scripts and setup a interval which regularly clears it + private _addedScriptHashes: { [sha: string]: true } = {}; + private _addedScriptHashesCleanInterval?: ReturnType< + typeof setInterval + > | null = null; + + constructor(port: number, host: string, options: RedisOptions); + constructor(path: string, options: RedisOptions); + constructor(port: number, options: RedisOptions); + constructor(port: number, host: string); + constructor(options: RedisOptions); + constructor(port: number); + constructor(path: string); + constructor(); + constructor(arg1?: unknown, arg2?: unknown, arg3?: unknown) { + super(); + this.parseOptions(arg1, arg2, arg3); + + EventEmitter.call(this); + + this.resetCommandQueue(); + this.resetOfflineQueue(); + + if ("Connector" in this.options && this.options.Connector) { + this.connector = new this.options.Connector(this.options); + } else if ("sentinels" in this.options && this.options.sentinels) { + const sentinelConnector = new SentinelConnector(this.options); + sentinelConnector.emitter = this; + + this.connector = sentinelConnector; + } else { + // @ts-expect-error + this.connector = new StandaloneConnector(this.options); + } + + // end(or wait) -> connecting -> connect -> ready -> end + if (this.options.lazyConnect) { + this.setStatus("wait"); + } else { + this.connect().catch(noop); + } + } + + get autoPipelineQueueSize() { + let queued = 0; + + for (const pipeline of this._autoPipelines.values()) { + queued += pipeline.length; + } + + return queued; + } + + parseOptions(...args: unknown[]) { + const options: Record = {}; + let isTls = false; + for (let i = 0; i < args.length; ++i) { + const arg = args[i]; + if (arg === null || typeof arg === "undefined") { + continue; + } + if (typeof arg === "object") { + defaults(options, arg); + } else if (typeof arg === "string") { + defaults(options, parseURL(arg)); + if (arg.startsWith("rediss://")) { + isTls = true; + } + } else if (typeof arg === "number") { + options.port = arg; + } else { + throw new Error("Invalid argument " + arg); + } + } + if (isTls) { + defaults(options, { tls: true }); + } + defaults(options, Redis.defaultOptions); + + if (typeof options.port === "string") { + options.port = parseInt(options.port, 10); + } + if (typeof options.db === "string") { + options.db = parseInt(options.db, 10); + } + + // @ts-expect-error + this.options = resolveTLSProfile(options); + } + + resetCommandQueue() { + this.commandQueue = new Deque(); + } + + resetOfflineQueue() { + this.offlineQueue = new Deque(); + } + + /** + * Change instance's status + */ + private setStatus(status: RedisStatus, arg?: unknown) { + // @ts-expect-error + if (debug.enabled) { + debug( + "status[%s]: %s -> %s", + this._getDescription(), + this.status || "[empty]", + status + ); + } + this.status = status; + process.nextTick(this.emit.bind(this, status, arg)); + } + + private clearAddedScriptHashesCleanInterval() { + if (this._addedScriptHashesCleanInterval) { + clearInterval(this._addedScriptHashesCleanInterval); + this._addedScriptHashesCleanInterval = null; + } + } + + /** + * Create a connection to Redis. + * This method will be invoked automatically when creating a new Redis instance + * unless `lazyConnect: true` is passed. + * + * When calling this method manually, a Promise is returned, which will + * be resolved when the connection status is ready. + */ + connect(callback?: CallbackFunction): Promise { + const promise = new Promise((resolve, reject) => { + if ( + this.status === "connecting" || + this.status === "connect" || + this.status === "ready" + ) { + reject(new Error("Redis is already connecting/connected")); + return; + } + + // Make sure only one timer is active at a time + this.clearAddedScriptHashesCleanInterval(); + + // Scripts need to get reset on reconnect as redis + // might have been restarted or some failover happened + this._addedScriptHashes = {}; + + // Start the script cache cleaning + this._addedScriptHashesCleanInterval = setInterval(() => { + this._addedScriptHashes = {}; + }, this.options.maxScriptsCachingTime); + + this.connectionEpoch += 1; + this.setStatus("connecting"); + + const { options } = this; + + this.condition = { + select: options.db, + auth: options.username + ? [options.username, options.password] + : options.password, + subscriber: false, + }; + + const _this = this; + asCallback( + this.connector.connect(function (type, err) { + _this.silentEmit(type, err); + }) as Promise, + function (err: Error | null, stream?: NetStream) { + if (err) { + _this.flushQueue(err); + _this.silentEmit("error", err); + reject(err); + _this.setStatus("end"); + return; + } + let CONNECT_EVENT = options.tls ? "secureConnect" : "connect"; + if ( + "sentinels" in options && + options.sentinels && + !options.enableTLSForSentinelMode + ) { + CONNECT_EVENT = "connect"; + } + + _this.stream = stream; + if (typeof options.keepAlive === "number") { + stream.setKeepAlive(true, options.keepAlive); + } + + if (stream.connecting) { + stream.once(CONNECT_EVENT, eventHandler.connectHandler(_this)); + + if (options.connectTimeout) { + /* + * Typically, Socket#setTimeout(0) will clear the timer + * set before. However, in some platforms (Electron 3.x~4.x), + * the timer will not be cleared. So we introduce a variable here. + * + * See https://github.com/electron/electron/issues/14915 + */ + let connectTimeoutCleared = false; + stream.setTimeout(options.connectTimeout, function () { + if (connectTimeoutCleared) { + return; + } + stream.setTimeout(0); + stream.destroy(); + + const err = new Error("connect ETIMEDOUT"); + // @ts-expect-error + err.errorno = "ETIMEDOUT"; + // @ts-expect-error + err.code = "ETIMEDOUT"; + // @ts-expect-error + err.syscall = "connect"; + eventHandler.errorHandler(_this)(err); + }); + stream.once(CONNECT_EVENT, function () { + connectTimeoutCleared = true; + stream.setTimeout(0); + }); + } + } else if (stream.destroyed) { + const firstError = _this.connector.firstError; + if (firstError) { + process.nextTick(() => { + eventHandler.errorHandler(_this)(firstError); + }); + } + process.nextTick(eventHandler.closeHandler(_this)); + } else { + process.nextTick(eventHandler.connectHandler(_this)); + } + if (!stream.destroyed) { + stream.once("error", eventHandler.errorHandler(_this)); + stream.once("close", eventHandler.closeHandler(_this)); + } + + if (options.noDelay) { + stream.setNoDelay(true); + } + + const connectionReadyHandler = function () { + _this.removeListener("close", connectionCloseHandler); + resolve(); + }; + var connectionCloseHandler = function () { + _this.removeListener("ready", connectionReadyHandler); + reject(new Error(CONNECTION_CLOSED_ERROR_MSG)); + }; + _this.once("ready", connectionReadyHandler); + _this.once("close", connectionCloseHandler); + } + ); + }); + + return asCallback(promise, callback); + } + + /** + * Disconnect from Redis. + * + * This method closes the connection immediately, + * and may lose some pending replies that haven't written to client. + * If you want to wait for the pending replies, use Redis#quit instead. + */ + disconnect(reconnect = false) { + this.clearAddedScriptHashesCleanInterval(); + + if (!reconnect) { + this.manuallyClosing = true; + } + if (this.reconnectTimeout && !reconnect) { + clearTimeout(this.reconnectTimeout); + this.reconnectTimeout = null; + } + if (this.status === "wait") { + eventHandler.closeHandler(this)(); + } else { + this.connector.disconnect(); + } + } + + /** + * Disconnect from Redis. + * + * @deprecated + */ + end() { + this.disconnect(); + } + + /** + * Create a new instance with the same options as the current one. + * + * @example + * ```js + * var redis = new Redis(6380); + * var anotherRedis = redis.duplicate(); + * ``` + */ + duplicate(override: RedisOptions) { + return new Redis(Object.assign({}, this.options, override || {})); + } + + recoverFromFatalError(commandError, err: Error | null, options) { + this.flushQueue(err, options); + this.silentEmit("error", err); + this.disconnect(true); + } + + handleReconnection(err: Error, item: ICommandItem) { + let needReconnect: ReturnType = false; + if (this.options.reconnectOnError) { + needReconnect = this.options.reconnectOnError(err); + } + + switch (needReconnect) { + case 1: + case true: + if (this.status !== "reconnecting") { + this.disconnect(true); + } + item.command.reject(err); + break; + case 2: + if (this.status !== "reconnecting") { + this.disconnect(true); + } + if ( + this.condition.select !== item.select && + item.command.name !== "select" + ) { + // @ts-expect-error + this.select(item.select); + } + // TODO + // @ts-expect-error + this.sendCommand(item.command); + break; + default: + item.command.reject(err); + } + } + + /** + * Flush offline queue and command queue with error. + * + * @param {Error} error - The error object to send to the commands + * @param {object} options + */ + private flushQueue(error: Error, options?: RedisOptions) { + options = defaults({}, options, { + offlineQueue: true, + commandQueue: true, + }); + + let item; + if (options.offlineQueue) { + while (this.offlineQueue.length > 0) { + item = this.offlineQueue.shift(); + item.command.reject(error); + } + } + + if (options.commandQueue) { + if (this.commandQueue.length > 0) { + if (this.stream) { + this.stream.removeAllListeners("data"); + } + while (this.commandQueue.length > 0) { + item = this.commandQueue.shift(); + item.command.reject(error); + } + } + } + } + + /** + * Check whether Redis has finished loading the persistent data and is able to + * process commands. + */ + private _readyCheck(callback: CallbackFunction) { + const _this = this; + // @ts-expect-error + this.info(function (err: Error | null, res: string) { + if (err) { + return callback(err); + } + if (typeof res !== "string") { + return callback(null, res); + } + + const info: { [key: string]: any } = {}; + + const lines = res.split("\r\n"); + for (let i = 0; i < lines.length; ++i) { + const [fieldName, ...fieldValueParts] = lines[i].split(":"); + const fieldValue = fieldValueParts.join(":"); + if (fieldValue) { + info[fieldName] = fieldValue; + } + } + + if (!info.loading || info.loading === "0") { + callback(null, info); + } else { + const loadingEtaMs = (info.loading_eta_seconds || 1) * 1000; + const retryTime = + _this.options.maxLoadingRetryTime && + _this.options.maxLoadingRetryTime < loadingEtaMs + ? _this.options.maxLoadingRetryTime + : loadingEtaMs; + debug( + "Redis server still loading, trying again in " + retryTime + "ms" + ); + setTimeout(function () { + _this._readyCheck(callback); + }, retryTime); + } + }); + } + + /** + * Emit only when there's at least one listener. + * + * @return {boolean} Returns true if event had listeners, false otherwise. + */ + silentEmit(eventName: string, arg?: unknown): boolean { + let error: unknown; + if (eventName === "error") { + error = arg; + + if (this.status === "end") { + return; + } + + if (this.manuallyClosing) { + // ignore connection related errors when manually disconnecting + if ( + error instanceof Error && + (error.message === CONNECTION_CLOSED_ERROR_MSG || + // @ts-expect-error + error.syscall === "connect" || + // @ts-expect-error + error.syscall === "read") + ) { + return; + } + } + } + if (this.listeners(eventName).length > 0) { + return this.emit.apply(this, arguments); + } + if (error && error instanceof Error) { + console.error("[ioredis] Unhandled error event:", error.stack); + } + return false; + } + + /** + * Listen for all requests received by the server in real time. + * + * This command will create a new connection to Redis and send a + * MONITOR command via the new connection in order to avoid disturbing + * the current connection. + * + * @param {function} [callback] The callback function. If omit, a promise will be returned. + * @example + * ```js + * var redis = new Redis(); + * redis.monitor(function (err, monitor) { + * // Entering monitoring mode. + * monitor.on('monitor', function (time, args, source, database) { + * console.log(time + ": " + util.inspect(args)); + * }); + * }); + * + * // supports promise as well as other commands + * redis.monitor().then(function (monitor) { + * monitor.on('monitor', function (time, args, source, database) { + * console.log(time + ": " + util.inspect(args)); + * }); + * }); + * ``` + */ + monitor(callback: CallbackFunction): Promise { + const monitorInstance = this.duplicate({ + monitor: true, + lazyConnect: false, + }); + + return asCallback( + new Promise(function (resolve) { + monitorInstance.once("monitoring", function () { + resolve(monitorInstance); + }); + }), + callback + ); + } + + /** + * Send a command to Redis + * + * This method is used internally by the `Redis#set`, `Redis#lpush` etc. + * Most of the time you won't invoke this method directly. + * However when you want to send a command that is not supported by ioredis yet, + * this command will be useful. + * + * @example + * ```js + * const redis = new Redis(); + * + * // Use callback + * const get = new Command('get', ['foo'], 'utf8', function (err, result) { + * console.log(result); + * }); + * redis.sendCommand(get); + * + * // Use promise + * const set = new Command('set', ['foo', 'bar'], 'utf8'); + * set.promise.then(function (result) { + * console.log(result); + * }); + * redis.sendCommand(set); + * ``` + */ + sendCommand(command: Command, stream?: NetStream): unknown { + if (this.status === "wait") { + this.connect().catch(noop); + } + if (this.status === "end") { + command.reject(new Error(CONNECTION_CLOSED_ERROR_MSG)); + return command.promise; + } + if ( + this.condition.subscriber && + !Command.checkFlag("VALID_IN_SUBSCRIBER_MODE", command.name) + ) { + command.reject( + new Error( + "Connection in subscriber mode, only subscriber commands may be used" + ) + ); + return command.promise; + } + + if (typeof this.options.commandTimeout === "number") { + command.setTimeout(this.options.commandTimeout); + } + + if (command.name === "quit") { + this.clearAddedScriptHashesCleanInterval(); + } + + let writable = + this.status === "ready" || + (!stream && + this.status === "connect" && + commands.exists(command.name) && + commands.hasFlag(command.name, "loading")); + if (!this.stream) { + writable = false; + } else if (!this.stream.writable) { + writable = false; + // @ts-expect-error + } else if (this.stream._writableState && this.stream._writableState.ended) { + // TODO: We should be able to remove this as the PR has already been merged. + // https://github.com/iojs/io.js/pull/1217 + writable = false; + } + + if (!writable && !this.options.enableOfflineQueue) { + command.reject( + new Error( + "Stream isn't writeable and enableOfflineQueue options is false" + ) + ); + return command.promise; + } + + if ( + !writable && + command.name === "quit" && + this.offlineQueue.length === 0 + ) { + this.disconnect(); + command.resolve(Buffer.from("OK")); + return command.promise; + } + + if (writable) { + // @ts-expect-error + if (debug.enabled) { + debug( + "write command[%s]: %d -> %s(%o)", + this._getDescription(), + this.condition.select, + command.name, + command.args + ); + } + (stream || this.stream).write(command.toWritable()); + + this.commandQueue.push({ + command: command, + stream: stream, + select: this.condition.select, + }); + + if (Command.checkFlag("WILL_DISCONNECT", command.name)) { + this.manuallyClosing = true; + } + } else if (this.options.enableOfflineQueue) { + // @ts-expect-error + if (debug.enabled) { + debug( + "queue command[%s]: %d -> %s(%o)", + this._getDescription(), + this.condition.select, + command.name, + command.args + ); + } + this.offlineQueue.push({ + command: command, + stream: stream, + select: this.condition.select, + }); + } + + if (command.name === "select" && isInt(command.args[0])) { + const db = parseInt(command.args[0], 10); + if (this.condition.select !== db) { + this.condition.select = db; + this.emit("select", db); + debug("switch to db [%d]", this.condition.select); + } + } + + return command.promise; + } + + /** + * Get description of the connection. Used for debugging. + */ + private _getDescription() { + let description; + if ("path" in this.options && this.options.path) { + description = this.options.path; + } else if ( + this.stream && + this.stream.remoteAddress && + this.stream.remotePort + ) { + description = this.stream.remoteAddress + ":" + this.stream.remotePort; + } else if ("host" in this.options && this.options.host) { + description = this.options.host + ":" + this.options.port; + } else { + // Unexpected + description = ""; + } + if (this.options.connectionName) { + description += ` (${this.options.connectionName})`; + } + return description; + } +} + +interface Redis extends EventEmitter {} +applyMixin(Redis, EventEmitter); + +[ + "scan", + "sscan", + "hscan", + "zscan", + "scanBuffer", + "sscanBuffer", + "hscanBuffer", + "zscanBuffer", +].forEach((command) => { + Redis.prototype[command + "Stream"] = function ( + key: string, + options: unknown + ) { + if (command === "scan" || command === "scanBuffer") { + options = key; + key = null; + } + return new ScanStream( + defaults( + { + objectMode: true, + key: key, + redis: this, + command: command, + }, + options + ) + ); + }; +}); + +addTransactionSupport(Redis.prototype); + +export default Redis; diff --git a/lib/cluster/ClusterOptions.ts b/lib/cluster/ClusterOptions.ts index bcc14b406..c12495a30 100644 --- a/lib/cluster/ClusterOptions.ts +++ b/lib/cluster/ClusterOptions.ts @@ -1,4 +1,5 @@ import { SrvRecord, resolveSrv, lookup } from "dns"; +import { CommanderOptions } from "../utils/Commander"; import { NodeRole } from "./util"; export type DNSResolveSrvFunction = ( @@ -25,9 +26,9 @@ export interface INatMap { * Options for Cluster constructor * * @export - * @interface IClusterOptions + * @interface ClusterOptions */ -export interface IClusterOptions { +export interface ClusterOptions extends CommanderOptions { /** * See "Quick Start" section. * @@ -189,7 +190,7 @@ export interface IClusterOptions { maxScriptsCachingTime?: number; } -export const DEFAULT_CLUSTER_OPTIONS: IClusterOptions = { +export const DEFAULT_CLUSTER_OPTIONS: ClusterOptions = { clusterRetryStrategy: (times) => Math.min(100 + times * 2, 2000), enableOfflineQueue: true, enableReadyCheck: true, diff --git a/lib/cluster/ClusterSubscriber.ts b/lib/cluster/ClusterSubscriber.ts index 8421e7694..557300517 100644 --- a/lib/cluster/ClusterSubscriber.ts +++ b/lib/cluster/ClusterSubscriber.ts @@ -2,7 +2,7 @@ import { EventEmitter } from "events"; import ConnectionPool from "./ConnectionPool"; import { getConnectionName, getNodeKey } from "./util"; import { sample, noop, Debug } from "../utils"; -import Redis from "../redis"; +import Redis from "../Redis"; const debug = Debug("cluster:subscriber"); @@ -94,9 +94,8 @@ export default class ClusterSubscriber { lastActiveSubscriber.condition || lastActiveSubscriber.prevCondition; if (condition && condition.subscriber) { previousChannels.subscribe = condition.subscriber.channels("subscribe"); - previousChannels.psubscribe = condition.subscriber.channels( - "psubscribe" - ); + previousChannels.psubscribe = + condition.subscriber.channels("psubscribe"); } } if ( diff --git a/lib/cluster/ConnectionPool.ts b/lib/cluster/ConnectionPool.ts index eade0737b..40ce6465a 100644 --- a/lib/cluster/ConnectionPool.ts +++ b/lib/cluster/ConnectionPool.ts @@ -1,7 +1,7 @@ import { EventEmitter } from "events"; import { sample, Debug, noop, defaults } from "../utils"; -import { IRedisOptions, getNodeKey, NodeKey, NodeRole } from "./util"; -import Redis from "../redis"; +import { RedisOptions, getNodeKey, NodeKey, NodeRole } from "./util"; +import Redis from "../Redis"; const debug = Debug("cluster:connectionPool"); @@ -39,12 +39,12 @@ export default class ConnectionPool extends EventEmitter { /** * Find or create a connection to the node * - * @param {IRedisOptions} node + * @param {RedisOptions} node * @param {boolean} [readOnly=false] * @returns {*} * @memberof ConnectionPool */ - public findOrCreate(node: IRedisOptions, readOnly = false): any { + public findOrCreate(node: RedisOptions, readOnly = false): any { const key = getNodeKey(node); readOnly = Boolean(readOnly); @@ -130,7 +130,7 @@ export default class ConnectionPool extends EventEmitter { * @param {(Array)} nodes * @memberof ConnectionPool */ - public reset(nodes: IRedisOptions[]): void { + public reset(nodes: RedisOptions[]): void { debug("Reset with %O", nodes); const newNodes = {}; nodes.forEach((node) => { diff --git a/lib/cluster/index.ts b/lib/cluster/index.ts index 20d1012e7..e317e42ce 100644 --- a/lib/cluster/index.ts +++ b/lib/cluster/index.ts @@ -4,7 +4,7 @@ import { defaults, noop, Debug } from "../utils"; import ConnectionPool from "./ConnectionPool"; import { NodeKey, - IRedisOptions, + RedisOptions, normalizeNodeOptions, NodeRole, getUniqueHostnamesFromOptions, @@ -19,8 +19,8 @@ import ScanStream from "../ScanStream"; import { AbortError, RedisError } from "redis-errors"; import asCallback from "standard-as-callback"; import * as PromiseContainer from "../promiseContainer"; -import { CallbackFunction } from "../types"; -import { IClusterOptions, DEFAULT_CLUSTER_OPTIONS } from "./ClusterOptions"; +import { CallbackFunction, NetStream } from "../types"; +import { ClusterOptions, DEFAULT_CLUSTER_OPTIONS } from "./ClusterOptions"; import { sample, CONNECTION_CLOSED_ERROR_MSG, @@ -30,10 +30,11 @@ import { } from "../utils"; import * as commands from "redis-commands"; import Command from "../command"; -import Redis from "../redis"; -import Commander from "../commander"; +import Redis from "../Redis"; +import Commander from "../utils/Commander"; import Deque = require("denque"); import { Pipeline } from ".."; +import applyMixin from "../utils/applyMixin"; const debug = Debug("cluster"); @@ -51,13 +52,12 @@ type ClusterStatus = * Client for the official Redis Cluster * * @class Cluster - * @extends {EventEmitter} */ -class Cluster extends EventEmitter { - private options: IClusterOptions; +class Cluster extends Commander { + options: ClusterOptions; private startupNodes: (string | number | object)[]; private connectionPool: ConnectionPool; - private slots: NodeKey[][] = []; + slots: NodeKey[][] = []; private manuallyClosing: boolean; private retryAttempts = 0; private delayQueue: DelayQueue = new DelayQueue(); @@ -69,8 +69,8 @@ class Cluster extends EventEmitter { private isRefreshing = false; public isCluster = true; private _autoPipelines: Map = new Map(); - private _groupsIds: { [key: string]: number } = {}; - private _groupsBySlot: number[] = Array(16384); + _groupsIds: { [key: string]: number } = {}; + _groupsBySlot: number[] = Array(16384); private _runningAutoPipelines: Set = new Set(); private _readyDelayedCallbacks: CallbackFunction[] = []; public _addedScriptHashes: { [key: string]: any } = {}; @@ -92,15 +92,15 @@ class Cluster extends EventEmitter { * Creates an instance of Cluster. * * @param {((string | number | object)[])} startupNodes - * @param {IClusterOptions} [options={}] + * @param {ClusterOptions} [options={}] * @memberof Cluster */ constructor( startupNodes: (string | number | object)[], - options: IClusterOptions = {} + options: ClusterOptions = {} ) { super(); - Commander.call(this); + EventEmitter.call(this); this.startupNodes = startupNodes; this.options = defaults({}, options, DEFAULT_CLUSTER_OPTIONS, this.options); @@ -436,7 +436,7 @@ class Cluster extends EventEmitter { * * @public * @param {((string | number | object)[])} [overrideStartupNodes=[]] - * @param {IClusterOptions} [overrideOptions={}] + * @param {ClusterOptions} [overrideOptions={}] * @memberof Cluster */ public duplicate(overrideStartupNodes = [], overrideOptions = {}) { @@ -501,12 +501,8 @@ class Cluster extends EventEmitter { /** * Refresh the slot cache - * - * @private - * @param {CallbackFunction} [callback] - * @memberof Cluster */ - private refreshSlotsCache(callback?: CallbackFunction): void { + refreshSlotsCache(callback?: CallbackFunction): void { if (this.isRefreshing) { if (typeof callback === "function") { process.nextTick(callback); @@ -586,7 +582,7 @@ class Cluster extends EventEmitter { } } - natMapper(nodeKey: NodeKey | IRedisOptions): IRedisOptions { + natMapper(nodeKey: NodeKey | RedisOptions): RedisOptions { if (this.options.natMap && typeof this.options.natMap === "object") { const key = typeof nodeKey === "string" @@ -603,7 +599,7 @@ class Cluster extends EventEmitter { : nodeKey; } - sendCommand(command, stream, node) { + sendCommand(command: Command, stream?: NetStream, node?: any): unknown { if (this.status === "wait") { this.connect().catch(noop); } @@ -625,8 +621,10 @@ class Cluster extends EventEmitter { let targetSlot = node ? node.slot : command.getSlot(); const ttl = {}; const _this = this; + // @ts-expect-error if (!node && !command.__is_reject_overwritten) { - // eslint-disable-next-line @typescript-eslint/camelcase + // TODO WeakMap + // @ts-expect-error command.__is_reject_overwritten = true; const reject = command.reject; command.reject = function (err) { @@ -941,7 +939,7 @@ class Cluster extends EventEmitter { }); } - private resolveSrv(hostname: string): Promise { + private resolveSrv(hostname: string): Promise { return new Promise((resolve, reject) => { this.options.resolveSrv(hostname, (err, records) => { if (err) { @@ -1007,9 +1005,9 @@ class Cluster extends EventEmitter { * #startupNodes and DNS records may chanage. * * @private - * @returns {Promise} + * @returns {Promise} */ - private resolveStartupNodeHostnames(): Promise { + private resolveStartupNodeHostnames(): Promise { if (!Array.isArray(this.startupNodes) || this.startupNodes.length === 0) { return Promise.reject( new Error("`startupNodes` should contain at least one node.") @@ -1045,11 +1043,8 @@ class Cluster extends EventEmitter { } } -Object.getOwnPropertyNames(Commander.prototype).forEach((name) => { - if (!Cluster.prototype.hasOwnProperty(name)) { - Cluster.prototype[name] = Commander.prototype[name]; - } -}); +interface Cluster extends EventEmitter {} +applyMixin(Cluster, EventEmitter); const scanCommands = [ "sscan", diff --git a/lib/cluster/util.ts b/lib/cluster/util.ts index 1f24ca41c..ff6c07369 100644 --- a/lib/cluster/util.ts +++ b/lib/cluster/util.ts @@ -5,7 +5,7 @@ import { SrvRecord } from "dns"; export type NodeKey = string; export type NodeRole = "master" | "slave" | "all"; -export interface IRedisOptions { +export interface RedisOptions { port: number; host: string; username?: string; @@ -22,13 +22,13 @@ export interface IGroupedSrvRecords { [key: number]: ISrvRecordsGroup; } -export function getNodeKey(node: IRedisOptions): NodeKey { +export function getNodeKey(node: RedisOptions): NodeKey { node.port = node.port || 6379; node.host = node.host || "127.0.0.1"; return node.host + ":" + node.port; } -export function nodeKeyToRedisOptions(nodeKey: NodeKey): IRedisOptions { +export function nodeKeyToRedisOptions(nodeKey: NodeKey): RedisOptions { const portIndex = nodeKey.lastIndexOf(":"); if (portIndex === -1) { throw new Error(`Invalid node key ${nodeKey}`); @@ -41,7 +41,7 @@ export function nodeKeyToRedisOptions(nodeKey: NodeKey): IRedisOptions { export function normalizeNodeOptions( nodes: Array -): IRedisOptions[] { +): RedisOptions[] { return nodes.map((node) => { const options: any = {}; if (typeof node === "object") { @@ -71,9 +71,7 @@ export function normalizeNodeOptions( }); } -export function getUniqueHostnamesFromOptions( - nodes: IRedisOptions[] -): string[] { +export function getUniqueHostnamesFromOptions(nodes: RedisOptions[]): string[] { const uniqueHostsMap = {}; nodes.forEach((node) => { uniqueHostsMap[node.host] = true; diff --git a/lib/connectors/AbstractConnector.ts b/lib/connectors/AbstractConnector.ts index a69cd473b..8b067ac0d 100644 --- a/lib/connectors/AbstractConnector.ts +++ b/lib/connectors/AbstractConnector.ts @@ -11,7 +11,7 @@ export default abstract class AbstractConnector { protected stream: NetStream; public firstError?: Error; - protected constructor(disconnectTimeout: number) { + constructor(disconnectTimeout: number) { this.disconnectTimeout = disconnectTimeout; } diff --git a/lib/connectors/ConnectorConstructor.ts b/lib/connectors/ConnectorConstructor.ts new file mode 100644 index 000000000..1236550ae --- /dev/null +++ b/lib/connectors/ConnectorConstructor.ts @@ -0,0 +1,7 @@ +import AbstractConnector from "./AbstractConnector"; + +interface ConnectorConstructor { + new (options: unknown): AbstractConnector; +} + +export default ConnectorConstructor; diff --git a/lib/connectors/SentinelConnector/index.ts b/lib/connectors/SentinelConnector/index.ts index c4b6981ae..ea655a20b 100644 --- a/lib/connectors/SentinelConnector/index.ts +++ b/lib/connectors/SentinelConnector/index.ts @@ -1,5 +1,5 @@ import { EventEmitter } from "events"; -import { createConnection } from "net"; +import { createConnection, TcpNetConnectOpts } from "net"; import { INatMap } from "../../cluster/ClusterOptions"; import { CONNECTION_CLOSED_ERROR_MSG, @@ -8,16 +8,12 @@ import { Debug, } from "../../utils"; import { connect as createTLSConnection, ConnectionOptions } from "tls"; -import { - ITcpConnectionOptions, - isIIpcConnectionOptions, -} from "../StandaloneConnector"; import SentinelIterator from "./SentinelIterator"; import { IRedisClient, ISentinelAddress, ISentinel } from "./types"; import AbstractConnector, { ErrorEmitter } from "../AbstractConnector"; import { NetStream } from "../../types"; -import Redis from "../../redis"; -import { IRedisOptions } from "../../redis/RedisOptions"; +import Redis from "../../Redis"; +import { RedisOptions } from "../../redis/RedisOptions"; import { FailoverDetector } from "./FailoverDetector"; const debug = Debug("SentinelConnector"); @@ -35,12 +31,13 @@ type PreferredSlaves = export { ISentinelAddress, SentinelIterator }; -export interface ISentinelConnectionOptions extends ITcpConnectionOptions { - role: "master" | "slave"; - name: string; +export interface SentinelConnectionOptions { + name?: string; + role?: "master" | "slave"; + tls?: ConnectionOptions; sentinelUsername?: string; sentinelPassword?: string; - sentinels: Array>; + sentinels?: Array>; sentinelRetryStrategy?: (retryAttempts: number) => number | void | null; sentinelReconnectStrategy?: (retryAttempts: number) => number | void | null; preferredSlaves?: PreferredSlaves; @@ -61,9 +58,10 @@ export default class SentinelConnector extends AbstractConnector { protected sentinelIterator: SentinelIterator; public emitter: EventEmitter | null = null; - constructor(protected options: ISentinelConnectionOptions) { + constructor(protected options: SentinelConnectionOptions) { super(options.disconnectTimeout); + console.log(this.options); if (!this.options.sentinels.length) { throw new Error("Requires at least one sentinel to connect to."); } @@ -137,7 +135,7 @@ export default class SentinelConnector extends AbstractConnector { } } - let resolved: ITcpConnectionOptions | null = null; + let resolved: TcpNetConnectOpts | null = null; let err: Error | null = null; try { @@ -234,7 +232,7 @@ export default class SentinelConnector extends AbstractConnector { private async resolveMaster( client: IRedisClient - ): Promise { + ): Promise { const result = await client.sentinel( "get-master-addr-by-name", this.options.name @@ -251,7 +249,7 @@ export default class SentinelConnector extends AbstractConnector { private async resolveSlave( client: IRedisClient - ): Promise { + ): Promise { const result = await client.sentinel("slaves", this.options.name); if (!Array.isArray(result)) { @@ -280,18 +278,20 @@ export default class SentinelConnector extends AbstractConnector { private connectToSentinel( endpoint: Partial, - options?: Partial + options?: Partial ): IRedisClient { - return new Redis({ + const redis = new Redis({ port: endpoint.port || 26379, host: endpoint.host, username: this.options.sentinelUsername || null, password: this.options.sentinelPassword || null, family: endpoint.family || - (isIIpcConnectionOptions(this.options) + // @ts-expect-error + ("path" in this.options && this.options.path ? undefined - : this.options.family), + : // @ts-expect-error + this.options.family), tls: this.options.sentinelTLS, retryStrategy: null, enableReadyCheck: false, @@ -300,11 +300,13 @@ export default class SentinelConnector extends AbstractConnector { dropBufferSupport: true, ...options, }); + // @ts-expect-error + return redis; } private async resolve( endpoint: Partial - ): Promise { + ): Promise { const client = this.connectToSentinel(endpoint); // ignore the errors since resolve* methods will handle them diff --git a/lib/connectors/SentinelConnector/types.ts b/lib/connectors/SentinelConnector/types.ts index 6d7ef7f44..cc1fc9890 100644 --- a/lib/connectors/SentinelConnector/types.ts +++ b/lib/connectors/SentinelConnector/types.ts @@ -1,4 +1,4 @@ -import { IRedisOptions } from "../../redis/RedisOptions"; +import { RedisOptions } from "../../redis/RedisOptions"; export interface ISentinelAddress { port: number; @@ -8,7 +8,7 @@ export interface ISentinelAddress { // TODO: A proper typedef. This one only declares a small subset of all the members. export interface IRedisClient { - options: IRedisOptions; + options: RedisOptions; sentinel(subcommand: "sentinels", name: string): Promise; sentinel( subcommand: "get-master-addr-by-name", diff --git a/lib/connectors/StandaloneConnector.ts b/lib/connectors/StandaloneConnector.ts index ac38a8460..97c043620 100644 --- a/lib/connectors/StandaloneConnector.ts +++ b/lib/connectors/StandaloneConnector.ts @@ -4,27 +4,13 @@ import { CONNECTION_CLOSED_ERROR_MSG } from "../utils"; import AbstractConnector, { ErrorEmitter } from "./AbstractConnector"; import { NetStream } from "../types"; -export function isIIpcConnectionOptions( - value: any -): value is IIpcConnectionOptions { - return value.path; -} - -export interface ITcpConnectionOptions extends TcpNetConnectOpts { - tls?: ConnectionOptions; -} - -export interface IIpcConnectionOptions extends IpcNetConnectOpts { - tls?: ConnectionOptions; -} - -type IStandaloneConnectionOptions = ( - | ITcpConnectionOptions - | IIpcConnectionOptions -) & { disconnectTimeout: number }; +export type StandaloneConnectionOptions = ( + | TcpNetConnectOpts + | IpcNetConnectOpts +) & { disconnectTimeout: number; tls?: ConnectionOptions }; export default class StandaloneConnector extends AbstractConnector { - constructor(protected options: IStandaloneConnectionOptions) { + constructor(protected options: StandaloneConnectionOptions) { super(options.disconnectTimeout); } @@ -33,19 +19,19 @@ export default class StandaloneConnector extends AbstractConnector { this.connecting = true; let connectionOptions: any; - if (isIIpcConnectionOptions(options)) { + if ("path" in options && options.path) { connectionOptions = { path: options.path, }; } else { connectionOptions = {}; - if (options.port != null) { + if ("port" in options && options.port != null) { connectionOptions.port = options.port; } - if (options.host != null) { + if ("host" in options && options.host != null) { connectionOptions.host = options.host; } - if (options.family != null) { + if ("family" in options && options.family != null) { connectionOptions.family = options.family; } } diff --git a/lib/index.ts b/lib/index.ts index 8302ac13c..226b16273 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -1,6 +1,5 @@ -exports = module.exports = require("./redis").default; +import Redis from "./Redis"; -export { default } from "./redis"; export { default as Cluster } from "./cluster"; export { default as Command } from "./command"; export { default as ScanStream } from "./ScanStream"; @@ -13,7 +12,7 @@ export { // Type Exports export { ISentinelAddress } from "./connectors/SentinelConnector"; -export { IRedisOptions } from "./redis/RedisOptions"; +export { RedisOptions } from "./redis/RedisOptions"; // No TS typings export const ReplyError = require("redis-errors").ReplyError; @@ -35,3 +34,5 @@ export function print(err: Error | null, reply?: any) { console.log("Reply: " + reply); } } + +export default Redis; diff --git a/lib/pipeline.ts b/lib/pipeline.ts index 87f5a36ff..0f44c7e1f 100644 --- a/lib/pipeline.ts +++ b/lib/pipeline.ts @@ -1,12 +1,13 @@ -import Command from "./command"; -import { deprecate } from "util"; -import asCallback from "standard-as-callback"; -import { exists, hasFlag } from "redis-commands"; import * as calculateSlot from "cluster-key-slot"; import * as pMap from "p-map"; +import { exists, hasFlag } from "redis-commands"; +import asCallback from "standard-as-callback"; +import { deprecate } from "util"; +import Redis, { Cluster } from "."; +import Command from "./command"; +import Commander from "./utils/Commander"; import * as PromiseContainer from "./promiseContainer"; import { CallbackFunction } from "./types"; -import Commander from "./commander"; import { noop } from "./utils"; /* @@ -27,212 +28,228 @@ function generateMultiWithNodes(redis, keys) { return slot; } -export default function Pipeline(redis) { - Commander.call(this); - - this.redis = redis; - this.isCluster = - this.redis.constructor.name === "Cluster" || this.redis.isCluster; - this.isPipeline = true; - this.options = redis.options; - this._queue = []; - this._result = []; - this._transactions = 0; - this._shaToScript = {}; - - Object.keys(redis.scriptsSet).forEach((name) => { - const script = redis.scriptsSet[name]; - this._shaToScript[script.sha] = script; - this[name] = redis[name]; - this[name + "Buffer"] = redis[name + "Buffer"]; - }); - - redis.addedBuiltinSet.forEach((name) => { - this[name] = redis[name]; - this[name + "Buffer"] = redis[name + "Buffer"]; - }); - - const Promise = PromiseContainer.get(); - this.promise = new Promise((resolve, reject) => { - this.resolve = resolve; - this.reject = reject; - }); - - const _this = this; - Object.defineProperty(this, "length", { - get: function () { - return _this._queue.length; - }, - }); -} +class Pipeline extends Commander { + isCluster: boolean; + isPipeline = true; + leftRedirections: { ttl?: number }; + private replyPending = 0; + private _queue = []; + private _result = []; + private _transactions = 0; + private _shaToScript = {}; + private preferKey: string; + promise: Promise; + resolve: (result: unknown) => void; + reject: (error: Error) => void; + + constructor(public redis: Redis | Cluster) { + super(); + this.isCluster = + this.redis.constructor.name === "Cluster" || this.redis.isCluster; + this.options = redis.options; + + Object.keys(redis.scriptsSet).forEach((name) => { + const script = redis.scriptsSet[name]; + this._shaToScript[script.sha] = script; + this[name] = redis[name]; + this[name + "Buffer"] = redis[name + "Buffer"]; + }); -Object.assign(Pipeline.prototype, Commander.prototype); + redis.addedBuiltinSet.forEach((name) => { + this[name] = redis[name]; + this[name + "Buffer"] = redis[name + "Buffer"]; + }); -Pipeline.prototype.fillResult = function (value, position) { - if (this._queue[position].name === "exec" && Array.isArray(value[1])) { - const execLength = value[1].length; - for (let i = 0; i < execLength; i++) { - if (value[1][i] instanceof Error) { - continue; - } - const cmd = this._queue[position - (execLength - i)]; - try { - value[1][i] = cmd.transformReply(value[1][i]); - } catch (err) { - value[1][i] = err; - } - } - } - this._result[position] = value; + this.promise = new Promise((resolve, reject) => { + this.resolve = resolve; + this.reject = reject; + }); - if (--this.replyPending) { - return; + const _this = this; + Object.defineProperty(this, "length", { + get: function () { + return _this._queue.length; + }, + }); } - if (this.isCluster) { - let retriable = true; - let commonError: { name: string; message: string }; - for (let i = 0; i < this._result.length; ++i) { - const error = this._result[i][0]; - const command = this._queue[i]; - if (error) { - if ( - command.name === "exec" && - error.message === - "EXECABORT Transaction discarded because of previous errors." - ) { + fillResult(value: unknown[], position: number) { + if (this._queue[position].name === "exec" && Array.isArray(value[1])) { + const execLength = value[1].length; + for (let i = 0; i < execLength; i++) { + if (value[1][i] instanceof Error) { continue; } - if (!commonError) { - commonError = { - name: error.name, - message: error.message, - }; - } else if ( - commonError.name !== error.name || - commonError.message !== error.message - ) { - retriable = false; - break; - } - } else if (!command.inTransaction) { - const isReadOnly = - exists(command.name) && hasFlag(command.name, "readonly"); - if (!isReadOnly) { - retriable = false; - break; + const cmd = this._queue[position - (execLength - i)]; + try { + value[1][i] = cmd.transformReply(value[1][i]); + } catch (err) { + value[1][i] = err; } } } - if (commonError && retriable) { - const _this = this; - const errv = commonError.message.split(" "); - const queue = this._queue; - let inTransaction = false; - this._queue = []; - for (let i = 0; i < queue.length; ++i) { - if ( - errv[0] === "ASK" && - !inTransaction && - queue[i].name !== "asking" && - (!queue[i - 1] || queue[i - 1].name !== "asking") - ) { - const asking = new Command("asking"); - asking.ignore = true; - this.sendCommand(asking); + this._result[position] = value; + + if (--this.replyPending) { + return; + } + + if (this.isCluster) { + let retriable = true; + let commonError: { name: string; message: string }; + for (let i = 0; i < this._result.length; ++i) { + const error = this._result[i][0]; + const command = this._queue[i]; + if (error) { + if ( + command.name === "exec" && + error.message === + "EXECABORT Transaction discarded because of previous errors." + ) { + continue; + } + if (!commonError) { + commonError = { + name: error.name, + message: error.message, + }; + } else if ( + commonError.name !== error.name || + commonError.message !== error.message + ) { + retriable = false; + break; + } + } else if (!command.inTransaction) { + const isReadOnly = + exists(command.name) && hasFlag(command.name, "readonly"); + if (!isReadOnly) { + retriable = false; + break; + } } - queue[i].initPromise(); - this.sendCommand(queue[i]); - inTransaction = queue[i].inTransaction; } + if (commonError && retriable) { + const _this = this; + const errv = commonError.message.split(" "); + const queue = this._queue; + let inTransaction = false; + this._queue = []; + for (let i = 0; i < queue.length; ++i) { + if ( + errv[0] === "ASK" && + !inTransaction && + queue[i].name !== "asking" && + (!queue[i - 1] || queue[i - 1].name !== "asking") + ) { + const asking = new Command("asking"); + asking.ignore = true; + this.sendCommand(asking); + } + queue[i].initPromise(); + this.sendCommand(queue[i]); + inTransaction = queue[i].inTransaction; + } - let matched = true; - if (typeof this.leftRedirections === "undefined") { - this.leftRedirections = {}; - } - const exec = function () { - _this.exec(); - }; - this.redis.handleError(commonError, this.leftRedirections, { - moved: function (slot, key) { - _this.preferKey = key; - _this.redis.slots[errv[1]] = [key]; - _this.redis._groupsBySlot[errv[1]] = - _this.redis._groupsIds[_this.redis.slots[errv[1]].join(";")]; - _this.redis.refreshSlotsCache(); - _this.exec(); - }, - ask: function (slot, key) { - _this.preferKey = key; + let matched = true; + if (typeof this.leftRedirections === "undefined") { + this.leftRedirections = {}; + } + const exec = function () { + // @ts-expect-error _this.exec(); - }, - tryagain: exec, - clusterDown: exec, - connectionClosed: exec, - maxRedirections: () => { - matched = false; - }, - defaults: () => { - matched = false; - }, - }); - if (matched) { - return; + }; + const cluster = this.redis as Cluster; + cluster.handleError(commonError, this.leftRedirections, { + moved: function (_slot: string, key: string) { + _this.preferKey = key; + cluster.slots[errv[1]] = [key]; + cluster._groupsBySlot[errv[1]] = + cluster._groupsIds[cluster.slots[errv[1]].join(";")]; + cluster.refreshSlotsCache(); + // @ts-expect-error + _this.exec(); + }, + ask: function (_slot: string, key: string) { + _this.preferKey = key; + // @ts-expect-error + _this.exec(); + }, + tryagain: exec, + clusterDown: exec, + connectionClosed: exec, + maxRedirections: () => { + matched = false; + }, + defaults: () => { + matched = false; + }, + }); + if (matched) { + return; + } } } - } - let ignoredCount = 0; - for (let i = 0; i < this._queue.length - ignoredCount; ++i) { - if (this._queue[i + ignoredCount].ignore) { - ignoredCount += 1; + let ignoredCount = 0; + for (let i = 0; i < this._queue.length - ignoredCount; ++i) { + if (this._queue[i + ignoredCount].ignore) { + ignoredCount += 1; + } + this._result[i] = this._result[i + ignoredCount]; } - this._result[i] = this._result[i + ignoredCount]; + this.resolve(this._result.slice(0, this._result.length - ignoredCount)); } - this.resolve(this._result.slice(0, this._result.length - ignoredCount)); -}; -Pipeline.prototype.sendCommand = function (command) { - if (this._transactions > 0) { - command.inTransaction = true; - } + sendCommand(command: Command): unknown { + if (this._transactions > 0) { + command.inTransaction = true; + } - const position = this._queue.length; - command.pipelineIndex = position; + const position = this._queue.length; + command.pipelineIndex = position; - command.promise - .then((result) => { - this.fillResult([null, result], position); - }) - .catch((error) => { - this.fillResult([error], position); - }); + command.promise + .then((result) => { + this.fillResult([null, result], position); + }) + .catch((error) => { + this.fillResult([error], position); + }); - this._queue.push(command); + this._queue.push(command); - return this; -}; + return this; + } + + addBatch(commands) { + let command, commandName, args; + for (let i = 0; i < commands.length; ++i) { + command = commands[i]; + commandName = command[0]; + args = command.slice(1); + this[commandName].apply(this, args); + } -Pipeline.prototype.addBatch = function (commands) { - let command, commandName, args; - for (let i = 0; i < commands.length; ++i) { - command = commands[i]; - commandName = command[0]; - args = command.slice(1); - this[commandName].apply(this, args); + return this; } +} - return this; -}; +export default Pipeline; +// @ts-expect-error const multi = Pipeline.prototype.multi; +// @ts-expect-error Pipeline.prototype.multi = function () { this._transactions += 1; return multi.apply(this, arguments); }; +// @ts-expect-error const execBuffer = Pipeline.prototype.execBuffer; +// @ts-expect-error const exec = Pipeline.prototype.exec; +// @ts-expect-error Pipeline.prototype.execBuffer = deprecate(function () { if (this._transactions > 0) { this._transactions -= 1; @@ -246,6 +263,7 @@ Pipeline.prototype.execBuffer = deprecate(function () { // // If a different promise instance were returned, that promise would cause its own unhandled promise rejection // errors, even if that promise unconditionally resolved to **the resolved value of** this.promise. +// @ts-expect-error Pipeline.prototype.exec = function ( callback: CallbackFunction ): Promise> { diff --git a/lib/redis/RedisOptions.ts b/lib/redis/RedisOptions.ts index b06889dc1..4dbb78cc8 100644 --- a/lib/redis/RedisOptions.ts +++ b/lib/redis/RedisOptions.ts @@ -1,15 +1,12 @@ -import { IClusterOptions } from "../cluster/ClusterOptions"; -import { ICommanderOptions } from "../commander"; -import AbstractConnector from "../connectors/AbstractConnector"; -import { ISentinelConnectionOptions } from "../connectors/SentinelConnector"; +import { CommanderOptions } from "../utils/Commander"; +import ConnectorConstructor from "../connectors/ConnectorConstructor"; +import { SentinelConnectionOptions } from "../connectors/SentinelConnector"; +import { StandaloneConnectionOptions } from "../connectors/StandaloneConnector"; export type ReconnectOnError = (err: Error) => boolean | 1 | 2; -export interface IRedisOptions - extends Partial, - Partial, - Partial { - Connector?: typeof AbstractConnector; +interface CommonRedisOptions extends CommanderOptions { + Connector?: ConnectorConstructor; retryStrategy?: (times: number) => number | void | null; commandTimeout?: number; keepAlive?: number; @@ -21,10 +18,11 @@ export interface IRedisOptions dropBufferSupport?: boolean; autoResubscribe?: boolean; autoResendUnfulfilledCommands?: boolean; - keyPrefix?: string; reconnectOnError?: ReconnectOnError; readOnly?: boolean; stringNumbers?: boolean; + connectTimeout?: number; + monitor?: boolean; maxRetriesPerRequest?: number; maxLoadingRetryTime?: number; enableAutoPipelining?: boolean; @@ -32,9 +30,16 @@ export interface IRedisOptions maxScriptsCachingTime?: number; offlineQueue?: boolean; commandQueue?: boolean; + enableOfflineQueue?: boolean; + enableReadyCheck?: boolean; + lazyConnect?: boolean; } -export const DEFAULT_REDIS_OPTIONS: IRedisOptions = { +export type RedisOptions = + | (CommonRedisOptions & SentinelConnectionOptions) + | (CommonRedisOptions & StandaloneConnectionOptions); + +export const DEFAULT_REDIS_OPTIONS: RedisOptions = { // Connection port: 6379, host: "localhost", diff --git a/lib/redis/index.ts b/lib/redis/index.ts deleted file mode 100644 index 7b9d37f4d..000000000 --- a/lib/redis/index.ts +++ /dev/null @@ -1,889 +0,0 @@ -import { defaults, noop } from "../utils/lodash"; -import { inherits } from "util"; -import { EventEmitter } from "events"; -import Deque = require("denque"); -import Command from "../command"; -import Commander from "../commander"; -import { - isInt, - CONNECTION_CLOSED_ERROR_MSG, - parseURL, - Debug, - resolveTLSProfile, -} from "../utils"; -import asCallback from "standard-as-callback"; -import * as eventHandler from "./event_handler"; -import { StandaloneConnector, SentinelConnector } from "../connectors"; -import ScanStream from "../ScanStream"; -import * as commands from "redis-commands"; -import * as PromiseContainer from "../promiseContainer"; -import { addTransactionSupport } from "../transaction"; -import { - IRedisOptions, - ReconnectOnError, - DEFAULT_REDIS_OPTIONS, -} from "./RedisOptions"; -import { NetStream, CallbackFunction, ICommandItem } from "../types"; - -const debug = Debug("redis"); - -/** - * Creates a Redis instance - * - * @constructor - * @param {(number|string|Object)} [port=6379] - Port of the Redis server, - * or a URL string(see the examples below), - * or the `options` object(see the third argument). - * @param {string|Object} [host=localhost] - Host of the Redis server, - * when the first argument is a URL string, - * this argument is an object represents the options. - * @param {Object} [options] - Other options. - * @param {number} [options.port=6379] - Port of the Redis server. - * @param {string} [options.host=localhost] - Host of the Redis server. - * @param {string} [options.family=4] - Version of IP stack. Defaults to 4. - * @param {string} [options.path=null] - Local domain socket path. If set the `port`, - * `host` and `family` will be ignored. - * @param {number} [options.keepAlive=0] - TCP KeepAlive on the socket with a X ms delay before start. - * Set to a non-number value to disable keepAlive. - * @param {boolean} [options.noDelay=true] - Whether to disable the Nagle's Algorithm. By default we disable - * it to reduce the latency. - * @param {string} [options.connectionName=null] - Connection name. - * @param {number} [options.db=0] - Database index to use. - * @param {string} [options.password=null] - If set, client will send AUTH command - * with the value of this option when connected. - * @param {string} [options.username=null] - Similar to `password`, Provide this for Redis ACL support. - * @param {boolean} [options.dropBufferSupport=false] - Drop the buffer support for better performance. - * This option is recommended to be enabled when - * handling large array response and you don't need the buffer support. - * @param {boolean} [options.enableReadyCheck=true] - When a connection is established to - * the Redis server, the server might still be loading the database from disk. - * While loading, the server not respond to any commands. - * To work around this, when this option is `true`, - * ioredis will check the status of the Redis server, - * and when the Redis server is able to process commands, - * a `ready` event will be emitted. - * @param {boolean} [options.enableOfflineQueue=true] - By default, - * if there is no active connection to the Redis server, - * commands are added to a queue and are executed once the connection is "ready" - * (when `enableReadyCheck` is `true`, - * "ready" means the Redis server has loaded the database from disk, otherwise means the connection - * to the Redis server has been established). If this option is false, - * when execute the command when the connection isn't ready, an error will be returned. - * @param {number} [options.connectTimeout=10000] - The milliseconds before a timeout occurs during the initial - * connection to the Redis server. - * @param {boolean} [options.autoResubscribe=true] - After reconnected, if the previous connection was in the - * subscriber mode, client will auto re-subscribe these channels. - * @param {boolean} [options.autoResendUnfulfilledCommands=true] - If true, client will resend unfulfilled - * commands(e.g. block commands) in the previous connection when reconnected. - * @param {boolean} [options.lazyConnect=false] - By default, - * When a new `Redis` instance is created, it will connect to Redis server automatically. - * If you want to keep the instance disconnected until a command is called, you can pass the `lazyConnect` option to - * the constructor: - * - * ```javascript - * var redis = new Redis({ lazyConnect: true }); - * // No attempting to connect to the Redis server here. - - * // Now let's connect to the Redis server - * redis.get('foo', function () { - * }); - * ``` - * @param {Object} [options.tls] - TLS connection support. See https://github.com/luin/ioredis#tls-options - * @param {string} [options.keyPrefix=''] - The prefix to prepend to all keys in a command. - * @param {function} [options.retryStrategy] - See "Quick Start" section - * @param {number} [options.maxRetriesPerRequest] - See "Quick Start" section - * @param {number} [options.maxLoadingRetryTime=10000] - when redis server is not ready, we will wait for - * `loading_eta_seconds` from `info` command or maxLoadingRetryTime (milliseconds), whichever is smaller. - * @param {function} [options.reconnectOnError] - See "Quick Start" section - * @param {boolean} [options.readOnly=false] - Enable READONLY mode for the connection. - * Only available for cluster mode. - * @param {boolean} [options.stringNumbers=false] - Force numbers to be always returned as JavaScript - * strings. This option is necessary when dealing with big numbers (exceed the [-2^53, +2^53] range). - * @param {boolean} [options.enableTLSForSentinelMode=false] - Whether to support the `tls` option - * when connecting to Redis via sentinel mode. - * @param {NatMap} [options.natMap=null] NAT map for sentinel connector. - * @param {boolean} [options.updateSentinels=true] - Update the given `sentinels` list with new IP - * addresses when communicating with existing sentinels. - * @param {boolean} [options.failoverDetector=false] - Detect failover actively by subscribing to the - * related channels. With this option disabled, ioredis is still able to detect failovers because Redis - * Sentinel will disconnect all clients whenever a failover happens, so ioredis will reconnect to the new - * master. This option is useful when you want to detect failover quicker, but it will create more TCP - * connections to Redis servers in order to subscribe to related channels. -* @param {boolean} [options.enableAutoPipelining=false] - When enabled, all commands issued during an event loop - * iteration are automatically wrapped in a pipeline and sent to the server at the same time. - * This can dramatically improve performance. - * @param {string[]} [options.autoPipeliningIgnoredCommands=[]] - The list of commands which must not be automatically wrapped in pipelines. - * @param {number} [options.maxScriptsCachingTime=60000] Default script definition caching time. - * @extends [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter) - * @extends Commander - * @example - * ```js - * var Redis = require('ioredis'); - * - * var redis = new Redis(); - * - * var redisOnPort6380 = new Redis(6380); - * var anotherRedis = new Redis(6380, '192.168.100.1'); - * var unixSocketRedis = new Redis({ path: '/tmp/echo.sock' }); - * var unixSocketRedis2 = new Redis('/tmp/echo.sock'); - * var urlRedis = new Redis('redis://user:password@redis-service.com:6379/'); - * var urlRedis2 = new Redis('//localhost:6379'); - * var urlRedisTls = new Redis('rediss://user:password@redis-service.com:6379/'); - * var authedRedis = new Redis(6380, '192.168.100.1', { password: 'password' }); - * ``` - */ -export default Redis; -function Redis(port: number, host: string, options: IRedisOptions): void; -function Redis(path: string, options: IRedisOptions): void; -function Redis(port: number, options: IRedisOptions): void; -function Redis(port: number, host: string): void; -function Redis(options: IRedisOptions): void; -function Redis(port: number): void; -function Redis(path: string): void; -function Redis(): void; -function Redis() { - if (!(this instanceof Redis)) { - console.error( - new Error( - "Calling `Redis()` like a function is deprecated. Using `new Redis()` instead." - ).stack.replace("Error", "Warning") - ); - return new Redis(arguments[0], arguments[1], arguments[2]); - } - - this.parseOptions(arguments[0], arguments[1], arguments[2]); - - EventEmitter.call(this); - Commander.call(this); - - this.resetCommandQueue(); - this.resetOfflineQueue(); - - this.connectionEpoch = 0; - - if (this.options.Connector) { - this.connector = new this.options.Connector(this.options); - } else if (this.options.sentinels) { - const sentinelConnector = new SentinelConnector(this.options); - sentinelConnector.emitter = this; - - this.connector = sentinelConnector; - } else { - this.connector = new StandaloneConnector(this.options); - } - - this.retryAttempts = 0; - - // Prepare a cache of scripts and setup a interval which regularly clears it - this._addedScriptHashes = {}; - - // Prepare autopipelines structures - this._autoPipelines = new Map(); - this._runningAutoPipelines = new Set(); - - Object.defineProperty(this, "autoPipelineQueueSize", { - get() { - let queued = 0; - - for (const pipeline of this._autoPipelines.values()) { - queued += pipeline.length; - } - - return queued; - }, - }); - - // end(or wait) -> connecting -> connect -> ready -> end - if (this.options.lazyConnect) { - this.setStatus("wait"); - } else { - this.connect().catch(noop); - } -} - -inherits(Redis, EventEmitter); -Object.assign(Redis.prototype, Commander.prototype); - -/** - * Create a Redis instance - * - * @deprecated - */ -// @ts-ignore -Redis.createClient = function (...args): Redis { - // @ts-ignore - return new Redis(...args); -}; - -/** - * Default options - * - * @var defaultOptions - * @private - */ -Redis.defaultOptions = DEFAULT_REDIS_OPTIONS; - -Redis.prototype.resetCommandQueue = function () { - this.commandQueue = new Deque(); -}; - -Redis.prototype.resetOfflineQueue = function () { - this.offlineQueue = new Deque(); -}; - -Redis.prototype.parseOptions = function () { - this.options = {}; - let isTls = false; - for (let i = 0; i < arguments.length; ++i) { - const arg = arguments[i]; - if (arg === null || typeof arg === "undefined") { - continue; - } - if (typeof arg === "object") { - defaults(this.options, arg); - } else if (typeof arg === "string") { - defaults(this.options, parseURL(arg)); - if (arg.startsWith("rediss://")) { - isTls = true; - } - } else if (typeof arg === "number") { - this.options.port = arg; - } else { - throw new Error("Invalid argument " + arg); - } - } - if (isTls) { - defaults(this.options, { tls: true }); - } - defaults(this.options, Redis.defaultOptions); - - if (typeof this.options.port === "string") { - this.options.port = parseInt(this.options.port, 10); - } - if (typeof this.options.db === "string") { - this.options.db = parseInt(this.options.db, 10); - } - if (this.options.parser === "hiredis") { - console.warn( - "Hiredis parser is abandoned since ioredis v3.0, and JavaScript parser will be used" - ); - } - - this.options = resolveTLSProfile(this.options); -}; - -/** - * Change instance's status - * @private - */ -Redis.prototype.setStatus = function (status, arg) { - // @ts-ignore - if (debug.enabled) { - debug( - "status[%s]: %s -> %s", - this._getDescription(), - this.status || "[empty]", - status - ); - } - this.status = status; - process.nextTick(this.emit.bind(this, status, arg)); -}; - -Redis.prototype.clearAddedScriptHashesCleanInterval = function () { - if (this._addedScriptHashesCleanInterval) { - clearInterval(this._addedScriptHashesCleanInterval); - this._addedScriptHashesCleanInterval = null; - } -}; - -/** - * Create a connection to Redis. - * This method will be invoked automatically when creating a new Redis instance - * unless `lazyConnect: true` is passed. - * - * When calling this method manually, a Promise is returned, which will - * be resolved when the connection status is ready. - * @param {function} [callback] - * @return {Promise} - * @public - */ -Redis.prototype.connect = function (callback) { - const _Promise = PromiseContainer.get(); - const promise = new _Promise((resolve, reject) => { - if ( - this.status === "connecting" || - this.status === "connect" || - this.status === "ready" - ) { - reject(new Error("Redis is already connecting/connected")); - return; - } - - // Make sure only one timer is active at a time - this.clearAddedScriptHashesCleanInterval(); - - // Scripts need to get reset on reconnect as redis - // might have been restarted or some failover happened - this._addedScriptHashes = {}; - - // Start the script cache cleaning - this._addedScriptHashesCleanInterval = setInterval(() => { - this._addedScriptHashes = {}; - }, this.options.maxScriptsCachingTime); - - this.connectionEpoch += 1; - this.setStatus("connecting"); - - const { options } = this; - - this.condition = { - select: options.db, - auth: options.username - ? [options.username, options.password] - : options.password, - subscriber: false, - }; - - const _this = this; - asCallback( - this.connector.connect(function (type, err) { - _this.silentEmit(type, err); - }) as Promise, - function (err: Error | null, stream?: NetStream) { - if (err) { - _this.flushQueue(err); - _this.silentEmit("error", err); - reject(err); - _this.setStatus("end"); - return; - } - let CONNECT_EVENT = options.tls ? "secureConnect" : "connect"; - if (options.sentinels && !options.enableTLSForSentinelMode) { - CONNECT_EVENT = "connect"; - } - - _this.stream = stream; - if (typeof options.keepAlive === "number") { - stream.setKeepAlive(true, options.keepAlive); - } - - if (stream.connecting) { - stream.once(CONNECT_EVENT, eventHandler.connectHandler(_this)); - - if (options.connectTimeout) { - /* - * Typically, Socket#setTimeout(0) will clear the timer - * set before. However, in some platforms (Electron 3.x~4.x), - * the timer will not be cleared. So we introduce a variable here. - * - * See https://github.com/electron/electron/issues/14915 - */ - let connectTimeoutCleared = false; - stream.setTimeout(options.connectTimeout, function () { - if (connectTimeoutCleared) { - return; - } - stream.setTimeout(0); - stream.destroy(); - - const err = new Error("connect ETIMEDOUT"); - // @ts-ignore - err.errorno = "ETIMEDOUT"; - // @ts-ignore - err.code = "ETIMEDOUT"; - // @ts-ignore - err.syscall = "connect"; - eventHandler.errorHandler(_this)(err); - }); - stream.once(CONNECT_EVENT, function () { - connectTimeoutCleared = true; - stream.setTimeout(0); - }); - } - } else if (stream.destroyed) { - const firstError = _this.connector.firstError; - if (firstError) { - process.nextTick(() => { - eventHandler.errorHandler(_this)(firstError); - }); - } - process.nextTick(eventHandler.closeHandler(_this)); - } else { - process.nextTick(eventHandler.connectHandler(_this)); - } - if (!stream.destroyed) { - stream.once("error", eventHandler.errorHandler(_this)); - stream.once("close", eventHandler.closeHandler(_this)); - } - - if (options.noDelay) { - stream.setNoDelay(true); - } - - const connectionReadyHandler = function () { - _this.removeListener("close", connectionCloseHandler); - resolve(); - }; - var connectionCloseHandler = function () { - _this.removeListener("ready", connectionReadyHandler); - reject(new Error(CONNECTION_CLOSED_ERROR_MSG)); - }; - _this.once("ready", connectionReadyHandler); - _this.once("close", connectionCloseHandler); - } - ); - }); - - return asCallback(promise, callback); -}; - -/** - * Disconnect from Redis. - * - * This method closes the connection immediately, - * and may lose some pending replies that haven't written to client. - * If you want to wait for the pending replies, use Redis#quit instead. - * @public - */ -Redis.prototype.disconnect = function (reconnect) { - this.clearAddedScriptHashesCleanInterval(); - - if (!reconnect) { - this.manuallyClosing = true; - } - if (this.reconnectTimeout && !reconnect) { - clearTimeout(this.reconnectTimeout); - this.reconnectTimeout = null; - } - if (this.status === "wait") { - eventHandler.closeHandler(this)(); - } else { - this.connector.disconnect(); - } -}; - -/** - * Disconnect from Redis. - * - * @deprecated - */ -Redis.prototype.end = function () { - this.disconnect(); -}; - -/** - * Create a new instance with the same options as the current one. - * - * @example - * ```js - * var redis = new Redis(6380); - * var anotherRedis = redis.duplicate(); - * ``` - * - * @public - */ -Redis.prototype.duplicate = function (override: IRedisOptions) { - return new Redis(Object.assign({}, this.options, override || {})); -}; - -Redis.prototype.recoverFromFatalError = function ( - commandError, - err: Error | null, - options -) { - this.flushQueue(err, options); - this.silentEmit("error", err); - this.disconnect(true); -}; - -Redis.prototype.handleReconnection = function handleReconnection( - err: Error, - item: ICommandItem -) { - let needReconnect: ReturnType = false; - if (this.options.reconnectOnError) { - needReconnect = this.options.reconnectOnError(err); - } - - switch (needReconnect) { - case 1: - case true: - if (this.status !== "reconnecting") { - this.disconnect(true); - } - item.command.reject(err); - break; - case 2: - if (this.status !== "reconnecting") { - this.disconnect(true); - } - if ( - this.condition.select !== item.select && - item.command.name !== "select" - ) { - this.select(item.select); - } - this.sendCommand(item.command); - break; - default: - item.command.reject(err); - } -}; - -/** - * Flush offline queue and command queue with error. - * - * @param {Error} error - The error object to send to the commands - * @param {object} options - * @private - */ -Redis.prototype.flushQueue = function (error: Error, options: IRedisOptions) { - options = defaults({}, options, { - offlineQueue: true, - commandQueue: true, - }); - - let item; - if (options.offlineQueue) { - while (this.offlineQueue.length > 0) { - item = this.offlineQueue.shift(); - item.command.reject(error); - } - } - - if (options.commandQueue) { - if (this.commandQueue.length > 0) { - if (this.stream) { - this.stream.removeAllListeners("data"); - } - while (this.commandQueue.length > 0) { - item = this.commandQueue.shift(); - item.command.reject(error); - } - } - } -}; - -/** - * Check whether Redis has finished loading the persistent data and is able to - * process commands. - * - * @param {Function} callback - * @private - */ -Redis.prototype._readyCheck = function (callback: CallbackFunction) { - const _this = this; - this.info(function (err: Error | null, res: string) { - if (err) { - return callback(err); - } - if (typeof res !== "string") { - return callback(null, res); - } - - const info: { [key: string]: any } = {}; - - const lines = res.split("\r\n"); - for (let i = 0; i < lines.length; ++i) { - const [fieldName, ...fieldValueParts] = lines[i].split(":"); - const fieldValue = fieldValueParts.join(":"); - if (fieldValue) { - info[fieldName] = fieldValue; - } - } - - if (!info.loading || info.loading === "0") { - callback(null, info); - } else { - const loadingEtaMs = (info.loading_eta_seconds || 1) * 1000; - const retryTime = - _this.options.maxLoadingRetryTime && - _this.options.maxLoadingRetryTime < loadingEtaMs - ? _this.options.maxLoadingRetryTime - : loadingEtaMs; - debug("Redis server still loading, trying again in " + retryTime + "ms"); - setTimeout(function () { - _this._readyCheck(callback); - }, retryTime); - } - }); -}; - -/** - * Emit only when there's at least one listener. - * - * @param {string} eventName - Event to emit - * @param {...*} arguments - Arguments - * @return {boolean} Returns true if event had listeners, false otherwise. - * @private - */ -Redis.prototype.silentEmit = function (eventName) { - let error; - if (eventName === "error") { - error = arguments[1]; - - if (this.status === "end") { - return; - } - - if (this.manuallyClosing) { - // ignore connection related errors when manually disconnecting - if ( - error instanceof Error && - (error.message === CONNECTION_CLOSED_ERROR_MSG || - // @ts-ignore - error.syscall === "connect" || - // @ts-ignore - error.syscall === "read") - ) { - return; - } - } - } - if (this.listeners(eventName).length > 0) { - return this.emit.apply(this, arguments); - } - if (error && error instanceof Error) { - console.error("[ioredis] Unhandled error event:", error.stack); - } - return false; -}; - -/** - * Listen for all requests received by the server in real time. - * - * This command will create a new connection to Redis and send a - * MONITOR command via the new connection in order to avoid disturbing - * the current connection. - * - * @param {function} [callback] The callback function. If omit, a promise will be returned. - * @example - * ```js - * var redis = new Redis(); - * redis.monitor(function (err, monitor) { - * // Entering monitoring mode. - * monitor.on('monitor', function (time, args, source, database) { - * console.log(time + ": " + util.inspect(args)); - * }); - * }); - * - * // supports promise as well as other commands - * redis.monitor().then(function (monitor) { - * monitor.on('monitor', function (time, args, source, database) { - * console.log(time + ": " + util.inspect(args)); - * }); - * }); - * ``` - * @public - */ -Redis.prototype.monitor = function (callback) { - const monitorInstance = this.duplicate({ - monitor: true, - lazyConnect: false, - }); - - const Promise = PromiseContainer.get(); - return asCallback( - new Promise(function (resolve) { - monitorInstance.once("monitoring", function () { - resolve(monitorInstance); - }); - }), - callback - ); -}; - -addTransactionSupport(Redis.prototype); - -/** - * Send a command to Redis - * - * This method is used internally by the `Redis#set`, `Redis#lpush` etc. - * Most of the time you won't invoke this method directly. - * However when you want to send a command that is not supported by ioredis yet, - * this command will be useful. - * - * @method sendCommand - * @memberOf Redis# - * @param {Command} command - The Command instance to send. - * @see {@link Command} - * @example - * ```js - * var redis = new Redis(); - * - * // Use callback - * var get = new Command('get', ['foo'], 'utf8', function (err, result) { - * console.log(result); - * }); - * redis.sendCommand(get); - * - * // Use promise - * var set = new Command('set', ['foo', 'bar'], 'utf8'); - * set.promise.then(function (result) { - * console.log(result); - * }); - * redis.sendCommand(set); - * ``` - * @private - */ -Redis.prototype.sendCommand = function (command: Command, stream: NetStream) { - if (this.status === "wait") { - this.connect().catch(noop); - } - if (this.status === "end") { - command.reject(new Error(CONNECTION_CLOSED_ERROR_MSG)); - return command.promise; - } - if ( - this.condition.subscriber && - !Command.checkFlag("VALID_IN_SUBSCRIBER_MODE", command.name) - ) { - command.reject( - new Error( - "Connection in subscriber mode, only subscriber commands may be used" - ) - ); - return command.promise; - } - - if (typeof this.options.commandTimeout === "number") { - command.setTimeout(this.options.commandTimeout); - } - - if (command.name === "quit") { - this.clearAddedScriptHashesCleanInterval(); - } - - let writable = - this.status === "ready" || - (!stream && - this.status === "connect" && - commands.exists(command.name) && - commands.hasFlag(command.name, "loading")); - if (!this.stream) { - writable = false; - } else if (!this.stream.writable) { - writable = false; - } else if (this.stream._writableState && this.stream._writableState.ended) { - // https://github.com/iojs/io.js/pull/1217 - writable = false; - } - - if (!writable && !this.options.enableOfflineQueue) { - command.reject( - new Error( - "Stream isn't writeable and enableOfflineQueue options is false" - ) - ); - return command.promise; - } - - if (!writable && command.name === "quit" && this.offlineQueue.length === 0) { - this.disconnect(); - command.resolve(Buffer.from("OK")); - return command.promise; - } - - if (writable) { - // @ts-ignore - if (debug.enabled) { - debug( - "write command[%s]: %d -> %s(%o)", - this._getDescription(), - this.condition.select, - command.name, - command.args - ); - } - (stream || this.stream).write(command.toWritable()); - - this.commandQueue.push({ - command: command, - stream: stream, - select: this.condition.select, - }); - - if (Command.checkFlag("WILL_DISCONNECT", command.name)) { - this.manuallyClosing = true; - } - } else if (this.options.enableOfflineQueue) { - // @ts-ignore - if (debug.enabled) { - debug( - "queue command[%s]: %d -> %s(%o)", - this._getDescription(), - this.condition.select, - command.name, - command.args - ); - } - this.offlineQueue.push({ - command: command, - stream: stream, - select: this.condition.select, - }); - } - - if (command.name === "select" && isInt(command.args[0])) { - const db = parseInt(command.args[0], 10); - if (this.condition.select !== db) { - this.condition.select = db; - this.emit("select", db); - debug("switch to db [%d]", this.condition.select); - } - } - - return command.promise; -}; - -/** - * Get description of the connection. Used for debugging. - * @private - */ -Redis.prototype._getDescription = function () { - let description; - if (this.options.path) { - description = this.options.path; - } else if ( - this.stream && - this.stream.remoteAddress && - this.stream.remotePort - ) { - description = this.stream.remoteAddress + ":" + this.stream.remotePort; - } else { - description = this.options.host + ":" + this.options.port; - } - if (this.options.connectionName) { - description += ` (${this.options.connectionName})`; - } - return description; -}; -[ - "scan", - "sscan", - "hscan", - "zscan", - "scanBuffer", - "sscanBuffer", - "hscanBuffer", - "zscanBuffer", -].forEach(function (command) { - Redis.prototype[command + "Stream"] = function (key, options) { - if (command === "scan" || command === "scanBuffer") { - options = key; - key = null; - } - return new ScanStream( - defaults( - { - objectMode: true, - key: key, - redis: this, - command: command, - }, - options - ) - ); - }; -}); diff --git a/lib/transaction.ts b/lib/transaction.ts index 26fcea0e7..eb26b0274 100644 --- a/lib/transaction.ts +++ b/lib/transaction.ts @@ -22,11 +22,14 @@ export function addTransactionSupport(redis) { return multi.call(this); } const pipeline = new Pipeline(this); + // @ts-expect-error pipeline.multi(); if (Array.isArray(commands)) { pipeline.addBatch(commands); } + // @ts-expect-error const exec = pipeline.exec; + // @ts-expect-error pipeline.exec = function (callback: CallbackFunction) { // Wait for the cluster to be connected, since we need nodes information before continuing if (this.isCluster && !this.redis.slots.length) { @@ -79,11 +82,14 @@ export function addTransactionSupport(redis) { ); }; + // @ts-expect-error const { execBuffer } = pipeline; + // @ts-expect-error pipeline.execBuffer = function (callback: CallbackFunction) { if (this._transactions > 0) { execBuffer.call(pipeline); } + // @ts-expect-error return pipeline.exec(callback); }; return pipeline; diff --git a/lib/commander.ts b/lib/utils/Commander.ts similarity index 62% rename from lib/commander.ts rename to lib/utils/Commander.ts index 644ee73aa..51571c15d 100644 --- a/lib/commander.ts +++ b/lib/utils/Commander.ts @@ -1,14 +1,15 @@ -import { defaults } from "./utils/lodash"; -import Command from "./command"; -import Script from "./script"; -import * as PromiseContainer from "./promiseContainer"; import asCallback from "standard-as-callback"; import { executeWithAutoPipelining, shouldUseAutoPipelining, -} from "./autoPipelining"; - -export interface ICommanderOptions { +} from "../autoPipelining"; +import Command from "../command"; +import * as PromiseContainer from "../promiseContainer"; +import Script from "../script"; +import { NetStream } from "../types"; + +export interface CommanderOptions { + keyPrefix?: string; showFriendlyErrorStack?: boolean; } @@ -26,12 +27,76 @@ const DROP_BUFFER_SUPPORT_ERROR = * Will decrease the performance significantly. * @constructor */ -export default function Commander() { - this.options = defaults({}, this.options || {}, { - showFriendlyErrorStack: false, - }); - this.scriptsSet = {}; - this.addedBuiltinSet = new Set(); +class Commander { + options: CommanderOptions = {}; + scriptsSet = {}; + addedBuiltinSet = new Set(); + + /** + * Return supported builtin commands + * + * @return {string[]} command list + */ + getBuiltinCommands() { + return commands.slice(0); + } + + /** + * Create a builtin command + * + * @param {string} commandName - command name + * @return {object} functions + */ + createBuiltinCommand(commandName: string) { + return { + string: generateFunction(null, commandName, "utf8"), + buffer: generateFunction(null, commandName, null), + }; + } + + /** + * Create add builtin command + */ + addBuiltinCommand(commandName: string) { + this.addedBuiltinSet.add(commandName); + this[commandName] = generateFunction(commandName, commandName, "utf8"); + this[commandName + "Buffer"] = generateFunction( + commandName + "Buffer", + commandName, + null + ); + } + + /** + * Define a custom command using lua script + * + * @param {string} name - the command name + * @param {object} definition + * @param {string} definition.lua - the lua code + * @param {number} [definition.numberOfKeys=null] - the number of keys. + * @param {boolean} [definition.readOnly=false] - force this script to be readonly so it executes on slaves as well. + * If omit, you have to pass the number of keys as the first argument every time you invoke the command + */ + defineCommand(name, definition) { + const script = new Script( + definition.lua, + definition.numberOfKeys, + this.options.keyPrefix, + definition.readOnly + ); + this.scriptsSet[name] = script; + this[name] = generateScriptingFunction(name, name, script, "utf8"); + this[name + "Buffer"] = generateScriptingFunction( + name + "Buffer", + name, + script, + null + ); + } + + sendCommand(command: Command, stream?: NetStream, node?: unknown): unknown { + throw new Error('"sendCommand" is not implemented'); + } } const commands = require("redis-commands").list.filter(function (command) { @@ -39,47 +104,6 @@ const commands = require("redis-commands").list.filter(function (command) { }); commands.push("sentinel"); -/** - * Return supported builtin commands - * - * @return {string[]} command list - * @public - */ -Commander.prototype.getBuiltinCommands = function () { - return commands.slice(0); -}; - -/** - * Create a builtin command - * - * @param {string} commandName - command name - * @return {object} functions - * @public - */ -Commander.prototype.createBuiltinCommand = function (commandName) { - return { - string: generateFunction(null, commandName, "utf8"), - buffer: generateFunction(null, commandName, null), - }; -}; - -/** - * Create add builtin command - * - * @param {string} commandName - command name - * @return {object} functions - * @public - */ -Commander.prototype.addBuiltinCommand = function (commandName) { - this.addedBuiltinSet.add(commandName); - this[commandName] = generateFunction(commandName, commandName, "utf8"); - this[commandName + "Buffer"] = generateFunction( - commandName + "Buffer", - commandName, - null - ); -}; - commands.forEach(function (commandName) { Commander.prototype[commandName] = generateFunction( commandName, @@ -93,46 +117,13 @@ commands.forEach(function (commandName) { ); }); +// @ts-expect-error Commander.prototype.call = generateFunction("call", "utf8"); +// @ts-expect-error Commander.prototype.callBuffer = generateFunction("callBuffer", null); -// eslint-disable-next-line @typescript-eslint/camelcase +// @ts-expect-error Commander.prototype.send_command = Commander.prototype.call; -/** - * Define a custom command using lua script - * - * @param {string} name - the command name - * @param {object} definition - * @param {string} definition.lua - the lua code - * @param {number} [definition.numberOfKeys=null] - the number of keys. - * @param {boolean} [definition.readOnly=false] - force this script to be readonly so it executes on slaves as well. - * If omit, you have to pass the number of keys as the first argument every time you invoke the command - */ -Commander.prototype.defineCommand = function (name, definition) { - const script = new Script( - definition.lua, - definition.numberOfKeys, - this.options.keyPrefix, - definition.readOnly - ); - this.scriptsSet[name] = script; - this[name] = generateScriptingFunction(name, name, script, "utf8"); - this[name + "Buffer"] = generateScriptingFunction( - name + "Buffer", - name, - script, - null - ); -}; - -/** - * Send a command - * - * @abstract - * @public - */ -Commander.prototype.sendCommand = function () {}; - function generateFunction(functionName: string | null, _encoding: string); function generateFunction( functionName: string | null, @@ -242,3 +233,5 @@ function generateScriptingFunction( ); }; } + +export default Commander; diff --git a/lib/utils/applyMixin.ts b/lib/utils/applyMixin.ts new file mode 100644 index 000000000..767389dca --- /dev/null +++ b/lib/utils/applyMixin.ts @@ -0,0 +1,15 @@ +type Constructor = new (...args: any[]) => void; +function applyMixin( + derivedConstructor: Constructor, + mixinConstructor: Constructor +) { + Object.getOwnPropertyNames(mixinConstructor.prototype).forEach((name) => { + Object.defineProperty( + derivedConstructor.prototype, + name, + Object.getOwnPropertyDescriptor(mixinConstructor.prototype, name) + ); + }); +} + +export default applyMixin; diff --git a/package-lock.json b/package-lock.json index 8e922b0fa..6aa0c75b6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,65 +5,67 @@ "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", "dev": true, "requires": { - "@babel/highlight": "^7.14.5" + "@babel/highlight": "^7.16.7" } }, "@babel/helper-validator-identifier": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", "dev": true }, "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.16.7", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, + "@commitlint/config-validator": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-16.1.0.tgz", + "integrity": "sha512-2cHeZPNTuf1JWbMqyA46MkExor5HMSgv8JrdmzEakUbJHUreh35/wN00FJf57qGs134exQW2thiSQ1IJUsVx2Q==", + "dev": true, + "requires": { + "@commitlint/types": "^16.0.0", + "ajv": "^6.12.6" + } + }, "@commitlint/execute-rule": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-13.2.0.tgz", - "integrity": "sha512-6nPwpN0hwTYmsH3WM4hCdN+NrMopgRIuQ0aqZa+jnwMoS/g6ljliQNYfL+m5WO306BaIu1W3yYpbW5aI8gEr0g==", + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-16.0.0.tgz", + "integrity": "sha512-8edcCibmBb386x5JTHSPHINwA5L0xPkHQFY8TAuDEt5QyRZY/o5DF8OPHSa5Hx2xJvGaxxuIz4UtAT6IiRDYkw==", "dev": true, "optional": true }, "@commitlint/load": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-13.2.0.tgz", - "integrity": "sha512-Nhkv+hwWCCxWGjmE9jd1U8kfGGCkZVpwzlTtdKxpY+Aj2VCFg3BjY+qA81pMF3oAsIpxchSaZG5llb8kduVjYg==", + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-16.1.0.tgz", + "integrity": "sha512-MtlEhKjP8jAF85jjX4mw8DUUwCxKsCgAc865hhpnwxjrfBcmGP7Up2AFE/M3ZMGDmSl1X1TMybQk/zohj8Cqdg==", "dev": true, "optional": true, "requires": { - "@commitlint/execute-rule": "^13.2.0", - "@commitlint/resolve-extends": "^13.2.0", - "@commitlint/types": "^13.2.0", - "@endemolshinegroup/cosmiconfig-typescript-loader": "^3.0.2", + "@commitlint/config-validator": "^16.1.0", + "@commitlint/execute-rule": "^16.0.0", + "@commitlint/resolve-extends": "^16.1.0", + "@commitlint/types": "^16.0.0", "chalk": "^4.0.0", "cosmiconfig": "^7.0.0", + "cosmiconfig-typescript-loader": "^1.0.0", "lodash": "^4.17.19", - "resolve-from": "^5.0.0" + "resolve-from": "^5.0.0", + "typescript": "^4.4.3" }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "optional": true, - "requires": { - "color-convert": "^2.0.1" - } - }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -74,33 +76,18 @@ "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "optional": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "optional": true } } }, "@commitlint/resolve-extends": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-13.2.0.tgz", - "integrity": "sha512-HLCMkqMKtvl1yYLZ1Pm0UpFvd0kYjsm1meLOGZ7VkOd9G/XX+Fr1S2G5AT2zeiDw7WUVYK8lGVMNa319bnV+aw==", + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-16.1.0.tgz", + "integrity": "sha512-8182s6AFoUFX6+FT1PgQDt15nO2ogdR/EN8SYVAdhNXw1rLz8kT5saB/ICw567GuRAUgFTUMGCXy3ctMOXPEDg==", "dev": true, "optional": true, "requires": { + "@commitlint/config-validator": "^16.1.0", + "@commitlint/types": "^16.0.0", "import-fresh": "^3.0.0", "lodash": "^4.17.19", "resolve-from": "^5.0.0", @@ -108,92 +95,115 @@ } }, "@commitlint/types": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-13.2.0.tgz", - "integrity": "sha512-RRVHEqmk1qn/dIaSQhvuca6k/6Z54G+r/KyimZ8gnAFielGiGUpsFRhIY3qhd5rXClVxDaa3nlcyTWckSccotQ==", + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-16.0.0.tgz", + "integrity": "sha512-+0FvYOAS39bJ4aKjnYn/7FD4DfWkmQ6G/06I4F0Gvu4KS5twirEg8mIcLhmeRDOOKn4Tp8PwpLwBiSA6npEMQA==", "dev": true, - "optional": true, "requires": { "chalk": "^4.0.0" }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "optional": true, - "requires": { - "color-convert": "^2.0.1" - } - }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "optional": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "optional": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "optional": true } } }, - "@endemolshinegroup/cosmiconfig-typescript-loader": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@endemolshinegroup/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-3.0.2.tgz", - "integrity": "sha512-QRVtqJuS1mcT56oHpVegkKBlgtWjXw/gHNWO3eL9oyB5Sc7HBoc2OLG/nYpVfT/Jejvo3NUrD0Udk7XgoyDKkA==", + "@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true + }, + "@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dev": true, + "requires": { + "@cspotcode/source-map-consumer": "0.8.0" + } + }, + "@eslint/eslintrc": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "dev": true, - "optional": true, "requires": { - "lodash.get": "^4", - "make-error": "^1", - "ts-node": "^9", - "tslib": "^2" + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" }, "dependencies": { - "ts-node": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", - "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", - "dev": true, - "optional": true, - "requires": { - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.17", - "yn": "3.1.1" - } + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true }, - "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", - "dev": true, - "optional": true + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true } } }, + "@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, "@semantic-release/changelog": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/@semantic-release/changelog/-/changelog-5.0.1.tgz", @@ -263,10 +273,28 @@ "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", "dev": true }, - "@types/bluebird": { - "version": "3.5.36", - "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.36.tgz", - "integrity": "sha512-HBNx4lhkxN7bx6P0++W8E289foSu8kO8GCk2unhuVggO+cE7rh9DhZUyPhUxNRG9m+5B5BTKxZQ5ZP92x/mx9Q==", + "@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", "dev": true }, "@types/chai": { @@ -293,12 +321,6 @@ "@types/ms": "*" } }, - "@types/eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", - "dev": true - }, "@types/json-schema": { "version": "7.0.9", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", @@ -306,9 +328,9 @@ "dev": true }, "@types/lodash": { - "version": "4.14.175", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.175.tgz", - "integrity": "sha512-XmdEOrKQ8a1Y/yxQFOMbC47G/V2VDO1GvMRnl4O75M4GW/abC5tnfzadQYkqEveqRM1dEJGFFegfPNA2vvx2iw==", + "version": "4.14.178", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz", + "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==", "dev": true }, "@types/lodash.defaults": { @@ -345,9 +367,9 @@ "dev": true }, "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", + "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", "dev": true }, "@types/ms": { @@ -384,124 +406,116 @@ } }, "@types/sinonjs__fake-timers": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.4.tgz", - "integrity": "sha512-IFQTJARgMUBF+xVd2b+hIgXWrZEjND3vJtRCvIelcFB5SIXfjV4bOHbHJ0eXKh+0COrBRc8MqteKAz/j88rE0A==", - "dev": true - }, - "@types/uuid": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.1.tgz", - "integrity": "sha512-Y2mHTRAbqfFkpjldbkHGY8JIzRN6XqYRliG8/24FcHm2D2PwW24fl5xMRTVGdrb7iMrwCaIEbLWerGIkXuFWVg==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", + "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.13.0.tgz", - "integrity": "sha512-WQHCozMnuNADiqMtsNzp96FNox5sOVpU8Xt4meaT4em8lOG1SrOv92/mUbEHQVh90sldKSfcOc/I0FOb/14G1g==", + "version": "5.10.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.10.2.tgz", + "integrity": "sha512-4W/9lLuE+v27O/oe7hXJKjNtBLnZE8tQAFpapdxwSVHqtmIoPB1gph3+ahNwVuNL37BX7YQHyGF9Xv6XCnIX2Q==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "1.13.0", - "eslint-utils": "^1.3.1", + "@typescript-eslint/scope-manager": "5.10.2", + "@typescript-eslint/type-utils": "5.10.2", + "@typescript-eslint/utils": "5.10.2", + "debug": "^4.3.2", "functional-red-black-tree": "^1.0.1", - "regexpp": "^2.0.1", - "tsutils": "^3.7.0" + "ignore": "^5.1.8", + "regexpp": "^3.2.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" } }, - "@typescript-eslint/experimental-utils": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.13.0.tgz", - "integrity": "sha512-zmpS6SyqG4ZF64ffaJ6uah6tWWWgZ8m+c54XXgwFtUv0jNz8aJAVx8chMCvnk7yl6xwn8d+d96+tWp7fXzTuDg==", + "@typescript-eslint/parser": { + "version": "5.10.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.10.2.tgz", + "integrity": "sha512-JaNYGkaQVhP6HNF+lkdOr2cAs2wdSZBoalE22uYWq8IEv/OVH0RksSGydk+sW8cLoSeYmC+OHvRyv2i4AQ7Czg==", "dev": true, "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "1.13.0", - "eslint-scope": "^4.0.0" + "@typescript-eslint/scope-manager": "5.10.2", + "@typescript-eslint/types": "5.10.2", + "@typescript-eslint/typescript-estree": "5.10.2", + "debug": "^4.3.2" } }, - "@typescript-eslint/parser": { - "version": "2.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.34.0.tgz", - "integrity": "sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA==", + "@typescript-eslint/scope-manager": { + "version": "5.10.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.10.2.tgz", + "integrity": "sha512-39Tm6f4RoZoVUWBYr3ekS75TYgpr5Y+X0xLZxXqcZNDWZdJdYbKd3q2IR4V9y5NxxiPu/jxJ8XP7EgHiEQtFnw==", "dev": true, "requires": { - "@types/eslint-visitor-keys": "^1.0.0", - "@typescript-eslint/experimental-utils": "2.34.0", - "@typescript-eslint/typescript-estree": "2.34.0", - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "@typescript-eslint/experimental-utils": { - "version": "2.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz", - "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.34.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - } - }, - "@typescript-eslint/typescript-estree": { - "version": "2.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", - "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "eslint-visitor-keys": "^1.1.0", - "glob": "^7.1.6", - "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } + "@typescript-eslint/types": "5.10.2", + "@typescript-eslint/visitor-keys": "5.10.2" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.10.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.10.2.tgz", + "integrity": "sha512-uRKSvw/Ccs5FYEoXW04Z5VfzF2iiZcx8Fu7DGIB7RHozuP0VbKNzP1KfZkHBTM75pCpsWxIthEH1B33dmGBKHw==", + "dev": true, + "requires": { + "@typescript-eslint/utils": "5.10.2", + "debug": "^4.3.2", + "tsutils": "^3.21.0" } }, + "@typescript-eslint/types": { + "version": "5.10.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.10.2.tgz", + "integrity": "sha512-Qfp0qk/5j2Rz3p3/WhWgu4S1JtMcPgFLnmAKAW061uXxKSa7VWKZsDXVaMXh2N60CX9h6YLaBoy9PJAfCOjk3w==", + "dev": true + }, "@typescript-eslint/typescript-estree": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.13.0.tgz", - "integrity": "sha512-b5rCmd2e6DCC6tCTN9GSUAuxdYwCM/k/2wdjHGrIRGPSJotWMCe/dGpi66u42bhuh8q3QBzqM4TMA1GUUCJvdw==", + "version": "5.10.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.10.2.tgz", + "integrity": "sha512-WHHw6a9vvZls6JkTgGljwCsMkv8wu8XU8WaYKeYhxhWXH/atZeiMW6uDFPLZOvzNOGmuSMvHtZKd6AuC8PrwKQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.10.2", + "@typescript-eslint/visitor-keys": "5.10.2", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/utils": { + "version": "5.10.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.10.2.tgz", + "integrity": "sha512-vuJaBeig1NnBRkf7q9tgMLREiYD7zsMrsN1DA3wcoMDvr3BTFiIpKjGiYZoKPllfEwN7spUjv7ZqD+JhbVjEPg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.10.2", + "@typescript-eslint/types": "5.10.2", + "@typescript-eslint/typescript-estree": "5.10.2", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.10.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.10.2.tgz", + "integrity": "sha512-zHIhYGGGrFJvvyfwHk5M08C5B5K4bewkm+rrvNTKk1/S15YHR+SA/QUF8ZWscXSfEaB8Nn2puZj+iHcoxVOD/Q==", "dev": true, "requires": { - "lodash.unescape": "4.0.1", - "semver": "5.5.0" + "@typescript-eslint/types": "5.10.2", + "eslint-visitor-keys": "^3.0.0" } }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, "acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", "dev": true }, "acorn-jsx": { @@ -510,10 +524,10 @@ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true }, - "acquerello": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/acquerello/-/acquerello-0.1.4.tgz", - "integrity": "sha512-YyZ+ZZ+/zvNlKoPBCGO7Y+7aMh6NJIzaTdC0u0q7fAckS9ovfkOKnTFmMI3IXtHKHAHTMU0QguuUXwF1/9iAsw==", + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true }, "aggregate-error": { @@ -539,9 +553,9 @@ } }, "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true }, "ansi-escapes": { @@ -551,18 +565,28 @@ "dev": true }, "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" } }, "arg": { @@ -605,9 +629,9 @@ "dev": true }, "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, "at-least-node": { @@ -622,16 +646,10 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "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 - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, "brace-expansion": { @@ -659,28 +677,12 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, "cachedir": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.2.0.tgz", "integrity": "sha512-VvxA0xhNqIIfg0V9AmJkDg91DaJwryutH5rVEZAhcNi4iJFj9f+QxmAjgK1LT9I8OgToX27fypX6/MeCXVbBjQ==", "dev": true }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -688,9 +690,9 @@ "dev": true }, "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true }, "chai": { @@ -727,6 +729,30 @@ "supports-color": "^5.3.0" }, "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -756,6 +782,22 @@ "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", "dev": true }, + "chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, "ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", @@ -784,14 +826,48 @@ "dev": true }, "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } } }, "cluster-key-slot": { @@ -800,18 +876,18 @@ "integrity": "sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==" }, "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "color-name": "1.1.3" + "color-name": "~1.1.4" } }, "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "commitizen": { @@ -862,20 +938,6 @@ "universalify": "^0.1.0" } }, - "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", @@ -924,23 +986,22 @@ "yaml": "^1.10.0" } }, + "cosmiconfig-typescript-loader": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-1.0.4.tgz", + "integrity": "sha512-ulv2dvwurP/MZAIthXm69bO7EzzIUThZ6RJ1qXhdlXM6to3F+IKBL/17EnhYSG52A5N1KcAUu66vSG/3/77KrA==", + "dev": true, + "optional": true, + "requires": { + "cosmiconfig": "^7", + "ts-node": "^10.4.0" + } + }, "create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "optional": true - }, - "cronometro": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cronometro/-/cronometro-0.6.0.tgz", - "integrity": "sha512-5CrTlj3JRlcHexKoiINIHb786y94SHb38nm1i4jYTSMYNPhaGk9eAK7s46MmheVY9v+reP+d9SW0AiHgEMsA6w==", - "dev": true, - "requires": { - "acquerello": "^0.1.2", - "hdr-histogram-js": "^1.2.0", - "table": "^5.4.6" - } + "dev": true }, "cross-spawn": { "version": "7.0.3", @@ -969,17 +1030,17 @@ } }, "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "requires": { "ms": "2.1.2" } }, "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true }, "dedent": { @@ -1003,15 +1064,6 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, "denque": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", @@ -1054,9 +1106,9 @@ } }, "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "end-of-stream": { @@ -1068,6 +1120,15 @@ "once": "^1.4.0" } }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -1077,58 +1138,11 @@ "is-arrayish": "^0.2.1" } }, - "es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - }, - "dependencies": { - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - } - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true }, "escape-string-regexp": { "version": "1.0.5", @@ -1137,164 +1151,192 @@ "dev": true }, "eslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", - "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", - "eslint-scope": "^4.0.3", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", - "esquery": "^1.0.1", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.13.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.11", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", + "optionator": "^0.9.1", "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0" + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" }, "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { - "shebang-regex": "^1.0.0" + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } } }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^5.0.1" } }, "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } } } }, "eslint-config-prettier": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz", - "integrity": "sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw==", - "dev": true, - "requires": { - "get-stdin": "^6.0.0" - } + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", + "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", + "dev": true }, "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "requires": { - "esrecurse": "^4.1.0", + "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.1.0" + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } } }, "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz", + "integrity": "sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==", "dev": true }, "espree": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", - "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "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": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } } }, "esprima": { @@ -1313,9 +1355,9 @@ }, "dependencies": { "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } @@ -1330,9 +1372,9 @@ }, "dependencies": { "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } @@ -1392,6 +1434,19 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -1404,6 +1459,15 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, "figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", @@ -1414,12 +1478,12 @@ } }, "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.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "requires": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" } }, "fill-range": { @@ -1479,29 +1543,25 @@ } }, "flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - } + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true }, "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.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", "dev": true }, "fs-extra": { @@ -1522,11 +1582,12 @@ "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 + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true }, "functional-red-black-tree": { "version": "1.0.1", @@ -1546,43 +1607,16 @@ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-stdin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", - "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", - "dev": true - }, "get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -1593,6 +1627,15 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, "global-dirs": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", @@ -1639,15 +1682,40 @@ } }, "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "version": "13.12.1", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", + "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + }, + "dependencies": { + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } }, "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "dev": true }, "growl": { @@ -1656,52 +1724,12 @@ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, - "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-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true - }, "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 }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "hdr-histogram-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/hdr-histogram-js/-/hdr-histogram-js-1.2.0.tgz", - "integrity": "sha512-h0YToJ3ewqsaZ3nFTTa6dLOD7sqx+EgdC4+OcJ9Ou7zZDlT0sXSPHHr3cyenQsPqqbVHGn/oFY6zjfEKXGvzmQ==", - "dev": true, - "requires": { - "base64-js": "^1.2.0", - "pako": "^1.0.3" - } - }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -1741,15 +1769,6 @@ "which-pm-runs": "^1.0.0" }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1759,21 +1778,6 @@ "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true } } }, @@ -1787,9 +1791,9 @@ } }, "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true }, "import-fresh": { @@ -1863,46 +1867,6 @@ "string-width": "^2.1.0", "strip-ansi": "^5.1.0", "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - } - } - }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" } }, "is-arrayish": { @@ -1911,44 +1875,13 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "dev": true - }, - "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "requires": { - "has-tostringtag": "^1.0.0" + "binary-extensions": "^2.0.0" } }, "is-extglob": { @@ -1972,41 +1905,16 @@ "is-extglob": "^2.1.1" } }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "dev": true - }, "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-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, "is-stream": { @@ -2015,39 +1923,12 @@ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, "is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", "dev": true }, - "is-weakref": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", - "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0" - } - }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -2117,19 +1998,19 @@ "dev": true }, "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" } }, "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, "locate-path": { @@ -2174,19 +2055,37 @@ "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=", "dev": true }, - "lodash.unescape": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", - "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=", + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", "dev": true }, "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", "dev": true, "requires": { - "chalk": "^2.0.1" + "chalk": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } } }, "longest": { @@ -2222,6 +2121,12 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, "micromatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", @@ -2253,74 +2158,78 @@ "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" - } - }, "mocha": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.3.tgz", - "integrity": "sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", + "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", "dev": true, "requires": { - "ansi-colors": "3.2.3", + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", + "chokidar": "3.5.1", + "debug": "4.3.1", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", "growl": "1.10.5", "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "2.2.0", + "js-yaml": "4.0.0", + "log-symbols": "4.0.0", "minimatch": "3.0.4", - "mkdirp": "0.5.4", - "ms": "2.1.1", - "node-environment-flags": "1.0.5", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", + "ms": "2.1.3", + "nanoid": "3.1.20", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" + "workerpool": "6.1.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" }, "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } } }, "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true }, "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -2331,93 +2240,34 @@ "path-is-absolute": "^1.0.0" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "mkdirp": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", - "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "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 - }, - "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": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", "dev": true, "requires": { - "p-limit": "^2.0.0" + "argparse": "^2.0.1" } }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { - "isexe": "^2.0.0" + "has-flag": "^4.0.0" } } } @@ -2452,18 +2302,18 @@ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, + "nanoid": { + "version": "3.1.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "dev": true + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, "nise": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/nise/-/nise-4.1.0.tgz", @@ -2477,23 +2327,11 @@ "path-to-regexp": "^1.7.0" } }, - "node-environment-flags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", - "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true }, "npm-run-path": { "version": "4.0.1", @@ -2504,41 +2342,6 @@ "path-key": "^3.0.0" } }, - "object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz", - "integrity": "sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2564,17 +2367,17 @@ "dev": true }, "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" } }, "os-tmpdir": { @@ -2624,12 +2427,6 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -2669,12 +2466,6 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -2703,9 +2494,9 @@ "dev": true }, "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, "pkg-dir": { @@ -2727,15 +2518,15 @@ } }, "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, "prettier": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", - "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", + "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", "dev": true }, "pretty-quick": { @@ -2788,12 +2579,6 @@ "pump": "^3.0.0" } }, - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -2854,6 +2639,30 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, "redis-commands": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz", @@ -2873,9 +2682,9 @@ } }, "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, "require-directory": { @@ -2884,10 +2693,10 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true }, "resolve-dir": { @@ -2904,8 +2713,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "optional": true + "dev": true }, "resolve-global": { "version": "1.0.0", @@ -2944,10 +2752,16 @@ } } }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, "rimraf": { - "version": "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" @@ -2959,6 +2773,15 @@ "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", "dev": true }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, "rxjs": { "version": "6.6.7", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", @@ -2968,6 +2791,12 @@ "tslib": "^1.9.0" } }, + "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", @@ -2975,10 +2804,13 @@ "dev": true }, "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", - "dev": true + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } }, "semver-compare": { "version": "1.0.0", @@ -2992,18 +2824,21 @@ "integrity": "sha512-Aqi54Mk9uYTjVexLnR67rTyBusmwd04cLkHy9hNvk3+G3nT2Oyg7E0l4XVbOaNwIvQ3hHeYxGcyEy+mKreyBFQ==", "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" + } + }, "server-destroy": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", "integrity": "sha1-8Tv5KOQrnD55OD5hzDmYtdFObN0=", "dev": true }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -3019,21 +2854,10 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, "signal-exit": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, "sinon": { @@ -3057,30 +2881,22 @@ "dev": true }, "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - } - }, - "source-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-support": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + } } }, "sprintf-js": { @@ -3095,34 +2911,24 @@ "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==" }, "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } } }, "strip-ansi": { @@ -3132,6 +2938,14 @@ "dev": true, "requires": { "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + } } }, "strip-bom": { @@ -3162,15 +2976,68 @@ } }, "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", + "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", "dev": true, "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "ajv": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz", + "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } } }, "text-table": { @@ -3204,15 +3071,22 @@ } }, "ts-node": { - "version": "8.10.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", - "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", - "dev": true, - "requires": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", + "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", "arg": "^4.1.0", + "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", - "source-map-support": "^0.5.17", "yn": "3.1.1" } }, @@ -3232,12 +3106,12 @@ } }, "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "requires": { - "prelude-ls": "~1.1.2" + "prelude-ls": "^1.2.1" } }, "type-detect": { @@ -3246,23 +3120,17 @@ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, - "typescript": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz", - "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==", + "type-fest": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.11.1.tgz", + "integrity": "sha512-fPcV5KLAqFfmhHobtAUwEpbpfYhVF7wSLVgbG/7mIGe/Pete7ky/bPAPRkzbWdrj0/EkswFAAR2feJCgigkUKg==", "dev": true }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } + "typescript": { + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", + "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", + "dev": true }, "universalify": { "version": "2.0.0", @@ -3285,6 +3153,12 @@ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -3294,25 +3168,6 @@ "isexe": "^2.0.0" } }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, "which-pm-runs": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", @@ -3326,71 +3181,75 @@ "dev": true, "requires": { "string-width": "^1.0.2 || 2" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "workerpool": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", + "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "dependencies": { "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" } }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^5.0.1" } } } }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^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" - } - }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yallist": { @@ -3406,87 +3265,70 @@ "dev": true }, "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" }, "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true }, - "locate-path": { + "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { - "p-try": "^2.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" } }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "p-limit": "^2.0.0" + "ansi-regex": "^5.0.1" } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true } } }, "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true }, "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" } }, "yn": { diff --git a/package.json b/package.json index 087761698..ff0c561b0 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ }, "dependencies": { "cluster-key-slot": "^1.1.0", - "debug": "^4.3.1", + "debug": "^4.3.3", "denque": "^1.1.0", "lodash.defaults": "^4.2.0", "lodash.flatten": "^4.4.0", @@ -48,39 +48,36 @@ "devDependencies": { "@semantic-release/changelog": "^5.0.1", "@semantic-release/git": "^9.0.0", - "@types/bluebird": "^3.5.30", "@types/chai": "^4.2.11", "@types/chai-as-promised": "^7.1.3", "@types/debug": "^4.1.5", "@types/lodash.defaults": "^4.2.6", "@types/lodash.flatten": "^4.4.6", "@types/lodash.isarguments": "^3.1.6", - "@types/mocha": "^7.0.2", + "@types/mocha": "^8.2.3", "@types/node": "^13.11.0", "@types/redis-errors": "1.2.0", "@types/sinon": "^9.0.0", - "@types/uuid": "^8.3.0", - "@typescript-eslint/eslint-plugin": "^1.13.0", - "@typescript-eslint/parser": "^2.26.0", - "bluebird": "^3.7.2", + "@typescript-eslint/eslint-plugin": "^5.10.2", + "@typescript-eslint/parser": "^5.10.2", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", - "cronometro": "^0.6.0", "cz-conventional-changelog": "^3.1.0", - "eslint": "^5.16.0", - "eslint-config-prettier": "^6.10.1", + "eslint": "^7.32.0", + "eslint-config-prettier": "^8.3.0", "husky": "^4.2.3", - "mocha": "^6.2.3", - "prettier": "^2.0.2", + "mocha": "^8.4.0", + "prettier": "^2.5.1", "pretty-quick": "^2.0.1", "server-destroy": "^1.0.1", "sinon": "^9.0.1", - "ts-node": "^8.8.1", - "typescript": "3.8.3", + "ts-node": "^10.4.0", + "type-fest": "^2.11.1", + "typescript": "^4.5.5", "uuid": "^8.3.0" }, "engines": { - "node": ">=6" + "node": ">=10" }, "config": { "commitizen": { diff --git a/test/docker/main.sh b/test/docker/main.sh index f186e3ffe..9b09fbc42 100755 --- a/test/docker/main.sh +++ b/test/docker/main.sh @@ -15,7 +15,7 @@ docker run --rm \ -v $PWD/test:/code/test:ro \ -v $PWD/tsconfig.json:/code/tsconfig.json:ro \ -v $PWD/.eslintignore:/code/.eslintignore:ro \ - -v $PWD/.eslintrc.yml:/code/.eslintrc.yml:ro \ + -v $PWD/.eslintrc.json:/code/.eslintrc.json:ro \ --entrypoint=/bin/bash \ $IMAGE_NAME \ test/docker/worker.sh diff --git a/test/functional/auth.ts b/test/functional/auth.ts index 9739dc410..81c8bae84 100644 --- a/test/functional/auth.ts +++ b/test/functional/auth.ts @@ -1,6 +1,6 @@ import MockServer from "../helpers/mock_server"; import { expect } from "chai"; -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import * as sinon from "sinon"; describe("auth", function () { diff --git a/test/functional/autopipelining.ts b/test/functional/autopipelining.ts index 648ac6edc..05f7a52c5 100644 --- a/test/functional/autopipelining.ts +++ b/test/functional/autopipelining.ts @@ -1,5 +1,5 @@ import { expect, use } from "chai"; -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; use(require("chai-as-promised")); diff --git a/test/functional/cluster/disconnection.ts b/test/functional/cluster/disconnection.ts index 5ae47abca..42d2aa199 100644 --- a/test/functional/cluster/disconnection.ts +++ b/test/functional/cluster/disconnection.ts @@ -1,4 +1,3 @@ -import Redis from "../../../lib/redis"; import * as sinon from "sinon"; import { expect } from "chai"; import { Cluster } from "../../../lib"; diff --git a/test/functional/cluster/dnsLookup.ts b/test/functional/cluster/dnsLookup.ts index 3dd222950..a5863dddf 100644 --- a/test/functional/cluster/dnsLookup.ts +++ b/test/functional/cluster/dnsLookup.ts @@ -8,8 +8,8 @@ describe("cluster:dnsLookup", () => { [0, 1000, ["127.0.0.1", 30001]], [1001, 16383, ["127.0.0.1", 30002]], ]; - new MockServer(30001, (argv, c) => {}, slotTable); - new MockServer(30002, (argv, c) => {}, slotTable); + new MockServer(30001, () => {}, slotTable); + new MockServer(30002, () => {}, slotTable); const cluster = new Cluster([{ host: "localhost", port: "30001" }]); cluster.on("ready", () => { diff --git a/test/functional/cluster/pub_sub.ts b/test/functional/cluster/pub_sub.ts index 2d00c6ffc..8b47e5808 100644 --- a/test/functional/cluster/pub_sub.ts +++ b/test/functional/cluster/pub_sub.ts @@ -2,7 +2,7 @@ import MockServer, { getConnectionName } from "../../helpers/mock_server"; import { expect } from "chai"; import { Cluster } from "../../../lib"; import * as sinon from "sinon"; -import Redis from "../../../lib/redis"; +import Redis from "../../../lib/Redis"; import { noop } from "../../../lib/utils"; describe("cluster:pub/sub", function () { diff --git a/test/functional/cluster/tls.ts b/test/functional/cluster/tls.ts index e3ec7178c..00178339e 100644 --- a/test/functional/cluster/tls.ts +++ b/test/functional/cluster/tls.ts @@ -22,11 +22,11 @@ describe("cluster:tls option", () => { new MockServer(30002, argvHandler); new MockServer(30003, argvHandler); - // @ts-ignore + // @ts-expect-error const stub = sinon.stub(tls, "connect").callsFake((op) => { - // @ts-ignore + // @ts-expect-error expect(op.ca).to.eql("123"); - // @ts-ignore + // @ts-expect-error expect(op.port).to.be.oneOf([30001, 30003, 30003]); const stream = net.createConnection(op); stream.on("connect", (data) => { diff --git a/test/functional/commandTimeout.ts b/test/functional/commandTimeout.ts index 6258bbbe2..50f56fc6d 100644 --- a/test/functional/commandTimeout.ts +++ b/test/functional/commandTimeout.ts @@ -1,6 +1,6 @@ import { expect } from "chai"; import * as sinon from "sinon"; -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import MockServer from "../helpers/mock_server"; describe("commandTimeout", function () { diff --git a/test/functional/connection.ts b/test/functional/connection.ts index d235427f6..0e67b6eab 100644 --- a/test/functional/connection.ts +++ b/test/functional/connection.ts @@ -1,9 +1,8 @@ import * as net from "net"; -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import * as sinon from "sinon"; import { expect } from "chai"; import MockServer from "../helpers/mock_server"; -import * as Bluebird from "bluebird"; import { StandaloneConnector } from "../../lib/connectors"; import { CONNECTION_CLOSED_ERROR_MSG } from "../../lib/utils"; @@ -107,7 +106,7 @@ describe("connection", function () { // TODO: use spy const stub = sinon .stub(net.Socket.prototype, "setTimeout") - // @ts-ignore + // @ts-expect-error .callsFake((timeout) => { if (timeout === connectTimeout) { set = true; @@ -133,7 +132,7 @@ describe("connection", function () { // TODO: use spy sinon .stub(net.Socket.prototype, "setTimeout") - // @ts-ignore + // @ts-expect-error .callsFake((timeout, callback) => { if (timeout === 0) { if (!isReady) { @@ -450,18 +449,6 @@ describe("connection", function () { }); describe("sync connection", () => { - it("works with synchronous connection", (done) => { - // @ts-ignore - Redis.Promise = Bluebird; - const redis = new Redis("/data"); - redis.on("error", () => { - // @ts-ignore - Redis.Promise = Promise; - redis.disconnect(); - done(); - }); - }); - it("works when connection established before promise is resolved", (done) => { const socket = new net.Socket(); sinon.stub(StandaloneConnector.prototype, "connect").resolves(socket); diff --git a/test/functional/disconnection.ts b/test/functional/disconnection.ts index 65905d068..34133b0f5 100644 --- a/test/functional/disconnection.ts +++ b/test/functional/disconnection.ts @@ -1,4 +1,4 @@ -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import * as sinon from "sinon"; import { expect } from "chai"; import MockServer from "../helpers/mock_server"; diff --git a/test/functional/drop_buffer_support.ts b/test/functional/drop_buffer_support.ts index 990910b1c..0efbfa0db 100644 --- a/test/functional/drop_buffer_support.ts +++ b/test/functional/drop_buffer_support.ts @@ -1,4 +1,4 @@ -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import { expect } from "chai"; describe("dropBufferSupport", function () { diff --git a/test/functional/duplicate.ts b/test/functional/duplicate.ts index e5702aaa2..4ed130758 100644 --- a/test/functional/duplicate.ts +++ b/test/functional/duplicate.ts @@ -1,4 +1,4 @@ -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import { expect } from "chai"; describe("duplicate", () => { diff --git a/test/functional/elasticache.ts b/test/functional/elasticache.ts index c355e04fb..d840e2422 100644 --- a/test/functional/elasticache.ts +++ b/test/functional/elasticache.ts @@ -1,4 +1,4 @@ -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import { expect } from "chai"; import MockServer from "../helpers/mock_server"; diff --git a/test/functional/fatal_error.ts b/test/functional/fatal_error.ts index 30e101ad3..bd517ceff 100644 --- a/test/functional/fatal_error.ts +++ b/test/functional/fatal_error.ts @@ -1,4 +1,4 @@ -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import { expect } from "chai"; import MockServer from "../helpers/mock_server"; diff --git a/test/functional/hgetall.ts b/test/functional/hgetall.ts index 344f702c2..cb4941dc6 100644 --- a/test/functional/hgetall.ts +++ b/test/functional/hgetall.ts @@ -1,4 +1,4 @@ -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import { expect } from "chai"; const CUSTOM_PROPERTY = "_myCustomProperty"; diff --git a/test/functional/lazy_connect.ts b/test/functional/lazy_connect.ts index ed5a542ab..94c9d4b8d 100644 --- a/test/functional/lazy_connect.ts +++ b/test/functional/lazy_connect.ts @@ -1,4 +1,4 @@ -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import { expect } from "chai"; import * as sinon from "sinon"; import { Cluster } from "../../lib"; diff --git a/test/functional/maxRetriesPerRequest.ts b/test/functional/maxRetriesPerRequest.ts index eb397a35b..ab5322e48 100644 --- a/test/functional/maxRetriesPerRequest.ts +++ b/test/functional/maxRetriesPerRequest.ts @@ -1,4 +1,4 @@ -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import { expect } from "chai"; import { MaxRetriesPerRequestError } from "../../lib/errors"; diff --git a/test/functional/monitor.ts b/test/functional/monitor.ts index efe3955a2..43d504184 100644 --- a/test/functional/monitor.ts +++ b/test/functional/monitor.ts @@ -1,4 +1,4 @@ -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import { expect } from "chai"; import * as sinon from "sinon"; diff --git a/test/functional/pipeline.ts b/test/functional/pipeline.ts index cd0228cbe..400b9db99 100644 --- a/test/functional/pipeline.ts +++ b/test/functional/pipeline.ts @@ -1,4 +1,4 @@ -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import { expect } from "chai"; import * as sinon from "sinon"; diff --git a/test/functional/promise.ts b/test/functional/promise.ts deleted file mode 100644 index dbf2bbc91..000000000 --- a/test/functional/promise.ts +++ /dev/null @@ -1,26 +0,0 @@ -import Redis from "../../lib/redis"; -import { expect } from "chai"; -import * as bluebirdPromise from "bluebird"; - -const nativePromise = global.Promise; - -describe("Promise", function () { - it("uses native promise by default", function () { - const redis = new Redis(); - expect(redis.get("foo").constructor).to.eql(nativePromise); - }); - - it("can switch to a custom Promise implementation", function () { - const origin = Promise; - - // @ts-ignore - Redis.Promise = bluebirdPromise; - - const redis = new Redis(); - expect(redis.get("foo").constructor).to.eql(bluebirdPromise); - - // @ts-ignore - Redis.Promise = origin; - expect(redis.get("foo").constructor).to.eql(origin); - }); -}); diff --git a/test/functional/pub_sub.ts b/test/functional/pub_sub.ts index 96976d3a0..98f4bbda5 100644 --- a/test/functional/pub_sub.ts +++ b/test/functional/pub_sub.ts @@ -1,4 +1,4 @@ -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import { expect } from "chai"; describe("pub/sub", function () { diff --git a/test/functional/ready_check.ts b/test/functional/ready_check.ts index 7cb36f02d..030a6cbee 100644 --- a/test/functional/ready_check.ts +++ b/test/functional/ready_check.ts @@ -1,4 +1,4 @@ -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import { noop } from "../../lib/utils"; import * as sinon from "sinon"; @@ -9,7 +9,7 @@ describe("ready_check", function () { sinon.stub(redis, "info").callsFake((callback) => { callback(null, "loading:1\r\nloading_eta_seconds:7"); }); - // @ts-ignore + // @ts-expect-error const stub = sinon.stub(global, "setTimeout").callsFake((body, ms) => { if (ms === 7000) { redis.info.restore(); diff --git a/test/functional/reconnect_on_error.ts b/test/functional/reconnect_on_error.ts index 169a29b84..b854b8581 100644 --- a/test/functional/reconnect_on_error.ts +++ b/test/functional/reconnect_on_error.ts @@ -1,4 +1,4 @@ -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import { expect } from "chai"; import * as sinon from "sinon"; diff --git a/test/functional/scan_stream.ts b/test/functional/scan_stream.ts index 478c64b56..8721f9a2e 100644 --- a/test/functional/scan_stream.ts +++ b/test/functional/scan_stream.ts @@ -1,4 +1,4 @@ -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import { expect } from "chai"; import { Readable } from "stream"; import * as sinon from "sinon"; @@ -265,9 +265,9 @@ describe("*scanStream", function () { const cluster = new Cluster([{ host: "127.0.0.1", port: "30001" }]); let keys = []; - // @ts-ignore + // @ts-expect-error cluster.sadd("set", serverKeys, function () { - // @ts-ignore + // @ts-expect-error const stream = cluster.sscanStream("set"); stream.on("data", function (data) { keys = keys.concat(data); diff --git a/test/functional/scripting.ts b/test/functional/scripting.ts index 56907781c..66bdfa2ab 100644 --- a/test/functional/scripting.ts +++ b/test/functional/scripting.ts @@ -1,4 +1,4 @@ -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import { expect } from "chai"; describe("scripting", function () { diff --git a/test/functional/select.ts b/test/functional/select.ts index 5e5441442..1cd30d0e4 100644 --- a/test/functional/select.ts +++ b/test/functional/select.ts @@ -1,4 +1,4 @@ -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import { expect } from "chai"; describe("select", function () { diff --git a/test/functional/send_command.ts b/test/functional/send_command.ts index f23371ff0..408311ede 100644 --- a/test/functional/send_command.ts +++ b/test/functional/send_command.ts @@ -1,4 +1,4 @@ -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import { expect } from "chai"; describe("send command", function () { @@ -51,12 +51,14 @@ describe("send command", function () { it("should support get & set buffer via `call`", function (done) { const redis = new Redis(); - redis.call("set", Buffer.from("foo"), Buffer.from("bar"), function ( - err, - res - ) { - expect(res).to.eql("OK"); - }); + redis.call( + "set", + Buffer.from("foo"), + Buffer.from("bar"), + function (err, res) { + expect(res).to.eql("OK"); + } + ); redis.callBuffer("get", Buffer.from("foo"), function (err, result) { expect(result).to.be.instanceof(Buffer); expect(result.toString()).to.eql("bar"); @@ -154,16 +156,22 @@ describe("send command", function () { redis.zadd("zset2", 1, "one"); redis.zadd("zset2", 2, "two"); redis.zadd("zset2", 3, "three"); - redis.zunionstore("out", 2, "zset1", "zset2", "WEIGHTS", 2, 3, function ( - err, - result - ) { - expect(result).to.eql(3); - redis.keys("*", function (err, result) { - expect(result).to.have.members(["foo:zset1", "foo:zset2", "foo:out"]); - done(); - }); - }); + redis.zunionstore( + "out", + 2, + "zset1", + "zset2", + "WEIGHTS", + 2, + 3, + function (err, result) { + expect(result).to.eql(3); + redis.keys("*", function (err, result) { + expect(result).to.have.members(["foo:zset1", "foo:zset2", "foo:out"]); + done(); + }); + } + ); }); it("should support key prefixing for sort", function (done) { diff --git a/test/functional/sentinel.ts b/test/functional/sentinel.ts index 698c470c0..0106052bd 100644 --- a/test/functional/sentinel.ts +++ b/test/functional/sentinel.ts @@ -1,6 +1,6 @@ import { Socket } from "net"; -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import MockServer from "../helpers/mock_server"; import { once } from "../helpers/once"; import { expect } from "chai"; diff --git a/test/functional/sentinel_nat.ts b/test/functional/sentinel_nat.ts index a89b4ae78..c57558337 100644 --- a/test/functional/sentinel_nat.ts +++ b/test/functional/sentinel_nat.ts @@ -1,4 +1,4 @@ -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import MockServer from "../helpers/mock_server"; describe("sentinel_nat", function () { diff --git a/test/functional/show_friendly_error_stack.ts b/test/functional/show_friendly_error_stack.ts index 214ecec42..75caf284b 100644 --- a/test/functional/show_friendly_error_stack.ts +++ b/test/functional/show_friendly_error_stack.ts @@ -1,4 +1,4 @@ -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import { expect } from "chai"; const path = require("path"); diff --git a/test/functional/string_numbers.ts b/test/functional/string_numbers.ts index c9dc1fefe..eda144c1d 100644 --- a/test/functional/string_numbers.ts +++ b/test/functional/string_numbers.ts @@ -1,4 +1,4 @@ -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import { expect } from "chai"; const MAX_NUMBER = 9007199254740991; // Number.MAX_SAFE_INTEGER diff --git a/test/functional/tls.ts b/test/functional/tls.ts index fac9a002d..a1197c0b9 100644 --- a/test/functional/tls.ts +++ b/test/functional/tls.ts @@ -1,6 +1,6 @@ import * as tls from "tls"; import * as net from "net"; -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import { expect } from "chai"; import * as sinon from "sinon"; import MockServer from "../helpers/mock_server"; @@ -10,15 +10,15 @@ describe("tls option", () => { it("supports tls", (done) => { let redis; - // @ts-ignore + // @ts-expect-error const stub = sinon.stub(tls, "connect").callsFake((op) => { - // @ts-ignore + // @ts-expect-error expect(op.ca).to.eql("123"); - // @ts-ignore + // @ts-expect-error expect(op.servername).to.eql("localhost"); - // @ts-ignore + // @ts-expect-error expect(op.rejectUnauthorized).to.eql(false); - // @ts-ignore + // @ts-expect-error expect(op.port).to.eql(6379); const stream = net.createConnection(op); stream.on("connect", (data) => { @@ -72,11 +72,11 @@ describe("tls option", () => { let redis; const stub = sinon.stub(tls, "connect").callsFake((op) => { - // @ts-ignore + // @ts-expect-error expect(op.ca).to.eql("123"); - // @ts-ignore + // @ts-expect-error expect(op.servername).to.eql("localhost"); - // @ts-ignore + // @ts-expect-error expect(op.rejectUnauthorized).to.eql(false); redis.disconnect(); stub.restore(); @@ -101,15 +101,15 @@ describe("tls option", () => { let redis; - // @ts-ignore + // @ts-expect-error const stub = sinon.stub(tls, "connect").callsFake((op) => { - // @ts-ignore + // @ts-expect-error expect(op.ca).to.eql("123"); - // @ts-ignore + // @ts-expect-error expect(op.servername).to.eql("localhost"); - // @ts-ignore + // @ts-expect-error expect(op.rejectUnauthorized).to.eql(false); - // @ts-ignore + // @ts-expect-error expect(op.port).to.eql(27379); const stream = net.createConnection(op); stream.on("connect", (data) => { diff --git a/test/functional/transaction.ts b/test/functional/transaction.ts index 8ed77c42f..06e837990 100644 --- a/test/functional/transaction.ts +++ b/test/functional/transaction.ts @@ -1,4 +1,4 @@ -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import { expect } from "chai"; import Command from "../../lib/command"; @@ -166,7 +166,7 @@ describe("transaction", function () { it("should handle custom transformer exception", function (done) { const transformError = "transformer error"; - // @ts-ignore + // @ts-expect-error Command._transformer.reply.get = function () { throw new Error(transformError); }; @@ -177,7 +177,7 @@ describe("transaction", function () { .get("foo") .exec(function (err, res) { expect(res[0][0]).to.have.property("message", transformError); - // @ts-ignore + // @ts-expect-error delete Command._transformer.reply.get; done(); }); diff --git a/test/functional/transformer.ts b/test/functional/transformer.ts index 4def65400..97e688cb8 100644 --- a/test/functional/transformer.ts +++ b/test/functional/transformer.ts @@ -1,4 +1,4 @@ -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import { getRedisVersion } from "../helpers/util"; import { expect } from "chai"; diff --git a/test/functional/watch-exec.ts b/test/functional/watch-exec.ts index 4485cd520..181fbd4b2 100644 --- a/test/functional/watch-exec.ts +++ b/test/functional/watch-exec.ts @@ -1,4 +1,4 @@ -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; import { expect } from "chai"; describe("watch-exec", function () { diff --git a/test/helpers/global.ts b/test/helpers/global.ts index b3a2c97dd..fb7a82daf 100644 --- a/test/helpers/global.ts +++ b/test/helpers/global.ts @@ -1,5 +1,5 @@ import * as sinon from "sinon"; -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; afterEach(function (done) { sinon.restore(); diff --git a/test/helpers/mock_server.ts b/test/helpers/mock_server.ts index 979f2306c..fb99dbfc5 100644 --- a/test/helpers/mock_server.ts +++ b/test/helpers/mock_server.ts @@ -110,7 +110,6 @@ export default class MockServer extends EventEmitter { }); c.on("data", (data) => { - // @ts-ignore parser.execute(data); }); }); @@ -119,8 +118,8 @@ export default class MockServer extends EventEmitter { enableDestroy(this.socket); } - disconnect(callback?: Function) { - // @ts-ignore + disconnect(callback?: () => void) { + // @ts-expect-error this.socket.destroy(callback); } diff --git a/test/unit/autoPipelining.ts b/test/unit/autoPipelining.ts index f8cc053b0..e29f975e7 100644 --- a/test/unit/autoPipelining.ts +++ b/test/unit/autoPipelining.ts @@ -16,23 +16,23 @@ describe("autoPipelining", function () { expectGetFirstValueIs(["key", "value"], "key"); expectGetFirstValueIs([[], "key"], "key"); expectGetFirstValueIs([["key"]], "key"); - // @ts-ignore + // @ts-expect-error expectGetFirstValueIs([[["key"]]], ["key"]); - // @ts-ignore + // @ts-expect-error expectGetFirstValueIs([0, 1, 2, 3, 4], 0); - // @ts-ignore + // @ts-expect-error expectGetFirstValueIs([[true]], true); - // @ts-ignore + // @ts-expect-error expectGetFirstValueIs([Buffer.from("test")], Buffer.from("test")); - // @ts-ignore + // @ts-expect-error expectGetFirstValueIs([{}], {}); // lodash.isArguments is true for this legacy js way to get argument lists const createArguments = function () { return arguments; }; - // @ts-ignore + // @ts-expect-error expectGetFirstValueIs([createArguments(), createArguments("key")], "key"); - // @ts-ignore + // @ts-expect-error expectGetFirstValueIs([createArguments("")], ""); }); }); diff --git a/test/unit/clusters/index.ts b/test/unit/clusters/index.ts index cec80f035..7fce58bd3 100644 --- a/test/unit/clusters/index.ts +++ b/test/unit/clusters/index.ts @@ -16,7 +16,6 @@ describe("cluster", function () { const options = Object.freeze({ maxRedirections: 1000 }); const cluster = new Cluster([{ port: 7777 }], options); expect(cluster.options).to.have.property("maxRedirections", 1000); - expect(cluster.options).to.have.property("showFriendlyErrorStack", false); expect(cluster.options).to.have.property("scaleReads", "master"); }); diff --git a/test/unit/commander.ts b/test/unit/commander.ts index a9ed3d6e5..a228ca249 100644 --- a/test/unit/commander.ts +++ b/test/unit/commander.ts @@ -1,6 +1,6 @@ import * as sinon from "sinon"; import { expect } from "chai"; -import Commander from "../../lib/commander"; +import Commander from "../../lib/utils/Commander"; describe("Commander", function () { describe("#getBuiltinCommands()", () => { @@ -14,7 +14,7 @@ describe("Commander", function () { }); describe("#addBuiltinCommand()", () => { - beforeEach(() => sinon.spy(Commander.prototype, "sendCommand")); + beforeEach(() => sinon.stub(Commander.prototype, "sendCommand")); afterEach(() => sinon.restore()); it("adds string command", () => { const c = new Commander(); diff --git a/test/unit/debug.ts b/test/unit/debug.ts index 309955a9d..28a755c2b 100644 --- a/test/unit/debug.ts +++ b/test/unit/debug.ts @@ -44,12 +44,12 @@ describe("utils/debug", function () { const logspy = sinon.spy(); const fn = debug("debugtest"); - // @ts-ignore + // @ts-expect-error fn.log = logspy; - // @ts-ignore + // @ts-expect-error expect(fn.enabled).to.equal(true); - // @ts-ignore + // @ts-expect-error expect(fn.namespace).to.equal(dbgNS); let data = [], diff --git a/test/unit/pipeline.ts b/test/unit/pipeline.ts index 1a3034635..084ab9969 100644 --- a/test/unit/pipeline.ts +++ b/test/unit/pipeline.ts @@ -1,8 +1,8 @@ import * as sinon from "sinon"; import { expect } from "chai"; import Pipeline from "../../lib/pipeline"; -import Commander from "../../lib/commander"; -import Redis from "../../lib/redis"; +import Commander from "../../lib/utils/Commander"; +import Redis from "../../lib/Redis"; describe("Pipeline", function () { beforeEach(() => { diff --git a/test/unit/redis.ts b/test/unit/redis.ts index 226ce2364..090bf3493 100644 --- a/test/unit/redis.ts +++ b/test/unit/redis.ts @@ -1,6 +1,6 @@ import * as sinon from "sinon"; import { expect } from "chai"; -import Redis from "../../lib/redis"; +import Redis from "../../lib/Redis"; describe("Redis", function () { describe("constructor", function () { @@ -103,7 +103,7 @@ describe("Redis", function () { stub.restore(); function getOption(...args) { - // @ts-ignore + // @ts-expect-error const redis = new Redis(...args); return redis.options; } @@ -111,7 +111,7 @@ describe("Redis", function () { it("should throw when arguments is invalid", function () { expect(function () { - // @ts-ignore + // @ts-expect-error new Redis(function () {}); }).to.throw(Error); }); diff --git a/tsconfig.json b/tsconfig.json index 2b93196ba..2096ae207 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,16 +1,10 @@ { "compilerOptions": { - "outDir": "./built", - "allowJs": true, - "target": "es6", - "lib": ["es6"], + "target": "es2018", + "lib": ["es2018"], "moduleResolution": "node", - "types": ["node", "mocha"], - "typeRoots": ["node_modules/@types"], - "module": "commonjs" + "module": "commonjs", + "outDir": "./built" }, - "include": [ - "./lib/**/*" - ] + "include": ["./lib/**/*"] } -