You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-12-09 21:21:11 +03:00
fix: add typed/untyped mode support for multi-commands (#3084)
This commit is contained in:
committed by
Nikolay Karadzhov
parent
7b56e9a3dc
commit
17fdb8c667
@@ -10,7 +10,7 @@ import { TcpSocketConnectOpts } from 'node:net';
|
|||||||
import { PUBSUB_TYPE, PubSubType, PubSubListener, PubSubTypeListeners, ChannelListeners } from './pub-sub';
|
import { PUBSUB_TYPE, PubSubType, PubSubListener, PubSubTypeListeners, ChannelListeners } from './pub-sub';
|
||||||
import { Command, CommandSignature, TypeMapping, CommanderConfig, RedisFunction, RedisFunctions, RedisModules, RedisScript, RedisScripts, ReplyUnion, RespVersions, RedisArgument, ReplyWithTypeMapping, SimpleStringReply, TransformReply, CommandArguments } from '../RESP/types';
|
import { Command, CommandSignature, TypeMapping, CommanderConfig, RedisFunction, RedisFunctions, RedisModules, RedisScript, RedisScripts, ReplyUnion, RespVersions, RedisArgument, ReplyWithTypeMapping, SimpleStringReply, TransformReply, CommandArguments } from '../RESP/types';
|
||||||
import RedisClientMultiCommand, { RedisClientMultiCommandType } from './multi-command';
|
import RedisClientMultiCommand, { RedisClientMultiCommandType } from './multi-command';
|
||||||
import { RedisMultiQueuedCommand } from '../multi-command';
|
import { MULTI_MODE, MultiMode, RedisMultiQueuedCommand } from '../multi-command';
|
||||||
import HELLO, { HelloOptions } from '../commands/HELLO';
|
import HELLO, { HelloOptions } from '../commands/HELLO';
|
||||||
import { ScanOptions, ScanCommonOptions } from '../commands/SCAN';
|
import { ScanOptions, ScanCommonOptions } from '../commands/SCAN';
|
||||||
import { RedisLegacyClient, RedisLegacyClientType } from './legacy-mode';
|
import { RedisLegacyClient, RedisLegacyClientType } from './legacy-mode';
|
||||||
@@ -1187,8 +1187,8 @@ export default class RedisClient<
|
|||||||
return execResult as Array<unknown>;
|
return execResult as Array<unknown>;
|
||||||
}
|
}
|
||||||
|
|
||||||
MULTI() {
|
MULTI<isTyped extends MultiMode = MULTI_MODE['TYPED']>() {
|
||||||
type Multi = new (...args: ConstructorParameters<typeof RedisClientMultiCommand>) => RedisClientMultiCommandType<[], M, F, S, RESP, TYPE_MAPPING>;
|
type Multi = new (...args: ConstructorParameters<typeof RedisClientMultiCommand>) => RedisClientMultiCommandType<isTyped, [], M, F, S, RESP, TYPE_MAPPING>;
|
||||||
return new ((this as any).Multi as Multi)(
|
return new ((this as any).Multi as Multi)(
|
||||||
this._executeMulti.bind(this),
|
this._executeMulti.bind(this),
|
||||||
this._executePipeline.bind(this),
|
this._executePipeline.bind(this),
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import COMMANDS from '../commands';
|
import COMMANDS from '../commands';
|
||||||
import RedisMultiCommand, { MULTI_REPLY, MultiReply, MultiReplyType, RedisMultiQueuedCommand } from '../multi-command';
|
import RedisMultiCommand, { MULTI_MODE, MULTI_REPLY, MultiMode, MultiReply, MultiReplyType, RedisMultiQueuedCommand } from '../multi-command';
|
||||||
import { ReplyWithTypeMapping, CommandReply, Command, CommandArguments, CommanderConfig, RedisFunctions, RedisModules, RedisScripts, RespVersions, TransformReply, RedisScript, RedisFunction, TypeMapping } from '../RESP/types';
|
import { ReplyWithTypeMapping, CommandReply, Command, CommandArguments, CommanderConfig, RedisFunctions, RedisModules, RedisScripts, RespVersions, TransformReply, RedisScript, RedisFunction, TypeMapping } from '../RESP/types';
|
||||||
import { attachConfig, functionArgumentsPrefix, getTransformReply } from '../commander';
|
import { attachConfig, functionArgumentsPrefix, getTransformReply } from '../commander';
|
||||||
import { BasicCommandParser } from './parser';
|
import { BasicCommandParser } from './parser';
|
||||||
@@ -13,7 +13,7 @@ type CommandSignature<
|
|||||||
S extends RedisScripts,
|
S extends RedisScripts,
|
||||||
RESP extends RespVersions,
|
RESP extends RespVersions,
|
||||||
TYPE_MAPPING extends TypeMapping
|
TYPE_MAPPING extends TypeMapping
|
||||||
> = (...args: Tail<Parameters<C['parseCommand']>>) => RedisClientMultiCommandType<
|
> = (...args: Tail<Parameters<C['parseCommand']>>) => InternalRedisClientMultiCommandType<
|
||||||
[...REPLIES, ReplyWithTypeMapping<CommandReply<C, RESP>, TYPE_MAPPING>],
|
[...REPLIES, ReplyWithTypeMapping<CommandReply<C, RESP>, TYPE_MAPPING>],
|
||||||
M,
|
M,
|
||||||
F,
|
F,
|
||||||
@@ -70,7 +70,7 @@ type WithScripts<
|
|||||||
[P in keyof S]: CommandSignature<REPLIES, S[P], M, F, S, RESP, TYPE_MAPPING>;
|
[P in keyof S]: CommandSignature<REPLIES, S[P], M, F, S, RESP, TYPE_MAPPING>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type RedisClientMultiCommandType<
|
type InternalRedisClientMultiCommandType<
|
||||||
REPLIES extends Array<any>,
|
REPLIES extends Array<any>,
|
||||||
M extends RedisModules,
|
M extends RedisModules,
|
||||||
F extends RedisFunctions,
|
F extends RedisFunctions,
|
||||||
@@ -85,6 +85,19 @@ export type RedisClientMultiCommandType<
|
|||||||
WithScripts<REPLIES, M, F, S, RESP, TYPE_MAPPING>
|
WithScripts<REPLIES, M, F, S, RESP, TYPE_MAPPING>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
type TypedOrAny<Flag extends MultiMode, T> =
|
||||||
|
[Flag] extends [MULTI_MODE['TYPED']] ? T : any;
|
||||||
|
|
||||||
|
export type RedisClientMultiCommandType<
|
||||||
|
isTyped extends MultiMode,
|
||||||
|
REPLIES extends Array<any>,
|
||||||
|
M extends RedisModules,
|
||||||
|
F extends RedisFunctions,
|
||||||
|
S extends RedisScripts,
|
||||||
|
RESP extends RespVersions,
|
||||||
|
TYPE_MAPPING extends TypeMapping
|
||||||
|
> = TypedOrAny<isTyped, InternalRedisClientMultiCommandType<REPLIES, M, F, S, RESP, TYPE_MAPPING>>;
|
||||||
|
|
||||||
type ExecuteMulti = (commands: Array<RedisMultiQueuedCommand>, selectedDB?: number) => Promise<Array<unknown>>;
|
type ExecuteMulti = (commands: Array<RedisMultiQueuedCommand>, selectedDB?: number) => Promise<Array<unknown>>;
|
||||||
|
|
||||||
export default class RedisClientMultiCommand<REPLIES = []> {
|
export default class RedisClientMultiCommand<REPLIES = []> {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import RedisClientMultiCommand, { RedisClientMultiCommandType } from './multi-co
|
|||||||
import { BasicPooledClientSideCache, ClientSideCacheConfig, PooledClientSideCacheProvider } from './cache';
|
import { BasicPooledClientSideCache, ClientSideCacheConfig, PooledClientSideCacheProvider } from './cache';
|
||||||
import { BasicCommandParser } from './parser';
|
import { BasicCommandParser } from './parser';
|
||||||
import SingleEntryCache from '../single-entry-cache';
|
import SingleEntryCache from '../single-entry-cache';
|
||||||
|
import { MULTI_MODE, MultiMode } from '../multi-command';
|
||||||
|
|
||||||
export interface RedisPoolOptions {
|
export interface RedisPoolOptions {
|
||||||
/**
|
/**
|
||||||
@@ -486,8 +487,9 @@ export class RedisClientPool<
|
|||||||
return this.execute(client => client.sendCommand(args, options));
|
return this.execute(client => client.sendCommand(args, options));
|
||||||
}
|
}
|
||||||
|
|
||||||
MULTI() {
|
|
||||||
type Multi = new (...args: ConstructorParameters<typeof RedisClientMultiCommand>) => RedisClientMultiCommandType<[], M, F, S, RESP, TYPE_MAPPING>;
|
MULTI<isTyped extends MultiMode = MULTI_MODE['TYPED']>() {
|
||||||
|
type Multi = new (...args: ConstructorParameters<typeof RedisClientMultiCommand>) => RedisClientMultiCommandType<isTyped, [], M, F, S, RESP, TYPE_MAPPING>;
|
||||||
return new ((this as any).Multi as Multi)(
|
return new ((this as any).Multi as Multi)(
|
||||||
(commands, selectedDB) => this.execute(client => client._executeMulti(commands, selectedDB)),
|
(commands, selectedDB) => this.execute(client => client._executeMulti(commands, selectedDB)),
|
||||||
commands => this.execute(client => client._executePipeline(commands)),
|
commands => this.execute(client => client._executePipeline(commands)),
|
||||||
|
|||||||
@@ -6,6 +6,13 @@ export type MULTI_REPLY = {
|
|||||||
TYPED: 'typed';
|
TYPED: 'typed';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type MULTI_MODE = {
|
||||||
|
TYPED: 'typed';
|
||||||
|
UNTYPED: 'untyped';
|
||||||
|
};
|
||||||
|
|
||||||
|
export type MultiMode = MULTI_MODE[keyof MULTI_MODE];
|
||||||
|
|
||||||
export type MultiReply = MULTI_REPLY[keyof MULTI_REPLY];
|
export type MultiReply = MULTI_REPLY[keyof MULTI_REPLY];
|
||||||
|
|
||||||
export type MultiReplyType<T extends MultiReply, REPLIES> = T extends MULTI_REPLY['TYPED'] ? REPLIES : Array<ReplyUnion>;
|
export type MultiReplyType<T extends MultiReply, REPLIES> = T extends MULTI_REPLY['TYPED'] ? REPLIES : Array<ReplyUnion>;
|
||||||
|
|||||||
Reference in New Issue
Block a user