"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Command = void 0;
const error_js_1 = require("../error.js");
const util_js_1 = require("../util.js");
const defaultSerializer = (c) => {
    switch (typeof c) {
        case "string":
        case "number":
        case "boolean":
            return c;
        default:
            return JSON.stringify(c);
    }
};
/**
 * Command offers default (de)serialization and the exec method to all commands.
 *
 * TData represents what the user will enter or receive,
 * TResult is the raw data returned from upstash, which may need to be transformed or parsed.
 */
class Command {
    /**
     * Create a new command instance.
     *
     * You can define a custom `deserialize` function. By default we try to deserialize as json.
     */
    constructor(command, opts) {
        Object.defineProperty(this, "command", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "serialize", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "deserialize", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        this.serialize = defaultSerializer;
        this.deserialize = typeof opts?.automaticDeserialization === "undefined" ||
            opts.automaticDeserialization
            ? opts?.deserialize ?? util_js_1.parseResponse
            : (x) => x;
        this.command = command.map((c) => this.serialize(c));
    }
    /**
     * Execute the command using a client.
     */
    async exec(client) {
        const { result, error } = await client.request({
            body: this.command,
        });
        if (error) {
            throw new error_js_1.UpstashError(error);
        }
        if (typeof result === "undefined") {
            throw new Error("Request did not return a result");
        }
        return this.deserialize(result);
    }
}
exports.Command = Command;
