"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Pipeline = void 0;
const mod_js_1 = require("./commands/mod.js");
const error_js_1 = require("./error.js");
const zmscore_js_1 = require("./commands/zmscore.js");
const hrandfield_js_1 = require("./commands/hrandfield.js");
const zdiffstore_js_1 = require("./commands/zdiffstore.js");
/**
 * Upstash REST API supports command pipelining to send multiple commands in
 * batch, instead of sending each command one by one and waiting for a response.
 * When using pipelines, several commands are sent using a single HTTP request,
 * and a single JSON array response is returned. Each item in the response array
 * corresponds to the command in the same order within the pipeline.
 *
 * **NOTE:**
 *
 * Execution of the pipeline is not atomic. Even though each command in
 * the pipeline will be executed in order, commands sent by other clients can
 * interleave with the pipeline.
 *
 * **Examples:**
 *
 * ```ts
 *  const p = redis.pipeline() // or redis.multi()
 * p.set("key","value")
 * p.get("key")
 * const res = await p.exec()
 * ```
 *
 * You can also chain commands together
 * ```ts
 * const p = redis.pipeline()
 * const res = await p.set("key","value").get("key").exec()
 * ```
 *
 * Return types are inferred if all commands are chained, but you can still
 * override the response type manually:
 * ```ts
 *  redis.pipeline()
 *   .set("key", { greeting: "hello"})
 *   .get("key")
 *   .exec<["OK", { greeting: string } ]>()
 *
 * ```
 */
class Pipeline {
    constructor(opts) {
        Object.defineProperty(this, "client", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "commands", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "commandOptions", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "multiExec", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        /**
         * Send the pipeline request to upstash.
         *
         * Returns an array with the results of all pipelined commands.
         *
         * If all commands are statically chained from start to finish, types are inferred. You can still define a return type manually if necessary though:
         * ```ts
         * const p = redis.pipeline()
         * p.get("key")
         * const result = p.exec<[{ greeting: string }]>()
         * ```
         */
        Object.defineProperty(this, "exec", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: async () => {
                if (this.commands.length === 0) {
                    throw new Error("Pipeline is empty");
                }
                const path = this.multiExec ? ["multi-exec"] : ["pipeline"];
                const res = (await this.client.request({
                    path,
                    body: Object.values(this.commands).map((c) => c.command),
                }));
                return res.map(({ error, result }, i) => {
                    if (error) {
                        throw new error_js_1.UpstashError(`Command ${i + 1} [ ${this.commands[i].command[0]} ] failed: ${error}`);
                    }
                    return this.commands[i].deserialize(result);
                });
            }
        });
        /**
         * @see https://redis.io/commands/append
         */
        Object.defineProperty(this, "append", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.AppendCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/bitcount
         */
        Object.defineProperty(this, "bitcount", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.BitCountCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/bitop
         */
        Object.defineProperty(this, "bitop", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (op, destinationKey, sourceKey, ...sourceKeys) => this.chain(new mod_js_1.BitOpCommand([op, destinationKey, sourceKey, ...sourceKeys], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/bitpos
         */
        Object.defineProperty(this, "bitpos", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.BitPosCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/zdiffstore
         */
        Object.defineProperty(this, "zdiffstore", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new zdiffstore_js_1.ZDiffStoreCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/dbsize
         */
        Object.defineProperty(this, "dbsize", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: () => this.chain(new mod_js_1.DBSizeCommand(this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/decr
         */
        Object.defineProperty(this, "decr", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.DecrCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/decrby
         */
        Object.defineProperty(this, "decrby", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.DecrByCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/del
         */
        Object.defineProperty(this, "del", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.DelCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/echo
         */
        Object.defineProperty(this, "echo", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.EchoCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/eval
         */
        Object.defineProperty(this, "eval", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.EvalCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/evalsha
         */
        Object.defineProperty(this, "evalsha", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.EvalshaCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/exists
         */
        Object.defineProperty(this, "exists", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.ExistsCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/expire
         */
        Object.defineProperty(this, "expire", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.ExpireCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/expireat
         */
        Object.defineProperty(this, "expireat", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.ExpireAtCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/flushall
         */
        Object.defineProperty(this, "flushall", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (args) => this.chain(new mod_js_1.FlushAllCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/flushdb
         */
        Object.defineProperty(this, "flushdb", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.FlushDBCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/get
         */
        Object.defineProperty(this, "get", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.GetCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/getbit
         */
        Object.defineProperty(this, "getbit", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.GetBitCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/getdel
         */
        Object.defineProperty(this, "getdel", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.GetDelCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/getrange
         */
        Object.defineProperty(this, "getrange", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.GetRangeCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/getset
         */
        Object.defineProperty(this, "getset", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, value) => this.chain(new mod_js_1.GetSetCommand([key, value], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/hdel
         */
        Object.defineProperty(this, "hdel", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.HDelCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/hexists
         */
        Object.defineProperty(this, "hexists", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.HExistsCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/hget
         */
        Object.defineProperty(this, "hget", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.HGetCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/hgetall
         */
        Object.defineProperty(this, "hgetall", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.HGetAllCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/hincrby
         */
        Object.defineProperty(this, "hincrby", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.HIncrByCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/hincrbyfloat
         */
        Object.defineProperty(this, "hincrbyfloat", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.HIncrByFloatCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/hkeys
         */
        Object.defineProperty(this, "hkeys", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.HKeysCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/hlen
         */
        Object.defineProperty(this, "hlen", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.HLenCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/hmget
         */
        Object.defineProperty(this, "hmget", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.HMGetCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/hmset
         */
        Object.defineProperty(this, "hmset", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, kv) => this.chain(new mod_js_1.HMSetCommand([key, kv], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/hrandfield
         */
        Object.defineProperty(this, "hrandfield", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, count, withValues) => this.chain(new hrandfield_js_1.HRandFieldCommand([key, count, withValues], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/hscan
         */
        Object.defineProperty(this, "hscan", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.HScanCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/hset
         */
        Object.defineProperty(this, "hset", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, kv) => this.chain(new mod_js_1.HSetCommand([key, kv], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/hsetnx
         */
        Object.defineProperty(this, "hsetnx", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, field, value) => this.chain(new mod_js_1.HSetNXCommand([key, field, value], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/hstrlen
         */
        Object.defineProperty(this, "hstrlen", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.HStrLenCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/hvals
         */
        Object.defineProperty(this, "hvals", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.HValsCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/incr
         */
        Object.defineProperty(this, "incr", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.IncrCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/incrby
         */
        Object.defineProperty(this, "incrby", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.IncrByCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/incrbyfloat
         */
        Object.defineProperty(this, "incrbyfloat", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.IncrByFloatCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/keys
         */
        Object.defineProperty(this, "keys", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.KeysCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/lindex
         */
        Object.defineProperty(this, "lindex", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.LIndexCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/linsert
         */
        Object.defineProperty(this, "linsert", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, direction, pivot, value) => this.chain(new mod_js_1.LInsertCommand([key, direction, pivot, value], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/llen
         */
        Object.defineProperty(this, "llen", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.LLenCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/lmove
         */
        Object.defineProperty(this, "lmove", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.LMoveCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/lpop
         */
        Object.defineProperty(this, "lpop", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.LPopCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/lpos
         */
        Object.defineProperty(this, "lpos", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.LPosCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/lpush
         */
        Object.defineProperty(this, "lpush", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, ...elements) => this.chain(new mod_js_1.LPushCommand([key, ...elements], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/lpushx
         */
        Object.defineProperty(this, "lpushx", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, ...elements) => this.chain(new mod_js_1.LPushXCommand([key, ...elements], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/lrange
         */
        Object.defineProperty(this, "lrange", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.LRangeCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/lrem
         */
        Object.defineProperty(this, "lrem", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, count, value) => this.chain(new mod_js_1.LRemCommand([key, count, value], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/lset
         */
        Object.defineProperty(this, "lset", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, index, value) => this.chain(new mod_js_1.LSetCommand([key, index, value], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/ltrim
         */
        Object.defineProperty(this, "ltrim", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.LTrimCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/mget
         */
        Object.defineProperty(this, "mget", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.MGetCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/mset
         */
        Object.defineProperty(this, "mset", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (kv) => this.chain(new mod_js_1.MSetCommand([kv], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/msetnx
         */
        Object.defineProperty(this, "msetnx", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (kv) => this.chain(new mod_js_1.MSetNXCommand([kv], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/persist
         */
        Object.defineProperty(this, "persist", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.PersistCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/pexpire
         */
        Object.defineProperty(this, "pexpire", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.PExpireCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/pexpireat
         */
        Object.defineProperty(this, "pexpireat", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.PExpireAtCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/ping
         */
        Object.defineProperty(this, "ping", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (args) => this.chain(new mod_js_1.PingCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/psetex
         */
        Object.defineProperty(this, "psetex", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, ttl, value) => this.chain(new mod_js_1.PSetEXCommand([key, ttl, value], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/pttl
         */
        Object.defineProperty(this, "pttl", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.PTtlCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/publish
         */
        Object.defineProperty(this, "publish", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.PublishCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/randomkey
         */
        Object.defineProperty(this, "randomkey", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: () => this.chain(new mod_js_1.RandomKeyCommand(this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/rename
         */
        Object.defineProperty(this, "rename", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.RenameCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/renamenx
         */
        Object.defineProperty(this, "renamenx", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.RenameNXCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/rpop
         */
        Object.defineProperty(this, "rpop", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.RPopCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/rpush
         */
        Object.defineProperty(this, "rpush", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, ...elements) => this.chain(new mod_js_1.RPushCommand([key, ...elements], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/rpushx
         */
        Object.defineProperty(this, "rpushx", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, ...elements) => this.chain(new mod_js_1.RPushXCommand([key, ...elements], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/sadd
         */
        Object.defineProperty(this, "sadd", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, ...members) => this.chain(new mod_js_1.SAddCommand([key, ...members], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/scan
         */
        Object.defineProperty(this, "scan", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.ScanCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/scard
         */
        Object.defineProperty(this, "scard", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.SCardCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/script-exists
         */
        Object.defineProperty(this, "scriptExists", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.ScriptExistsCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/script-flush
         */
        Object.defineProperty(this, "scriptFlush", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.ScriptFlushCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/script-load
         */
        Object.defineProperty(this, "scriptLoad", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.ScriptLoadCommand(args, this.commandOptions))
        });
        /*)*
         * @see https://redis.io/commands/sdiff
         */
        Object.defineProperty(this, "sdiff", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.SDiffCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/sdiffstore
         */
        Object.defineProperty(this, "sdiffstore", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.SDiffStoreCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/set
         */
        Object.defineProperty(this, "set", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, value, opts) => this.chain(new mod_js_1.SetCommand([key, value, opts], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/setbit
         */
        Object.defineProperty(this, "setbit", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.SetBitCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/setex
         */
        Object.defineProperty(this, "setex", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, ttl, value) => this.chain(new mod_js_1.SetExCommand([key, ttl, value], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/setnx
         */
        Object.defineProperty(this, "setnx", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, value) => this.chain(new mod_js_1.SetNxCommand([key, value], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/setrange
         */
        Object.defineProperty(this, "setrange", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.SetRangeCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/sinter
         */
        Object.defineProperty(this, "sinter", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.SInterCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/sinterstore
         */
        Object.defineProperty(this, "sinterstore", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.SInterStoreCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/sismember
         */
        Object.defineProperty(this, "sismember", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, member) => this.chain(new mod_js_1.SIsMemberCommand([key, member], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/smembers
         */
        Object.defineProperty(this, "smembers", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.SMembersCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/smismember
         */
        Object.defineProperty(this, "smismember", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, members) => this.chain(new mod_js_1.SMIsMemberCommand([key, members], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/smove
         */
        Object.defineProperty(this, "smove", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (source, destination, member) => this.chain(new mod_js_1.SMoveCommand([source, destination, member], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/spop
         */
        Object.defineProperty(this, "spop", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.SPopCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/srandmember
         */
        Object.defineProperty(this, "srandmember", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.SRandMemberCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/srem
         */
        Object.defineProperty(this, "srem", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, ...members) => this.chain(new mod_js_1.SRemCommand([key, ...members], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/sscan
         */
        Object.defineProperty(this, "sscan", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.SScanCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/strlen
         */
        Object.defineProperty(this, "strlen", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.StrLenCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/sunion
         */
        Object.defineProperty(this, "sunion", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.SUnionCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/sunionstore
         */
        Object.defineProperty(this, "sunionstore", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.SUnionStoreCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/time
         */
        Object.defineProperty(this, "time", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: () => this.chain(new mod_js_1.TimeCommand(this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/touch
         */
        Object.defineProperty(this, "touch", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.TouchCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/ttl
         */
        Object.defineProperty(this, "ttl", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.TtlCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/type
         */
        Object.defineProperty(this, "type", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.TypeCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/unlink
         */
        Object.defineProperty(this, "unlink", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.UnlinkCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/zadd
         */
        Object.defineProperty(this, "zadd", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => {
                if ("score" in args[1]) {
                    return this.chain(new mod_js_1.ZAddCommand([args[0], args[1], ...args.slice(2)], this.commandOptions));
                }
                return this.chain(new mod_js_1.ZAddCommand([args[0], args[1], ...args.slice(2)], this.commandOptions));
            }
        });
        /**
         * @see https://redis.io/commands/zcard
         */
        Object.defineProperty(this, "zcard", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.ZCardCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/zcount
         */
        Object.defineProperty(this, "zcount", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.ZCountCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/zincrby
         */
        Object.defineProperty(this, "zincrby", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, increment, member) => this.chain(new mod_js_1.ZIncrByCommand([key, increment, member], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/zinterstore
         */
        Object.defineProperty(this, "zinterstore", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.ZInterStoreCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/zlexcount
         */
        Object.defineProperty(this, "zlexcount", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.ZLexCountCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/zmscore
         */
        Object.defineProperty(this, "zmscore", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new zmscore_js_1.ZMScoreCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/zpopmax
         */
        Object.defineProperty(this, "zpopmax", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.ZPopMaxCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/zpopmin
         */
        Object.defineProperty(this, "zpopmin", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.ZPopMinCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/zrange
         */
        Object.defineProperty(this, "zrange", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.ZRangeCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/zrank
         */
        Object.defineProperty(this, "zrank", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, member) => this.chain(new mod_js_1.ZRankCommand([key, member], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/zrem
         */
        Object.defineProperty(this, "zrem", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, ...members) => this.chain(new mod_js_1.ZRemCommand([key, ...members], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/zremrangebylex
         */
        Object.defineProperty(this, "zremrangebylex", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.ZRemRangeByLexCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/zremrangebyrank
         */
        Object.defineProperty(this, "zremrangebyrank", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.ZRemRangeByRankCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/zremrangebyscore
         */
        Object.defineProperty(this, "zremrangebyscore", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.ZRemRangeByScoreCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/zrevrank
         */
        Object.defineProperty(this, "zrevrank", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, member) => this.chain(new mod_js_1.ZRevRankCommand([key, member], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/zscan
         */
        Object.defineProperty(this, "zscan", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.ZScanCommand(args, this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/zscore
         */
        Object.defineProperty(this, "zscore", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (key, member) => this.chain(new mod_js_1.ZScoreCommand([key, member], this.commandOptions))
        });
        /**
         * @see https://redis.io/commands/zunionstore
         */
        Object.defineProperty(this, "zunionstore", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: (...args) => this.chain(new mod_js_1.ZUnionStoreCommand(args, this.commandOptions))
        });
        this.client = opts.client;
        this.commands = []; // the TCommands generic in the class definition is only used for carrying through chained command types and should never be explicitly set when instantiating the class
        this.commandOptions = opts.commandOptions;
        this.multiExec = opts.multiExec ?? false;
    }
    /**
     * Pushes a command into the pipeline and returns a chainable instance of the
     * pipeline
     */
    chain(command) {
        this.commands.push(command);
        return this; // TS thinks we're returning Pipeline<[]> here, because we're not creating a new instance of the class, hence the cast
    }
    /**
     * @see https://redis.io/commands/?group=json
     */
    get json() {
        return {
            /**
             * @see https://redis.io/commands/json.arrappend
             */
            arrappend: (...args) => this.chain(new mod_js_1.JsonArrAppendCommand(args, this.commandOptions)),
            /**
             * @see https://redis.io/commands/json.arrindex
             */
            arrindex: (...args) => this.chain(new mod_js_1.JsonArrIndexCommand(args, this.commandOptions)),
            /**
             * @see https://redis.io/commands/json.arrinsert
             */
            arrinsert: (...args) => this.chain(new mod_js_1.JsonArrInsertCommand(args, this.commandOptions)),
            /**
             * @see https://redis.io/commands/json.arrlen
             */
            arrlen: (...args) => this.chain(new mod_js_1.JsonArrLenCommand(args, this.commandOptions)),
            /**
             * @see https://redis.io/commands/json.arrpop
             */
            arrpop: (...args) => this.chain(new mod_js_1.JsonArrPopCommand(args, this.commandOptions)),
            /**
             * @see https://redis.io/commands/json.arrtrim
             */
            arrtrim: (...args) => this.chain(new mod_js_1.JsonArrTrimCommand(args, this.commandOptions)),
            /**
             * @see https://redis.io/commands/json.clear
             */
            clear: (...args) => this.chain(new mod_js_1.JsonClearCommand(args, this.commandOptions)),
            /**
             * @see https://redis.io/commands/json.del
             */
            del: (...args) => this.chain(new mod_js_1.JsonDelCommand(args, this.commandOptions)),
            /**
             * @see https://redis.io/commands/json.forget
             */
            forget: (...args) => this.chain(new mod_js_1.JsonForgetCommand(args, this.commandOptions)),
            /**
             * @see https://redis.io/commands/json.get
             */
            get: (...args) => this.chain(new mod_js_1.JsonGetCommand(args, this.commandOptions)),
            /**
             * @see https://redis.io/commands/json.mget
             */
            mget: (...args) => this.chain(new mod_js_1.JsonMGetCommand(args, this.commandOptions)),
            /**
             * @see https://redis.io/commands/json.numincrby
             */
            numincrby: (...args) => this.chain(new mod_js_1.JsonNumIncrByCommand(args, this.commandOptions)),
            /**
             * @see https://redis.io/commands/json.nummultby
             */
            nummultby: (...args) => this.chain(new mod_js_1.JsonNumMultByCommand(args, this.commandOptions)),
            /**
             * @see https://redis.io/commands/json.objkeys
             */
            objkeys: (...args) => this.chain(new mod_js_1.JsonObjKeysCommand(args, this.commandOptions)),
            /**
             * @see https://redis.io/commands/json.objlen
             */
            objlen: (...args) => this.chain(new mod_js_1.JsonObjLenCommand(args, this.commandOptions)),
            /**
             * @see https://redis.io/commands/json.resp
             */
            resp: (...args) => this.chain(new mod_js_1.JsonRespCommand(args, this.commandOptions)),
            /**
             * @see https://redis.io/commands/json.set
             */
            set: (...args) => this.chain(new mod_js_1.JsonSetCommand(args, this.commandOptions)),
            /**
             * @see https://redis.io/commands/json.strappend
             */
            strappend: (...args) => this.chain(new mod_js_1.JsonStrAppendCommand(args, this.commandOptions)),
            /**
             * @see https://redis.io/commands/json.strlen
             */
            strlen: (...args) => this.chain(new mod_js_1.JsonStrLenCommand(args, this.commandOptions)),
            /**
             * @see https://redis.io/commands/json.toggle
             */
            toggle: (...args) => this.chain(new mod_js_1.JsonToggleCommand(args, this.commandOptions)),
            /**
             * @see https://redis.io/commands/json.type
             */
            type: (...args) => this.chain(new mod_js_1.JsonTypeCommand(args, this.commandOptions)),
        };
    }
}
exports.Pipeline = Pipeline;
