Skip to content

Commit 17fdb8c

Browse files
PavelPashovnkaradzhov
authored andcommitted
fix: add typed/untyped mode support for multi-commands (#3084)
1 parent 7b56e9a commit 17fdb8c

File tree

4 files changed

+30
-8
lines changed

4 files changed

+30
-8
lines changed

packages/client/lib/client/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { TcpSocketConnectOpts } from 'node:net';
1010
import { PUBSUB_TYPE, PubSubType, PubSubListener, PubSubTypeListeners, ChannelListeners } from './pub-sub';
1111
import { Command, CommandSignature, TypeMapping, CommanderConfig, RedisFunction, RedisFunctions, RedisModules, RedisScript, RedisScripts, ReplyUnion, RespVersions, RedisArgument, ReplyWithTypeMapping, SimpleStringReply, TransformReply, CommandArguments } from '../RESP/types';
1212
import RedisClientMultiCommand, { RedisClientMultiCommandType } from './multi-command';
13-
import { RedisMultiQueuedCommand } from '../multi-command';
13+
import { MULTI_MODE, MultiMode, RedisMultiQueuedCommand } from '../multi-command';
1414
import HELLO, { HelloOptions } from '../commands/HELLO';
1515
import { ScanOptions, ScanCommonOptions } from '../commands/SCAN';
1616
import { RedisLegacyClient, RedisLegacyClientType } from './legacy-mode';
@@ -1187,8 +1187,8 @@ export default class RedisClient<
11871187
return execResult as Array<unknown>;
11881188
}
11891189

1190-
MULTI() {
1191-
type Multi = new (...args: ConstructorParameters<typeof RedisClientMultiCommand>) => RedisClientMultiCommandType<[], M, F, S, RESP, TYPE_MAPPING>;
1190+
MULTI<isTyped extends MultiMode = MULTI_MODE['TYPED']>() {
1191+
type Multi = new (...args: ConstructorParameters<typeof RedisClientMultiCommand>) => RedisClientMultiCommandType<isTyped, [], M, F, S, RESP, TYPE_MAPPING>;
11921192
return new ((this as any).Multi as Multi)(
11931193
this._executeMulti.bind(this),
11941194
this._executePipeline.bind(this),

packages/client/lib/client/multi-command.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import COMMANDS from '../commands';
2-
import RedisMultiCommand, { MULTI_REPLY, MultiReply, MultiReplyType, RedisMultiQueuedCommand } from '../multi-command';
2+
import RedisMultiCommand, { MULTI_MODE, MULTI_REPLY, MultiMode, MultiReply, MultiReplyType, RedisMultiQueuedCommand } from '../multi-command';
33
import { ReplyWithTypeMapping, CommandReply, Command, CommandArguments, CommanderConfig, RedisFunctions, RedisModules, RedisScripts, RespVersions, TransformReply, RedisScript, RedisFunction, TypeMapping } from '../RESP/types';
44
import { attachConfig, functionArgumentsPrefix, getTransformReply } from '../commander';
55
import { BasicCommandParser } from './parser';
@@ -13,7 +13,7 @@ type CommandSignature<
1313
S extends RedisScripts,
1414
RESP extends RespVersions,
1515
TYPE_MAPPING extends TypeMapping
16-
> = (...args: Tail<Parameters<C['parseCommand']>>) => RedisClientMultiCommandType<
16+
> = (...args: Tail<Parameters<C['parseCommand']>>) => InternalRedisClientMultiCommandType<
1717
[...REPLIES, ReplyWithTypeMapping<CommandReply<C, RESP>, TYPE_MAPPING>],
1818
M,
1919
F,
@@ -70,7 +70,7 @@ type WithScripts<
7070
[P in keyof S]: CommandSignature<REPLIES, S[P], M, F, S, RESP, TYPE_MAPPING>;
7171
};
7272

73-
export type RedisClientMultiCommandType<
73+
type InternalRedisClientMultiCommandType<
7474
REPLIES extends Array<any>,
7575
M extends RedisModules,
7676
F extends RedisFunctions,
@@ -85,6 +85,19 @@ export type RedisClientMultiCommandType<
8585
WithScripts<REPLIES, M, F, S, RESP, TYPE_MAPPING>
8686
);
8787

88+
type TypedOrAny<Flag extends MultiMode, T> =
89+
[Flag] extends [MULTI_MODE['TYPED']] ? T : any;
90+
91+
export type RedisClientMultiCommandType<
92+
isTyped extends MultiMode,
93+
REPLIES extends Array<any>,
94+
M extends RedisModules,
95+
F extends RedisFunctions,
96+
S extends RedisScripts,
97+
RESP extends RespVersions,
98+
TYPE_MAPPING extends TypeMapping
99+
> = TypedOrAny<isTyped, InternalRedisClientMultiCommandType<REPLIES, M, F, S, RESP, TYPE_MAPPING>>;
100+
88101
type ExecuteMulti = (commands: Array<RedisMultiQueuedCommand>, selectedDB?: number) => Promise<Array<unknown>>;
89102

90103
export default class RedisClientMultiCommand<REPLIES = []> {

packages/client/lib/client/pool.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import RedisClientMultiCommand, { RedisClientMultiCommandType } from './multi-co
1010
import { BasicPooledClientSideCache, ClientSideCacheConfig, PooledClientSideCacheProvider } from './cache';
1111
import { BasicCommandParser } from './parser';
1212
import SingleEntryCache from '../single-entry-cache';
13+
import { MULTI_MODE, MultiMode } from '../multi-command';
1314

1415
export interface RedisPoolOptions {
1516
/**
@@ -486,8 +487,9 @@ export class RedisClientPool<
486487
return this.execute(client => client.sendCommand(args, options));
487488
}
488489

489-
MULTI() {
490-
type Multi = new (...args: ConstructorParameters<typeof RedisClientMultiCommand>) => RedisClientMultiCommandType<[], M, F, S, RESP, TYPE_MAPPING>;
490+
491+
MULTI<isTyped extends MultiMode = MULTI_MODE['TYPED']>() {
492+
type Multi = new (...args: ConstructorParameters<typeof RedisClientMultiCommand>) => RedisClientMultiCommandType<isTyped, [], M, F, S, RESP, TYPE_MAPPING>;
491493
return new ((this as any).Multi as Multi)(
492494
(commands, selectedDB) => this.execute(client => client._executeMulti(commands, selectedDB)),
493495
commands => this.execute(client => client._executePipeline(commands)),

packages/client/lib/multi-command.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ export type MULTI_REPLY = {
66
TYPED: 'typed';
77
};
88

9+
export type MULTI_MODE = {
10+
TYPED: 'typed';
11+
UNTYPED: 'untyped';
12+
};
13+
14+
export type MultiMode = MULTI_MODE[keyof MULTI_MODE];
15+
916
export type MultiReply = MULTI_REPLY[keyof MULTI_REPLY];
1017

1118
export type MultiReplyType<T extends MultiReply, REPLIES> = T extends MULTI_REPLY['TYPED'] ? REPLIES : Array<ReplyUnion>;

0 commit comments

Comments
 (0)