1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-04 15:02:09 +03:00

Merge branch 'master' of github.com:redis/node-redis into COMMAND_DOCS

This commit is contained in:
Avital-Fine
2022-04-03 14:08:19 +03:00
117 changed files with 2861 additions and 1054 deletions

View File

@@ -13,20 +13,32 @@ describe('ACL GETUSER', () => {
});
testUtils.testWithClient('client.aclGetUser', async client => {
const expectedReply: any = {
passwords: [],
commands: '+@all',
};
if (testUtils.isVersionGreaterThan([7])) {
expectedReply.flags = ['on', 'nopass'];
expectedReply.keys = '~*';
expectedReply.channels = '&*';
expectedReply.selectors = [];
} else {
expectedReply.keys = ['*'];
expectedReply.selectors = undefined;
if (testUtils.isVersionGreaterThan([6, 2])) {
expectedReply.flags = ['on', 'allkeys', 'allchannels', 'allcommands', 'nopass'];
expectedReply.channels = ['*'];
} else {
expectedReply.flags = ['on', 'allkeys', 'allcommands', 'nopass'];
expectedReply.channels = undefined;
}
}
assert.deepEqual(
await client.aclGetUser('default'),
{
passwords: [],
commands: '+@all',
keys: ['*'],
...(testUtils.isVersionGreaterThan([6, 2]) ? {
flags: ['on', 'allkeys', 'allchannels', 'allcommands', 'nopass'],
channels: ['*']
} : {
flags: ['on', 'allkeys', 'allcommands', 'nopass'],
channels: undefined
})
}
expectedReply
);
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -5,24 +5,27 @@ export function transformArguments(username: RedisCommandArgument): RedisCommand
}
type AclGetUserRawReply = [
_: RedisCommandArgument,
flags: Array<RedisCommandArgument>,
_: RedisCommandArgument,
passwords: Array<RedisCommandArgument>,
_: RedisCommandArgument,
commands: RedisCommandArgument,
_: RedisCommandArgument,
keys: Array<RedisCommandArgument>,
_: RedisCommandArgument,
channels: Array<RedisCommandArgument>
'flags',
Array<RedisCommandArgument>,
'passwords',
Array<RedisCommandArgument>,
'commands',
RedisCommandArgument,
'keys',
Array<RedisCommandArgument> | RedisCommandArgument,
'channels',
Array<RedisCommandArgument> | RedisCommandArgument,
'selectors' | undefined,
Array<Array<string>> | undefined
];
interface AclUser {
flags: Array<RedisCommandArgument>;
passwords: Array<RedisCommandArgument>;
commands: RedisCommandArgument;
keys: Array<RedisCommandArgument>;
channels: Array<RedisCommandArgument>
keys: Array<RedisCommandArgument> | RedisCommandArgument;
channels: Array<RedisCommandArgument> | RedisCommandArgument;
selectors?: Array<Array<string>>;
}
export function transformReply(reply: AclGetUserRawReply): AclUser {
@@ -31,6 +34,7 @@ export function transformReply(reply: AclGetUserRawReply): AclUser {
passwords: reply[3],
commands: reply[5],
keys: reply[7],
channels: reply[9]
channels: reply[9],
selectors: reply[11]
};
}

View File

@@ -11,14 +11,27 @@ describe('BITCOUNT', () => {
);
});
it('with range', () => {
assert.deepEqual(
transformArguments('key', {
start: 0,
end: 1
}),
['BITCOUNT', 'key', '0', '1']
);
describe('with range', () => {
it('simple', () => {
assert.deepEqual(
transformArguments('key', {
start: 0,
end: 1
}),
['BITCOUNT', 'key', '0', '1']
);
});
it('with mode', () => {
assert.deepEqual(
transformArguments('key', {
start: 0,
end: 1,
mode: 'BIT'
}),
['BITCOUNT', 'key', '0', '1', 'BIT']
);
});
});
});

View File

@@ -7,6 +7,7 @@ export const IS_READ_ONLY = true;
interface BitCountRange {
start: number;
end: number;
mode?: 'BYTE' | 'BIT';
}
export function transformArguments(
@@ -20,6 +21,10 @@ export function transformArguments(
range.start.toString(),
range.end.toString()
);
if (range.mode) {
args.push(range.mode);
}
}
return args;

View File

@@ -18,12 +18,19 @@ describe('BITPOS', () => {
);
});
it('with start, end', () => {
it('with start and end', () => {
assert.deepEqual(
transformArguments('key', 1, 1, -1),
['BITPOS', 'key', '1', '1', '-1']
);
});
it('with start, end and mode', () => {
assert.deepEqual(
transformArguments('key', 1, 1, -1, 'BIT'),
['BITPOS', 'key', '1', '1', '-1', 'BIT']
);
});
});
testUtils.testWithClient('client.bitPos', async client => {

View File

@@ -9,7 +9,8 @@ export function transformArguments(
key: RedisCommandArgument,
bit: BitValue,
start?: number,
end?: number
end?: number,
mode?: 'BYTE' | 'BIT'
): RedisCommandArguments {
const args = ['BITPOS', key, bit.toString()];
@@ -21,6 +22,10 @@ export function transformArguments(
args.push(end.toString());
}
if (mode) {
args.push(mode);
}
return args;
}

View File

@@ -1,13 +1,11 @@
export function transformArguments(slots: number | Array<number>): Array<string> {
const args = ['CLUSTER', 'ADDSLOTS'];
import { RedisCommandArguments } from '.';
import { pushVerdictNumberArguments } from './generic-transformers';
if (typeof slots === 'number') {
args.push(slots.toString());
} else {
args.push(...slots.map(String));
}
return args;
export function transformArguments(slots: number | Array<number>): RedisCommandArguments {
return pushVerdictNumberArguments(
['CLUSTER', 'ADDSLOTS'],
slots
);
}
export declare function transformReply(): string;

View File

@@ -0,0 +1,29 @@
import { strict as assert } from 'assert';
import { transformArguments } from './CLUSTER_ADDSLOTSRANGE';
describe('CLUSTER ADDSLOTSRANGE', () => {
describe('transformArguments', () => {
it('single', () => {
assert.deepEqual(
transformArguments({
start: 0,
end: 1
}),
['CLUSTER', 'ADDSLOTSRANGE', '0', '1']
);
});
it('multiple', () => {
assert.deepEqual(
transformArguments([{
start: 0,
end: 1
}, {
start: 2,
end: 3
}]),
['CLUSTER', 'ADDSLOTSRANGE', '0', '1', '2', '3']
);
});
});
});

View File

@@ -0,0 +1,13 @@
import { RedisCommandArguments } from '.';
import { pushSlotRangesArguments, SlotRange } from './generic-transformers';
export function transformArguments(
ranges: SlotRange | Array<SlotRange>
): RedisCommandArguments {
return pushSlotRangesArguments(
['CLUSTER', 'ADDSLOTSRANGE'],
ranges
);
}
export declare function transformReply(): 'OK';

View File

@@ -0,0 +1,19 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './CLUSTER_BUMPEPOCH';
describe('CLUSTER BUMPEPOCH', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments(),
['CLUSTER', 'BUMPEPOCH']
);
});
testUtils.testWithCluster('clusterNode.clusterBumpEpoch', async cluster => {
assert.equal(
typeof await cluster.getSlotMaster(0).client.clusterBumpEpoch(),
'string'
);
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -0,0 +1,5 @@
export function transformArguments(): Array<string> {
return ['CLUSTER', 'BUMPEPOCH'];
}
export declare function transformReply(): 'BUMPED' | 'STILL';

View File

@@ -0,0 +1,22 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './CLUSTER_COUNT-FAILURE-REPORTS';
describe('CLUSTER COUNT-FAILURE-REPORTS', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments('0'),
['CLUSTER', 'COUNT-FAILURE-REPORTS', '0']
);
});
testUtils.testWithCluster('clusterNode.clusterCountFailureReports', async cluster => {
const { client } = cluster.getSlotMaster(0);
assert.equal(
typeof await client.clusterCountFailureReports(
await client.clusterMyId()
),
'number'
);
}, GLOBAL.CLUSTERS.OPEN);
});

View File

@@ -0,0 +1,5 @@
export function transformArguments(nodeId: string): Array<string> {
return ['CLUSTER', 'COUNT-FAILURE-REPORTS', nodeId];
}
export declare function transformReply(): number;

View File

@@ -0,0 +1,19 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './CLUSTER_COUNTKEYSINSLOT';
describe('CLUSTER COUNTKEYSINSLOT', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments(0),
['CLUSTER', 'COUNTKEYSINSLOT', '0']
);
});
testUtils.testWithCluster('clusterNode.clusterCountKeysInSlot', async cluster => {
assert.equal(
typeof await cluster.getSlotMaster(0).client.clusterCountKeysInSlot(0),
'number'
);
}, GLOBAL.CLUSTERS.OPEN);
});

View File

@@ -0,0 +1,5 @@
export function transformArguments(slot: number): Array<string> {
return ['CLUSTER', 'COUNTKEYSINSLOT', slot.toString()];
}
export declare function transformReply(): number;

View File

@@ -0,0 +1,20 @@
import { strict as assert } from 'assert';
import { transformArguments } from './CLUSTER_DELSLOTS';
describe('CLUSTER DELSLOTS', () => {
describe('transformArguments', () => {
it('single', () => {
assert.deepEqual(
transformArguments(0),
['CLUSTER', 'DELSLOTS', '0']
);
});
it('multiple', () => {
assert.deepEqual(
transformArguments([0, 1]),
['CLUSTER', 'DELSLOTS', '0', '1']
);
});
});
});

View File

@@ -0,0 +1,11 @@
import { RedisCommandArguments } from '.';
import { pushVerdictNumberArguments } from './generic-transformers';
export function transformArguments(slots: number | Array<number>): RedisCommandArguments {
return pushVerdictNumberArguments(
['CLUSTER', 'DELSLOTS'],
slots
);
}
export declare function transformReply(): 'OK';

View File

@@ -0,0 +1,29 @@
import { strict as assert } from 'assert';
import { transformArguments } from './CLUSTER_DELSLOTSRANGE';
describe('CLUSTER DELSLOTSRANGE', () => {
describe('transformArguments', () => {
it('single', () => {
assert.deepEqual(
transformArguments({
start: 0,
end: 1
}),
['CLUSTER', 'DELSLOTSRANGE', '0', '1']
);
});
it('multiple', () => {
assert.deepEqual(
transformArguments([{
start: 0,
end: 1
}, {
start: 2,
end: 3
}]),
['CLUSTER', 'DELSLOTSRANGE', '0', '1', '2', '3']
);
});
});
});

View File

@@ -0,0 +1,13 @@
import { RedisCommandArguments } from '.';
import { pushSlotRangesArguments, SlotRange } from './generic-transformers';
export function transformArguments(
ranges: SlotRange | Array<SlotRange>
): RedisCommandArguments {
return pushSlotRangesArguments(
['CLUSTER', 'DELSLOTSRANGE'],
ranges
);
}
export declare function transformReply(): 'OK';

View File

@@ -0,0 +1,20 @@
import { strict as assert } from 'assert';
import { FailoverModes, transformArguments } from './CLUSTER_FAILOVER';
describe('CLUSTER FAILOVER', () => {
describe('transformArguments', () => {
it('simple', () => {
assert.deepEqual(
transformArguments(),
['CLUSTER', 'FAILOVER']
);
});
it('with mode', () => {
assert.deepEqual(
transformArguments(FailoverModes.FORCE),
['CLUSTER', 'FAILOVER', 'FORCE']
);
});
});
});

View File

@@ -0,0 +1,16 @@
export enum FailoverModes {
FORCE = 'FORCE',
TAKEOVER = 'TAKEOVER'
}
export function transformArguments(mode?: FailoverModes): Array<string> {
const args = ['CLUSTER', 'FAILOVER'];
if (mode) {
args.push(mode);
}
return args;
}
export declare function transformReply(): 'OK';

View File

@@ -2,4 +2,4 @@ export function transformArguments(): Array<string> {
return ['CLUSTER', 'FLUSHSLOTS'];
}
export declare function transformReply(): string;
export declare function transformReply(): 'OK';

View File

@@ -0,0 +1,11 @@
import { strict as assert } from 'assert';
import { transformArguments } from './CLUSTER_FORGET';
describe('CLUSTER FORGET', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments('0'),
['CLUSTER', 'FORGET', '0']
);
});
});

View File

@@ -0,0 +1,5 @@
export function transformArguments(nodeId: string): Array<string> {
return ['CLUSTER', 'FORGET', nodeId];
}
export declare function transformReply(): 'OK';

View File

@@ -1,4 +1,5 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './CLUSTER_GETKEYSINSLOT';
describe('CLUSTER GETKEYSINSLOT', () => {
@@ -8,4 +9,12 @@ describe('CLUSTER GETKEYSINSLOT', () => {
['CLUSTER', 'GETKEYSINSLOT', '0', '10']
);
});
testUtils.testWithCluster('clusterNode.clusterGetKeysInSlot', async cluster => {
const reply = await cluster.getSlotMaster(0).client.clusterGetKeysInSlot(0, 1);
assert.ok(Array.isArray(reply));
for (const item of reply) {
assert.equal(typeof item, 'string');
}
}, GLOBAL.CLUSTERS.OPEN);
});

View File

@@ -2,4 +2,4 @@ export function transformArguments(slot: number, count: number): Array<string> {
return ['CLUSTER', 'GETKEYSINSLOT', slot.toString(), count.toString()];
}
export declare function transformReply(): string;
export declare function transformReply(): Array<string>;

View File

@@ -1,4 +1,5 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments, transformReply } from './CLUSTER_INFO';
describe('CLUSTER INFO', () => {
@@ -43,4 +44,11 @@ describe('CLUSTER INFO', () => {
}
);
});
testUtils.testWithCluster('clusterNode.clusterInfo', async cluster => {
assert.notEqual(
await cluster.getSlotMaster(0).client.clusterInfo(),
null
);
}, GLOBAL.CLUSTERS.OPEN);
});

View File

@@ -0,0 +1,19 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './CLUSTER_KEYSLOT';
describe('CLUSTER KEYSLOT', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments('key'),
['CLUSTER', 'KEYSLOT', 'key']
);
});
testUtils.testWithCluster('clusterNode.clusterKeySlot', async cluster => {
assert.equal(
typeof await cluster.getSlotMaster(0).client.clusterKeySlot('key'),
'number'
);
}, GLOBAL.CLUSTERS.OPEN);
});

View File

@@ -0,0 +1,5 @@
export function transformArguments(key: string): Array<string> {
return ['CLUSTER', 'KEYSLOT', key];
}
export declare function transformReply(): number;

View File

@@ -0,0 +1,27 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './CLUSTER_LINKS';
describe('CLUSTER LINKS', () => {
testUtils.isVersionGreaterThanHook([7, 0]);
it('transformArguments', () => {
assert.deepEqual(
transformArguments(),
['CLUSTER', 'LINKS']
);
});
testUtils.testWithCluster('clusterNode.clusterLinks', async cluster => {
const links = await cluster.getSlotMaster(0).client.clusterLinks();
assert.ok(Array.isArray(links));
for (const link of links) {
assert.equal(typeof link.direction, 'string');
assert.equal(typeof link.node, 'string');
assert.equal(typeof link.createTime, 'number');
assert.equal(typeof link.events, 'string');
assert.equal(typeof link.sendBufferAllocated, 'number');
assert.equal(typeof link.sendBufferUsed, 'number');
}
}, GLOBAL.CLUSTERS.OPEN);
});

View File

@@ -0,0 +1,38 @@
export function transformArguments(): Array<string> {
return ['CLUSTER', 'LINKS'];
}
type ClusterLinksRawReply = Array<[
'direction',
string,
'node',
string,
'createTime',
number,
'events',
string,
'send-buffer-allocated',
number,
'send-buffer-used',
number
]>;
type ClusterLinksReply = Array<{
direction: string;
node: string;
createTime: number;
events: string;
sendBufferAllocated: number;
sendBufferUsed: number;
}>;
export function transformReply(reply: ClusterLinksRawReply): ClusterLinksReply {
return reply.map(peerLink => ({
direction: peerLink[1],
node: peerLink[3],
createTime: Number(peerLink[5]),
events: peerLink[7],
sendBufferAllocated: Number(peerLink[9]),
sendBufferUsed: Number(peerLink[11])
}));
}

View File

@@ -2,4 +2,4 @@ export function transformArguments(ip: string, port: number): Array<string> {
return ['CLUSTER', 'MEET', ip, port.toString()];
}
export declare function transformReply(): string;
export declare function transformReply(): 'OK';

View File

@@ -0,0 +1,19 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './CLUSTER_MYID';
describe('CLUSTER MYID', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments(),
['CLUSTER', 'MYID']
);
});
testUtils.testWithCluster('clusterNode.clusterMyId', async cluster => {
assert.equal(
typeof await cluster.getSlotMaster(0).client.clusterMyId(),
'string'
);
}, GLOBAL.CLUSTERS.OPEN);
});

View File

@@ -0,0 +1,5 @@
export function transformArguments(): Array<string> {
return ['CLUSTER', 'MYID'];
}
export declare function transformReply(): string;

View File

@@ -0,0 +1,11 @@
import { strict as assert } from 'assert';
import { transformArguments } from './CLUSTER_REPLICAS';
describe('CLUSTER REPLICAS', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments('0'),
['CLUSTER', 'REPLICAS', '0']
);
});
});

View File

@@ -0,0 +1,5 @@
export function transformArguments(nodeId: string): Array<string> {
return ['CLUSTER', 'REPLICAS', nodeId];
}
export { transformReply } from './CLUSTER_NODES';

View File

@@ -0,0 +1,11 @@
import { strict as assert } from 'assert';
import { transformArguments } from './CLUSTER_REPLICATE';
describe('CLUSTER REPLICATE', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments('0'),
['CLUSTER', 'REPLICATE', '0']
);
});
});

View File

@@ -0,0 +1,5 @@
export function transformArguments(nodeId: string): Array<string> {
return ['CLUSTER', 'REPLICATE', nodeId];
}
export declare function transformReply(): 'OK';

View File

@@ -10,18 +10,11 @@ describe('CLUSTER RESET', () => {
);
});
it('HARD', () => {
it('with mode', () => {
assert.deepEqual(
transformArguments('HARD'),
['CLUSTER', 'RESET', 'HARD']
);
});
it('SOFT', () => {
assert.deepEqual(
transformArguments('SOFT'),
['CLUSTER', 'RESET', 'SOFT']
);
});
});
});

View File

@@ -1,6 +1,4 @@
export type ClusterResetModes = 'HARD' | 'SOFT';
export function transformArguments(mode?: ClusterResetModes): Array<string> {
export function transformArguments(mode?: 'HARD' | 'SOFT'): Array<string> {
const args = ['CLUSTER', 'RESET'];
if (mode) {

View File

@@ -0,0 +1,19 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './CLUSTER_SAVECONFIG';
describe('CLUSTER SAVECONFIG', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments(),
['CLUSTER', 'SAVECONFIG']
);
});
testUtils.testWithCluster('clusterNode.clusterSaveConfig', async cluster => {
assert.equal(
await cluster.getSlotMaster(0).client.clusterSaveConfig(),
'OK'
);
}, GLOBAL.CLUSTERS.OPEN);
});

View File

@@ -0,0 +1,5 @@
export function transformArguments(): Array<string> {
return ['CLUSTER', 'SAVECONFIG'];
}
export declare function transformReply(): 'OK';

View File

@@ -0,0 +1,11 @@
import { strict as assert } from 'assert';
import { transformArguments } from './CLUSTER_SET-CONFIG-EPOCH';
describe('CLUSTER SET-CONFIG-EPOCH', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments(0),
['CLUSTER', 'SET-CONFIG-EPOCH', '0']
);
});
});

View File

@@ -0,0 +1,5 @@
export function transformArguments(configEpoch: number): Array<string> {
return ['CLUSTER', 'SET-CONFIG-EPOCH', configEpoch.toString()];
}
export declare function transformReply(): 'OK';

View File

@@ -5,7 +5,11 @@ export enum ClusterSlotStates {
NODE = 'NODE'
}
export function transformArguments(slot: number, state: ClusterSlotStates, nodeId?: string): Array<string> {
export function transformArguments(
slot: number,
state: ClusterSlotStates,
nodeId?: string
): Array<string> {
const args = ['CLUSTER', 'SETSLOT', slot.toString(), state];
if (nodeId) {
@@ -15,4 +19,4 @@ export function transformArguments(slot: number, state: ClusterSlotStates, nodeI
return args;
}
export declare function transformReply(): string;
export declare function transformReply(): 'OK';

View File

@@ -6,7 +6,12 @@ export function transformArguments(): RedisCommandArguments {
type ClusterSlotsRawNode = [ip: string, port: number, id: string];
type ClusterSlotsRawReply = Array<[from: number, to: number, master: ClusterSlotsRawNode, ...replicas: Array<ClusterSlotsRawNode>]>;
type ClusterSlotsRawReply = Array<[
from: number,
to: number,
master: ClusterSlotsRawNode,
...replicas: Array<ClusterSlotsRawNode>
]>;
type ClusterSlotsNode = {
ip: string;

View File

@@ -0,0 +1,24 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './COMMAND_GETKEYSANDFLAGS';
describe('COMMAND GETKEYSANDFLAGS', () => {
testUtils.isVersionGreaterThanHook([7, 0]);
it('transformArguments', () => {
assert.deepEqual(
transformArguments(['GET', 'key']),
['COMMAND', 'GETKEYSANDFLAGS', 'GET', 'key']
);
});
testUtils.testWithClient('client.commandGetKeysAndFlags', async client => {
assert.deepEqual(
await client.commandGetKeysAndFlags(['GET', 'key']),
[{
key: 'key',
flags: ['RO', 'access']
}]
);
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -0,0 +1,24 @@
import { RedisCommandArgument, RedisCommandArguments } from '.';
export const IS_READ_ONLY = true;
export function transformArguments(args: Array<RedisCommandArgument>): RedisCommandArguments {
return ['COMMAND', 'GETKEYSANDFLAGS', ...args];
}
type KeysAndFlagsRawReply = Array<[
RedisCommandArgument,
RedisCommandArguments
]>;
type KeysAndFlagsReply = Array<{
key: RedisCommandArgument;
flags: RedisCommandArguments;
}>;
export function transformReply(reply: KeysAndFlagsRawReply): KeysAndFlagsReply {
return reply.map(([key, flags]) => ({
key,
flags
}));
}

View File

@@ -9,7 +9,11 @@ export function assertPingCommand(commandInfo: CommandReply | null | undefined):
{
name: 'ping',
arity: -1,
flags: new Set([CommandFlags.STALE, CommandFlags.FAST]),
flags: new Set(
testUtils.isVersionGreaterThan([7]) ?
[CommandFlags.FAST] :
[CommandFlags.STALE, CommandFlags.FAST]
),
firstKeyIndex: 0,
lastKeyIndex: 0,
step: 0,

View File

@@ -2,10 +2,23 @@ import { strict as assert } from 'assert';
import { transformArguments } from './CONFIG_SET';
describe('CONFIG SET', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments('parameter', 'value'),
['CONFIG', 'SET', 'parameter', 'value']
);
describe('transformArguments', () => {
it('set one parameter (old version)', () => {
assert.deepEqual(
transformArguments('parameter', 'value'),
['CONFIG', 'SET', 'parameter', 'value']
);
});
it('set muiltiple parameters', () => {
assert.deepEqual(
transformArguments({
1: 'a',
2: 'b',
3: 'c'
}),
['CONFIG', 'SET', '1', 'a', '2', 'b', '3', 'c']
);
});
});
});

View File

@@ -1,5 +1,23 @@
export function transformArguments(parameter: string, value: string): Array<string> {
return ['CONFIG', 'SET', parameter, value];
import { RedisCommandArgument, RedisCommandArguments } from '.';
type SingleParameter = [parameter: RedisCommandArgument, value: RedisCommandArgument];
type MultipleParameters = [config: Record<string, RedisCommandArgument>];
export function transformArguments(
...[parameterOrConfig, value]: SingleParameter | MultipleParameters
): RedisCommandArguments {
const args: RedisCommandArguments = ['CONFIG', 'SET'];
if (typeof parameterOrConfig === 'string') {
args.push(parameterOrConfig, value!);
} else {
for (const [key, value] of Object.entries(parameterOrConfig)) {
args.push(key, value);
}
}
return args;
}
export declare function transformReply(): string;

View File

@@ -3,11 +3,20 @@ import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './EXPIRE';
describe('EXPIRE', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments('key', 1),
['EXPIRE', 'key', '1']
);
describe('transformArguments', () => {
it('simple', () => {
assert.deepEqual(
transformArguments('key', 1),
['EXPIRE', 'key', '1']
);
});
it('with set option', () => {
assert.deepEqual(
transformArguments('key', 1, 'NX'),
['EXPIRE', 'key', '1', 'NX']
);
});
});
testUtils.testWithClient('client.expire', async client => {

View File

@@ -4,9 +4,16 @@ export const FIRST_KEY_INDEX = 1;
export function transformArguments(
key: RedisCommandArgument,
seconds: number
seconds: number,
mode?: 'NX' | 'XX' | 'GT' | 'LT'
): RedisCommandArguments {
return ['EXPIRE', key, seconds.toString()];
const args = ['EXPIRE', key, seconds.toString()];
if (mode) {
args.push(mode);
}
return args;
}
export { transformBooleanReply as transformReply } from './generic-transformers';

View File

@@ -18,6 +18,13 @@ describe('EXPIREAT', () => {
['EXPIREAT', 'key', Math.floor(d.getTime() / 1000).toString()]
);
});
it('with set option', () => {
assert.deepEqual(
transformArguments('key', 1, 'GT'),
['EXPIREAT', 'key', '1', 'GT']
);
});
});
testUtils.testWithClient('client.expireAt', async client => {

View File

@@ -5,13 +5,20 @@ export const FIRST_KEY_INDEX = 1;
export function transformArguments(
key: RedisCommandArgument,
timestamp: number | Date
timestamp: number | Date,
mode?: 'NX' | 'XX' | 'GT' | 'LT'
): RedisCommandArguments {
return [
const args = [
'EXPIREAT',
key,
transformEXAT(timestamp)
];
if (mode) {
args.push(mode);
}
return args;
}
export { transformBooleanReply as transformReply } from './generic-transformers';

View File

@@ -0,0 +1,21 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './EXPIRETIME';
describe('EXPIRETIME', () => {
testUtils.isVersionGreaterThanHook([7, 0]);
it('transformArguments', () => {
assert.deepEqual(
transformArguments('key'),
['EXPIRETIME', 'key']
);
});
testUtils.testWithClient('client.expireTime', async client => {
assert.equal(
await client.expireTime('key'),
-2
);
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -0,0 +1,9 @@
import { RedisCommandArgument, RedisCommandArguments } from '.';
export const FIRST_KEY_INDEX = 1;
export function transformArguments(key: RedisCommandArgument): RedisCommandArguments {
return ['EXPIRETIME', key];
}
export declare function transformReply(): number;

View File

@@ -0,0 +1,19 @@
import {strict as assert} from 'assert';
import testUtils, {GLOBAL} from '../test-utils';
import { transformArguments } from './LATENCY_DOCTOR';
describe('LATENCY DOCTOR', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments(),
['LATENCY', 'DOCTOR']
);
});
testUtils.testWithClient('client.latencyDoctor', async client => {
assert.equal(
typeof (await client.latencyDoctor()),
'string'
);
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -0,0 +1,5 @@
export function transformArguments(): Array<string> {
return ['LATENCY', 'DOCTOR'];
}
export declare function transformReply(): string;

View File

@@ -0,0 +1,19 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './OBJECT_ENCODING';
describe('OBJECT ENCODING', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments('key'),
['OBJECT', 'ENCODING', 'key']
);
});
testUtils.testWithClient('client.objectEncoding', async client => {
assert.equal(
await client.objectEncoding('key'),
null
);
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -0,0 +1,11 @@
import { RedisCommandArgument, RedisCommandArguments } from '.';
export const FIRST_KEY_INDEX = 2;
export const IS_READ_ONLY = true;
export function transformArguments(key: RedisCommandArgument): RedisCommandArguments {
return ['OBJECT', 'ENCODING', key];
}
export declare function transformReply(): string | null;

View File

@@ -0,0 +1,19 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './OBJECT_FREQ';
describe('OBJECT FREQ', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments('key'),
['OBJECT', 'FREQ', 'key']
);
});
testUtils.testWithClient('client.objectFreq', async client => {
assert.equal(
await client.objectFreq('key'),
null
);
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -0,0 +1,11 @@
import { RedisCommandArgument, RedisCommandArguments } from '.';
export const FIRST_KEY_INDEX = 2;
export const IS_READ_ONLY = true;
export function transformArguments(key: RedisCommandArgument): RedisCommandArguments {
return ['OBJECT', 'FREQ', key];
}
export declare function transformReply(): number | null;

View File

@@ -0,0 +1,19 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './OBJECT_IDLETIME';
describe('OBJECT IDLETIME', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments('key'),
['OBJECT', 'IDLETIME', 'key']
);
});
testUtils.testWithClient('client.objectIdleTime', async client => {
assert.equal(
await client.objectIdleTime('key'),
null
);
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -0,0 +1,11 @@
import { RedisCommandArgument, RedisCommandArguments } from '.';
export const FIRST_KEY_INDEX = 2;
export const IS_READ_ONLY = true;
export function transformArguments(key: RedisCommandArgument): RedisCommandArguments {
return ['OBJECT', 'IDLETIME', key];
}
export declare function transformReply(): number | null;

View File

@@ -0,0 +1,19 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './OBJECT_REFCOUNT';
describe('OBJECT REFCOUNT', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments('key'),
['OBJECT', 'REFCOUNT', 'key']
);
});
testUtils.testWithClient('client.objectRefCount', async client => {
assert.equal(
await client.objectRefCount('key'),
null
);
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -0,0 +1,11 @@
import { RedisCommandArgument, RedisCommandArguments } from '.';
export const FIRST_KEY_INDEX = 2;
export const IS_READ_ONLY = true;
export function transformArguments(key: RedisCommandArgument): RedisCommandArguments {
return ['OBJECT', 'REFCOUNT', key];
}
export declare function transformReply(): number | null;

View File

@@ -3,11 +3,20 @@ import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './PEXPIRE';
describe('PEXPIRE', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments('key', 1),
['PEXPIRE', 'key', '1']
);
describe('transformArguments', () => {
it('simple', () => {
assert.deepEqual(
transformArguments('key', 1),
['PEXPIRE', 'key', '1']
);
});
it('with set option', () => {
assert.deepEqual(
transformArguments('key', 1, 'GT'),
['PEXPIRE', 'key', '1', 'GT']
);
});
});
testUtils.testWithClient('client.pExpire', async client => {

View File

@@ -4,9 +4,16 @@ export const FIRST_KEY_INDEX = 1;
export function transformArguments(
key: RedisCommandArgument,
milliseconds: number
milliseconds: number,
mode?: 'NX' | 'XX' | 'GT' | 'LT'
): RedisCommandArguments {
return ['PEXPIRE', key, milliseconds.toString()];
const args = ['PEXPIRE', key, milliseconds.toString()];
if (mode) {
args.push(mode);
}
return args;
}
export { transformBooleanReply as transformReply } from './generic-transformers';

View File

@@ -18,6 +18,13 @@ describe('PEXPIREAT', () => {
['PEXPIREAT', 'key', d.getTime().toString()]
);
});
it('with set option', () => {
assert.deepEqual(
transformArguments('key', 1, 'XX'),
['PEXPIREAT', 'key', '1', 'XX']
);
});
});
testUtils.testWithClient('client.pExpireAt', async client => {

View File

@@ -5,13 +5,20 @@ export const FIRST_KEY_INDEX = 1;
export function transformArguments(
key: RedisCommandArgument,
millisecondsTimestamp: number | Date
millisecondsTimestamp: number | Date,
mode?: 'NX' | 'XX' | 'GT' | 'LT'
): RedisCommandArguments {
return [
const args = [
'PEXPIREAT',
key,
transformPXAT(millisecondsTimestamp)
];
if (mode) {
args.push(mode);
}
return args;
}
export { transformBooleanReply as transformReply } from './generic-transformers';

View File

@@ -0,0 +1,21 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './PEXPIRETIME';
describe('PEXPIRETIME', () => {
testUtils.isVersionGreaterThanHook([7, 0]);
it('transformArguments', () => {
assert.deepEqual(
transformArguments('key'),
['PEXPIRETIME', 'key']
);
});
testUtils.testWithClient('client.pExpireTime', async client => {
assert.equal(
await client.pExpireTime('key'),
-2
);
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -0,0 +1,9 @@
import { RedisCommandArgument, RedisCommandArguments } from '.';
export const FIRST_KEY_INDEX = 1;
export function transformArguments(key: RedisCommandArgument): RedisCommandArguments {
return ['PEXPIRETIME', key];
}
export declare function transformReply(): number;

View File

@@ -0,0 +1,30 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './SINTERCARD';
describe('SINTERCARD', () => {
testUtils.isVersionGreaterThanHook([7, 0]);
describe('transformArguments', () => {
it('simple', () => {
assert.deepEqual(
transformArguments(['1', '2']),
['SINTERCARD', '2', '1', '2']
);
});
it('with limit', () => {
assert.deepEqual(
transformArguments(['1', '2'], 1),
['SINTERCARD', '2', '1', '2', 'LIMIT', '1']
);
});
});
testUtils.testWithClient('client.sInterCard', async client => {
assert.deepEqual(
await client.sInterCard('key'),
0
);
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -0,0 +1,21 @@
import { RedisCommandArgument, RedisCommandArguments } from '.';
import { pushVerdictArgument } from './generic-transformers';
export const FIRST_KEY_INDEX = 2;
export const IS_READ_ONLY = true;
export function transformArguments(
keys: Array<RedisCommandArgument> | RedisCommandArgument,
limit?: number
): RedisCommandArguments {
const args = pushVerdictArgument(['SINTERCARD'], keys);
if (limit) {
args.push('LIMIT', limit.toString());
}
return args;
}
export declare function transformReply(): number;

View File

@@ -70,16 +70,7 @@ describe('SORT', () => {
);
});
it('with STORE', () => {
assert.deepEqual(
transformArguments('key', {
STORE: 'destination'
}),
['SORT', 'key', 'STORE', 'destination']
);
});
it('with BY, LIMIT, GET, DIRECTION, ALPHA, STORE', () => {
it('with BY, LIMIT, GET, DIRECTION, ALPHA', () => {
assert.deepEqual(
transformArguments('key', {
BY: 'pattern',
@@ -89,10 +80,9 @@ describe('SORT', () => {
},
GET: 'pattern',
DIRECTION: 'ASC',
ALPHA: true,
STORE: 'destination'
ALPHA: true
}),
['SORT', 'key', 'BY', 'pattern', 'LIMIT', '0', '1', 'GET', 'pattern', 'ASC', 'ALPHA', 'STORE', 'destination']
['SORT', 'key', 'BY', 'pattern', 'LIMIT', '0', '1', 'GET', 'pattern', 'ASC', 'ALPHA']
);
});
});

View File

@@ -1,56 +1,13 @@
import { RedisCommandArguments } from '.';
import { pushSortArguments, SortOptions } from './generic-transformers';
export const FIRST_KEY_INDEX = 1;
export const IS_READ_ONLY = true;
interface SortOptions {
BY?: string;
LIMIT?: {
offset: number;
count: number;
},
GET?: string | Array<string>;
DIRECTION?: 'ASC' | 'DESC';
ALPHA?: true;
STORE?: string;
export function transformArguments(
key: string,
options?: SortOptions
): RedisCommandArguments {
return pushSortArguments(['SORT', key], options);
}
export function transformArguments(key: string, options?: SortOptions): Array<string> {
const args = ['SORT', key];
if (options?.BY) {
args.push('BY', options.BY);
}
if (options?.LIMIT) {
args.push(
'LIMIT',
options.LIMIT.offset.toString(),
options.LIMIT.count.toString()
);
}
if (options?.GET) {
for (const pattern of (typeof options.GET === 'string' ? [options.GET] : options.GET)) {
args.push('GET', pattern);
}
}
if (options?.DIRECTION) {
args.push(options.DIRECTION);
}
if (options?.ALPHA) {
args.push('ALPHA');
}
if (options?.STORE) {
args.push('STORE', options.STORE);
}
return args;
}
// integer when using `STORE`
export function transformReply(reply: Array<string> | number): Array<string> | number {
return reply;
}
export declare function transformReply(): Array<string>;

View File

@@ -0,0 +1,98 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './SORT_RO';
describe('SORT_RO', () => {
testUtils.isVersionGreaterThanHook([7, 0]);
describe('transformArguments', () => {
it('simple', () => {
assert.deepEqual(
transformArguments('key'),
['SORT_RO', 'key']
);
});
it('with BY', () => {
assert.deepEqual(
transformArguments('key', {
BY: 'pattern'
}),
['SORT_RO', 'key', 'BY', 'pattern']
);
});
it('with LIMIT', () => {
assert.deepEqual(
transformArguments('key', {
LIMIT: {
offset: 0,
count: 1
}
}),
['SORT_RO', 'key', 'LIMIT', '0', '1']
);
});
describe('with GET', () => {
it('string', () => {
assert.deepEqual(
transformArguments('key', {
GET: 'pattern'
}),
['SORT_RO', 'key', 'GET', 'pattern']
);
});
it('array', () => {
assert.deepEqual(
transformArguments('key', {
GET: ['1', '2']
}),
['SORT_RO', 'key', 'GET', '1', 'GET', '2']
);
});
});
it('with DIRECTION', () => {
assert.deepEqual(
transformArguments('key', {
DIRECTION: 'ASC'
}),
['SORT_RO', 'key', 'ASC']
);
});
it('with ALPHA', () => {
assert.deepEqual(
transformArguments('key', {
ALPHA: true
}),
['SORT_RO', 'key', 'ALPHA']
);
});
it('with BY, LIMIT, GET, DIRECTION, ALPHA', () => {
assert.deepEqual(
transformArguments('key', {
BY: 'pattern',
LIMIT: {
offset: 0,
count: 1
},
GET: 'pattern',
DIRECTION: 'ASC',
ALPHA: true,
}),
['SORT_RO', 'key', 'BY', 'pattern', 'LIMIT', '0', '1', 'GET', 'pattern', 'ASC', 'ALPHA']
);
});
});
testUtils.testWithClient('client.sortRo', async client => {
assert.deepEqual(
await client.sortRo('key'),
[]
);
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -0,0 +1,15 @@
import { RedisCommandArguments } from '.';
import { pushSortArguments, SortOptions } from "./generic-transformers";
export const FIRST_KEY_INDEX = 1;
export const IS_READ_ONLY = true;
export function transformArguments(
key: string,
options?: SortOptions
): RedisCommandArguments {
return pushSortArguments(['SORT_RO', key], options);
}
export declare function transformReply(): Array<string>;

View File

@@ -0,0 +1,96 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './SORT_STORE';
describe('SORT STORE', () => {
describe('transformArguments', () => {
it('simple', () => {
assert.deepEqual(
transformArguments('source', 'destination'),
['SORT', 'source', 'STORE', 'destination']
);
});
it('with BY', () => {
assert.deepEqual(
transformArguments('source', 'destination', {
BY: 'pattern'
}),
['SORT', 'source', 'BY', 'pattern', 'STORE', 'destination']
);
});
it('with LIMIT', () => {
assert.deepEqual(
transformArguments('source', 'destination', {
LIMIT: {
offset: 0,
count: 1
}
}),
['SORT', 'source', 'LIMIT', '0', '1', 'STORE', 'destination']
);
});
describe('with GET', () => {
it('string', () => {
assert.deepEqual(
transformArguments('source', 'destination', {
GET: 'pattern'
}),
['SORT', 'source', 'GET', 'pattern', 'STORE', 'destination']
);
});
it('array', () => {
assert.deepEqual(
transformArguments('source', 'destination', {
GET: ['1', '2']
}),
['SORT', 'source', 'GET', '1', 'GET', '2', 'STORE', 'destination']
);
});
});
it('with DIRECTION', () => {
assert.deepEqual(
transformArguments('source', 'destination', {
DIRECTION: 'ASC'
}),
['SORT', 'source', 'ASC', 'STORE', 'destination']
);
});
it('with ALPHA', () => {
assert.deepEqual(
transformArguments('source', 'destination', {
ALPHA: true
}),
['SORT', 'source', 'ALPHA', 'STORE', 'destination']
);
});
it('with BY, LIMIT, GET, DIRECTION, ALPHA', () => {
assert.deepEqual(
transformArguments('source', 'destination', {
BY: 'pattern',
LIMIT: {
offset: 0,
count: 1
},
GET: 'pattern',
DIRECTION: 'ASC',
ALPHA: true
}),
['SORT', 'source', 'BY', 'pattern', 'LIMIT', '0', '1', 'GET', 'pattern', 'ASC', 'ALPHA', 'STORE', 'destination']
);
});
});
testUtils.testWithClient('client.sortStore', async client => {
assert.equal(
await client.sortStore('source', 'destination'),
0
);
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -0,0 +1,17 @@
import { RedisCommandArguments } from '.';
import { SortOptions } from './generic-transformers';
import { transformArguments as transformSortArguments } from './SORT';
export const FIRST_KEY_INDEX = 1;
export function transformArguments(
source: string,
destination: string,
options?: SortOptions
): RedisCommandArguments {
const args = transformSortArguments(source, options);
args.push('STORE', destination);
return args;
}
export declare function transformReply(): number;

View File

@@ -0,0 +1,30 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './ZINTERCARD';
describe('ZINTERCARD', () => {
testUtils.isVersionGreaterThanHook([7, 0]);
describe('transformArguments', () => {
it('simple', () => {
assert.deepEqual(
transformArguments(['1', '2']),
['ZINTERCARD', '2', '1', '2']
);
});
it('with limit', () => {
assert.deepEqual(
transformArguments(['1', '2'], 1),
['ZINTERCARD', '2', '1', '2', 'LIMIT', '1']
);
});
});
testUtils.testWithClient('client.zInterCard', async client => {
assert.deepEqual(
await client.zInterCard('key'),
0
);
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -0,0 +1,21 @@
import { RedisCommandArgument, RedisCommandArguments } from '.';
import { pushVerdictArgument } from './generic-transformers';
export const FIRST_KEY_INDEX = 2;
export const IS_READ_ONLY = true;
export function transformArguments(
keys: Array<RedisCommandArgument> | RedisCommandArgument,
limit?: number
): RedisCommandArguments {
const args = pushVerdictArgument(['ZINTERCARD'], keys);
if (limit) {
args.push('LIMIT', limit.toString());
}
return args;
}
export declare function transformReply(): number;

View File

@@ -19,11 +19,13 @@ import {
transformPXAT,
pushEvalArguments,
pushVerdictArguments,
pushVerdictNumberArguments,
pushVerdictArgument,
pushOptionalVerdictArgument,
transformCommandReply,
CommandFlags,
CommandCategories
CommandCategories,
pushSlotRangesArguments
} from './generic-transformers';
describe('Generic Transformers', () => {
@@ -578,6 +580,22 @@ describe('Generic Transformers', () => {
});
});
describe('pushVerdictNumberArguments', () => {
it('number', () => {
assert.deepEqual(
pushVerdictNumberArguments([], 0),
['0']
);
});
it('array', () => {
assert.deepEqual(
pushVerdictNumberArguments([], [0, 1]),
['0', '1']
);
});
});
describe('pushVerdictArgument', () => {
it('string', () => {
assert.deepEqual(
@@ -639,4 +657,29 @@ describe('Generic Transformers', () => {
}
);
});
describe('pushSlotRangesArguments', () => {
it('single range', () => {
assert.deepEqual(
pushSlotRangesArguments([], {
start: 0,
end: 1
}),
['0', '1']
);
});
it('multiple ranges', () => {
assert.deepEqual(
pushSlotRangesArguments([], [{
start: 0,
end: 1
}, {
start: 2,
end: 3
}]),
['0', '1', '2', '3']
);
});
});
});

View File

@@ -322,6 +322,21 @@ export function pushVerdictArguments(args: RedisCommandArguments, value: RedisCo
return args;
}
export function pushVerdictNumberArguments(
args: RedisCommandArguments,
value: number | Array<number>
): RedisCommandArguments {
if (Array.isArray(value)) {
for (const item of value) {
args.push(item.toString());
}
} else {
args.push(value.toString());
}
return args;
}
export function pushVerdictArgument(
args: RedisCommandArguments,
value: RedisCommandArgument | Array<RedisCommandArgument>
@@ -422,3 +437,77 @@ export function transformCommandReply(
categories: new Set(categories)
};
}
export interface SortOptions {
BY?: string;
LIMIT?: {
offset: number;
count: number;
},
GET?: string | Array<string>;
DIRECTION?: 'ASC' | 'DESC';
ALPHA?: true;
}
export function pushSortArguments(
args: RedisCommandArguments,
options?: SortOptions
): RedisCommandArguments {
if (options?.BY) {
args.push('BY', options.BY);
}
if (options?.LIMIT) {
args.push(
'LIMIT',
options.LIMIT.offset.toString(),
options.LIMIT.count.toString()
);
}
if (options?.GET) {
for (const pattern of (typeof options.GET === 'string' ? [options.GET] : options.GET)) {
args.push('GET', pattern);
}
}
if (options?.DIRECTION) {
args.push(options.DIRECTION);
}
if (options?.ALPHA) {
args.push('ALPHA');
}
return args;
}
export interface SlotRange {
start: number;
end: number;
}
function pushSlotRangeArguments(
args: RedisCommandArguments,
range: SlotRange
): void {
args.push(
range.start.toString(),
range.end.toString()
);
}
export function pushSlotRangesArguments(
args: RedisCommandArguments,
ranges: SlotRange | Array<SlotRange>
): RedisCommandArguments {
if (Array.isArray(ranges)) {
for (const range of ranges) {
pushSlotRangeArguments(args, range);
}
} else {
pushSlotRangeArguments(args, ranges);
}
return args;
}