You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-06 02:15:48 +03:00
fix #1707 - handle number arguments in legacy mode
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL, waitTillBeenCalled } from '../test-utils';
|
import testUtils, { GLOBAL, waitTillBeenCalled } from '../test-utils';
|
||||||
import RedisClient, { RedisClientType } from '.';
|
import RedisClient, { ClientLegacyCommandArguments, RedisClientType } from '.';
|
||||||
import { RedisClientMultiCommandType } from './multi-command';
|
import { RedisClientMultiCommandType } from './multi-command';
|
||||||
import { RedisCommandArguments, RedisCommandRawReply, RedisModules, RedisScripts } from '../commands';
|
import { RedisCommandArguments, RedisCommandRawReply, RedisModules, RedisScripts } from '../commands';
|
||||||
import { AbortError, ClientClosedError, ConnectionTimeoutError, DisconnectsClientError, SocketClosedUnexpectedlyError, WatchError } from '../errors';
|
import { AbortError, ClientClosedError, ConnectionTimeoutError, DisconnectsClientError, SocketClosedUnexpectedlyError, WatchError } from '../errors';
|
||||||
@@ -170,7 +170,7 @@ describe('Client', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function setAsync<M extends RedisModules, S extends RedisScripts>(client: RedisClientType<M, S>, ...args: Array<string | Buffer | RedisCommandArguments>): Promise<RedisCommandRawReply> {
|
function setAsync<M extends RedisModules, S extends RedisScripts>(client: RedisClientType<M, S>, ...args: ClientLegacyCommandArguments): Promise<RedisCommandRawReply> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
(client as any).set(...args, (err: Error | undefined, reply: RedisCommandRawReply) => {
|
(client as any).set(...args, (err: Error | undefined, reply: RedisCommandRawReply) => {
|
||||||
if (err) return reject(err);
|
if (err) return reject(err);
|
||||||
@@ -204,10 +204,10 @@ describe('Client', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.{command} should accept mix of strings and array of strings', async client => {
|
testUtils.testWithClient('client.{command} should accept mix of arrays and arguments', async client => {
|
||||||
assert.equal(
|
assert.equal(
|
||||||
await setAsync(client, ['a'], 'b', ['XX']),
|
await setAsync(client, ['a'], 'b', ['EX', 1]),
|
||||||
null
|
'OK'
|
||||||
);
|
);
|
||||||
}, {
|
}, {
|
||||||
...GLOBAL.SERVERS.OPEN,
|
...GLOBAL.SERVERS.OPEN,
|
||||||
|
@@ -9,7 +9,7 @@ import { CommandOptions, commandOptions, isCommandOptions } from '../command-opt
|
|||||||
import { ScanOptions, ZMember } from '../commands/generic-transformers';
|
import { ScanOptions, ZMember } from '../commands/generic-transformers';
|
||||||
import { ScanCommandOptions } from '../commands/SCAN';
|
import { ScanCommandOptions } from '../commands/SCAN';
|
||||||
import { HScanTuple } from '../commands/HSCAN';
|
import { HScanTuple } from '../commands/HSCAN';
|
||||||
import { extendWithCommands, extendWithModulesAndScripts, transformCommandArguments, transformCommandReply } from '../commander';
|
import { extendWithCommands, extendWithModulesAndScripts, LegacyCommandArguments, transformCommandArguments, transformCommandReply, transformLegacyCommandArguments } from '../commander';
|
||||||
import { Pool, Options as PoolOptions, createPool } from 'generic-pool';
|
import { Pool, Options as PoolOptions, createPool } from 'generic-pool';
|
||||||
import { ClientClosedError, DisconnectsClientError } from '../errors';
|
import { ClientClosedError, DisconnectsClientError } from '../errors';
|
||||||
import { URL } from 'url';
|
import { URL } from 'url';
|
||||||
@@ -55,6 +55,7 @@ export interface ClientCommandOptions extends QueueCommandOptions {
|
|||||||
|
|
||||||
type ClientLegacyCallback = (err: Error | null, reply?: RedisCommandRawReply) => void;
|
type ClientLegacyCallback = (err: Error | null, reply?: RedisCommandRawReply) => void;
|
||||||
|
|
||||||
|
export type ClientLegacyCommandArguments = LegacyCommandArguments | [...LegacyCommandArguments, ClientLegacyCallback];
|
||||||
export default class RedisClient<M extends RedisModules, S extends RedisScripts> extends EventEmitter {
|
export default class RedisClient<M extends RedisModules, S extends RedisScripts> extends EventEmitter {
|
||||||
static commandOptions(options: ClientCommandOptions): CommandOptions<ClientCommandOptions> {
|
static commandOptions(options: ClientCommandOptions): CommandOptions<ClientCommandOptions> {
|
||||||
return commandOptions(options);
|
return commandOptions(options);
|
||||||
@@ -246,12 +247,13 @@ export default class RedisClient<M extends RedisModules, S extends RedisScripts>
|
|||||||
if (!this.#options?.legacyMode) return;
|
if (!this.#options?.legacyMode) return;
|
||||||
|
|
||||||
(this as any).#v4.sendCommand = this.#sendCommand.bind(this);
|
(this as any).#v4.sendCommand = this.#sendCommand.bind(this);
|
||||||
(this as any).sendCommand = (...args: Array<unknown>): void => {
|
(this as any).sendCommand = (...args: ClientLegacyCommandArguments): void => {
|
||||||
const callback = typeof args[args.length - 1] === 'function' ?
|
let callback: ClientLegacyCallback;
|
||||||
args[args.length - 1] as ClientLegacyCallback :
|
if (typeof args[args.length - 1] === 'function') {
|
||||||
undefined,
|
callback = args.pop() as ClientLegacyCallback;
|
||||||
actualArgs = !callback ? args : args.slice(0, -1);
|
}
|
||||||
this.#sendCommand(actualArgs.flat() as Array<string>)
|
|
||||||
|
this.#sendCommand(transformLegacyCommandArguments(args as LegacyCommandArguments))
|
||||||
.then((reply: RedisCommandRawReply) => {
|
.then((reply: RedisCommandRawReply) => {
|
||||||
if (!callback) return;
|
if (!callback) return;
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import COMMANDS from './commands';
|
import COMMANDS from './commands';
|
||||||
import { RedisCommand, RedisCommandArguments, RedisCommandRawReply, RedisModules, RedisPlugins, RedisScript, RedisScripts } from '../commands';
|
import { RedisCommand, RedisCommandArguments, RedisCommandRawReply, RedisModules, RedisPlugins, RedisScript, RedisScripts } from '../commands';
|
||||||
import RedisMultiCommand, { RedisMultiQueuedCommand } from '../multi-command';
|
import RedisMultiCommand, { RedisMultiQueuedCommand } from '../multi-command';
|
||||||
import { extendWithCommands, extendWithModulesAndScripts } from '../commander';
|
import { extendWithCommands, extendWithModulesAndScripts, LegacyCommandArguments, transformLegacyCommandArguments } from '../commander';
|
||||||
|
|
||||||
type RedisClientMultiCommandSignature<C extends RedisCommand, M extends RedisModules, S extends RedisScripts> =
|
type RedisClientMultiCommandSignature<C extends RedisCommand, M extends RedisModules, S extends RedisScripts> =
|
||||||
(...args: Parameters<C['transformArguments']>) => RedisClientMultiCommandType<M, S>;
|
(...args: Parameters<C['transformArguments']>) => RedisClientMultiCommandType<M, S>;
|
||||||
@@ -52,8 +52,8 @@ export default class RedisClientMultiCommand {
|
|||||||
|
|
||||||
#legacyMode(): void {
|
#legacyMode(): void {
|
||||||
this.v4.addCommand = this.addCommand.bind(this);
|
this.v4.addCommand = this.addCommand.bind(this);
|
||||||
(this as any).addCommand = (...args: Array<string | Buffer | Array<string | Buffer>>): this => {
|
(this as any).addCommand = (...args: LegacyCommandArguments): this => {
|
||||||
this.#multi.addCommand(args.flat());
|
this.#multi.addCommand(transformLegacyCommandArguments(args));
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
this.v4.exec = this.exec.bind(this);
|
this.v4.exec = this.exec.bind(this);
|
||||||
|
@@ -113,3 +113,18 @@ export function transformCommandReply(
|
|||||||
|
|
||||||
return command.transformReply(rawReply, preserved);
|
return command.transformReply(rawReply, preserved);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type LegacyCommandArguments = Array<string | number | Buffer | LegacyCommandArguments>;
|
||||||
|
|
||||||
|
export function transformLegacyCommandArguments(args: LegacyCommandArguments, flat: RedisCommandArguments = []): RedisCommandArguments {
|
||||||
|
for (const arg of args) {
|
||||||
|
if (Array.isArray(arg)) {
|
||||||
|
transformLegacyCommandArguments(arg, flat);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
flat.push(typeof arg === 'number' ? arg.toString() : arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return flat;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user