@upstash/redis
Version:
An HTTP/REST based Redis client built on top of Upstash REST API.
1,602 lines (1,452 loc) • 149 kB
text/typescript
type CommandArgs<TCommand extends new (..._args: any) => any> = ConstructorParameters<TCommand>[0];
type Telemetry = {
/**
* Upstash-Telemetry-Sdk
* @example @upstash/redis@v1.1.1
*/
sdk?: string;
/**
* Upstash-Telemetry-Platform
* @example cloudflare
*/
platform?: string;
/**
* Upstash-Telemetry-Runtime
* @example node@v18
*/
runtime?: string;
};
type RedisOptions = {
/**
* Automatically try to deserialize the returned data from upstash using `JSON.deserialize`
*
* @default true
*/
automaticDeserialization?: boolean;
latencyLogging?: boolean;
enableTelemetry?: boolean;
enableAutoPipelining?: boolean;
readYourWrites?: boolean;
};
type CacheSetting = "default" | "force-cache" | "no-cache" | "no-store" | "only-if-cached" | "reload";
type UpstashRequest = {
path?: string[];
/**
* Request body will be serialized to json
*/
body?: unknown;
/**
* Additional headers for the request
*/
headers?: Record<string, string>;
upstashSyncToken?: string;
/**
* Callback for handling streaming messages
*/
onMessage?: (data: string) => void;
/**
* Whether this request expects a streaming response
*/
isStreaming?: boolean;
/**
* Abort signal for the request
*/
signal?: AbortSignal;
};
type UpstashResponse<TResult> = {
result?: TResult;
error?: string;
};
interface Requester {
/**
* When this flag is enabled, any subsequent commands issued by this client are guaranteed to observe the effects of all earlier writes submitted by the same client.
*/
readYourWrites?: boolean;
/**
* This token is used to ensure that the client is in sync with the server. On each request, we send this token in the header, and the server will return a new token.
*/
upstashSyncToken?: string;
request: <TResult = unknown>(req: UpstashRequest) => Promise<UpstashResponse<TResult>>;
}
type RetryConfig = false | {
/**
* The number of retries to attempt before giving up.
*
* @default 5
*/
retries?: number;
/**
* A backoff function receives the current retry count and returns a number in milliseconds to wait before retrying.
*
* @default
* ```ts
* Math.exp(retryCount) * 50
* ```
*/
backoff?: (retryCount: number) => number;
};
type Options$1 = {
backend?: string;
};
type RequesterConfig = {
/**
* Configure the retry behaviour in case of network errors
*/
retry?: RetryConfig;
/**
* Due to the nature of dynamic and custom data, it is possible to write data to redis that is not
* valid json and will therefore cause errors when deserializing. This used to happen very
* frequently with non-utf8 data, such as emojis.
*
* By default we will therefore encode the data as base64 on the server, before sending it to the
* client. The client will then decode the base64 data and parse it as utf8.
*
* For very large entries, this can add a few milliseconds, so if you are sure that your data is
* valid utf8, you can disable this behaviour by setting this option to false.
*
* Here's what the response body looks like:
*
* ```json
* {
* result?: "base64-encoded",
* error?: string
* }
* ```
*
* @default "base64"
*/
responseEncoding?: false | "base64";
/**
* Configure the cache behaviour
* @default "no-store"
*/
cache?: CacheSetting;
};
type HttpClientConfig = {
headers?: Record<string, string>;
baseUrl: string;
options?: Options$1;
retry?: RetryConfig;
agent?: any;
signal?: AbortSignal | (() => AbortSignal);
keepAlive?: boolean;
/**
* When this flag is enabled, any subsequent commands issued by this client are guaranteed to observe the effects of all earlier writes submitted by the same client.
*/
readYourWrites?: boolean;
} & RequesterConfig;
type Serialize = (data: unknown) => string | number | boolean;
type Deserialize<TResult, TData> = (result: TResult) => TData;
type CommandOptions<TResult, TData> = {
/**
* Custom deserializer
*/
deserialize?: (result: TResult) => TData;
/**
* Automatically try to deserialize the returned data from upstash using `JSON.deserialize`
*
* @default true
*/
automaticDeserialization?: boolean;
latencyLogging?: boolean;
/**
* Additional headers to be sent with the request
*/
headers?: Record<string, string>;
/**
* Path to append to the URL
*/
path?: string[];
/**
* Options for streaming requests, mainly used for subscribe, monitor commands
**/
streamOptions?: {
/**
* Callback to be called when a message is received
*/
onMessage?: (data: string) => void;
/**
* Whether the request is streaming
*/
isStreaming?: boolean;
/**
* Signal to abort the request
*/
signal?: AbortSignal;
};
};
/**
* 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.
*/
declare class Command<TResult, TData> {
readonly command: (string | number | boolean)[];
readonly serialize: Serialize;
readonly deserialize: Deserialize<TResult, TData>;
protected readonly headers?: Record<string, string>;
protected readonly path?: string[];
protected readonly onMessage?: (data: string) => void;
protected readonly isStreaming: boolean;
protected readonly signal?: AbortSignal;
/**
* Create a new command instance.
*
* You can define a custom `deserialize` function. By default we try to deserialize as json.
*/
constructor(command: (string | boolean | number | unknown)[], opts?: CommandOptions<TResult, TData>);
/**
* Execute the command using a client.
*/
exec(client: Requester): Promise<TData>;
}
type ZUnionStoreCommandOptions = {
aggregate?: "sum" | "min" | "max";
} & ({
weight: number;
weights?: never;
} | {
weight?: never;
weights: number[];
} | {
weight?: never;
weights?: never;
});
/**
* @see https://redis.io/commands/zunionstore
*/
declare class ZUnionStoreCommand extends Command<number, number> {
constructor(cmd: [destination: string, numKeys: 1, key: string, opts?: ZUnionStoreCommandOptions], cmdOpts?: CommandOptions<number, number>);
constructor(cmd: [destination: string, numKeys: number, keys: string[], opts?: ZUnionStoreCommandOptions], cmdOpts?: CommandOptions<number, number>);
}
type ZUnionCommandOptions = {
withScores?: boolean;
aggregate?: "sum" | "min" | "max";
} & ({
weight: number;
weights?: never;
} | {
weight?: never;
weights: number[];
} | {
weight?: never;
weights?: never;
});
/**
* @see https://redis.io/commands/zunion
*/
declare class ZUnionCommand<TData extends unknown[]> extends Command<string[], TData> {
constructor(cmd: [numKeys: 1, key: string, opts?: ZUnionCommandOptions], cmdOpts?: CommandOptions<string[], TData>);
constructor(cmd: [numKeys: number, keys: string[], opts?: ZUnionCommandOptions], cmdOpts?: CommandOptions<string[], TData>);
}
type ZInterStoreCommandOptions = {
aggregate?: "sum" | "min" | "max";
} & ({
weight: number;
weights?: never;
} | {
weight?: never;
weights: number[];
} | {
weight?: never;
weights?: never;
});
/**
* @see https://redis.io/commands/zInterstore
*/
declare class ZInterStoreCommand extends Command<number, number> {
constructor(cmd: [destination: string, numKeys: 1, key: string, opts?: ZInterStoreCommandOptions], cmdOpts?: CommandOptions<number, number>);
constructor(cmd: [destination: string, numKeys: number, keys: string[], opts?: ZInterStoreCommandOptions], cmdOpts?: CommandOptions<number, number>);
}
type Type = "string" | "list" | "set" | "zset" | "hash" | "none";
/**
* @see https://redis.io/commands/type
*/
declare class TypeCommand extends Command<Type, Type> {
constructor(cmd: [key: string], opts?: CommandOptions<Type, Type>);
}
type ScriptFlushCommandOptions = {
sync: true;
async?: never;
} | {
sync?: never;
async: true;
};
/**
* @see https://redis.io/commands/script-flush
*/
declare class ScriptFlushCommand extends Command<"OK", "OK"> {
constructor([opts]: [opts?: ScriptFlushCommandOptions], cmdOpts?: CommandOptions<"OK", "OK">);
}
type GeoAddCommandOptions = {
nx?: boolean;
xx?: never;
} | ({
nx?: never;
xx?: boolean;
} & {
ch?: boolean;
});
type GeoMember<TMemberType> = {
latitude: number;
longitude: number;
member: TMemberType;
};
/**
* @see https://redis.io/commands/geoadd
*/
declare class GeoAddCommand<TMemberType = string> extends Command<number | null, number | null> {
constructor([key, arg1, ...arg2]: [
string,
GeoMember<TMemberType> | GeoAddCommandOptions,
...GeoMember<TMemberType>[]
], opts?: CommandOptions<number | null, number | null>);
}
type ExpireOption = "NX" | "nx" | "XX" | "xx" | "GT" | "gt" | "LT" | "lt";
declare class ExpireCommand extends Command<"0" | "1", 0 | 1> {
constructor(cmd: [key: string, seconds: number, option?: ExpireOption], opts?: CommandOptions<"0" | "1", 0 | 1>);
}
type FunctionListArgs = {
/**
* Pattern for matching library names. Supports glob patterns.
*
* Example: "my_library_*"
*/
libraryName?: string;
/**
* Includes the library source code in the response.
*
* @default false
*/
withCode?: boolean;
};
type FunctionLoadArgs = {
/**
* The Lua code to load.
*
* Example:
* ```lua
* #!lua name=mylib
* redis.register_function('myfunc', function() return 'ok' end)
* ```
*/
code: string;
/**
* If true, the library will replace the existing library with the same name.
*
* @default false
*/
replace?: boolean;
};
/**
* @see https://redis.io/commands/append
*/
declare class AppendCommand extends Command<number, number> {
constructor(cmd: [key: string, value: string], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/bitcount
*/
declare class BitCountCommand extends Command<number, number> {
constructor(cmd: [key: string, start?: never, end?: never], opts?: CommandOptions<number, number>);
constructor(cmd: [key: string, start: number, end: number], opts?: CommandOptions<number, number>);
}
type SubCommandArgs<TRest extends unknown[] = []> = [
encoding: string,
offset: number | string,
...rest: TRest
];
/**
* @see https://redis.io/commands/bitfield
*/
declare class BitFieldCommand<T = Promise<number[]>> {
private client;
private opts?;
private execOperation;
private command;
constructor(args: [key: string], client: Requester, opts?: CommandOptions<number[], number[]> | undefined, execOperation?: (command: Command<number[], number[]>) => T);
private chain;
get(...args: SubCommandArgs): this;
set(...args: SubCommandArgs<[value: number]>): this;
incrby(...args: SubCommandArgs<[increment: number]>): this;
overflow(overflow: "WRAP" | "SAT" | "FAIL"): this;
exec(): T;
}
/**
* @see https://redis.io/commands/bitop
*/
declare class BitOpCommand extends Command<number, number> {
constructor(cmd: [op: "and" | "or" | "xor", destinationKey: string, ...sourceKeys: string[]], opts?: CommandOptions<number, number>);
constructor(cmd: [op: "not", destinationKey: string, sourceKey: string], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/bitpos
*/
declare class BitPosCommand extends Command<number, number> {
constructor(cmd: [key: string, bit: 0 | 1, start?: number, end?: number], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/copy
*/
declare class CopyCommand extends Command<number, "COPIED" | "NOT_COPIED"> {
constructor([key, destinationKey, opts]: [key: string, destinationKey: string, opts?: {
replace: boolean;
}], commandOptions?: CommandOptions<number, "COPIED" | "NOT_COPIED">);
}
/**
* @see https://redis.io/commands/dbsize
*/
declare class DBSizeCommand extends Command<number, number> {
constructor(opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/decr
*/
declare class DecrCommand extends Command<number, number> {
constructor(cmd: [key: string], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/decrby
*/
declare class DecrByCommand extends Command<number, number> {
constructor(cmd: [key: string, decrement: number], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/del
*/
declare class DelCommand extends Command<number, number> {
constructor(cmd: [...keys: string[]], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/echo
*/
declare class EchoCommand extends Command<string, string> {
constructor(cmd: [message: string], opts?: CommandOptions<string, string>);
}
/**
* @see https://redis.io/commands/eval_ro
*/
declare class EvalROCommand<TArgs extends unknown[], TData> extends Command<unknown, TData> {
constructor([script, keys, args]: [script: string, keys: string[], args: TArgs], opts?: CommandOptions<unknown, TData>);
}
/**
* @see https://redis.io/commands/eval
*/
declare class EvalCommand<TArgs extends unknown[], TData> extends Command<unknown, TData> {
constructor([script, keys, args]: [script: string, keys: string[], args: TArgs], opts?: CommandOptions<unknown, TData>);
}
/**
* @see https://redis.io/commands/evalsha_ro
*/
declare class EvalshaROCommand<TArgs extends unknown[], TData> extends Command<unknown, TData> {
constructor([sha, keys, args]: [sha: string, keys: string[], args?: TArgs], opts?: CommandOptions<unknown, TData>);
}
/**
* @see https://redis.io/commands/evalsha
*/
declare class EvalshaCommand<TArgs extends unknown[], TData> extends Command<unknown, TData> {
constructor([sha, keys, args]: [sha: string, keys: string[], args?: TArgs], opts?: CommandOptions<unknown, TData>);
}
/**
* @see https://redis.io/commands/exists
*/
declare class ExistsCommand extends Command<number, number> {
constructor(cmd: [...keys: string[]], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/expireat
*/
declare class ExpireAtCommand extends Command<"0" | "1", 0 | 1> {
constructor(cmd: [key: string, unix: number, option?: ExpireOption], opts?: CommandOptions<"0" | "1", 0 | 1>);
}
/**
* @see https://redis.io/commands/flushall
*/
declare class FlushAllCommand extends Command<"OK", "OK"> {
constructor(args?: [{
async?: boolean;
}], opts?: CommandOptions<"OK", "OK">);
}
/**
* @see https://redis.io/commands/flushdb
*/
declare class FlushDBCommand extends Command<"OK", "OK"> {
constructor([opts]: [opts?: {
async?: boolean;
}], cmdOpts?: CommandOptions<"OK", "OK">);
}
/**
* @see https://redis.io/commands/geodist
*/
declare class GeoDistCommand<TMemberType = string> extends Command<number | null, number | null> {
constructor([key, member1, member2, unit]: [
key: string,
member1: TMemberType,
member2: TMemberType,
unit?: "M" | "KM" | "FT" | "MI"
], opts?: CommandOptions<number | null, number | null>);
}
/**
* @see https://redis.io/commands/geohash
*/
declare class GeoHashCommand<TMember = string> extends Command<(string | null)[], (string | null)[]> {
constructor(cmd: [string, ...TMember[]], opts?: CommandOptions<(string | null)[], (string | null)[]>);
}
type Coordinates = {
lng: number;
lat: number;
};
/**
* @see https://redis.io/commands/geopos
*/
declare class GeoPosCommand<TMember = string> extends Command<(string | null)[][], Coordinates[]> {
constructor(cmd: [string, ...(TMember[] | TMember[])], opts?: CommandOptions<(string | null)[][], Coordinates[]>);
}
type RadiusOptions$1 = "M" | "KM" | "FT" | "MI";
type CenterPoint$1<TMemberType> = {
type: "FROMMEMBER" | "frommember";
member: TMemberType;
} | {
type: "FROMLONLAT" | "fromlonlat";
coordinate: {
lon: number;
lat: number;
};
};
type Shape$1 = {
type: "BYRADIUS" | "byradius";
radius: number;
radiusType: RadiusOptions$1;
} | {
type: "BYBOX" | "bybox";
rect: {
width: number;
height: number;
};
rectType: RadiusOptions$1;
};
type GeoSearchCommandOptions$1 = {
count?: {
limit: number;
any?: boolean;
};
withCoord?: boolean;
withDist?: boolean;
withHash?: boolean;
};
type OptionMappings = {
withHash: "hash";
withCoord: "coord";
withDist: "dist";
};
type GeoSearchOptions<TOptions> = {
[K in keyof TOptions as K extends keyof OptionMappings ? OptionMappings[K] : never]: K extends "withHash" ? string : K extends "withCoord" ? {
long: number;
lat: number;
} : K extends "withDist" ? number : never;
};
type GeoSearchResponse<TOptions, TMemberType> = ({
member: TMemberType;
} & GeoSearchOptions<TOptions>)[];
/**
* @see https://redis.io/commands/geosearch
*/
declare class GeoSearchCommand<TMemberType = string, TOptions extends GeoSearchCommandOptions$1 = GeoSearchCommandOptions$1> extends Command<any[] | any[][], GeoSearchResponse<TOptions, TMemberType>> {
constructor([key, centerPoint, shape, order, opts]: [
key: string,
centerPoint: CenterPoint$1<TMemberType>,
shape: Shape$1,
order: "ASC" | "DESC" | "asc" | "desc",
opts?: TOptions
], commandOptions?: CommandOptions<any[] | any[][], GeoSearchResponse<TOptions, TMemberType>>);
}
type RadiusOptions = "M" | "KM" | "FT" | "MI";
type CenterPoint<TMemberType> = {
type: "FROMMEMBER" | "frommember";
member: TMemberType;
} | {
type: "FROMLONLAT" | "fromlonlat";
coordinate: {
lon: number;
lat: number;
};
};
type Shape = {
type: "BYRADIUS" | "byradius";
radius: number;
radiusType: RadiusOptions;
} | {
type: "BYBOX" | "bybox";
rect: {
width: number;
height: number;
};
rectType: RadiusOptions;
};
type GeoSearchCommandOptions = {
count?: {
limit: number;
any?: boolean;
};
storeDist?: boolean;
};
/**
* @see https://redis.io/commands/geosearchstore
*/
declare class GeoSearchStoreCommand<TMemberType = string, TOptions extends GeoSearchCommandOptions = GeoSearchCommandOptions> extends Command<any[] | any[][], number> {
constructor([destination, key, centerPoint, shape, order, opts]: [
destination: string,
key: string,
centerPoint: CenterPoint<TMemberType>,
shape: Shape,
order: "ASC" | "DESC" | "asc" | "desc",
opts?: TOptions
], commandOptions?: CommandOptions<any[] | any[][], number>);
}
/**
* @see https://redis.io/commands/get
*/
declare class GetCommand<TData = string> extends Command<unknown | null, TData | null> {
constructor(cmd: [key: string], opts?: CommandOptions<unknown | null, TData | null>);
}
/**
* @see https://redis.io/commands/getbit
*/
declare class GetBitCommand extends Command<"0" | "1", 0 | 1> {
constructor(cmd: [key: string, offset: number], opts?: CommandOptions<"0" | "1", 0 | 1>);
}
/**
* @see https://redis.io/commands/getdel
*/
declare class GetDelCommand<TData = string> extends Command<unknown | null, TData | null> {
constructor(cmd: [key: string], opts?: CommandOptions<unknown | null, TData | null>);
}
type GetExCommandOptions = {
ex: number;
px?: never;
exat?: never;
pxat?: never;
persist?: never;
} | {
ex?: never;
px: number;
exat?: never;
pxat?: never;
persist?: never;
} | {
ex?: never;
px?: never;
exat: number;
pxat?: never;
persist?: never;
} | {
ex?: never;
px?: never;
exat?: never;
pxat: number;
persist?: never;
} | {
ex?: never;
px?: never;
exat?: never;
pxat?: never;
persist: true;
} | {
ex?: never;
px?: never;
exat?: never;
pxat?: never;
persist?: never;
};
/**
* @see https://redis.io/commands/getex
*/
declare class GetExCommand<TData = string> extends Command<unknown | null, TData | null> {
constructor([key, opts]: [key: string, opts?: GetExCommandOptions], cmdOpts?: CommandOptions<unknown | null, TData | null>);
}
/**
* @see https://redis.io/commands/getrange
*/
declare class GetRangeCommand extends Command<string, string> {
constructor(cmd: [key: string, start: number, end: number], opts?: CommandOptions<string, string>);
}
/**
* @see https://redis.io/commands/getset
*/
declare class GetSetCommand<TData = string> extends Command<unknown | null, TData | null> {
constructor(cmd: [key: string, value: TData], opts?: CommandOptions<unknown | null, TData | null>);
}
/**
* @see https://redis.io/commands/hdel
*/
declare class HDelCommand extends Command<"0" | "1", 0 | 1> {
constructor(cmd: [key: string, ...fields: string[]], opts?: CommandOptions<"0" | "1", 0 | 1>);
}
/**
* @see https://redis.io/commands/hexists
*/
declare class HExistsCommand extends Command<number, number> {
constructor(cmd: [key: string, field: string], opts?: CommandOptions<number, number>);
}
declare class HExpireCommand extends Command<(-2 | 0 | 1 | 2)[], (-2 | 0 | 1 | 2)[]> {
constructor(cmd: [
key: string,
fields: (string | number) | (string | number)[],
seconds: number,
option?: ExpireOption
], opts?: CommandOptions<(-2 | 0 | 1 | 2)[], (-2 | 0 | 1 | 2)[]>);
}
declare class HExpireAtCommand extends Command<(-2 | 0 | 1 | 2)[], (-2 | 0 | 1 | 2)[]> {
constructor(cmd: [
key: string,
fields: (string | number) | (string | number)[],
timestamp: number,
option?: ExpireOption
], opts?: CommandOptions<(-2 | 0 | 1 | 2)[], (-2 | 0 | 1 | 2)[]>);
}
declare class HExpireTimeCommand extends Command<number[], number[]> {
constructor(cmd: [key: string, fields: (string | number) | (string | number)[]], opts?: CommandOptions<number[], number[]>);
}
declare class HPersistCommand extends Command<(-2 | -1 | 1)[], (-2 | -1 | 1)[]> {
constructor(cmd: [key: string, fields: (string | number) | (string | number)[]], opts?: CommandOptions<(-2 | -1 | 1)[], (-2 | -1 | 1)[]>);
}
declare class HPExpireCommand extends Command<(-2 | 0 | 1 | 2)[], (-2 | 0 | 1 | 2)[]> {
constructor(cmd: [
key: string,
fields: (string | number) | (string | number)[],
milliseconds: number,
option?: ExpireOption
], opts?: CommandOptions<(-2 | 0 | 1 | 2)[], (-2 | 0 | 1 | 2)[]>);
}
declare class HPExpireAtCommand extends Command<(-2 | 0 | 1 | 2)[], (-2 | 0 | 1 | 2)[]> {
constructor(cmd: [
key: string,
fields: (string | number) | (string | number)[],
timestamp: number,
option?: ExpireOption
], opts?: CommandOptions<(-2 | 0 | 1 | 2)[], (-2 | 0 | 1 | 2)[]>);
}
declare class HPExpireTimeCommand extends Command<number[], number[]> {
constructor(cmd: [key: string, fields: (string | number) | (string | number)[]], opts?: CommandOptions<number[], number[]>);
}
declare class HPTtlCommand extends Command<number[], number[]> {
constructor(cmd: [key: string, fields: (string | number) | (string | number)[]], opts?: CommandOptions<number[], number[]>);
}
/**
* @see https://redis.io/commands/hget
*/
declare class HGetCommand<TData> extends Command<unknown | null, TData | null> {
constructor(cmd: [key: string, field: string], opts?: CommandOptions<unknown | null, TData | null>);
}
/**
* @see https://redis.io/commands/hgetall
*/
declare class HGetAllCommand<TData extends Record<string, unknown>> extends Command<unknown | null, TData | null> {
constructor(cmd: [key: string], opts?: CommandOptions<unknown | null, TData | null>);
}
/**
* @see https://redis.io/commands/hincrby
*/
declare class HIncrByCommand extends Command<number, number> {
constructor(cmd: [key: string, field: string, increment: number], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/hincrbyfloat
*/
declare class HIncrByFloatCommand extends Command<number, number> {
constructor(cmd: [key: string, field: string, increment: number], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/hkeys
*/
declare class HKeysCommand extends Command<string[], string[]> {
constructor([key]: [key: string], opts?: CommandOptions<string[], string[]>);
}
/**
* @see https://redis.io/commands/hlen
*/
declare class HLenCommand extends Command<number, number> {
constructor(cmd: [key: string], opts?: CommandOptions<number, number>);
}
/**
* hmget returns an object of all requested fields from a hash
* The field values are returned as an object like this:
* ```ts
* {[fieldName: string]: T | null}
* ```
*
* In case the hash does not exist or all fields are empty `null` is returned
*
* @see https://redis.io/commands/hmget
*/
declare class HMGetCommand<TData extends Record<string, unknown>> extends Command<(string | null)[], TData | null> {
constructor([key, ...fields]: [key: string, ...fields: string[]], opts?: CommandOptions<(string | null)[], TData | null>);
}
/**
* @see https://redis.io/commands/hmset
*/
declare class HMSetCommand<TData> extends Command<"OK", "OK"> {
constructor([key, kv]: [key: string, kv: Record<string, TData>], opts?: CommandOptions<"OK", "OK">);
}
/**
* @see https://redis.io/commands/hrandfield
*/
declare class HRandFieldCommand<TData extends string | string[] | Record<string, unknown>> extends Command<string | string[], TData> {
constructor(cmd: [key: string], opts?: CommandOptions<string, string>);
constructor(cmd: [key: string, count: number], opts?: CommandOptions<string[], string[]>);
constructor(cmd: [key: string, count: number, withValues: boolean], opts?: CommandOptions<string[], Partial<TData>>);
}
type ScanCommandOptionsStandard = {
match?: string;
count?: number;
type?: string;
withType?: false;
};
type ScanCommandOptionsWithType = {
match?: string;
count?: number;
/**
* Includes types of each key in the result
*
* @example
* ```typescript
* await redis.scan("0", { withType: true })
* // ["0", [{ key: "key1", type: "string" }, { key: "key2", type: "list" }]]
* ```
*/
withType: true;
};
type ScanCommandOptions = ScanCommandOptionsStandard | ScanCommandOptionsWithType;
type ScanResultStandard = [string, string[]];
type ScanResultWithType = [string, {
key: string;
type: string;
}[]];
/**
* @see https://redis.io/commands/scan
*/
declare class ScanCommand<TData = ScanResultStandard> extends Command<[string, string[]], TData> {
constructor([cursor, opts]: [cursor: string | number, opts?: ScanCommandOptions], cmdOpts?: CommandOptions<[string, string[]], TData>);
}
/**
* @see https://redis.io/commands/hscan
*/
declare class HScanCommand extends Command<[
string,
(string | number)[]
], [
string,
(string | number)[]
]> {
constructor([key, cursor, cmdOpts]: [key: string, cursor: string | number, cmdOpts?: ScanCommandOptions], opts?: CommandOptions<[string, (string | number)[]], [string, (string | number)[]]>);
}
/**
* @see https://redis.io/commands/hset
*/
declare class HSetCommand<TData> extends Command<number, number> {
constructor([key, kv]: [key: string, kv: Record<string, TData>], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/hsetnx
*/
declare class HSetNXCommand<TData> extends Command<"0" | "1", 0 | 1> {
constructor(cmd: [key: string, field: string, value: TData], opts?: CommandOptions<"0" | "1", 0 | 1>);
}
/**
* @see https://redis.io/commands/hstrlen
*/
declare class HStrLenCommand extends Command<number, number> {
constructor(cmd: [key: string, field: string], opts?: CommandOptions<number, number>);
}
declare class HTtlCommand extends Command<number[], number[]> {
constructor(cmd: [key: string, fields: (string | number) | (string | number)[]], opts?: CommandOptions<number[], number[]>);
}
/**
* @see https://redis.io/commands/hvals
*/
declare class HValsCommand<TData extends unknown[]> extends Command<unknown[], TData> {
constructor(cmd: [key: string], opts?: CommandOptions<unknown[], TData>);
}
/**
* @see https://redis.io/commands/incr
*/
declare class IncrCommand extends Command<number, number> {
constructor(cmd: [key: string], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/incrby
*/
declare class IncrByCommand extends Command<number, number> {
constructor(cmd: [key: string, value: number], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/incrbyfloat
*/
declare class IncrByFloatCommand extends Command<number, number> {
constructor(cmd: [key: string, value: number], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/json.arrappend
*/
declare class JsonArrAppendCommand<TData extends unknown[]> extends Command<(null | string)[], (null | number)[]> {
constructor(cmd: [key: string, path: string, ...values: TData], opts?: CommandOptions<(null | string)[], (null | number)[]>);
}
/**
* @see https://redis.io/commands/json.arrindex
*/
declare class JsonArrIndexCommand<TValue> extends Command<(null | string)[], (null | number)[]> {
constructor(cmd: [key: string, path: string, value: TValue, start?: number, stop?: number], opts?: CommandOptions<(null | string)[], (null | number)[]>);
}
/**
* @see https://redis.io/commands/json.arrinsert
*/
declare class JsonArrInsertCommand<TData extends unknown[]> extends Command<(null | string)[], (null | number)[]> {
constructor(cmd: [key: string, path: string, index: number, ...values: TData], opts?: CommandOptions<(null | string)[], (null | number)[]>);
}
/**
* @see https://redis.io/commands/json.arrlen
*/
declare class JsonArrLenCommand extends Command<(null | string)[], (null | number)[]> {
constructor(cmd: [key: string, path?: string], opts?: CommandOptions<(null | string)[], (null | number)[]>);
}
/**
* @see https://redis.io/commands/json.arrpop
*/
declare class JsonArrPopCommand<TData> extends Command<(null | string)[], (TData | null)[]> {
constructor(cmd: [key: string, path?: string, index?: number], opts?: CommandOptions<(null | string)[], (TData | null)[]>);
}
/**
* @see https://redis.io/commands/json.arrtrim
*/
declare class JsonArrTrimCommand extends Command<(null | string)[], (null | number)[]> {
constructor(cmd: [key: string, path?: string, start?: number, stop?: number], opts?: CommandOptions<(null | string)[], (null | number)[]>);
}
/**
* @see https://redis.io/commands/json.clear
*/
declare class JsonClearCommand extends Command<number, number> {
constructor(cmd: [key: string, path?: string], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/json.del
*/
declare class JsonDelCommand extends Command<number, number> {
constructor(cmd: [key: string, path?: string], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/json.forget
*/
declare class JsonForgetCommand extends Command<number, number> {
constructor(cmd: [key: string, path?: string], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/json.get
*/
declare class JsonGetCommand<TData extends (unknown | Record<string, unknown>) | (unknown | Record<string, unknown>)[]> extends Command<TData | null, TData | null> {
constructor(cmd: [
key: string,
opts?: {
indent?: string;
newline?: string;
space?: string;
},
...path: string[]
] | [key: string, ...path: string[]], opts?: CommandOptions<TData | null, TData | null>);
}
/**
* @see https://redis.io/commands/json.merge
*/
declare class JsonMergeCommand<TData extends string | number | Record<string, unknown> | Array<unknown>> extends Command<"OK" | null, "OK" | null> {
constructor(cmd: [key: string, path: string, value: TData], opts?: CommandOptions<"OK" | null, "OK" | null>);
}
/**
* @see https://redis.io/commands/json.mget
*/
declare class JsonMGetCommand<TData = unknown[]> extends Command<TData, TData> {
constructor(cmd: [keys: string[], path: string], opts?: CommandOptions<TData, TData>);
}
/**
* @see https://redis.io/commands/json.mset
*/
declare class JsonMSetCommand<TData extends number | string | boolean | Record<string, unknown> | (number | string | boolean | Record<string, unknown>)[]> extends Command<"OK" | null, "OK" | null> {
constructor(cmd: {
key: string;
path: string;
value: TData;
}[], opts?: CommandOptions<"OK" | null, "OK" | null>);
}
/**
* @see https://redis.io/commands/json.numincrby
*/
declare class JsonNumIncrByCommand extends Command<(null | string)[], (null | number)[]> {
constructor(cmd: [key: string, path: string, value: number], opts?: CommandOptions<(null | string)[], (null | number)[]>);
}
/**
* @see https://redis.io/commands/json.nummultby
*/
declare class JsonNumMultByCommand extends Command<(null | string)[], (null | number)[]> {
constructor(cmd: [key: string, path: string, value: number], opts?: CommandOptions<(null | string)[], (null | number)[]>);
}
/**
* @see https://redis.io/commands/json.objkeys
*/
declare class JsonObjKeysCommand extends Command<(string[] | null)[], (string[] | null)[]> {
constructor(cmd: [key: string, path?: string], opts?: CommandOptions<(string[] | null)[], (string[] | null)[]>);
}
/**
* @see https://redis.io/commands/json.objlen
*/
declare class JsonObjLenCommand extends Command<(number | null)[], (number | null)[]> {
constructor(cmd: [key: string, path?: string], opts?: CommandOptions<(number | null)[], (number | null)[]>);
}
/**
* @see https://redis.io/commands/json.resp
*/
declare class JsonRespCommand<TData extends unknown[]> extends Command<TData, TData> {
constructor(cmd: [key: string, path?: string], opts?: CommandOptions<TData, TData>);
}
/**
* @see https://redis.io/commands/json.set
*/
declare class JsonSetCommand<TData extends number | string | boolean | Record<string, unknown> | (number | string | boolean | Record<string, unknown>)[]> extends Command<"OK" | null, "OK" | null> {
constructor(cmd: [
key: string,
path: string,
value: TData,
opts?: {
nx: true;
xx?: never;
} | {
nx?: never;
xx: true;
}
], opts?: CommandOptions<"OK" | null, "OK" | null>);
}
/**
* @see https://redis.io/commands/json.strappend
*/
declare class JsonStrAppendCommand extends Command<(null | string)[], (null | number)[]> {
constructor(cmd: [key: string, path: string, value: string], opts?: CommandOptions<(null | string)[], (null | number)[]>);
}
/**
* @see https://redis.io/commands/json.strlen
*/
declare class JsonStrLenCommand extends Command<(number | null)[], (number | null)[]> {
constructor(cmd: [key: string, path?: string], opts?: CommandOptions<(number | null)[], (number | null)[]>);
}
/**
* @see https://redis.io/commands/json.toggle
*/
declare class JsonToggleCommand extends Command<number[], number[]> {
constructor(cmd: [key: string, path: string], opts?: CommandOptions<number[], number[]>);
}
/**
* @see https://redis.io/commands/json.type
*/
declare class JsonTypeCommand extends Command<string[], string[]> {
constructor(cmd: [key: string, path?: string], opts?: CommandOptions<string[], string[]>);
}
/**
* @see https://redis.io/commands/keys
*/
declare class KeysCommand extends Command<string[], string[]> {
constructor(cmd: [pattern: string], opts?: CommandOptions<string[], string[]>);
}
declare class LIndexCommand<TData = string> extends Command<unknown | null, TData | null> {
constructor(cmd: [key: string, index: number], opts?: CommandOptions<unknown | null, TData | null>);
}
declare class LInsertCommand<TData = string> extends Command<number, number> {
constructor(cmd: [key: string, direction: "before" | "after", pivot: TData, value: TData], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/llen
*/
declare class LLenCommand extends Command<number, number> {
constructor(cmd: [key: string], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/lmove
*/
declare class LMoveCommand<TData = string> extends Command<TData, TData> {
constructor(cmd: [
source: string,
destination: string,
whereFrom: "left" | "right",
whereTo: "left" | "right"
], opts?: CommandOptions<TData, TData>);
}
/**
* @see https://redis.io/commands/lpop
*/
declare class LPopCommand<TData = string> extends Command<unknown | null, TData | null> {
constructor(cmd: [key: string, count?: number], opts?: CommandOptions<unknown | null, TData | null>);
}
/**
* @see https://redis.io/commands/lpush
*/
declare class LPushCommand<TData = string> extends Command<number, number> {
constructor(cmd: [key: string, ...elements: TData[]], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/lpushx
*/
declare class LPushXCommand<TData> extends Command<number, number> {
constructor(cmd: [key: string, ...elements: TData[]], opts?: CommandOptions<number, number>);
}
declare class LRangeCommand<TData = string> extends Command<unknown[], TData[]> {
constructor(cmd: [key: string, start: number, end: number], opts?: CommandOptions<unknown[], TData[]>);
}
declare class LRemCommand<TData> extends Command<number, number> {
constructor(cmd: [key: string, count: number, value: TData], opts?: CommandOptions<number, number>);
}
declare class LSetCommand<TData = string> extends Command<"OK", "OK"> {
constructor(cmd: [key: string, index: number, data: TData], opts?: CommandOptions<"OK", "OK">);
}
declare class LTrimCommand extends Command<"OK", "OK"> {
constructor(cmd: [key: string, start: number, end: number], opts?: CommandOptions<"OK", "OK">);
}
/**
* @see https://redis.io/commands/mget
*/
declare class MGetCommand<TData extends unknown[]> extends Command<(string | null)[], TData> {
constructor(cmd: [string[]] | [...string[]], opts?: CommandOptions<(string | null)[], TData>);
}
/**
* @see https://redis.io/commands/mset
*/
declare class MSetCommand<TData> extends Command<"OK", "OK"> {
constructor([kv]: [kv: Record<string, TData>], opts?: CommandOptions<"OK", "OK">);
}
/**
* @see https://redis.io/commands/msetnx
*/
declare class MSetNXCommand<TData = string> extends Command<number, number> {
constructor([kv]: [kv: Record<string, TData>], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/persist
*/
declare class PersistCommand extends Command<"0" | "1", 0 | 1> {
constructor(cmd: [key: string], opts?: CommandOptions<"0" | "1", 0 | 1>);
}
/**
* @see https://redis.io/commands/pexpire
*/
declare class PExpireCommand extends Command<"0" | "1", 0 | 1> {
constructor(cmd: [key: string, milliseconds: number, option?: ExpireOption], opts?: CommandOptions<"0" | "1", 0 | 1>);
}
/**
* @see https://redis.io/commands/pexpireat
*/
declare class PExpireAtCommand extends Command<"0" | "1", 0 | 1> {
constructor(cmd: [key: string, unix: number, option?: ExpireOption], opts?: CommandOptions<"0" | "1", 0 | 1>);
}
/**
* @see https://redis.io/commands/ping
*/
declare class PingCommand extends Command<string | "PONG", string | "PONG"> {
constructor(cmd?: [message?: string], opts?: CommandOptions<string | "PONG", string | "PONG">);
}
/**
* @see https://redis.io/commands/psetex
*/
declare class PSetEXCommand<TData = string> extends Command<string, string> {
constructor(cmd: [key: string, ttl: number, value: TData], opts?: CommandOptions<string, string>);
}
/**
* @see https://redis.io/commands/pttl
*/
declare class PTtlCommand extends Command<number, number> {
constructor(cmd: [key: string], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/publish
*/
declare class PublishCommand<TMessage = unknown> extends Command<number, number> {
constructor(cmd: [channel: string, message: TMessage], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/randomkey
*/
declare class RandomKeyCommand extends Command<string | null, string | null> {
constructor(opts?: CommandOptions<string | null, string | null>);
}
/**
* @see https://redis.io/commands/rename
*/
declare class RenameCommand extends Command<"OK", "OK"> {
constructor(cmd: [source: string, destination: string], opts?: CommandOptions<"OK", "OK">);
}
/**
* @see https://redis.io/commands/renamenx
*/
declare class RenameNXCommand extends Command<"0" | "1", 0 | 1> {
constructor(cmd: [source: string, destination: string], opts?: CommandOptions<"0" | "1", 0 | 1>);
}
/**
* @see https://redis.io/commands/rpop
*/
declare class RPopCommand<TData extends unknown | unknown[] = string> extends Command<unknown | null, TData | null> {
constructor(cmd: [key: string, count?: number], opts?: CommandOptions<unknown | null, TData | null>);
}
/**
* @see https://redis.io/commands/rpush
*/
declare class RPushCommand<TData = string> extends Command<number, number> {
constructor(cmd: [key: string, ...elements: TData[]], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/rpushx
*/
declare class RPushXCommand<TData = string> extends Command<number, number> {
constructor(cmd: [key: string, ...elements: TData[]], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/sadd
*/
declare class SAddCommand<TData = string> extends Command<number, number> {
constructor(cmd: [key: string, member: TData, ...members: TData[]], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/scard
*/
declare class SCardCommand extends Command<number, number> {
constructor(cmd: [key: string], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/script-exists
*/
declare class ScriptExistsCommand<T extends string[]> extends Command<string[], number[]> {
constructor(hashes: T, opts?: CommandOptions<string[], number[]>);
}
/**
* @see https://redis.io/commands/script-load
*/
declare class ScriptLoadCommand extends Command<string, string> {
constructor(args: [script: string], opts?: CommandOptions<string, string>);
}
/**
* @see https://redis.io/commands/sdiff
*/
declare class SDiffCommand<TData> extends Command<unknown[], TData[]> {
constructor(cmd: [key: string, ...keys: string[]], opts?: CommandOptions<unknown[], TData[]>);
}
/**
* @see https://redis.io/commands/sdiffstore
*/
declare class SDiffStoreCommand extends Command<number, number> {
constructor(cmd: [destination: string, ...keys: string[]], opts?: CommandOptions<number, number>);
}
type SetCommandOptions = {
get?: boolean;
} & ({
ex: number;
px?: never;
exat?: never;
pxat?: never;
keepTtl?: never;
} | {
ex?: never;
px: number;
exat?: never;
pxat?: never;
keepTtl?: never;
} | {
ex?: never;
px?: never;
exat: number;
pxat?: never;
keepTtl?: never;
} | {
ex?: never;
px?: never;
exat?: never;
pxat: number;
keepTtl?: never;
} | {
ex?: never;
px?: never;
exat?: never;
pxat?: never;
keepTtl: true;
} | {
ex?: never;
px?: never;
exat?: never;
pxat?: never;
keepTtl?: never;
}) & ({
nx: true;
xx?: never;
} | {
xx: true;
nx?: never;
} | {
xx?: never;
nx?: never;
});
/**
* @see https://redis.io/commands/set
*/
declare class SetCommand<TData, TResult = TData | "OK" | null> extends Command<TResult, TData | "OK" | null> {
constructor([key, value, opts]: [key: string, value: TData, opts?: SetCommandOptions], cmdOpts?: CommandOptions<TResult, TData>);
}
/**
* @see https://redis.io/commands/setbit
*/
declare class SetBitCommand extends Command<"0" | "1", 0 | 1> {
constructor(cmd: [key: string, offset: number, value: 0 | 1], opts?: CommandOptions<"0" | "1", 0 | 1>);
}
/**
* @see https://redis.io/commands/setex
*/
declare class SetExCommand<TData = string> extends Command<"OK", "OK"> {
constructor(cmd: [key: string, ttl: number, value: TData], opts?: CommandOptions<"OK", "OK">);
}
/**
* @see https://redis.io/commands/setnx
*/
declare class SetNxCommand<TData = string> extends Command<number, number> {
constructor(cmd: [key: string, value: TData], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/setrange
*/
declare class SetRangeCommand extends Command<number, number> {
constructor(cmd: [key: string, offset: number, value: string], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/sinter
*/
declare class SInterCommand<TData = string> extends Command<unknown[], TData[]> {
constructor(cmd: [key: string, ...keys: string[]], opts?: CommandOptions<unknown[], TData[]>);
}
/**
* @see https://redis.io/commands/sinterstore
*/
declare class SInterStoreCommand extends Command<number, number> {
constructor(cmd: [destination: string, key: string, ...keys: string[]], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/sismember
*/
declare class SIsMemberCommand<TData = string> extends Command<"0" | "1", 0 | 1> {
constructor(cmd: [key: string, member: TData], opts?: CommandOptions<"0" | "1", 0 | 1>);
}
/**
* @see https://redis.io/commands/smembers
*/
declare class SMembersCommand<TData extends unknown[] = string[]> extends Command<unknown[], TData> {
constructor(cmd: [key: string], opts?: CommandOptions<unknown[], TData>);
}
/**
* @see https://redis.io/commands/smismember
*/
declare class SMIsMemberCommand<TMembers extends unknown[]> extends Command<("0" | "1")[], (0 | 1)[]> {
constructor(cmd: [key: string, members: TMembers], opts?: CommandOptions<("0" | "1")[], (0 | 1)[]>);
}
/**
* @see https://redis.io/commands/smove
*/
declare class SMoveCommand<TData> extends Command<"0" | "1", 0 | 1> {
constructor(cmd: [source: string, destination: string, member: TData], opts?: CommandOptions<"0" | "1", 0 | 1>);
}
/**
* @see https://redis.io/commands/spop
*/
declare class SPopCommand<TData> extends Command<string | string[] | null, TData | null> {
constructor([key, count]: [key: string, count?: number], opts?: CommandOptions<string | string[] | null, TData | null>);
}
/**
* @see https://redis.io/commands/srandmember
*/
declare class SRandMemberCommand<TData> extends Command<string | null, TData | null> {
constructor([key, count]: [key: string, count?: number], opts?: CommandOptions<string | null, TData | null>);
}
/**
* @see https://redis.io/commands/srem
*/
declare class SRemCommand<TData = string> extends Command<number, number> {
constructor(cmd: [key: string, ...members: TData[]], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/sscan
*/
declare class SScanCommand extends Command<[
string,
(string | number)[]
], [
string,
(string | number)[]
]> {
constructor([key, cursor, opts]: [key: string, cursor: string | number, opts?: ScanCommandOptions], cmdOpts?: CommandOptions<[string, (string | number)[]], [string, (string | number)[]]>);
}
/**
* @see https://redis.io/commands/strlen
*/
declare class StrLenCommand extends Command<number, number> {
constructor(cmd: [key: string], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/sunion
*/
declare class SUnionCommand<TData> extends Command<string[], TData[]> {
constructor(cmd: [key: string, ...keys: string[]], opts?: CommandOptions<string[], TData[]>);
}
/**
* @see https://redis.io/commands/sunionstore
*/
declare class SUnionStoreCommand extends Command<number, number> {
constructor(cmd: [destination: string, key: string, ...keys: string[]], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/time
*/
declare class TimeCommand extends Command<[number, number], [number, number]> {
constructor(opts?: CommandOptions<[number, number], [number, number]>);
}
/**
* @see https://redis.io/commands/touch
*/
declare class TouchCommand extends Command<number, number> {
constructor(cmd: [...keys: string[]], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/ttl
*/
declare class TtlCommand extends Command<number, number> {
constructor(cmd: [key: string], opts?: CommandOptions<number, number>);
}
/**
* @see https://redis.io/commands/unlink
*/
declare class UnlinkCommand extends Command<number, number> {
constructor(cmd: [...keys: string[]], opts?: CommandOptions<number, number>);
}
type XAddCommandOptions = {
nomkStream?: boolean;
trim?: ({
type: "MAXLEN" | "maxlen";
threshold: number;
} | {
type: "MINID" | "minid";
threshold: string;
}) & ({
comparison: "~";
limit?: number;
} | {
comparison: "=";
limit?: never;
});
};
/**
* @see https://redis.io/commands/xadd
*/
declare class XAddCommand extends Command<string, string> {
constructor([key, id, entries, opts]: [
key: string,
id: "*" | string,
entries: Record<string, unknown>,
opts?: XAddCommandOptions
], commandOptions?: CommandOptions<s