You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-06 02:15:48 +03:00
V5 bringing RESP3, Sentinel and TypeMapping to node-redis
RESP3 Support - Some commands responses in RESP3 aren't stable yet and therefore return an "untyped" ReplyUnion. Sentinel TypeMapping Correctly types Multi commands Note: some API changes to be further documented in v4-to-v5.md
This commit is contained in:
@@ -1,23 +1,31 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import testUtils from '../test-utils';
|
||||
import { transformArguments } from './ACL_CAT';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import ACL_CAT from './ACL_CAT';
|
||||
|
||||
describe('ACL CAT', () => {
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
|
||||
describe('transformArguments', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(),
|
||||
['ACL', 'CAT']
|
||||
);
|
||||
});
|
||||
|
||||
it('with categoryName', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('dangerous'),
|
||||
['ACL', 'CAT', 'dangerous']
|
||||
);
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
ACL_CAT.transformArguments(),
|
||||
['ACL', 'CAT']
|
||||
);
|
||||
});
|
||||
|
||||
it('with categoryName', () => {
|
||||
assert.deepEqual(
|
||||
ACL_CAT.transformArguments('dangerous'),
|
||||
['ACL', 'CAT', 'dangerous']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.aclCat', async client => {
|
||||
const categories = await client.aclCat();
|
||||
assert.ok(Array.isArray(categories));
|
||||
for (const category of categories) {
|
||||
assert.equal(typeof category, 'string');
|
||||
}
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
||||
|
@@ -1,13 +1,16 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types';
|
||||
|
||||
export function transformArguments(categoryName?: RedisCommandArgument): RedisCommandArguments {
|
||||
const args: RedisCommandArguments = ['ACL', 'CAT'];
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments(categoryName?: RedisArgument) {
|
||||
const args: Array<RedisArgument> = ['ACL', 'CAT'];
|
||||
|
||||
if (categoryName) {
|
||||
args.push(categoryName);
|
||||
args.push(categoryName);
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
export declare function transformReply(): Array<RedisCommandArgument>;
|
||||
},
|
||||
transformReply: undefined as unknown as () => ArrayReply<BlobStringReply>
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,30 +1,30 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments } from './ACL_DELUSER';
|
||||
import ACL_DELUSER from './ACL_DELUSER';
|
||||
|
||||
describe('ACL DELUSER', () => {
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
|
||||
describe('transformArguments', () => {
|
||||
it('string', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('username'),
|
||||
['ACL', 'DELUSER', 'username']
|
||||
);
|
||||
});
|
||||
|
||||
it('array', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(['1', '2']),
|
||||
['ACL', 'DELUSER', '1', '2']
|
||||
);
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
it('string', () => {
|
||||
assert.deepEqual(
|
||||
ACL_DELUSER.transformArguments('username'),
|
||||
['ACL', 'DELUSER', 'username']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.aclDelUser', async client => {
|
||||
assert.equal(
|
||||
await client.aclDelUser('dosenotexists'),
|
||||
0
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
it('array', () => {
|
||||
assert.deepEqual(
|
||||
ACL_DELUSER.transformArguments(['1', '2']),
|
||||
['ACL', 'DELUSER', '1', '2']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.aclDelUser', async client => {
|
||||
assert.equal(
|
||||
typeof await client.aclDelUser('user'),
|
||||
'number'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
||||
|
@@ -1,10 +1,11 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { pushVerdictArguments } from './generic-transformers';
|
||||
import { NumberReply, Command } from '../RESP/types';
|
||||
import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers';
|
||||
|
||||
export function transformArguments(
|
||||
username: RedisCommandArgument | Array<RedisCommandArgument>
|
||||
): RedisCommandArguments {
|
||||
return pushVerdictArguments(['ACL', 'DELUSER'], username);
|
||||
}
|
||||
|
||||
export declare function transformReply(): number;
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments(username: RedisVariadicArgument) {
|
||||
return pushVariadicArguments(['ACL', 'DELUSER'], username);
|
||||
},
|
||||
transformReply: undefined as unknown as () => NumberReply
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,21 +1,21 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments } from './ACL_DRYRUN';
|
||||
import ACL_DRYRUN from './ACL_DRYRUN';
|
||||
|
||||
describe('ACL DRYRUN', () => {
|
||||
testUtils.isVersionGreaterThanHook([7]);
|
||||
testUtils.isVersionGreaterThanHook([7]);
|
||||
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('default', ['GET', 'key']),
|
||||
['ACL', 'DRYRUN', 'default', 'GET', 'key']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
ACL_DRYRUN.transformArguments('default', ['GET', 'key']),
|
||||
['ACL', 'DRYRUN', 'default', 'GET', 'key']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.aclDryRun', async client => {
|
||||
assert.equal(
|
||||
await client.aclDryRun('default', ['GET', 'key']),
|
||||
'OK'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
testUtils.testWithClient('client.aclDryRun', async client => {
|
||||
assert.equal(
|
||||
await client.aclDryRun('default', ['GET', 'key']),
|
||||
'OK'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
||||
|
@@ -1,18 +1,16 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { RedisArgument, SimpleStringReply, BlobStringReply, Command } from '../RESP/types';
|
||||
|
||||
export const IS_READ_ONLY = true;
|
||||
|
||||
export function transformArguments(
|
||||
username: RedisCommandArgument,
|
||||
command: Array<RedisCommandArgument>
|
||||
): RedisCommandArguments {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments(username: RedisArgument, command: Array<RedisArgument>) {
|
||||
return [
|
||||
'ACL',
|
||||
'DRYRUN',
|
||||
username,
|
||||
...command
|
||||
'ACL',
|
||||
'DRYRUN',
|
||||
username,
|
||||
...command
|
||||
];
|
||||
}
|
||||
|
||||
export declare function transformReply(): RedisCommandArgument;
|
||||
},
|
||||
transformReply: undefined as unknown as () => SimpleStringReply<'OK'> | BlobStringReply
|
||||
} as const satisfies Command;
|
||||
|
||||
|
@@ -1,23 +1,30 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import testUtils from '../test-utils';
|
||||
import { transformArguments } from './ACL_GENPASS';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import ACL_GENPASS from './ACL_GENPASS';
|
||||
|
||||
describe('ACL GENPASS', () => {
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
|
||||
describe('transformArguments', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(),
|
||||
['ACL', 'GENPASS']
|
||||
);
|
||||
});
|
||||
|
||||
it('with bits', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(128),
|
||||
['ACL', 'GENPASS', '128']
|
||||
);
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
ACL_GENPASS.transformArguments(),
|
||||
['ACL', 'GENPASS']
|
||||
);
|
||||
});
|
||||
|
||||
it('with bits', () => {
|
||||
assert.deepEqual(
|
||||
ACL_GENPASS.transformArguments(128),
|
||||
['ACL', 'GENPASS', '128']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.aclGenPass', async client => {
|
||||
assert.equal(
|
||||
typeof await client.aclGenPass(),
|
||||
'string'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
||||
|
@@ -1,13 +1,17 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { BlobStringReply, Command } from '../RESP/types';
|
||||
|
||||
export function transformArguments(bits?: number): RedisCommandArguments {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments(bits?: number) {
|
||||
const args = ['ACL', 'GENPASS'];
|
||||
|
||||
if (bits) {
|
||||
args.push(bits.toString());
|
||||
args.push(bits.toString());
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
},
|
||||
transformReply: undefined as unknown as () => BlobStringReply
|
||||
} as const satisfies Command;
|
||||
|
||||
export declare function transformReply(): RedisCommandArgument;
|
||||
|
@@ -1,34 +1,34 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments } from './ACL_GETUSER';
|
||||
import ACL_GETUSER from './ACL_GETUSER';
|
||||
|
||||
describe('ACL GETUSER', () => {
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('username'),
|
||||
['ACL', 'GETUSER', 'username']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
ACL_GETUSER.transformArguments('username'),
|
||||
['ACL', 'GETUSER', 'username']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.aclGetUser', async client => {
|
||||
const reply = await client.aclGetUser('default');
|
||||
testUtils.testWithClient('client.aclGetUser', async client => {
|
||||
const reply = await client.aclGetUser('default');
|
||||
|
||||
assert.ok(Array.isArray(reply.passwords));
|
||||
assert.equal(typeof reply.commands, 'string');
|
||||
assert.ok(Array.isArray(reply.flags));
|
||||
assert.ok(Array.isArray(reply.passwords));
|
||||
assert.equal(typeof reply.commands, 'string');
|
||||
assert.ok(Array.isArray(reply.flags));
|
||||
|
||||
if (testUtils.isVersionGreaterThan([7])) {
|
||||
assert.equal(typeof reply.keys, 'string');
|
||||
assert.equal(typeof reply.channels, 'string');
|
||||
assert.ok(Array.isArray(reply.selectors));
|
||||
} else {
|
||||
assert.ok(Array.isArray(reply.keys));
|
||||
if (testUtils.isVersionGreaterThan([7])) {
|
||||
assert.equal(typeof reply.keys, 'string');
|
||||
assert.equal(typeof reply.channels, 'string');
|
||||
assert.ok(Array.isArray(reply.selectors));
|
||||
} else {
|
||||
assert.ok(Array.isArray(reply.keys));
|
||||
|
||||
if (testUtils.isVersionGreaterThan([6, 2])) {
|
||||
assert.ok(Array.isArray(reply.channels));
|
||||
}
|
||||
}
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
if (testUtils.isVersionGreaterThan([6, 2])) {
|
||||
assert.ok(Array.isArray(reply.channels));
|
||||
}
|
||||
}
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
||||
|
@@ -1,40 +1,43 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { RedisArgument, TuplesToMapReply, BlobStringReply, ArrayReply, UnwrapReply, Resp2Reply, Command } from '../RESP/types';
|
||||
|
||||
export function transformArguments(username: RedisCommandArgument): RedisCommandArguments {
|
||||
type AclUser = TuplesToMapReply<[
|
||||
[BlobStringReply<'flags'>, ArrayReply<BlobStringReply>],
|
||||
[BlobStringReply<'passwords'>, ArrayReply<BlobStringReply>],
|
||||
[BlobStringReply<'commands'>, BlobStringReply],
|
||||
/** changed to BlobStringReply in 7.0 */
|
||||
[BlobStringReply<'keys'>, ArrayReply<BlobStringReply> | BlobStringReply],
|
||||
/** added in 6.2, changed to BlobStringReply in 7.0 */
|
||||
[BlobStringReply<'channels'>, ArrayReply<BlobStringReply> | BlobStringReply],
|
||||
/** added in 7.0 */
|
||||
[BlobStringReply<'selectors'>, ArrayReply<TuplesToMapReply<[
|
||||
[BlobStringReply<'commands'>, BlobStringReply],
|
||||
[BlobStringReply<'keys'>, BlobStringReply],
|
||||
[BlobStringReply<'channels'>, BlobStringReply]
|
||||
]>>],
|
||||
]>;
|
||||
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments(username: RedisArgument) {
|
||||
return ['ACL', 'GETUSER', username];
|
||||
}
|
||||
|
||||
type AclGetUserRawReply = [
|
||||
'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> | RedisCommandArgument;
|
||||
channels: Array<RedisCommandArgument> | RedisCommandArgument;
|
||||
selectors?: Array<Array<string>>;
|
||||
}
|
||||
|
||||
export function transformReply(reply: AclGetUserRawReply): AclUser {
|
||||
return {
|
||||
flags: reply[1],
|
||||
passwords: reply[3],
|
||||
commands: reply[5],
|
||||
keys: reply[7],
|
||||
channels: reply[9],
|
||||
selectors: reply[11]
|
||||
};
|
||||
}
|
||||
},
|
||||
transformReply: {
|
||||
2: (reply: UnwrapReply<Resp2Reply<AclUser>>) => ({
|
||||
flags: reply[1],
|
||||
passwords: reply[3],
|
||||
commands: reply[5],
|
||||
keys: reply[7],
|
||||
channels: reply[9],
|
||||
selectors: (reply[11] as unknown as UnwrapReply<typeof reply[11]>)?.map(selector => {
|
||||
const inferred = selector as unknown as UnwrapReply<typeof selector>;
|
||||
return {
|
||||
commands: inferred[1],
|
||||
keys: inferred[3],
|
||||
channels: inferred[5]
|
||||
};
|
||||
})
|
||||
}),
|
||||
3: undefined as unknown as () => AclUser
|
||||
}
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,14 +1,22 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import testUtils from '../test-utils';
|
||||
import { transformArguments } from './ACL_LIST';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import ACL_LIST from './ACL_LIST';
|
||||
|
||||
describe('ACL LIST', () => {
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(),
|
||||
['ACL', 'LIST']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
ACL_LIST.transformArguments(),
|
||||
['ACL', 'LIST']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.aclList', async client => {
|
||||
const users = await client.aclList();
|
||||
assert.ok(Array.isArray(users));
|
||||
for (const user of users) {
|
||||
assert.equal(typeof user, 'string');
|
||||
}
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
||||
|
@@ -1,7 +1,10 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { ArrayReply, BlobStringReply, Command } from '../RESP/types';
|
||||
|
||||
export function transformArguments(): RedisCommandArguments {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments() {
|
||||
return ['ACL', 'LIST'];
|
||||
}
|
||||
|
||||
export declare function transformReply(): Array<RedisCommandArgument>;
|
||||
},
|
||||
transformReply: undefined as unknown as () => ArrayReply<BlobStringReply>
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,14 +1,14 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils from '../test-utils';
|
||||
import { transformArguments } from './ACL_SAVE';
|
||||
import ACL_LOAD from './ACL_LOAD';
|
||||
|
||||
describe('ACL SAVE', () => {
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
describe('ACL LOAD', () => {
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(),
|
||||
['ACL', 'SAVE']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
ACL_LOAD.transformArguments(),
|
||||
['ACL', 'LOAD']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@@ -1,7 +1,10 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { SimpleStringReply, Command } from '../RESP/types';
|
||||
|
||||
export function transformArguments(): RedisCommandArguments {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments() {
|
||||
return ['ACL', 'LOAD'];
|
||||
}
|
||||
|
||||
export declare function transformReply(): RedisCommandArgument;
|
||||
},
|
||||
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,53 +1,50 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import testUtils from '../test-utils';
|
||||
import { transformArguments, transformReply } from './ACL_LOG';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import ACL_LOG from './ACL_LOG';
|
||||
|
||||
describe('ACL LOG', () => {
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
|
||||
describe('transformArguments', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(),
|
||||
['ACL', 'LOG']
|
||||
);
|
||||
});
|
||||
|
||||
it('with count', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(10),
|
||||
['ACL', 'LOG', '10']
|
||||
);
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
ACL_LOG.transformArguments(),
|
||||
['ACL', 'LOG']
|
||||
);
|
||||
});
|
||||
|
||||
it('transformReply', () => {
|
||||
assert.deepEqual(
|
||||
transformReply([[
|
||||
'count',
|
||||
1,
|
||||
'reason',
|
||||
'auth',
|
||||
'context',
|
||||
'toplevel',
|
||||
'object',
|
||||
'AUTH',
|
||||
'username',
|
||||
'someuser',
|
||||
'age-seconds',
|
||||
'4.096',
|
||||
'client-info',
|
||||
'id=6 addr=127.0.0.1:63026 fd=8 name= age=9 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=48 qbuf-free=32720 obl=0 oll=0 omem=0 events=r cmd=auth user=default'
|
||||
]]),
|
||||
[{
|
||||
count: 1,
|
||||
reason: 'auth',
|
||||
context: 'toplevel',
|
||||
object: 'AUTH',
|
||||
username: 'someuser',
|
||||
ageSeconds: 4.096,
|
||||
clientInfo: 'id=6 addr=127.0.0.1:63026 fd=8 name= age=9 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=48 qbuf-free=32720 obl=0 oll=0 omem=0 events=r cmd=auth user=default'
|
||||
}]
|
||||
);
|
||||
it('with count', () => {
|
||||
assert.deepEqual(
|
||||
ACL_LOG.transformArguments(10),
|
||||
['ACL', 'LOG', '10']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.aclLog', async client => {
|
||||
// make sure to create one log
|
||||
await assert.rejects(
|
||||
client.auth({
|
||||
username: 'incorrect',
|
||||
password: 'incorrect'
|
||||
})
|
||||
);
|
||||
|
||||
const logs = await client.aclLog();
|
||||
assert.ok(Array.isArray(logs));
|
||||
for (const log of logs) {
|
||||
assert.equal(typeof log.count, 'number');
|
||||
assert.equal(typeof log.reason, 'string');
|
||||
assert.equal(typeof log.context, 'string');
|
||||
assert.equal(typeof log.object, 'string');
|
||||
assert.equal(typeof log.username, 'string');
|
||||
assert.equal(typeof log['age-seconds'], 'number');
|
||||
assert.equal(typeof log['client-info'], 'string');
|
||||
if (testUtils.isVersionGreaterThan([7, 2])) {
|
||||
assert.equal(typeof log['entry-id'], 'number');
|
||||
assert.equal(typeof log['timestamp-created'], 'number');
|
||||
assert.equal(typeof log['timestamp-last-updated'], 'number');
|
||||
}
|
||||
}
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
||||
|
@@ -1,50 +1,52 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { ArrayReply, TuplesToMapReply, BlobStringReply, NumberReply, DoubleReply, UnwrapReply, Resp2Reply, Command, TypeMapping } from '../RESP/types';
|
||||
import { transformDoubleReply } from './generic-transformers';
|
||||
|
||||
export function transformArguments(count?: number): RedisCommandArguments {
|
||||
export type AclLogReply = ArrayReply<TuplesToMapReply<[
|
||||
[BlobStringReply<'count'>, NumberReply],
|
||||
[BlobStringReply<'reason'>, BlobStringReply],
|
||||
[BlobStringReply<'context'>, BlobStringReply],
|
||||
[BlobStringReply<'object'>, BlobStringReply],
|
||||
[BlobStringReply<'username'>, BlobStringReply],
|
||||
[BlobStringReply<'age-seconds'>, DoubleReply],
|
||||
[BlobStringReply<'client-info'>, BlobStringReply],
|
||||
/** added in 7.0 */
|
||||
[BlobStringReply<'entry-id'>, NumberReply],
|
||||
/** added in 7.0 */
|
||||
[BlobStringReply<'timestamp-created'>, NumberReply],
|
||||
/** added in 7.0 */
|
||||
[BlobStringReply<'timestamp-last-updated'>, NumberReply]
|
||||
]>>;
|
||||
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments(count?: number) {
|
||||
const args = ['ACL', 'LOG'];
|
||||
|
||||
if (count) {
|
||||
args.push(count.toString());
|
||||
if (count !== undefined) {
|
||||
args.push(count.toString());
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
type AclLogRawReply = [
|
||||
_: RedisCommandArgument,
|
||||
count: number,
|
||||
_: RedisCommandArgument,
|
||||
reason: RedisCommandArgument,
|
||||
_: RedisCommandArgument,
|
||||
context: RedisCommandArgument,
|
||||
_: RedisCommandArgument,
|
||||
object: RedisCommandArgument,
|
||||
_: RedisCommandArgument,
|
||||
username: RedisCommandArgument,
|
||||
_: RedisCommandArgument,
|
||||
ageSeconds: RedisCommandArgument,
|
||||
_: RedisCommandArgument,
|
||||
clientInfo: RedisCommandArgument
|
||||
];
|
||||
|
||||
interface AclLog {
|
||||
count: number;
|
||||
reason: RedisCommandArgument;
|
||||
context: RedisCommandArgument;
|
||||
object: RedisCommandArgument;
|
||||
username: RedisCommandArgument;
|
||||
ageSeconds: number;
|
||||
clientInfo: RedisCommandArgument;
|
||||
}
|
||||
|
||||
export function transformReply(reply: Array<AclLogRawReply>): Array<AclLog> {
|
||||
return reply.map(log => ({
|
||||
count: log[1],
|
||||
reason: log[3],
|
||||
context: log[5],
|
||||
object: log[7],
|
||||
username: log[9],
|
||||
ageSeconds: Number(log[11]),
|
||||
clientInfo: log[13]
|
||||
}));
|
||||
}
|
||||
},
|
||||
transformReply: {
|
||||
2: (reply: UnwrapReply<Resp2Reply<AclLogReply>>, preserve?: any, typeMapping?: TypeMapping) => {
|
||||
return reply.map(item => {
|
||||
const inferred = item as unknown as UnwrapReply<typeof item>;
|
||||
return {
|
||||
count: inferred[1],
|
||||
reason: inferred[3],
|
||||
context: inferred[5],
|
||||
object: inferred[7],
|
||||
username: inferred[9],
|
||||
'age-seconds': transformDoubleReply[2](inferred[11], preserve, typeMapping),
|
||||
'client-info': inferred[13],
|
||||
'entry-id': inferred[15],
|
||||
'timestamp-created': inferred[17],
|
||||
'timestamp-last-updated': inferred[19]
|
||||
};
|
||||
})
|
||||
},
|
||||
3: undefined as unknown as () => AclLogReply
|
||||
}
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,14 +1,21 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import testUtils from '../test-utils';
|
||||
import { transformArguments } from './ACL_LOG_RESET';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import ACL_LOG_RESET from './ACL_LOG_RESET';
|
||||
|
||||
describe('ACL LOG RESET', () => {
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(),
|
||||
['ACL', 'LOG', 'RESET']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
ACL_LOG_RESET.transformArguments(),
|
||||
['ACL', 'LOG', 'RESET']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.aclLogReset', async client => {
|
||||
assert.equal(
|
||||
await client.aclLogReset(),
|
||||
'OK'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
||||
|
@@ -1,7 +1,11 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { SimpleStringReply, Command } from '../RESP/types';
|
||||
import ACL_LOG from './ACL_LOG';
|
||||
|
||||
export function transformArguments(): RedisCommandArguments {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: ACL_LOG.IS_READ_ONLY,
|
||||
transformArguments() {
|
||||
return ['ACL', 'LOG', 'RESET'];
|
||||
}
|
||||
|
||||
export declare function transformReply(): RedisCommandArgument;
|
||||
},
|
||||
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,14 +1,14 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils from '../test-utils';
|
||||
import { transformArguments } from './ACL_LOAD';
|
||||
import ACL_SAVE from './ACL_SAVE';
|
||||
|
||||
describe('ACL LOAD', () => {
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
describe('ACL SAVE', () => {
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(),
|
||||
['ACL', 'LOAD']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
ACL_SAVE.transformArguments(),
|
||||
['ACL', 'SAVE']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@@ -1,7 +1,10 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { SimpleStringReply, Command } from '../RESP/types';
|
||||
|
||||
export function transformArguments(): RedisCommandArguments {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments() {
|
||||
return ['ACL', 'SAVE'];
|
||||
}
|
||||
|
||||
export declare function transformReply(): RedisCommandArgument;
|
||||
},
|
||||
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,23 +1,23 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils from '../test-utils';
|
||||
import { transformArguments } from './ACL_SETUSER';
|
||||
import ACL_SETUSER from './ACL_SETUSER';
|
||||
|
||||
describe('ACL SETUSER', () => {
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
|
||||
describe('transformArguments', () => {
|
||||
it('string', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('username', 'allkeys'),
|
||||
['ACL', 'SETUSER', 'username', 'allkeys']
|
||||
);
|
||||
});
|
||||
|
||||
it('array', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('username', ['allkeys', 'allchannels']),
|
||||
['ACL', 'SETUSER', 'username', 'allkeys', 'allchannels']
|
||||
);
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
it('string', () => {
|
||||
assert.deepEqual(
|
||||
ACL_SETUSER.transformArguments('username', 'allkeys'),
|
||||
['ACL', 'SETUSER', 'username', 'allkeys']
|
||||
);
|
||||
});
|
||||
|
||||
it('array', () => {
|
||||
assert.deepEqual(
|
||||
ACL_SETUSER.transformArguments('username', ['allkeys', 'allchannels']),
|
||||
['ACL', 'SETUSER', 'username', 'allkeys', 'allchannels']
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,11 +1,11 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { pushVerdictArguments } from './generic-transformers';
|
||||
import { RedisArgument, SimpleStringReply, Command } from '../RESP/types';
|
||||
import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers';
|
||||
|
||||
export function transformArguments(
|
||||
username: RedisCommandArgument,
|
||||
rule: RedisCommandArgument | Array<RedisCommandArgument>
|
||||
): RedisCommandArguments {
|
||||
return pushVerdictArguments(['ACL', 'SETUSER', username], rule);
|
||||
}
|
||||
|
||||
export declare function transformReply(): RedisCommandArgument;
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments(username: RedisArgument, rule: RedisVariadicArgument) {
|
||||
return pushVariadicArguments(['ACL', 'SETUSER', username], rule);
|
||||
},
|
||||
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,14 +1,14 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils from '../test-utils';
|
||||
import { transformArguments } from './ACL_USERS';
|
||||
import ACL_USERS from './ACL_USERS';
|
||||
|
||||
describe('ACL USERS', () => {
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(),
|
||||
['ACL', 'USERS']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
ACL_USERS.transformArguments(),
|
||||
['ACL', 'USERS']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@@ -1,7 +1,10 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { ArrayReply, BlobStringReply, Command } from '../RESP/types';
|
||||
|
||||
export function transformArguments(): RedisCommandArguments {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments() {
|
||||
return ['ACL', 'USERS'];
|
||||
}
|
||||
|
||||
export declare function transformReply(): Array<RedisCommandArgument>;
|
||||
},
|
||||
transformReply: undefined as unknown as () => ArrayReply<BlobStringReply>
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,14 +1,14 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils from '../test-utils';
|
||||
import { transformArguments } from './ACL_WHOAMI';
|
||||
import ACL_WHOAMI from './ACL_WHOAMI';
|
||||
|
||||
describe('ACL WHOAMI', () => {
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(),
|
||||
['ACL', 'WHOAMI']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
ACL_WHOAMI.transformArguments(),
|
||||
['ACL', 'WHOAMI']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@@ -1,7 +1,10 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { BlobStringReply, Command } from '../RESP/types';
|
||||
|
||||
export function transformArguments(): RedisCommandArguments {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments() {
|
||||
return ['ACL', 'WHOAMI'];
|
||||
}
|
||||
|
||||
export declare function transformReply(): RedisCommandArgument;
|
||||
},
|
||||
transformReply: undefined as unknown as () => BlobStringReply
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,11 +1,22 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { transformArguments } from './APPEND';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import APPEND from './APPEND';
|
||||
|
||||
describe('APPEND', () => {
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('key', 'value'),
|
||||
['APPEND', 'key', 'value']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
APPEND.transformArguments('key', 'value'),
|
||||
['APPEND', 'key', 'value']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testAll('append', async client => {
|
||||
assert.equal(
|
||||
await client.append('key', 'value'),
|
||||
5
|
||||
);
|
||||
}, {
|
||||
client: GLOBAL.SERVERS.OPEN,
|
||||
cluster: GLOBAL.CLUSTERS.OPEN
|
||||
});
|
||||
});
|
||||
|
@@ -1,12 +1,10 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { RedisArgument, NumberReply, Command } from '../RESP/types';
|
||||
|
||||
export const FIRST_KEY_INDEX = 1;
|
||||
|
||||
export function transformArguments(
|
||||
key: RedisCommandArgument,
|
||||
value: RedisCommandArgument
|
||||
): RedisCommandArguments {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: 1,
|
||||
IS_READ_ONLY: false,
|
||||
transformArguments(key: RedisArgument, value: RedisArgument) {
|
||||
return ['APPEND', key, value];
|
||||
}
|
||||
|
||||
export declare function transformReply(): number;
|
||||
},
|
||||
transformReply: undefined as unknown as () => NumberReply
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,11 +1,11 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { transformArguments } from './ASKING';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import ASKING from './ASKING';
|
||||
|
||||
describe('ASKING', () => {
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(),
|
||||
['ASKING']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
ASKING.transformArguments(),
|
||||
['ASKING']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@@ -1,7 +1,10 @@
|
||||
import { RedisCommandArguments, RedisCommandArgument } from '.';
|
||||
import { SimpleStringReply, Command } from '../RESP/types';
|
||||
|
||||
export function transformArguments(): RedisCommandArguments {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments() {
|
||||
return ['ASKING'];
|
||||
}
|
||||
|
||||
export declare function transformReply(): RedisCommandArgument;
|
||||
},
|
||||
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,25 +1,25 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { transformArguments } from './AUTH';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import AUTH from './AUTH';
|
||||
|
||||
describe('AUTH', () => {
|
||||
describe('transformArguments', () => {
|
||||
it('password only', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments({
|
||||
password: 'password'
|
||||
}),
|
||||
['AUTH', 'password']
|
||||
);
|
||||
});
|
||||
|
||||
it('username & password', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments({
|
||||
username: 'username',
|
||||
password: 'password'
|
||||
}),
|
||||
['AUTH', 'username', 'password']
|
||||
);
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
it('password only', () => {
|
||||
assert.deepEqual(
|
||||
AUTH.transformArguments({
|
||||
password: 'password'
|
||||
}),
|
||||
['AUTH', 'password']
|
||||
);
|
||||
});
|
||||
|
||||
it('username & password', () => {
|
||||
assert.deepEqual(
|
||||
AUTH.transformArguments({
|
||||
username: 'username',
|
||||
password: 'password'
|
||||
}),
|
||||
['AUTH', 'username', 'password']
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,16 +1,23 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { RedisArgument, SimpleStringReply, Command } from '../RESP/types';
|
||||
|
||||
export interface AuthOptions {
|
||||
username?: RedisCommandArgument;
|
||||
password: RedisCommandArgument;
|
||||
username?: RedisArgument;
|
||||
password: RedisArgument;
|
||||
}
|
||||
|
||||
export function transformArguments({ username, password }: AuthOptions): RedisCommandArguments {
|
||||
if (!username) {
|
||||
return ['AUTH', password];
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments({ username, password }: AuthOptions) {
|
||||
const args: Array<RedisArgument> = ['AUTH'];
|
||||
|
||||
if (username !== undefined) {
|
||||
args.push(username);
|
||||
}
|
||||
|
||||
return ['AUTH', username, password];
|
||||
}
|
||||
args.push(password);
|
||||
|
||||
export declare function transformReply(): RedisCommandArgument;
|
||||
return args;
|
||||
},
|
||||
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,11 +1,19 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { transformArguments } from './BGREWRITEAOF';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import BGREWRITEAOF from './BGREWRITEAOF';
|
||||
|
||||
describe('BGREWRITEAOF', () => {
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(),
|
||||
['BGREWRITEAOF']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
BGREWRITEAOF.transformArguments(),
|
||||
['BGREWRITEAOF']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.bgRewriteAof', async client => {
|
||||
assert.equal(
|
||||
typeof await client.bgRewriteAof(),
|
||||
'string'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
||||
|
@@ -1,7 +1,10 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { SimpleStringReply, Command } from '../RESP/types';
|
||||
|
||||
export function transformArguments(): RedisCommandArguments {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments() {
|
||||
return ['BGREWRITEAOF'];
|
||||
}
|
||||
|
||||
export declare function transformReply(): RedisCommandArgument;
|
||||
},
|
||||
transformReply: undefined as unknown as () => SimpleStringReply
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,23 +1,32 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { describe } from 'mocha';
|
||||
import { transformArguments } from './BGSAVE';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import BGSAVE from './BGSAVE';
|
||||
|
||||
describe('BGSAVE', () => {
|
||||
describe('transformArguments', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(),
|
||||
['BGSAVE']
|
||||
);
|
||||
});
|
||||
|
||||
it('with SCHEDULE', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments({
|
||||
SCHEDULE: true
|
||||
}),
|
||||
['BGSAVE', 'SCHEDULE']
|
||||
);
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
BGSAVE.transformArguments(),
|
||||
['BGSAVE']
|
||||
);
|
||||
});
|
||||
|
||||
it('with SCHEDULE', () => {
|
||||
assert.deepEqual(
|
||||
BGSAVE.transformArguments({
|
||||
SCHEDULE: true
|
||||
}),
|
||||
['BGSAVE', 'SCHEDULE']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.bgSave', async client => {
|
||||
assert.equal(
|
||||
typeof await client.bgSave({
|
||||
SCHEDULE: true // using `SCHEDULE` to make sure it won't throw an error
|
||||
}),
|
||||
'string'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
||||
|
@@ -1,17 +1,20 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { SimpleStringReply, Command } from '../RESP/types';
|
||||
|
||||
interface BgSaveOptions {
|
||||
SCHEDULE?: true;
|
||||
export interface BgSaveOptions {
|
||||
SCHEDULE?: boolean;
|
||||
}
|
||||
|
||||
export function transformArguments(options?: BgSaveOptions): RedisCommandArguments {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments(options?: BgSaveOptions) {
|
||||
const args = ['BGSAVE'];
|
||||
|
||||
|
||||
if (options?.SCHEDULE) {
|
||||
args.push('SCHEDULE');
|
||||
args.push('SCHEDULE');
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
export declare function transformReply(): RedisCommandArgument;
|
||||
},
|
||||
transformReply: undefined as unknown as () => SimpleStringReply
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,44 +1,47 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments } from './BITCOUNT';
|
||||
import BITCOUNT from './BITCOUNT';
|
||||
|
||||
describe('BITCOUNT', () => {
|
||||
describe('transformArguments', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('key'),
|
||||
['BITCOUNT', 'key']
|
||||
);
|
||||
});
|
||||
|
||||
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']
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
BITCOUNT.transformArguments('key'),
|
||||
['BITCOUNT', 'key']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.bitCount', async client => {
|
||||
assert.equal(
|
||||
await client.bitCount('key'),
|
||||
0
|
||||
describe('with range', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
BITCOUNT.transformArguments('key', {
|
||||
start: 0,
|
||||
end: 1
|
||||
}),
|
||||
['BITCOUNT', 'key', '0', '1']
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
||||
|
||||
it('with mode', () => {
|
||||
assert.deepEqual(
|
||||
BITCOUNT.transformArguments('key', {
|
||||
start: 0,
|
||||
end: 1,
|
||||
mode: 'BIT'
|
||||
}),
|
||||
['BITCOUNT', 'key', '0', '1', 'BIT']
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
testUtils.testAll('bitCount', async client => {
|
||||
assert.equal(
|
||||
await client.bitCount('key'),
|
||||
0
|
||||
);
|
||||
}, {
|
||||
client: GLOBAL.SERVERS.OPEN,
|
||||
cluster: GLOBAL.CLUSTERS.OPEN
|
||||
});
|
||||
});
|
||||
|
@@ -1,33 +1,29 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { RedisArgument, NumberReply, Command } from '../RESP/types';
|
||||
|
||||
export const FIRST_KEY_INDEX = 1;
|
||||
|
||||
export const IS_READ_ONLY = true;
|
||||
|
||||
interface BitCountRange {
|
||||
start: number;
|
||||
end: number;
|
||||
mode?: 'BYTE' | 'BIT';
|
||||
export interface BitCountRange {
|
||||
start: number;
|
||||
end: number;
|
||||
mode?: 'BYTE' | 'BIT';
|
||||
}
|
||||
|
||||
export function transformArguments(
|
||||
key: RedisCommandArgument,
|
||||
range?: BitCountRange
|
||||
): RedisCommandArguments {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: 1,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments(key: RedisArgument, range?: BitCountRange) {
|
||||
const args = ['BITCOUNT', key];
|
||||
|
||||
if (range) {
|
||||
args.push(
|
||||
range.start.toString(),
|
||||
range.end.toString()
|
||||
);
|
||||
args.push(
|
||||
range.start.toString(),
|
||||
range.end.toString()
|
||||
);
|
||||
|
||||
if (range.mode) {
|
||||
args.push(range.mode);
|
||||
}
|
||||
if (range.mode) {
|
||||
args.push(range.mode);
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
export declare function transformReply(): number;
|
||||
},
|
||||
transformReply: undefined as unknown as () => NumberReply
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,46 +1,55 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments } from './BITFIELD';
|
||||
import BITFIELD from './BITFIELD';
|
||||
|
||||
describe('BITFIELD', () => {
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('key', [{
|
||||
operation: 'OVERFLOW',
|
||||
behavior: 'WRAP'
|
||||
}, {
|
||||
operation: 'GET',
|
||||
encoding: 'i8',
|
||||
offset: 0
|
||||
}, {
|
||||
operation: 'OVERFLOW',
|
||||
behavior: 'SAT'
|
||||
}, {
|
||||
operation: 'SET',
|
||||
encoding: 'i16',
|
||||
offset: 1,
|
||||
value: 0
|
||||
}, {
|
||||
operation: 'OVERFLOW',
|
||||
behavior: 'FAIL'
|
||||
}, {
|
||||
operation: 'INCRBY',
|
||||
encoding: 'i32',
|
||||
offset: 2,
|
||||
increment: 1
|
||||
}]),
|
||||
['BITFIELD', 'key', 'OVERFLOW', 'WRAP', 'GET', 'i8', '0', 'OVERFLOW', 'SAT', 'SET', 'i16', '1', '0', 'OVERFLOW', 'FAIL', 'INCRBY', 'i32', '2', '1']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
BITFIELD.transformArguments('key', [{
|
||||
operation: 'OVERFLOW',
|
||||
behavior: 'WRAP'
|
||||
}, {
|
||||
operation: 'GET',
|
||||
encoding: 'i8',
|
||||
offset: 0
|
||||
}, {
|
||||
operation: 'OVERFLOW',
|
||||
behavior: 'SAT'
|
||||
}, {
|
||||
operation: 'SET',
|
||||
encoding: 'i16',
|
||||
offset: 1,
|
||||
value: 0
|
||||
}, {
|
||||
operation: 'OVERFLOW',
|
||||
behavior: 'FAIL'
|
||||
}, {
|
||||
operation: 'INCRBY',
|
||||
encoding: 'i32',
|
||||
offset: 2,
|
||||
increment: 1
|
||||
}]),
|
||||
['BITFIELD', 'key', 'OVERFLOW', 'WRAP', 'GET', 'i8', '0', 'OVERFLOW', 'SAT', 'SET', 'i16', '1', '0', 'OVERFLOW', 'FAIL', 'INCRBY', 'i32', '2', '1']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.bitField', async client => {
|
||||
assert.deepEqual(
|
||||
await client.bitField('key', [{
|
||||
operation: 'GET',
|
||||
encoding: 'i8',
|
||||
offset: 0
|
||||
}]),
|
||||
[0]
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
testUtils.testAll('bitField', async client => {
|
||||
const a = client.bitField('key', [{
|
||||
operation: 'GET',
|
||||
encoding: 'i8',
|
||||
offset: 0
|
||||
}]);
|
||||
|
||||
assert.deepEqual(
|
||||
await client.bitField('key', [{
|
||||
operation: 'GET',
|
||||
encoding: 'i8',
|
||||
offset: 0
|
||||
}]),
|
||||
[0]
|
||||
);
|
||||
}, {
|
||||
client: GLOBAL.SERVERS.OPEN,
|
||||
cluster: GLOBAL.CLUSTERS.OPEN
|
||||
});
|
||||
});
|
||||
|
@@ -1,80 +1,87 @@
|
||||
export const FIRST_KEY_INDEX = 1;
|
||||
import { RedisArgument, ArrayReply, NumberReply, NullReply, Command } from '../RESP/types';
|
||||
|
||||
export type BitFieldEncoding = `${'i' | 'u'}${number}`;
|
||||
|
||||
export interface BitFieldOperation<S extends string> {
|
||||
operation: S;
|
||||
operation: S;
|
||||
}
|
||||
|
||||
export interface BitFieldGetOperation extends BitFieldOperation<'GET'> {
|
||||
encoding: BitFieldEncoding;
|
||||
offset: number | string;
|
||||
encoding: BitFieldEncoding;
|
||||
offset: number | string;
|
||||
}
|
||||
|
||||
interface BitFieldSetOperation extends BitFieldOperation<'SET'> {
|
||||
encoding: BitFieldEncoding;
|
||||
offset: number | string;
|
||||
value: number;
|
||||
export interface BitFieldSetOperation extends BitFieldOperation<'SET'> {
|
||||
encoding: BitFieldEncoding;
|
||||
offset: number | string;
|
||||
value: number;
|
||||
}
|
||||
|
||||
interface BitFieldIncrByOperation extends BitFieldOperation<'INCRBY'> {
|
||||
encoding: BitFieldEncoding;
|
||||
offset: number | string;
|
||||
increment: number;
|
||||
export interface BitFieldIncrByOperation extends BitFieldOperation<'INCRBY'> {
|
||||
encoding: BitFieldEncoding;
|
||||
offset: number | string;
|
||||
increment: number;
|
||||
}
|
||||
|
||||
interface BitFieldOverflowOperation extends BitFieldOperation<'OVERFLOW'> {
|
||||
behavior: string;
|
||||
export interface BitFieldOverflowOperation extends BitFieldOperation<'OVERFLOW'> {
|
||||
behavior: string;
|
||||
}
|
||||
|
||||
type BitFieldOperations = Array<
|
||||
BitFieldGetOperation |
|
||||
BitFieldSetOperation |
|
||||
BitFieldIncrByOperation |
|
||||
BitFieldOverflowOperation
|
||||
export type BitFieldOperations = Array<
|
||||
BitFieldGetOperation |
|
||||
BitFieldSetOperation |
|
||||
BitFieldIncrByOperation |
|
||||
BitFieldOverflowOperation
|
||||
>;
|
||||
|
||||
export function transformArguments(key: string, operations: BitFieldOperations): Array<string> {
|
||||
export type BitFieldRoOperations = Array<
|
||||
Omit<BitFieldGetOperation, 'operation'>
|
||||
>;
|
||||
|
||||
export default {
|
||||
FIRST_KEY_INDEX: 1,
|
||||
IS_READ_ONLY: false,
|
||||
transformArguments(key: RedisArgument, operations: BitFieldOperations) {
|
||||
const args = ['BITFIELD', key];
|
||||
|
||||
for (const options of operations) {
|
||||
switch (options.operation) {
|
||||
case 'GET':
|
||||
args.push(
|
||||
'GET',
|
||||
options.encoding,
|
||||
options.offset.toString()
|
||||
);
|
||||
break;
|
||||
switch (options.operation) {
|
||||
case 'GET':
|
||||
args.push(
|
||||
'GET',
|
||||
options.encoding,
|
||||
options.offset.toString()
|
||||
);
|
||||
break;
|
||||
|
||||
case 'SET':
|
||||
args.push(
|
||||
'SET',
|
||||
options.encoding,
|
||||
options.offset.toString(),
|
||||
options.value.toString()
|
||||
);
|
||||
break;
|
||||
case 'SET':
|
||||
args.push(
|
||||
'SET',
|
||||
options.encoding,
|
||||
options.offset.toString(),
|
||||
options.value.toString()
|
||||
);
|
||||
break;
|
||||
|
||||
case 'INCRBY':
|
||||
args.push(
|
||||
'INCRBY',
|
||||
options.encoding,
|
||||
options.offset.toString(),
|
||||
options.increment.toString()
|
||||
);
|
||||
break;
|
||||
case 'INCRBY':
|
||||
args.push(
|
||||
'INCRBY',
|
||||
options.encoding,
|
||||
options.offset.toString(),
|
||||
options.increment.toString()
|
||||
);
|
||||
break;
|
||||
|
||||
case 'OVERFLOW':
|
||||
args.push(
|
||||
'OVERFLOW',
|
||||
options.behavior
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'OVERFLOW':
|
||||
args.push(
|
||||
'OVERFLOW',
|
||||
options.behavior
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
export declare function transformReply(): Array<number | null>;
|
||||
},
|
||||
transformReply: undefined as unknown as () => ArrayReply<NumberReply | NullReply>
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,27 +1,30 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments } from './BITFIELD_RO';
|
||||
import BITFIELD_RO from './BITFIELD_RO';
|
||||
|
||||
describe('BITFIELD RO', () => {
|
||||
testUtils.isVersionGreaterThanHook([6, 2]);
|
||||
describe('BITFIELD_RO', () => {
|
||||
testUtils.isVersionGreaterThanHook([6, 2]);
|
||||
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('key', [{
|
||||
encoding: 'i8',
|
||||
offset: 0
|
||||
}]),
|
||||
['BITFIELD_RO', 'key', 'GET', 'i8', '0']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
BITFIELD_RO.transformArguments('key', [{
|
||||
encoding: 'i8',
|
||||
offset: 0
|
||||
}]),
|
||||
['BITFIELD_RO', 'key', 'GET', 'i8', '0']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.bitFieldRo', async client => {
|
||||
assert.deepEqual(
|
||||
await client.bitFieldRo('key', [{
|
||||
encoding: 'i8',
|
||||
offset: 0
|
||||
}]),
|
||||
[0]
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
testUtils.testAll('bitFieldRo', async client => {
|
||||
assert.deepEqual(
|
||||
await client.bitFieldRo('key', [{
|
||||
encoding: 'i8',
|
||||
offset: 0
|
||||
}]),
|
||||
[0]
|
||||
);
|
||||
}, {
|
||||
client: GLOBAL.SERVERS.OPEN,
|
||||
cluster: GLOBAL.CLUSTERS.OPEN
|
||||
});
|
||||
});
|
||||
|
@@ -1,26 +1,25 @@
|
||||
import { RedisArgument, ArrayReply, NumberReply, Command } from '../RESP/types';
|
||||
import { BitFieldGetOperation } from './BITFIELD';
|
||||
|
||||
export const FIRST_KEY_INDEX = 1;
|
||||
|
||||
export const IS_READ_ONLY = true;
|
||||
|
||||
type BitFieldRoOperations = Array<
|
||||
Omit<BitFieldGetOperation, 'operation'> &
|
||||
Partial<Pick<BitFieldGetOperation, 'operation'>>
|
||||
export type BitFieldRoOperations = Array<
|
||||
Omit<BitFieldGetOperation, 'operation'>
|
||||
>;
|
||||
|
||||
export function transformArguments(key: string, operations: BitFieldRoOperations): Array<string> {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: 1,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments(key: RedisArgument, operations: BitFieldRoOperations) {
|
||||
const args = ['BITFIELD_RO', key];
|
||||
|
||||
for (const operation of operations) {
|
||||
args.push(
|
||||
'GET',
|
||||
operation.encoding,
|
||||
operation.offset.toString()
|
||||
);
|
||||
args.push(
|
||||
'GET',
|
||||
operation.encoding,
|
||||
operation.offset.toString()
|
||||
);
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
export declare function transformReply(): Array<number | null>;
|
||||
},
|
||||
transformReply: undefined as unknown as () => ArrayReply<NumberReply>
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,35 +1,31 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments } from './BITOP';
|
||||
import BITOP from './BITOP';
|
||||
|
||||
describe('BITOP', () => {
|
||||
describe('transformArguments', () => {
|
||||
it('single key', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('AND', 'destKey', 'key'),
|
||||
['BITOP', 'AND', 'destKey', 'key']
|
||||
);
|
||||
});
|
||||
|
||||
it('multiple keys', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('AND', 'destKey', ['1', '2']),
|
||||
['BITOP', 'AND', 'destKey', '1', '2']
|
||||
);
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
it('single key', () => {
|
||||
assert.deepEqual(
|
||||
BITOP.transformArguments('AND', 'destKey', 'key'),
|
||||
['BITOP', 'AND', 'destKey', 'key']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.bitOp', async client => {
|
||||
assert.equal(
|
||||
await client.bitOp('AND', 'destKey', 'key'),
|
||||
0
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
it('multiple keys', () => {
|
||||
assert.deepEqual(
|
||||
BITOP.transformArguments('AND', 'destKey', ['1', '2']),
|
||||
['BITOP', 'AND', 'destKey', '1', '2']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
testUtils.testWithCluster('cluster.bitOp', async cluster => {
|
||||
assert.equal(
|
||||
await cluster.bitOp('AND', '{tag}destKey', '{tag}key'),
|
||||
0
|
||||
);
|
||||
}, GLOBAL.CLUSTERS.OPEN);
|
||||
testUtils.testAll('bitOp', async client => {
|
||||
assert.equal(
|
||||
await client.bitOp('AND', '{tag}destKey', '{tag}key'),
|
||||
0
|
||||
);
|
||||
}, {
|
||||
client: GLOBAL.SERVERS.OPEN,
|
||||
cluster: GLOBAL.CLUSTERS.OPEN
|
||||
});
|
||||
});
|
||||
|
@@ -1,16 +1,17 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { pushVerdictArguments } from './generic-transformers';
|
||||
import { NumberReply, Command, RedisArgument } from '../RESP/types';
|
||||
import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers';
|
||||
|
||||
export const FIRST_KEY_INDEX = 2;
|
||||
export type BitOperations = 'AND' | 'OR' | 'XOR' | 'NOT';
|
||||
|
||||
type BitOperations = 'AND' | 'OR' | 'XOR' | 'NOT';
|
||||
|
||||
export function transformArguments(
|
||||
export default {
|
||||
FIRST_KEY_INDEX: 2,
|
||||
IS_READ_ONLY: false,
|
||||
transformArguments(
|
||||
operation: BitOperations,
|
||||
destKey: RedisCommandArgument,
|
||||
key: RedisCommandArgument | Array<RedisCommandArgument>
|
||||
): RedisCommandArguments {
|
||||
return pushVerdictArguments(['BITOP', operation, destKey], key);
|
||||
}
|
||||
|
||||
export declare function transformReply(): number;
|
||||
destKey: RedisArgument,
|
||||
key: RedisVariadicArgument
|
||||
) {
|
||||
return pushVariadicArguments(['BITOP', operation, destKey], key);
|
||||
},
|
||||
transformReply: undefined as unknown as () => NumberReply
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,49 +1,45 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments } from './BITPOS';
|
||||
import BITPOS from './BITPOS';
|
||||
|
||||
describe('BITPOS', () => {
|
||||
describe('transformArguments', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('key', 1),
|
||||
['BITPOS', 'key', '1']
|
||||
);
|
||||
});
|
||||
|
||||
it('with start', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('key', 1, 1),
|
||||
['BITPOS', 'key', '1', '1']
|
||||
);
|
||||
});
|
||||
|
||||
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']
|
||||
);
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
BITPOS.transformArguments('key', 1),
|
||||
['BITPOS', 'key', '1']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.bitPos', async client => {
|
||||
assert.equal(
|
||||
await client.bitPos('key', 1, 1),
|
||||
-1
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
it('with start', () => {
|
||||
assert.deepEqual(
|
||||
BITPOS.transformArguments('key', 1, 1),
|
||||
['BITPOS', 'key', '1', '1']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithCluster('cluster.bitPos', async cluster => {
|
||||
assert.equal(
|
||||
await cluster.bitPos('key', 1, 1),
|
||||
-1
|
||||
);
|
||||
}, GLOBAL.CLUSTERS.OPEN);
|
||||
it('with start and end', () => {
|
||||
assert.deepEqual(
|
||||
BITPOS.transformArguments('key', 1, 1, -1),
|
||||
['BITPOS', 'key', '1', '1', '-1']
|
||||
);
|
||||
});
|
||||
|
||||
it('with start, end and mode', () => {
|
||||
assert.deepEqual(
|
||||
BITPOS.transformArguments('key', 1, 1, -1, 'BIT'),
|
||||
['BITPOS', 'key', '1', '1', '-1', 'BIT']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
testUtils.testAll('bitPos', async client => {
|
||||
assert.equal(
|
||||
await client.bitPos('key', 1, 1),
|
||||
-1
|
||||
);
|
||||
}, {
|
||||
client: GLOBAL.SERVERS.OPEN,
|
||||
cluster: GLOBAL.CLUSTERS.OPEN
|
||||
});
|
||||
});
|
||||
|
@@ -1,32 +1,31 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { RedisArgument, NumberReply, Command } from '../RESP/types';
|
||||
import { BitValue } from './generic-transformers';
|
||||
|
||||
export const FIRST_KEY_INDEX = 1;
|
||||
|
||||
export const IS_READ_ONLY = true;
|
||||
|
||||
export function transformArguments(
|
||||
key: RedisCommandArgument,
|
||||
export default {
|
||||
FIRST_KEY_INDEX: 1,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments(
|
||||
key: RedisArgument,
|
||||
bit: BitValue,
|
||||
start?: number,
|
||||
end?: number,
|
||||
mode?: 'BYTE' | 'BIT'
|
||||
): RedisCommandArguments {
|
||||
) {
|
||||
const args = ['BITPOS', key, bit.toString()];
|
||||
|
||||
if (typeof start === 'number') {
|
||||
args.push(start.toString());
|
||||
if (start !== undefined) {
|
||||
args.push(start.toString());
|
||||
}
|
||||
|
||||
if (typeof end === 'number') {
|
||||
args.push(end.toString());
|
||||
if (end !== undefined) {
|
||||
args.push(end.toString());
|
||||
}
|
||||
|
||||
if (mode) {
|
||||
args.push(mode);
|
||||
args.push(mode);
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
export declare function transformReply(): number;
|
||||
},
|
||||
transformReply: undefined as unknown as () => NumberReply
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,43 +1,35 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments } from './BLMOVE';
|
||||
import { commandOptions } from '../../index';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL, BLOCKING_MIN_VALUE } from '../test-utils';
|
||||
import BLMOVE from './BLMOVE';
|
||||
|
||||
describe('BLMOVE', () => {
|
||||
testUtils.isVersionGreaterThanHook([6, 2]);
|
||||
testUtils.isVersionGreaterThanHook([6, 2]);
|
||||
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('source', 'destination', 'LEFT', 'RIGHT', 0),
|
||||
['BLMOVE', 'source', 'destination', 'LEFT', 'RIGHT', '0']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
BLMOVE.transformArguments('source', 'destination', 'LEFT', 'RIGHT', 0),
|
||||
['BLMOVE', 'source', 'destination', 'LEFT', 'RIGHT', '0']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.blMove', async client => {
|
||||
const [blMoveReply] = await Promise.all([
|
||||
client.blMove(commandOptions({
|
||||
isolated: true
|
||||
}), 'source', 'destination', 'LEFT', 'RIGHT', 0),
|
||||
client.lPush('source', 'element')
|
||||
]);
|
||||
testUtils.testAll('blMove - null', async client => {
|
||||
assert.equal(
|
||||
await client.blMove('{tag}source', '{tag}destination', 'LEFT', 'RIGHT', BLOCKING_MIN_VALUE),
|
||||
null
|
||||
);
|
||||
}, {
|
||||
client: GLOBAL.SERVERS.OPEN,
|
||||
cluster: GLOBAL.CLUSTERS.OPEN
|
||||
});
|
||||
|
||||
assert.equal(
|
||||
blMoveReply,
|
||||
'element'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
|
||||
testUtils.testWithCluster('cluster.blMove', async cluster => {
|
||||
const [blMoveReply] = await Promise.all([
|
||||
cluster.blMove(commandOptions({
|
||||
isolated: true
|
||||
}), '{tag}source', '{tag}destination', 'LEFT', 'RIGHT', 0),
|
||||
cluster.lPush('{tag}source', 'element')
|
||||
]);
|
||||
|
||||
assert.equal(
|
||||
blMoveReply,
|
||||
'element'
|
||||
);
|
||||
}, GLOBAL.CLUSTERS.OPEN);
|
||||
testUtils.testAll('blMove - with member', async client => {
|
||||
const [, reply] = await Promise.all([
|
||||
client.lPush('{tag}source', 'element'),
|
||||
client.blMove('{tag}source', '{tag}destination', 'LEFT', 'RIGHT', BLOCKING_MIN_VALUE)
|
||||
]);
|
||||
assert.equal(reply, 'element');
|
||||
}, {
|
||||
client: GLOBAL.SERVERS.OPEN,
|
||||
cluster: GLOBAL.CLUSTERS.OPEN
|
||||
});
|
||||
});
|
||||
|
@@ -1,23 +1,24 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types';
|
||||
import { ListSide } from './generic-transformers';
|
||||
|
||||
export const FIRST_KEY_INDEX = 1;
|
||||
|
||||
export function transformArguments(
|
||||
source: RedisCommandArgument,
|
||||
destination: RedisCommandArgument,
|
||||
sourceDirection: ListSide,
|
||||
destinationDirection: ListSide,
|
||||
export default {
|
||||
FIRST_KEY_INDEX: 1,
|
||||
IS_READ_ONLY: false,
|
||||
transformArguments(
|
||||
source: RedisArgument,
|
||||
destination: RedisArgument,
|
||||
sourceSide: ListSide,
|
||||
destinationSide: ListSide,
|
||||
timeout: number
|
||||
): RedisCommandArguments {
|
||||
) {
|
||||
return [
|
||||
'BLMOVE',
|
||||
source,
|
||||
destination,
|
||||
sourceDirection,
|
||||
destinationDirection,
|
||||
timeout.toString()
|
||||
'BLMOVE',
|
||||
source,
|
||||
destination,
|
||||
sourceSide,
|
||||
destinationSide,
|
||||
timeout.toString()
|
||||
];
|
||||
}
|
||||
|
||||
export declare function transformReply(): RedisCommandArgument | null;
|
||||
},
|
||||
transformReply: undefined as unknown as () => BlobStringReply | NullReply
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,32 +1,49 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments } from './BLMPOP';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL, BLOCKING_MIN_VALUE } from '../test-utils';
|
||||
import BLMPOP from './BLMPOP';
|
||||
|
||||
describe('BLMPOP', () => {
|
||||
testUtils.isVersionGreaterThanHook([7]);
|
||||
testUtils.isVersionGreaterThanHook([7]);
|
||||
|
||||
describe('transformArguments', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(0, 'key', 'LEFT'),
|
||||
['BLMPOP', '0', '1', 'key', 'LEFT']
|
||||
);
|
||||
});
|
||||
|
||||
it('with COUNT', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(0, 'key', 'LEFT', {
|
||||
COUNT: 2
|
||||
}),
|
||||
['BLMPOP', '0', '1', 'key', 'LEFT', 'COUNT', '2']
|
||||
);
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
BLMPOP.transformArguments(0, 'key', 'LEFT'),
|
||||
['BLMPOP', '0', '1', 'key', 'LEFT']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.blmPop', async client => {
|
||||
assert.deepEqual(
|
||||
await client.blmPop(1, 'key', 'RIGHT'),
|
||||
null
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
it('with COUNT', () => {
|
||||
assert.deepEqual(
|
||||
BLMPOP.transformArguments(0, 'key', 'LEFT', {
|
||||
COUNT: 1
|
||||
}),
|
||||
['BLMPOP', '0', '1', 'key', 'LEFT', 'COUNT', '1']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
testUtils.testAll('blmPop - null', async client => {
|
||||
assert.equal(
|
||||
await client.blmPop(BLOCKING_MIN_VALUE, 'key', 'RIGHT'),
|
||||
null
|
||||
);
|
||||
}, {
|
||||
client: GLOBAL.SERVERS.OPEN,
|
||||
cluster: GLOBAL.CLUSTERS.OPEN
|
||||
});
|
||||
|
||||
testUtils.testAll('blmPop - with member', async client => {
|
||||
const [, reply] = await Promise.all([
|
||||
client.lPush('key', 'element'),
|
||||
client.blmPop(BLOCKING_MIN_VALUE, 'key', 'RIGHT')
|
||||
]);
|
||||
assert.deepEqual(reply, [
|
||||
'key',
|
||||
['element']
|
||||
]);
|
||||
}, {
|
||||
client: GLOBAL.SERVERS.OPEN,
|
||||
cluster: GLOBAL.CLUSTERS.OPEN
|
||||
});
|
||||
});
|
||||
|
@@ -1,20 +1,17 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { transformLMPopArguments, LMPopOptions, ListSide } from './generic-transformers';
|
||||
import { Command } from '../RESP/types';
|
||||
import LMPOP, { LMPopArguments, transformLMPopArguments } from './LMPOP';
|
||||
|
||||
export const FIRST_KEY_INDEX = 3;
|
||||
|
||||
export function transformArguments(
|
||||
export default {
|
||||
FIRST_KEY_INDEX: 3,
|
||||
IS_READ_ONLY: false,
|
||||
transformArguments(
|
||||
timeout: number,
|
||||
keys: RedisCommandArgument | Array<RedisCommandArgument>,
|
||||
side: ListSide,
|
||||
options?: LMPopOptions
|
||||
): RedisCommandArguments {
|
||||
...args: LMPopArguments
|
||||
) {
|
||||
return transformLMPopArguments(
|
||||
['BLMPOP', timeout.toString()],
|
||||
keys,
|
||||
side,
|
||||
options
|
||||
['BLMPOP', timeout.toString()],
|
||||
...args
|
||||
);
|
||||
}
|
||||
|
||||
export { transformReply } from './LMPOP';
|
||||
},
|
||||
transformReply: LMPOP.transformReply
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,79 +1,46 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments, transformReply } from './BLPOP';
|
||||
import { commandOptions } from '../../index';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL, BLOCKING_MIN_VALUE } from '../test-utils';
|
||||
import BLPOP from './BLPOP';
|
||||
|
||||
describe('BLPOP', () => {
|
||||
describe('transformArguments', () => {
|
||||
it('single', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('key', 0),
|
||||
['BLPOP', 'key', '0']
|
||||
);
|
||||
});
|
||||
|
||||
it('multiple', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(['key1', 'key2'], 0),
|
||||
['BLPOP', 'key1', 'key2', '0']
|
||||
);
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
it('single', () => {
|
||||
assert.deepEqual(
|
||||
BLPOP.transformArguments('key', 0),
|
||||
['BLPOP', 'key', '0']
|
||||
);
|
||||
});
|
||||
|
||||
describe('transformReply', () => {
|
||||
it('null', () => {
|
||||
assert.equal(
|
||||
transformReply(null),
|
||||
null
|
||||
);
|
||||
});
|
||||
|
||||
it('member', () => {
|
||||
assert.deepEqual(
|
||||
transformReply(['key', 'element']),
|
||||
{
|
||||
key: 'key',
|
||||
element: 'element'
|
||||
}
|
||||
);
|
||||
});
|
||||
it('multiple', () => {
|
||||
assert.deepEqual(
|
||||
BLPOP.transformArguments(['1', '2'], 0),
|
||||
['BLPOP', '1', '2', '0']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.blPop', async client => {
|
||||
const [ blPopReply ] = await Promise.all([
|
||||
client.blPop(
|
||||
commandOptions({ isolated: true }),
|
||||
'key',
|
||||
1
|
||||
),
|
||||
client.lPush('key', 'element'),
|
||||
]);
|
||||
testUtils.testAll('blPop - null', async client => {
|
||||
assert.equal(
|
||||
await client.blPop('key', BLOCKING_MIN_VALUE),
|
||||
null
|
||||
);
|
||||
}, {
|
||||
client: GLOBAL.SERVERS.OPEN,
|
||||
cluster: GLOBAL.CLUSTERS.OPEN
|
||||
});
|
||||
|
||||
assert.deepEqual(
|
||||
blPopReply,
|
||||
{
|
||||
key: 'key',
|
||||
element: 'element'
|
||||
}
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
testUtils.testAll('blPop - with member', async client => {
|
||||
const [, reply] = await Promise.all([
|
||||
client.lPush('key', 'element'),
|
||||
client.blPop('key', 1)
|
||||
]);
|
||||
|
||||
testUtils.testWithCluster('cluster.blPop', async cluster => {
|
||||
const [ blPopReply ] = await Promise.all([
|
||||
cluster.blPop(
|
||||
commandOptions({ isolated: true }),
|
||||
'key',
|
||||
1
|
||||
),
|
||||
cluster.lPush('key', 'element')
|
||||
]);
|
||||
|
||||
assert.deepEqual(
|
||||
blPopReply,
|
||||
{
|
||||
key: 'key',
|
||||
element: 'element'
|
||||
}
|
||||
);
|
||||
}, GLOBAL.CLUSTERS.OPEN);
|
||||
assert.deepEqual(reply, {
|
||||
key: 'key',
|
||||
element: 'element'
|
||||
});
|
||||
}, {
|
||||
client: GLOBAL.SERVERS.OPEN,
|
||||
cluster: GLOBAL.CLUSTERS.OPEN
|
||||
});
|
||||
});
|
||||
|
@@ -1,31 +1,23 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { pushVerdictArguments } from './generic-transformers';
|
||||
import { UnwrapReply, NullReply, TuplesReply, BlobStringReply, Command } from '../RESP/types';
|
||||
import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers';
|
||||
|
||||
export const FIRST_KEY_INDEX = 1;
|
||||
|
||||
export function transformArguments(
|
||||
keys: RedisCommandArgument | Array<RedisCommandArgument>,
|
||||
export default {
|
||||
FIRST_KEY_INDEX: 1,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments(
|
||||
key: RedisVariadicArgument,
|
||||
timeout: number
|
||||
): RedisCommandArguments {
|
||||
const args = pushVerdictArguments(['BLPOP'], keys);
|
||||
|
||||
) {
|
||||
const args = pushVariadicArguments(['BLPOP'], key);
|
||||
args.push(timeout.toString());
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
type BLPopRawReply = null | [RedisCommandArgument, RedisCommandArgument];
|
||||
|
||||
type BLPopReply = null | {
|
||||
key: RedisCommandArgument;
|
||||
element: RedisCommandArgument;
|
||||
};
|
||||
|
||||
export function transformReply(reply: BLPopRawReply): BLPopReply {
|
||||
},
|
||||
transformReply(reply: UnwrapReply<NullReply | TuplesReply<[BlobStringReply, BlobStringReply]>>) {
|
||||
if (reply === null) return null;
|
||||
|
||||
return {
|
||||
key: reply[0],
|
||||
element: reply[1]
|
||||
key: reply[0],
|
||||
element: reply[1]
|
||||
};
|
||||
}
|
||||
}
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,79 +1,46 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments, transformReply } from './BRPOP';
|
||||
import { commandOptions } from '../../index';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL, BLOCKING_MIN_VALUE } from '../test-utils';
|
||||
import BRPOP from './BRPOP';
|
||||
|
||||
describe('BRPOP', () => {
|
||||
describe('transformArguments', () => {
|
||||
it('single', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('key', 0),
|
||||
['BRPOP', 'key', '0']
|
||||
);
|
||||
});
|
||||
|
||||
it('multiple', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(['key1', 'key2'], 0),
|
||||
['BRPOP', 'key1', 'key2', '0']
|
||||
);
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
it('single', () => {
|
||||
assert.deepEqual(
|
||||
BRPOP.transformArguments('key', 0),
|
||||
['BRPOP', 'key', '0']
|
||||
);
|
||||
});
|
||||
|
||||
describe('transformReply', () => {
|
||||
it('null', () => {
|
||||
assert.equal(
|
||||
transformReply(null),
|
||||
null
|
||||
);
|
||||
});
|
||||
|
||||
it('member', () => {
|
||||
assert.deepEqual(
|
||||
transformReply(['key', 'element']),
|
||||
{
|
||||
key: 'key',
|
||||
element: 'element'
|
||||
}
|
||||
);
|
||||
});
|
||||
it('multiple', () => {
|
||||
assert.deepEqual(
|
||||
BRPOP.transformArguments(['1', '2'], 0),
|
||||
['BRPOP', '1', '2', '0']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.brPop', async client => {
|
||||
const [ brPopReply ] = await Promise.all([
|
||||
client.brPop(
|
||||
commandOptions({ isolated: true }),
|
||||
'key',
|
||||
1
|
||||
),
|
||||
client.lPush('key', 'element'),
|
||||
]);
|
||||
testUtils.testAll('brPop - null', async client => {
|
||||
assert.equal(
|
||||
await client.brPop('key', BLOCKING_MIN_VALUE),
|
||||
null
|
||||
);
|
||||
}, {
|
||||
client: GLOBAL.SERVERS.OPEN,
|
||||
cluster: GLOBAL.CLUSTERS.OPEN
|
||||
});
|
||||
|
||||
assert.deepEqual(
|
||||
brPopReply,
|
||||
{
|
||||
key: 'key',
|
||||
element: 'element'
|
||||
}
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
testUtils.testAll('brPopblPop - with member', async client => {
|
||||
const [, reply] = await Promise.all([
|
||||
client.lPush('key', 'element'),
|
||||
client.brPop('key', 1)
|
||||
]);
|
||||
|
||||
testUtils.testWithCluster('cluster.brPop', async cluster => {
|
||||
const [ brPopReply ] = await Promise.all([
|
||||
cluster.brPop(
|
||||
commandOptions({ isolated: true }),
|
||||
'key',
|
||||
1
|
||||
),
|
||||
cluster.lPush('key', 'element'),
|
||||
]);
|
||||
|
||||
assert.deepEqual(
|
||||
brPopReply,
|
||||
{
|
||||
key: 'key',
|
||||
element: 'element'
|
||||
}
|
||||
);
|
||||
}, GLOBAL.CLUSTERS.OPEN);
|
||||
assert.deepEqual(reply, {
|
||||
key: 'key',
|
||||
element: 'element'
|
||||
});
|
||||
}, {
|
||||
client: GLOBAL.SERVERS.OPEN,
|
||||
cluster: GLOBAL.CLUSTERS.OPEN
|
||||
});
|
||||
});
|
||||
|
@@ -1,17 +1,17 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { pushVerdictArguments } from './generic-transformers';
|
||||
import { Command } from '../RESP/types';
|
||||
import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers';
|
||||
import BLPOP from './BLPOP';
|
||||
|
||||
export const FIRST_KEY_INDEX = 1;
|
||||
|
||||
export function transformArguments(
|
||||
key: RedisCommandArgument | Array<RedisCommandArgument>,
|
||||
export default {
|
||||
FIRST_KEY_INDEX: 1,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments(
|
||||
key: RedisVariadicArgument,
|
||||
timeout: number
|
||||
): RedisCommandArguments {
|
||||
const args = pushVerdictArguments(['BRPOP'], key);
|
||||
|
||||
) {
|
||||
const args = pushVariadicArguments(['BRPOP'], key);
|
||||
args.push(timeout.toString());
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
export { transformReply } from './BLPOP';
|
||||
},
|
||||
transformReply: BLPOP.transformReply
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,47 +1,42 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments } from './BRPOPLPUSH';
|
||||
import { commandOptions } from '../../index';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL, BLOCKING_MIN_VALUE } from '../test-utils';
|
||||
import BRPOPLPUSH from './BRPOPLPUSH';
|
||||
|
||||
describe('BRPOPLPUSH', () => {
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('source', 'destination', 0),
|
||||
['BRPOPLPUSH', 'source', 'destination', '0']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
BRPOPLPUSH.transformArguments('source', 'destination', 0),
|
||||
['BRPOPLPUSH', 'source', 'destination', '0']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.brPopLPush', async client => {
|
||||
const [ popReply ] = await Promise.all([
|
||||
client.brPopLPush(
|
||||
commandOptions({ isolated: true }),
|
||||
'source',
|
||||
'destination',
|
||||
0
|
||||
),
|
||||
client.lPush('source', 'element')
|
||||
]);
|
||||
testUtils.testAll('brPopLPush - null', async client => {
|
||||
assert.equal(
|
||||
await client.brPopLPush(
|
||||
'{tag}source',
|
||||
'{tag}destination',
|
||||
BLOCKING_MIN_VALUE
|
||||
),
|
||||
null
|
||||
);
|
||||
}, {
|
||||
client: GLOBAL.SERVERS.OPEN,
|
||||
cluster: GLOBAL.CLUSTERS.OPEN
|
||||
});
|
||||
|
||||
assert.equal(
|
||||
popReply,
|
||||
'element'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
testUtils.testAll('brPopLPush - with member', async client => {
|
||||
const [, reply] = await Promise.all([
|
||||
client.lPush('{tag}source', 'element'),
|
||||
client.brPopLPush(
|
||||
'{tag}source',
|
||||
'{tag}destination',
|
||||
0
|
||||
)
|
||||
]);
|
||||
|
||||
testUtils.testWithCluster('cluster.brPopLPush', async cluster => {
|
||||
const [ popReply ] = await Promise.all([
|
||||
cluster.brPopLPush(
|
||||
commandOptions({ isolated: true }),
|
||||
'{tag}source',
|
||||
'{tag}destination',
|
||||
0
|
||||
),
|
||||
cluster.lPush('{tag}source', 'element')
|
||||
]);
|
||||
|
||||
assert.equal(
|
||||
popReply,
|
||||
'element'
|
||||
);
|
||||
}, GLOBAL.CLUSTERS.OPEN);
|
||||
assert.equal(reply, 'element');
|
||||
}, {
|
||||
client: GLOBAL.SERVERS.OPEN,
|
||||
cluster: GLOBAL.CLUSTERS.OPEN
|
||||
});
|
||||
});
|
||||
|
@@ -1,13 +1,14 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types';
|
||||
|
||||
export const FIRST_KEY_INDEX = 1;
|
||||
|
||||
export function transformArguments(
|
||||
source: RedisCommandArgument,
|
||||
destination: RedisCommandArgument,
|
||||
export default {
|
||||
FIRST_KEY_INDEX: 1,
|
||||
IS_READ_ONLY: false,
|
||||
transformArguments(
|
||||
source: RedisArgument,
|
||||
destination: RedisArgument,
|
||||
timeout: number
|
||||
): RedisCommandArguments {
|
||||
) {
|
||||
return ['BRPOPLPUSH', source, destination, timeout.toString()];
|
||||
}
|
||||
|
||||
export declare function transformReply(): RedisCommandArgument | null;
|
||||
},
|
||||
transformReply: undefined as unknown as () => BlobStringReply | NullReply
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,32 +1,55 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments } from './BZMPOP';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL, BLOCKING_MIN_VALUE } from '../test-utils';
|
||||
import BZMPOP from './BZMPOP';
|
||||
|
||||
describe('BZMPOP', () => {
|
||||
testUtils.isVersionGreaterThanHook([7]);
|
||||
testUtils.isVersionGreaterThanHook([7]);
|
||||
|
||||
describe('transformArguments', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(0, 'key', 'MIN'),
|
||||
['BZMPOP', '0', '1', 'key', 'MIN']
|
||||
);
|
||||
});
|
||||
|
||||
it('with COUNT', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(0, 'key', 'MIN', {
|
||||
COUNT: 2
|
||||
}),
|
||||
['BZMPOP', '0', '1', 'key', 'MIN', 'COUNT', '2']
|
||||
);
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
BZMPOP.transformArguments(0, 'key', 'MIN'),
|
||||
['BZMPOP', '0', '1', 'key', 'MIN']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.bzmPop', async client => {
|
||||
assert.deepEqual(
|
||||
await client.bzmPop(1, 'key', 'MAX'),
|
||||
null
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
it('with COUNT', () => {
|
||||
assert.deepEqual(
|
||||
BZMPOP.transformArguments(0, 'key', 'MIN', {
|
||||
COUNT: 2
|
||||
}),
|
||||
['BZMPOP', '0', '1', 'key', 'MIN', 'COUNT', '2']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
testUtils.testAll('bzmPop - null', async client => {
|
||||
assert.equal(
|
||||
await client.bzmPop(BLOCKING_MIN_VALUE, 'key', 'MAX'),
|
||||
null
|
||||
);
|
||||
}, {
|
||||
client: GLOBAL.SERVERS.OPEN,
|
||||
cluster: GLOBAL.SERVERS.OPEN
|
||||
});
|
||||
|
||||
testUtils.testAll('bzmPop - with member', async client => {
|
||||
const key = 'key',
|
||||
member = {
|
||||
value: 'a',
|
||||
score: 1
|
||||
},
|
||||
[, reply] = await Promise.all([
|
||||
client.zAdd(key, member),
|
||||
client.bzmPop(BLOCKING_MIN_VALUE, key, 'MAX')
|
||||
]);
|
||||
|
||||
assert.deepEqual(reply, {
|
||||
key,
|
||||
members: [member]
|
||||
});
|
||||
}, {
|
||||
client: GLOBAL.SERVERS.OPEN,
|
||||
cluster: GLOBAL.SERVERS.OPEN
|
||||
});
|
||||
});
|
||||
|
@@ -1,20 +1,11 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { SortedSetSide, transformZMPopArguments, ZMPopOptions } from './generic-transformers';
|
||||
import { Command } from '../RESP/types';
|
||||
import ZMPOP, { ZMPopArguments, transformZMPopArguments } from './ZMPOP';
|
||||
|
||||
export const FIRST_KEY_INDEX = 3;
|
||||
|
||||
export function transformArguments(
|
||||
timeout: number,
|
||||
keys: RedisCommandArgument | Array<RedisCommandArgument>,
|
||||
side: SortedSetSide,
|
||||
options?: ZMPopOptions
|
||||
): RedisCommandArguments {
|
||||
return transformZMPopArguments(
|
||||
['BZMPOP', timeout.toString()],
|
||||
keys,
|
||||
side,
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
export { transformReply } from './ZMPOP';
|
||||
export default {
|
||||
FIRST_KEY_INDEX: 3,
|
||||
IS_READ_ONLY: false,
|
||||
transformArguments(timeout: number, ...args: ZMPopArguments) {
|
||||
return transformZMPopArguments(['BZMPOP', timeout.toString()], ...args);
|
||||
},
|
||||
transformReply: ZMPOP.transformReply
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,65 +1,51 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments, transformReply } from './BZPOPMAX';
|
||||
import { commandOptions } from '../../index';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL, BLOCKING_MIN_VALUE } from '../test-utils';
|
||||
import BZPOPMAX from './BZPOPMAX';
|
||||
|
||||
describe('BZPOPMAX', () => {
|
||||
describe('transformArguments', () => {
|
||||
it('single', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('key', 0),
|
||||
['BZPOPMAX', 'key', '0']
|
||||
);
|
||||
});
|
||||
|
||||
it('multiple', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(['1', '2'], 0),
|
||||
['BZPOPMAX', '1', '2', '0']
|
||||
);
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
it('single', () => {
|
||||
assert.deepEqual(
|
||||
BZPOPMAX.transformArguments('key', 0),
|
||||
['BZPOPMAX', 'key', '0']
|
||||
);
|
||||
});
|
||||
|
||||
describe('transformReply', () => {
|
||||
it('null', () => {
|
||||
assert.equal(
|
||||
transformReply(null),
|
||||
null
|
||||
);
|
||||
});
|
||||
|
||||
it('member', () => {
|
||||
assert.deepEqual(
|
||||
transformReply(['key', 'value', '1']),
|
||||
{
|
||||
key: 'key',
|
||||
value: 'value',
|
||||
score: 1
|
||||
}
|
||||
);
|
||||
});
|
||||
it('multiple', () => {
|
||||
assert.deepEqual(
|
||||
BZPOPMAX.transformArguments(['1', '2'], 0),
|
||||
['BZPOPMAX', '1', '2', '0']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.bzPopMax', async client => {
|
||||
const [ bzPopMaxReply ] = await Promise.all([
|
||||
client.bzPopMax(
|
||||
commandOptions({ isolated: true }),
|
||||
'key',
|
||||
1
|
||||
),
|
||||
client.zAdd('key', [{
|
||||
value: '1',
|
||||
score: 1
|
||||
}])
|
||||
]);
|
||||
testUtils.testAll('bzPopMax - null', async client => {
|
||||
assert.equal(
|
||||
await client.bzPopMax('key', BLOCKING_MIN_VALUE),
|
||||
null
|
||||
);
|
||||
}, {
|
||||
client: GLOBAL.SERVERS.OPEN,
|
||||
cluster: GLOBAL.SERVERS.OPEN
|
||||
});
|
||||
|
||||
assert.deepEqual(
|
||||
bzPopMaxReply,
|
||||
{
|
||||
key: 'key',
|
||||
value: '1',
|
||||
score: 1
|
||||
}
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
testUtils.testAll('bzPopMax - with member', async client => {
|
||||
const key = 'key',
|
||||
member = {
|
||||
value: 'a',
|
||||
score: 1
|
||||
},
|
||||
[, reply] = await Promise.all([
|
||||
client.zAdd(key, member),
|
||||
client.bzPopMax(key, BLOCKING_MIN_VALUE)
|
||||
]);
|
||||
|
||||
assert.deepEqual(reply, {
|
||||
key,
|
||||
...member
|
||||
});
|
||||
}, {
|
||||
client: GLOBAL.SERVERS.OPEN,
|
||||
cluster: GLOBAL.SERVERS.OPEN
|
||||
});
|
||||
});
|
||||
|
@@ -1,29 +1,43 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { pushVerdictArguments, transformNumberInfinityReply, ZMember } from './generic-transformers';
|
||||
import { RedisArgument, NullReply, TuplesReply, BlobStringReply, DoubleReply, UnwrapReply, Command, TypeMapping } from '../RESP/types';
|
||||
import { RedisVariadicArgument, pushVariadicArguments, transformDoubleReply } from './generic-transformers';
|
||||
|
||||
export const FIRST_KEY_INDEX = 1;
|
||||
|
||||
export function transformArguments(
|
||||
key: RedisCommandArgument | Array<RedisCommandArgument>,
|
||||
timeout: number
|
||||
): RedisCommandArguments {
|
||||
const args = pushVerdictArguments(['BZPOPMAX'], key);
|
||||
|
||||
args.push(timeout.toString());
|
||||
|
||||
return args;
|
||||
export function transformBZPopArguments(
|
||||
command: RedisArgument,
|
||||
key: RedisVariadicArgument,
|
||||
timeout: number
|
||||
) {
|
||||
const args = pushVariadicArguments([command], key);
|
||||
args.push(timeout.toString());
|
||||
return args;
|
||||
}
|
||||
|
||||
type ZMemberRawReply = [key: RedisCommandArgument, value: RedisCommandArgument, score: RedisCommandArgument] | null;
|
||||
export type BZPopArguments = typeof transformBZPopArguments extends (_: any, ...args: infer T) => any ? T : never;
|
||||
|
||||
type BZPopMaxReply = (ZMember & { key: RedisCommandArgument }) | null;
|
||||
|
||||
export function transformReply(reply: ZMemberRawReply): BZPopMaxReply | null {
|
||||
if (!reply) return null;
|
||||
|
||||
return {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: 1,
|
||||
IS_READ_ONLY: false,
|
||||
transformArguments(...args: BZPopArguments) {
|
||||
return transformBZPopArguments('BZPOPMAX', ...args);
|
||||
},
|
||||
transformReply: {
|
||||
2(
|
||||
reply: UnwrapReply<NullReply | TuplesReply<[BlobStringReply, BlobStringReply, BlobStringReply]>>,
|
||||
preserve?: any,
|
||||
typeMapping?: TypeMapping
|
||||
) {
|
||||
return reply === null ? null : {
|
||||
key: reply[0],
|
||||
value: reply[1],
|
||||
score: transformNumberInfinityReply(reply[2])
|
||||
};
|
||||
}
|
||||
score: transformDoubleReply[2](reply[2], preserve, typeMapping)
|
||||
};
|
||||
},
|
||||
3(reply: UnwrapReply<NullReply | TuplesReply<[BlobStringReply, BlobStringReply, DoubleReply]>>) {
|
||||
return reply === null ? null : {
|
||||
key: reply[0],
|
||||
value: reply[1],
|
||||
score: reply[2]
|
||||
};
|
||||
}
|
||||
}
|
||||
} as const satisfies Command;
|
||||
|
||||
|
@@ -1,65 +1,51 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments, transformReply } from './BZPOPMIN';
|
||||
import { commandOptions } from '../../index';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL, BLOCKING_MIN_VALUE } from '../test-utils';
|
||||
import BZPOPMIN from './BZPOPMIN';
|
||||
|
||||
describe('BZPOPMIN', () => {
|
||||
describe('transformArguments', () => {
|
||||
it('single', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('key', 0),
|
||||
['BZPOPMIN', 'key', '0']
|
||||
);
|
||||
});
|
||||
|
||||
it('multiple', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(['1', '2'], 0),
|
||||
['BZPOPMIN', '1', '2', '0']
|
||||
);
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
it('single', () => {
|
||||
assert.deepEqual(
|
||||
BZPOPMIN.transformArguments('key', 0),
|
||||
['BZPOPMIN', 'key', '0']
|
||||
);
|
||||
});
|
||||
|
||||
describe('transformReply', () => {
|
||||
it('null', () => {
|
||||
assert.equal(
|
||||
transformReply(null),
|
||||
null
|
||||
);
|
||||
});
|
||||
|
||||
it('member', () => {
|
||||
assert.deepEqual(
|
||||
transformReply(['key', 'value', '1']),
|
||||
{
|
||||
key: 'key',
|
||||
value: 'value',
|
||||
score: 1
|
||||
}
|
||||
);
|
||||
});
|
||||
it('multiple', () => {
|
||||
assert.deepEqual(
|
||||
BZPOPMIN.transformArguments(['1', '2'], 0),
|
||||
['BZPOPMIN', '1', '2', '0']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.bzPopMin', async client => {
|
||||
const [ bzPopMinReply ] = await Promise.all([
|
||||
client.bzPopMin(
|
||||
commandOptions({ isolated: true }),
|
||||
'key',
|
||||
1
|
||||
),
|
||||
client.zAdd('key', [{
|
||||
value: '1',
|
||||
score: 1
|
||||
}])
|
||||
]);
|
||||
testUtils.testAll('bzPopMin - null', async client => {
|
||||
assert.equal(
|
||||
await client.bzPopMin('key', BLOCKING_MIN_VALUE),
|
||||
null
|
||||
);
|
||||
}, {
|
||||
client: GLOBAL.SERVERS.OPEN,
|
||||
cluster: GLOBAL.SERVERS.OPEN
|
||||
});
|
||||
|
||||
assert.deepEqual(
|
||||
bzPopMinReply,
|
||||
{
|
||||
key: 'key',
|
||||
value: '1',
|
||||
score: 1
|
||||
}
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
testUtils.testAll('bzPopMin - with member', async client => {
|
||||
const key = 'key',
|
||||
member = {
|
||||
value: 'a',
|
||||
score: 1
|
||||
},
|
||||
[, reply] = await Promise.all([
|
||||
client.zAdd(key, member),
|
||||
client.bzPopMin(key, BLOCKING_MIN_VALUE)
|
||||
]);
|
||||
|
||||
assert.deepEqual(reply, {
|
||||
key,
|
||||
...member
|
||||
});
|
||||
}, {
|
||||
client: GLOBAL.SERVERS.OPEN,
|
||||
cluster: GLOBAL.SERVERS.OPEN
|
||||
});
|
||||
});
|
||||
|
@@ -1,17 +1,12 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { pushVerdictArguments } from './generic-transformers';
|
||||
import { Command } from '../RESP/types';
|
||||
import BZPOPMAX, { BZPopArguments, transformBZPopArguments } from './BZPOPMAX';
|
||||
|
||||
export const FIRST_KEY_INDEX = 1;
|
||||
export default {
|
||||
FIRST_KEY_INDEX: BZPOPMAX.FIRST_KEY_INDEX,
|
||||
IS_READ_ONLY: BZPOPMAX.IS_READ_ONLY,
|
||||
transformArguments(...args: BZPopArguments) {
|
||||
return transformBZPopArguments('BZPOPMIN', ...args);
|
||||
},
|
||||
transformReply: BZPOPMAX.transformReply
|
||||
} as const satisfies Command;
|
||||
|
||||
export function transformArguments(
|
||||
key: RedisCommandArgument | Array<RedisCommandArgument>,
|
||||
timeout: number
|
||||
): RedisCommandArguments {
|
||||
const args = pushVerdictArguments(['BZPOPMIN'], key);
|
||||
|
||||
args.push(timeout.toString());
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
export { transformReply } from './BZPOPMAX';
|
||||
|
@@ -1,20 +1,20 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { transformArguments } from './CLIENT_CACHING';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import CLIENT_CACHING from './CLIENT_CACHING';
|
||||
|
||||
describe('CLIENT CACHING', () => {
|
||||
describe('transformArguments', () => {
|
||||
it('true', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(true),
|
||||
['CLIENT', 'CACHING', 'YES']
|
||||
);
|
||||
});
|
||||
|
||||
it('false', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(false),
|
||||
['CLIENT', 'CACHING', 'NO']
|
||||
);
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
it('true', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_CACHING.transformArguments(true),
|
||||
['CLIENT', 'CACHING', 'YES']
|
||||
);
|
||||
});
|
||||
|
||||
it('false', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_CACHING.transformArguments(false),
|
||||
['CLIENT', 'CACHING', 'NO']
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,11 +1,14 @@
|
||||
import { RedisCommandArguments } from '.';
|
||||
import { SimpleStringReply, Command } from '../RESP/types';
|
||||
|
||||
export function transformArguments(value: boolean): RedisCommandArguments {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments(value: boolean) {
|
||||
return [
|
||||
'CLIENT',
|
||||
'CACHING',
|
||||
value ? 'YES' : 'NO'
|
||||
'CLIENT',
|
||||
'CACHING',
|
||||
value ? 'YES' : 'NO'
|
||||
];
|
||||
}
|
||||
|
||||
export declare function transformReply(): 'OK' | Buffer;
|
||||
},
|
||||
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,11 +1,19 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { transformArguments } from './CLIENT_GETNAME';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import CLIENT_GETNAME from './CLIENT_GETNAME';
|
||||
|
||||
describe('CLIENT GETNAME', () => {
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(),
|
||||
['CLIENT', 'GETNAME']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_GETNAME.transformArguments(),
|
||||
['CLIENT', 'GETNAME']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.clientGetName', async client => {
|
||||
assert.equal(
|
||||
await client.clientGetName(),
|
||||
null
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
||||
|
@@ -1,7 +1,13 @@
|
||||
import { RedisCommandArguments } from '.';
|
||||
import { BlobStringReply, NullReply, Command } from '../RESP/types';
|
||||
|
||||
export function transformArguments(): RedisCommandArguments {
|
||||
return ['CLIENT', 'GETNAME'];
|
||||
}
|
||||
|
||||
export declare function transformReply(): string | null;
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments() {
|
||||
return [
|
||||
'CLIENT',
|
||||
'GETNAME'
|
||||
];
|
||||
},
|
||||
transformReply: undefined as unknown as () => BlobStringReply | NullReply
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,11 +1,11 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { transformArguments } from './CLIENT_GETREDIR';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import CLIENT_GETREDIR from './CLIENT_GETREDIR';
|
||||
|
||||
describe('CLIENT GETREDIR', () => {
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(),
|
||||
['CLIENT', 'GETREDIR']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_GETREDIR.transformArguments(),
|
||||
['CLIENT', 'GETREDIR']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@@ -1,7 +1,10 @@
|
||||
import { RedisCommandArguments } from '.';
|
||||
import { NumberReply, Command } from '../RESP/types';
|
||||
|
||||
export function transformArguments(): RedisCommandArguments {
|
||||
return ['CLIENT', 'GETREDIR'];
|
||||
}
|
||||
|
||||
export declare function transformReply(): number;
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments() {
|
||||
return ['CLIENT', 'GETREDIR']
|
||||
},
|
||||
transformReply: undefined as unknown as () => NumberReply
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,19 +1,19 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments } from './CLIENT_ID';
|
||||
import CLIENT_ID from './CLIENT_ID';
|
||||
|
||||
describe('CLIENT ID', () => {
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(),
|
||||
['CLIENT', 'ID']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_ID.transformArguments(),
|
||||
['CLIENT', 'ID']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.clientId', async client => {
|
||||
assert.equal(
|
||||
typeof (await client.clientId()),
|
||||
'number'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
testUtils.testWithClient('client.clientId', async client => {
|
||||
assert.equal(
|
||||
typeof (await client.clientId()),
|
||||
'number'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
||||
|
@@ -1,7 +1,10 @@
|
||||
export const IS_READ_ONLY = true;
|
||||
import { NumberReply, Command } from '../RESP/types';
|
||||
|
||||
export function transformArguments(): Array<string> {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments() {
|
||||
return ['CLIENT', 'ID'];
|
||||
}
|
||||
|
||||
export declare function transformReply(): number;
|
||||
},
|
||||
transformReply: undefined as unknown as () => NumberReply
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,50 +1,50 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { transformArguments, transformReply } from './CLIENT_INFO';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import CLIENT_INFO from './CLIENT_INFO';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
|
||||
describe('CLIENT INFO', () => {
|
||||
testUtils.isVersionGreaterThanHook([6, 2]);
|
||||
testUtils.isVersionGreaterThanHook([6, 2]);
|
||||
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(),
|
||||
['CLIENT', 'INFO']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_INFO.transformArguments(),
|
||||
['CLIENT', 'INFO']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.clientInfo', async client => {
|
||||
const reply = await client.clientInfo();
|
||||
assert.equal(typeof reply.id, 'number');
|
||||
assert.equal(typeof reply.addr, 'string');
|
||||
assert.equal(typeof reply.laddr, 'string');
|
||||
assert.equal(typeof reply.fd, 'number');
|
||||
assert.equal(typeof reply.name, 'string');
|
||||
assert.equal(typeof reply.age, 'number');
|
||||
assert.equal(typeof reply.idle, 'number');
|
||||
assert.equal(typeof reply.flags, 'string');
|
||||
assert.equal(typeof reply.db, 'number');
|
||||
assert.equal(typeof reply.sub, 'number');
|
||||
assert.equal(typeof reply.psub, 'number');
|
||||
assert.equal(typeof reply.multi, 'number');
|
||||
assert.equal(typeof reply.qbuf, 'number');
|
||||
assert.equal(typeof reply.qbufFree, 'number');
|
||||
assert.equal(typeof reply.argvMem, 'number');
|
||||
assert.equal(typeof reply.obl, 'number');
|
||||
assert.equal(typeof reply.oll, 'number');
|
||||
assert.equal(typeof reply.omem, 'number');
|
||||
assert.equal(typeof reply.totMem, 'number');
|
||||
assert.equal(typeof reply.events, 'string');
|
||||
assert.equal(typeof reply.cmd, 'string');
|
||||
assert.equal(typeof reply.user, 'string');
|
||||
assert.equal(typeof reply.redir, 'number');
|
||||
testUtils.testWithClient('client.clientInfo', async client => {
|
||||
const reply = await client.clientInfo();
|
||||
assert.equal(typeof reply.id, 'number');
|
||||
assert.equal(typeof reply.addr, 'string');
|
||||
assert.equal(typeof reply.laddr, 'string');
|
||||
assert.equal(typeof reply.fd, 'number');
|
||||
assert.equal(typeof reply.name, 'string');
|
||||
assert.equal(typeof reply.age, 'number');
|
||||
assert.equal(typeof reply.idle, 'number');
|
||||
assert.equal(typeof reply.flags, 'string');
|
||||
assert.equal(typeof reply.db, 'number');
|
||||
assert.equal(typeof reply.sub, 'number');
|
||||
assert.equal(typeof reply.psub, 'number');
|
||||
assert.equal(typeof reply.multi, 'number');
|
||||
assert.equal(typeof reply.qbuf, 'number');
|
||||
assert.equal(typeof reply.qbufFree, 'number');
|
||||
assert.equal(typeof reply.argvMem, 'number');
|
||||
assert.equal(typeof reply.obl, 'number');
|
||||
assert.equal(typeof reply.oll, 'number');
|
||||
assert.equal(typeof reply.omem, 'number');
|
||||
assert.equal(typeof reply.totMem, 'number');
|
||||
assert.equal(typeof reply.events, 'string');
|
||||
assert.equal(typeof reply.cmd, 'string');
|
||||
assert.equal(typeof reply.user, 'string');
|
||||
assert.equal(typeof reply.redir, 'number');
|
||||
|
||||
if (testUtils.isVersionGreaterThan([7, 0])) {
|
||||
assert.equal(typeof reply.multiMem, 'number');
|
||||
assert.equal(typeof reply.resp, 'number');
|
||||
}
|
||||
if (testUtils.isVersionGreaterThan([7, 0])) {
|
||||
assert.equal(typeof reply.multiMem, 'number');
|
||||
assert.equal(typeof reply.resp, 'number');
|
||||
|
||||
if (testUtils.isVersionGreaterThan([7, 0, 3])) {
|
||||
assert.equal(typeof reply.ssub, 'number');
|
||||
}
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
if (testUtils.isVersionGreaterThan([7, 0, 3])) {
|
||||
assert.equal(typeof reply.ssub, 'number');
|
||||
}
|
||||
}
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
||||
|
@@ -1,94 +1,116 @@
|
||||
export const IS_READ_ONLY = true;
|
||||
|
||||
export function transformArguments(): Array<string> {
|
||||
return ['CLIENT', 'INFO'];
|
||||
}
|
||||
import { Command, VerbatimStringReply } from '../RESP/types';
|
||||
|
||||
export interface ClientInfoReply {
|
||||
id: number;
|
||||
addr: string;
|
||||
laddr?: string; // 6.2
|
||||
fd: number;
|
||||
name: string;
|
||||
age: number;
|
||||
idle: number;
|
||||
flags: string;
|
||||
db: number;
|
||||
sub: number;
|
||||
psub: number;
|
||||
ssub?: number; // 7.0.3
|
||||
multi: number;
|
||||
qbuf: number;
|
||||
qbufFree: number;
|
||||
argvMem?: number; // 6.0
|
||||
multiMem?: number; // 7.0
|
||||
obl: number;
|
||||
oll: number;
|
||||
omem: number;
|
||||
totMem?: number; // 6.0
|
||||
events: string;
|
||||
cmd: string;
|
||||
user?: string; // 6.0
|
||||
redir?: number; // 6.2
|
||||
resp?: number; // 7.0
|
||||
// 7.2
|
||||
libName?: string;
|
||||
libVer?: string;
|
||||
id: number;
|
||||
addr: string;
|
||||
/**
|
||||
* available since 6.2
|
||||
*/
|
||||
laddr?: string;
|
||||
fd: number;
|
||||
name: string;
|
||||
age: number;
|
||||
idle: number;
|
||||
flags: string;
|
||||
db: number;
|
||||
sub: number;
|
||||
psub: number;
|
||||
/**
|
||||
* available since 7.0.3
|
||||
*/
|
||||
ssub?: number;
|
||||
multi: number;
|
||||
qbuf: number;
|
||||
qbufFree: number;
|
||||
/**
|
||||
* available since 6.0
|
||||
*/
|
||||
argvMem?: number;
|
||||
/**
|
||||
* available since 7.0
|
||||
*/
|
||||
multiMem?: number;
|
||||
obl: number;
|
||||
oll: number;
|
||||
omem: number;
|
||||
/**
|
||||
* available since 6.0
|
||||
*/
|
||||
totMem?: number;
|
||||
events: string;
|
||||
cmd: string;
|
||||
/**
|
||||
* available since 6.0
|
||||
*/
|
||||
user?: string;
|
||||
/**
|
||||
* available since 6.2
|
||||
*/
|
||||
redir?: number;
|
||||
/**
|
||||
* available since 7.0
|
||||
*/
|
||||
resp?: number;
|
||||
}
|
||||
|
||||
const CLIENT_INFO_REGEX = /([^\s=]+)=([^\s]*)/g;
|
||||
|
||||
export function transformReply(rawReply: string): ClientInfoReply {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments() {
|
||||
return ['CLIENT', 'INFO']
|
||||
},
|
||||
transformReply(rawReply: VerbatimStringReply) {
|
||||
const map: Record<string, string> = {};
|
||||
for (const item of rawReply.matchAll(CLIENT_INFO_REGEX)) {
|
||||
map[item[1]] = item[2];
|
||||
for (const item of rawReply.toString().matchAll(CLIENT_INFO_REGEX)) {
|
||||
map[item[1]] = item[2];
|
||||
}
|
||||
|
||||
const reply: ClientInfoReply = {
|
||||
id: Number(map.id),
|
||||
addr: map.addr,
|
||||
fd: Number(map.fd),
|
||||
name: map.name,
|
||||
age: Number(map.age),
|
||||
idle: Number(map.idle),
|
||||
flags: map.flags,
|
||||
db: Number(map.db),
|
||||
sub: Number(map.sub),
|
||||
psub: Number(map.psub),
|
||||
multi: Number(map.multi),
|
||||
qbuf: Number(map.qbuf),
|
||||
qbufFree: Number(map['qbuf-free']),
|
||||
argvMem: Number(map['argv-mem']),
|
||||
obl: Number(map.obl),
|
||||
oll: Number(map.oll),
|
||||
omem: Number(map.omem),
|
||||
totMem: Number(map['tot-mem']),
|
||||
events: map.events,
|
||||
cmd: map.cmd,
|
||||
user: map.user,
|
||||
libName: map['lib-name'],
|
||||
libVer: map['lib-ver'],
|
||||
id: Number(map.id),
|
||||
addr: map.addr,
|
||||
fd: Number(map.fd),
|
||||
name: map.name,
|
||||
age: Number(map.age),
|
||||
idle: Number(map.idle),
|
||||
flags: map.flags,
|
||||
db: Number(map.db),
|
||||
sub: Number(map.sub),
|
||||
psub: Number(map.psub),
|
||||
multi: Number(map.multi),
|
||||
qbuf: Number(map.qbuf),
|
||||
qbufFree: Number(map['qbuf-free']),
|
||||
argvMem: Number(map['argv-mem']),
|
||||
obl: Number(map.obl),
|
||||
oll: Number(map.oll),
|
||||
omem: Number(map.omem),
|
||||
totMem: Number(map['tot-mem']),
|
||||
events: map.events,
|
||||
cmd: map.cmd,
|
||||
user: map.user
|
||||
};
|
||||
|
||||
if (map.laddr !== undefined) {
|
||||
reply.laddr = map.laddr;
|
||||
reply.laddr = map.laddr;
|
||||
}
|
||||
|
||||
if (map.redir !== undefined) {
|
||||
reply.redir = Number(map.redir);
|
||||
reply.redir = Number(map.redir);
|
||||
}
|
||||
|
||||
if (map.ssub !== undefined) {
|
||||
reply.ssub = Number(map.ssub);
|
||||
reply.ssub = Number(map.ssub);
|
||||
}
|
||||
|
||||
if (map['multi-mem'] !== undefined) {
|
||||
reply.multiMem = Number(map['multi-mem']);
|
||||
reply.multiMem = Number(map['multi-mem']);
|
||||
}
|
||||
|
||||
if (map.resp !== undefined) {
|
||||
reply.resp = Number(map.resp);
|
||||
reply.resp = Number(map.resp);
|
||||
}
|
||||
|
||||
return reply;
|
||||
}
|
||||
}
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,120 +1,120 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { ClientKillFilters, transformArguments } from './CLIENT_KILL';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import CLIENT_KILL, { CLIENT_KILL_FILTERS } from './CLIENT_KILL';
|
||||
|
||||
describe('CLIENT KILL', () => {
|
||||
describe('transformArguments', () => {
|
||||
it('ADDRESS', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments({
|
||||
filter: ClientKillFilters.ADDRESS,
|
||||
address: 'ip:6379'
|
||||
}),
|
||||
['CLIENT', 'KILL', 'ADDR', 'ip:6379']
|
||||
);
|
||||
});
|
||||
|
||||
it('LOCAL_ADDRESS', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments({
|
||||
filter: ClientKillFilters.LOCAL_ADDRESS,
|
||||
localAddress: 'ip:6379'
|
||||
}),
|
||||
['CLIENT', 'KILL', 'LADDR', 'ip:6379']
|
||||
);
|
||||
});
|
||||
|
||||
describe('ID', () => {
|
||||
it('string', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments({
|
||||
filter: ClientKillFilters.ID,
|
||||
id: '1'
|
||||
}),
|
||||
['CLIENT', 'KILL', 'ID', '1']
|
||||
);
|
||||
});
|
||||
|
||||
it('number', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments({
|
||||
filter: ClientKillFilters.ID,
|
||||
id: 1
|
||||
}),
|
||||
['CLIENT', 'KILL', 'ID', '1']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('TYPE', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments({
|
||||
filter: ClientKillFilters.TYPE,
|
||||
type: 'master'
|
||||
}),
|
||||
['CLIENT', 'KILL', 'TYPE', 'master']
|
||||
);
|
||||
});
|
||||
|
||||
it('USER', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments({
|
||||
filter: ClientKillFilters.USER,
|
||||
username: 'username'
|
||||
}),
|
||||
['CLIENT', 'KILL', 'USER', 'username']
|
||||
);
|
||||
});
|
||||
|
||||
it('MAXAGE', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments({
|
||||
filter: ClientKillFilters.MAXAGE,
|
||||
maxAge: 10
|
||||
}),
|
||||
['CLIENT', 'KILL', 'MAXAGE', '10']
|
||||
);
|
||||
});
|
||||
|
||||
describe('SKIP_ME', () => {
|
||||
it('undefined', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(ClientKillFilters.SKIP_ME),
|
||||
['CLIENT', 'KILL', 'SKIPME']
|
||||
);
|
||||
});
|
||||
|
||||
it('true', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments({
|
||||
filter: ClientKillFilters.SKIP_ME,
|
||||
skipMe: true
|
||||
}),
|
||||
['CLIENT', 'KILL', 'SKIPME', 'yes']
|
||||
);
|
||||
});
|
||||
|
||||
it('false', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments({
|
||||
filter: ClientKillFilters.SKIP_ME,
|
||||
skipMe: false
|
||||
}),
|
||||
['CLIENT', 'KILL', 'SKIPME', 'no']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('TYPE & SKIP_ME', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments([
|
||||
{
|
||||
filter: ClientKillFilters.TYPE,
|
||||
type: 'master'
|
||||
},
|
||||
ClientKillFilters.SKIP_ME
|
||||
]),
|
||||
['CLIENT', 'KILL', 'TYPE', 'master', 'SKIPME']
|
||||
);
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
it('ADDRESS', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_KILL.transformArguments({
|
||||
filter: CLIENT_KILL_FILTERS.ADDRESS,
|
||||
address: 'ip:6379'
|
||||
}),
|
||||
['CLIENT', 'KILL', 'ADDR', 'ip:6379']
|
||||
);
|
||||
});
|
||||
|
||||
it('LOCAL_ADDRESS', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_KILL.transformArguments({
|
||||
filter: CLIENT_KILL_FILTERS.LOCAL_ADDRESS,
|
||||
localAddress: 'ip:6379'
|
||||
}),
|
||||
['CLIENT', 'KILL', 'LADDR', 'ip:6379']
|
||||
);
|
||||
});
|
||||
|
||||
describe('ID', () => {
|
||||
it('string', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_KILL.transformArguments({
|
||||
filter: CLIENT_KILL_FILTERS.ID,
|
||||
id: '1'
|
||||
}),
|
||||
['CLIENT', 'KILL', 'ID', '1']
|
||||
);
|
||||
});
|
||||
|
||||
it('number', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_KILL.transformArguments({
|
||||
filter: CLIENT_KILL_FILTERS.ID,
|
||||
id: 1
|
||||
}),
|
||||
['CLIENT', 'KILL', 'ID', '1']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('TYPE', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_KILL.transformArguments({
|
||||
filter: CLIENT_KILL_FILTERS.TYPE,
|
||||
type: 'master'
|
||||
}),
|
||||
['CLIENT', 'KILL', 'TYPE', 'master']
|
||||
);
|
||||
});
|
||||
|
||||
it('USER', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_KILL.transformArguments({
|
||||
filter: CLIENT_KILL_FILTERS.USER,
|
||||
username: 'username'
|
||||
}),
|
||||
['CLIENT', 'KILL', 'USER', 'username']
|
||||
);
|
||||
});
|
||||
|
||||
it('MAXAGE', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_KILL.transformArguments({
|
||||
filter: CLIENT_KILL_FILTERS.MAXAGE,
|
||||
maxAge: 10
|
||||
}),
|
||||
['CLIENT', 'KILL', 'MAXAGE', '10']
|
||||
);
|
||||
});
|
||||
|
||||
describe('SKIP_ME', () => {
|
||||
it('undefined', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_KILL.transformArguments(CLIENT_KILL_FILTERS.SKIP_ME),
|
||||
['CLIENT', 'KILL', 'SKIPME']
|
||||
);
|
||||
});
|
||||
|
||||
it('true', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_KILL.transformArguments({
|
||||
filter: CLIENT_KILL_FILTERS.SKIP_ME,
|
||||
skipMe: true
|
||||
}),
|
||||
['CLIENT', 'KILL', 'SKIPME', 'yes']
|
||||
);
|
||||
});
|
||||
|
||||
it('false', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_KILL.transformArguments({
|
||||
filter: CLIENT_KILL_FILTERS.SKIP_ME,
|
||||
skipMe: false
|
||||
}),
|
||||
['CLIENT', 'KILL', 'SKIPME', 'no']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('TYPE & SKIP_ME', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_KILL.transformArguments([
|
||||
{
|
||||
filter: CLIENT_KILL_FILTERS.TYPE,
|
||||
type: 'master'
|
||||
},
|
||||
CLIENT_KILL_FILTERS.SKIP_ME
|
||||
]),
|
||||
['CLIENT', 'KILL', 'TYPE', 'master', 'SKIPME']
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,104 +1,109 @@
|
||||
import { RedisCommandArguments } from '.';
|
||||
import { RedisArgument, NumberReply, Command } from '../RESP/types';
|
||||
|
||||
export enum ClientKillFilters {
|
||||
ADDRESS = 'ADDR',
|
||||
LOCAL_ADDRESS = 'LADDR',
|
||||
ID = 'ID',
|
||||
TYPE = 'TYPE',
|
||||
USER = 'USER',
|
||||
SKIP_ME = 'SKIPME',
|
||||
MAXAGE = 'MAXAGE'
|
||||
export const CLIENT_KILL_FILTERS = {
|
||||
ADDRESS: 'ADDR',
|
||||
LOCAL_ADDRESS: 'LADDR',
|
||||
ID: 'ID',
|
||||
TYPE: 'TYPE',
|
||||
USER: 'USER',
|
||||
SKIP_ME: 'SKIPME',
|
||||
MAXAGE: 'MAXAGE'
|
||||
} as const;
|
||||
|
||||
type CLIENT_KILL_FILTERS = typeof CLIENT_KILL_FILTERS;
|
||||
|
||||
export interface ClientKillFilterCommon<T extends CLIENT_KILL_FILTERS[keyof CLIENT_KILL_FILTERS]> {
|
||||
filter: T;
|
||||
}
|
||||
|
||||
interface KillFilter<T extends ClientKillFilters> {
|
||||
filter: T;
|
||||
export interface ClientKillAddress extends ClientKillFilterCommon<CLIENT_KILL_FILTERS['ADDRESS']> {
|
||||
address: `${string}:${number}`;
|
||||
}
|
||||
|
||||
interface KillAddress extends KillFilter<ClientKillFilters.ADDRESS> {
|
||||
address: `${string}:${number}`;
|
||||
export interface ClientKillLocalAddress extends ClientKillFilterCommon<CLIENT_KILL_FILTERS['LOCAL_ADDRESS']> {
|
||||
localAddress: `${string}:${number}`;
|
||||
}
|
||||
|
||||
interface KillLocalAddress extends KillFilter<ClientKillFilters.LOCAL_ADDRESS> {
|
||||
localAddress: `${string}:${number}`;
|
||||
export interface ClientKillId extends ClientKillFilterCommon<CLIENT_KILL_FILTERS['ID']> {
|
||||
id: number | `${number}`;
|
||||
}
|
||||
|
||||
interface KillId extends KillFilter<ClientKillFilters.ID> {
|
||||
id: number | `${number}`;
|
||||
export interface ClientKillType extends ClientKillFilterCommon<CLIENT_KILL_FILTERS['TYPE']> {
|
||||
type: 'normal' | 'master' | 'replica' | 'pubsub';
|
||||
}
|
||||
|
||||
interface KillType extends KillFilter<ClientKillFilters.TYPE> {
|
||||
type: 'normal' | 'master' | 'replica' | 'pubsub';
|
||||
export interface ClientKillUser extends ClientKillFilterCommon<CLIENT_KILL_FILTERS['USER']> {
|
||||
username: string;
|
||||
}
|
||||
|
||||
interface KillUser extends KillFilter<ClientKillFilters.USER> {
|
||||
username: string;
|
||||
}
|
||||
|
||||
type KillSkipMe = ClientKillFilters.SKIP_ME | (KillFilter<ClientKillFilters.SKIP_ME> & {
|
||||
skipMe: boolean;
|
||||
export type ClientKillSkipMe = CLIENT_KILL_FILTERS['SKIP_ME'] | (ClientKillFilterCommon<CLIENT_KILL_FILTERS['SKIP_ME']> & {
|
||||
skipMe: boolean;
|
||||
});
|
||||
|
||||
interface KillMaxAge extends KillFilter<ClientKillFilters.MAXAGE> {
|
||||
maxAge: number;
|
||||
export interface ClientKillMaxAge extends ClientKillFilterCommon<CLIENT_KILL_FILTERS['MAXAGE']> {
|
||||
maxAge: number;
|
||||
}
|
||||
|
||||
type KillFilters = KillAddress | KillLocalAddress | KillId | KillType | KillUser | KillSkipMe | KillMaxAge;
|
||||
export type ClientKillFilter = ClientKillAddress | ClientKillLocalAddress | ClientKillId | ClientKillType | ClientKillUser | ClientKillSkipMe | ClientKillMaxAge;
|
||||
|
||||
export function transformArguments(filters: KillFilters | Array<KillFilters>): RedisCommandArguments {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments(filters: ClientKillFilter | Array<ClientKillFilter>) {
|
||||
const args = ['CLIENT', 'KILL'];
|
||||
|
||||
if (Array.isArray(filters)) {
|
||||
for (const filter of filters) {
|
||||
pushFilter(args, filter);
|
||||
}
|
||||
for (const filter of filters) {
|
||||
pushFilter(args, filter);
|
||||
}
|
||||
} else {
|
||||
pushFilter(args, filters);
|
||||
pushFilter(args, filters);
|
||||
}
|
||||
|
||||
return args;
|
||||
},
|
||||
transformReply: undefined as unknown as () => NumberReply
|
||||
} as const satisfies Command;
|
||||
|
||||
function pushFilter(args: Array<RedisArgument>, filter: ClientKillFilter): void {
|
||||
if (filter === CLIENT_KILL_FILTERS.SKIP_ME) {
|
||||
args.push('SKIPME');
|
||||
return;
|
||||
}
|
||||
|
||||
args.push(filter.filter);
|
||||
|
||||
switch (filter.filter) {
|
||||
case CLIENT_KILL_FILTERS.ADDRESS:
|
||||
args.push(filter.address);
|
||||
break;
|
||||
|
||||
case CLIENT_KILL_FILTERS.LOCAL_ADDRESS:
|
||||
args.push(filter.localAddress);
|
||||
break;
|
||||
|
||||
case CLIENT_KILL_FILTERS.ID:
|
||||
args.push(
|
||||
typeof filter.id === 'number' ?
|
||||
filter.id.toString() :
|
||||
filter.id
|
||||
);
|
||||
break;
|
||||
|
||||
case CLIENT_KILL_FILTERS.TYPE:
|
||||
args.push(filter.type);
|
||||
break;
|
||||
|
||||
case CLIENT_KILL_FILTERS.USER:
|
||||
args.push(filter.username);
|
||||
break;
|
||||
|
||||
case CLIENT_KILL_FILTERS.SKIP_ME:
|
||||
args.push(filter.skipMe ? 'yes' : 'no');
|
||||
break;
|
||||
|
||||
case CLIENT_KILL_FILTERS.MAXAGE:
|
||||
args.push(filter.maxAge.toString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function pushFilter(args: RedisCommandArguments, filter: KillFilters): void {
|
||||
if (filter === ClientKillFilters.SKIP_ME) {
|
||||
args.push('SKIPME');
|
||||
return;
|
||||
}
|
||||
|
||||
args.push(filter.filter);
|
||||
|
||||
switch(filter.filter) {
|
||||
case ClientKillFilters.ADDRESS:
|
||||
args.push(filter.address);
|
||||
break;
|
||||
|
||||
case ClientKillFilters.LOCAL_ADDRESS:
|
||||
args.push(filter.localAddress);
|
||||
break;
|
||||
|
||||
case ClientKillFilters.ID:
|
||||
args.push(
|
||||
typeof filter.id === 'number' ?
|
||||
filter.id.toString() :
|
||||
filter.id
|
||||
);
|
||||
break;
|
||||
|
||||
case ClientKillFilters.TYPE:
|
||||
args.push(filter.type);
|
||||
break;
|
||||
|
||||
case ClientKillFilters.USER:
|
||||
args.push(filter.username);
|
||||
break;
|
||||
|
||||
case ClientKillFilters.SKIP_ME:
|
||||
args.push(filter.skipMe ? 'yes' : 'no');
|
||||
break;
|
||||
|
||||
case ClientKillFilters.MAXAGE:
|
||||
args.push(filter.maxAge.toString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
export declare function transformReply(): number;
|
||||
|
@@ -1,78 +1,77 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { transformArguments, transformReply } from './CLIENT_LIST';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import CLIENT_LIST from './CLIENT_LIST';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
|
||||
describe('CLIENT LIST', () => {
|
||||
describe('transformArguments', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(),
|
||||
['CLIENT', 'LIST']
|
||||
);
|
||||
});
|
||||
|
||||
it('with TYPE', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments({
|
||||
TYPE: 'NORMAL'
|
||||
}),
|
||||
['CLIENT', 'LIST', 'TYPE', 'NORMAL']
|
||||
);
|
||||
});
|
||||
|
||||
it('with ID', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments({
|
||||
ID: ['1', '2']
|
||||
}),
|
||||
['CLIENT', 'LIST', 'ID', '1', '2']
|
||||
);
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_LIST.transformArguments(),
|
||||
['CLIENT', 'LIST']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.clientList', async client => {
|
||||
const reply = await client.clientList();
|
||||
assert.ok(Array.isArray(reply));
|
||||
it('with TYPE', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_LIST.transformArguments({
|
||||
TYPE: 'NORMAL'
|
||||
}),
|
||||
['CLIENT', 'LIST', 'TYPE', 'NORMAL']
|
||||
);
|
||||
});
|
||||
|
||||
for (const item of reply) {
|
||||
assert.equal(typeof item.id, 'number');
|
||||
assert.equal(typeof item.addr, 'string');
|
||||
assert.equal(typeof item.fd, 'number');
|
||||
assert.equal(typeof item.name, 'string');
|
||||
assert.equal(typeof item.age, 'number');
|
||||
assert.equal(typeof item.idle, 'number');
|
||||
assert.equal(typeof item.flags, 'string');
|
||||
assert.equal(typeof item.db, 'number');
|
||||
assert.equal(typeof item.sub, 'number');
|
||||
assert.equal(typeof item.psub, 'number');
|
||||
assert.equal(typeof item.multi, 'number');
|
||||
assert.equal(typeof item.qbuf, 'number');
|
||||
assert.equal(typeof item.qbufFree, 'number');
|
||||
assert.equal(typeof item.obl, 'number');
|
||||
assert.equal(typeof item.oll, 'number');
|
||||
assert.equal(typeof item.omem, 'number');
|
||||
assert.equal(typeof item.events, 'string');
|
||||
assert.equal(typeof item.cmd, 'string');
|
||||
it('with ID', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_LIST.transformArguments({
|
||||
ID: ['1', '2']
|
||||
}),
|
||||
['CLIENT', 'LIST', 'ID', '1', '2']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
if (testUtils.isVersionGreaterThan([6, 0])) {
|
||||
assert.equal(typeof item.argvMem, 'number');
|
||||
assert.equal(typeof item.totMem, 'number');
|
||||
assert.equal(typeof item.user, 'string');
|
||||
}
|
||||
testUtils.testWithClient('client.clientList', async client => {
|
||||
const reply = await client.clientList();
|
||||
assert.ok(Array.isArray(reply));
|
||||
for (const item of reply) {
|
||||
assert.equal(typeof item.id, 'number');
|
||||
assert.equal(typeof item.addr, 'string');
|
||||
assert.equal(typeof item.fd, 'number');
|
||||
assert.equal(typeof item.name, 'string');
|
||||
assert.equal(typeof item.age, 'number');
|
||||
assert.equal(typeof item.idle, 'number');
|
||||
assert.equal(typeof item.flags, 'string');
|
||||
assert.equal(typeof item.db, 'number');
|
||||
assert.equal(typeof item.sub, 'number');
|
||||
assert.equal(typeof item.psub, 'number');
|
||||
assert.equal(typeof item.multi, 'number');
|
||||
assert.equal(typeof item.qbuf, 'number');
|
||||
assert.equal(typeof item.qbufFree, 'number');
|
||||
assert.equal(typeof item.obl, 'number');
|
||||
assert.equal(typeof item.oll, 'number');
|
||||
assert.equal(typeof item.omem, 'number');
|
||||
assert.equal(typeof item.events, 'string');
|
||||
assert.equal(typeof item.cmd, 'string');
|
||||
|
||||
if (testUtils.isVersionGreaterThan([6, 2])) {
|
||||
assert.equal(typeof item.redir, 'number');
|
||||
assert.equal(typeof item.laddr, 'string');
|
||||
}
|
||||
|
||||
if (testUtils.isVersionGreaterThan([7, 0])) {
|
||||
assert.equal(typeof item.multiMem, 'number');
|
||||
assert.equal(typeof item.resp, 'number');
|
||||
}
|
||||
if (testUtils.isVersionGreaterThan([6, 0])) {
|
||||
assert.equal(typeof item.argvMem, 'number');
|
||||
assert.equal(typeof item.totMem, 'number');
|
||||
assert.equal(typeof item.user, 'string');
|
||||
|
||||
if (testUtils.isVersionGreaterThan([6, 2])) {
|
||||
assert.equal(typeof item.redir, 'number');
|
||||
assert.equal(typeof item.laddr, 'string');
|
||||
|
||||
if (testUtils.isVersionGreaterThan([7, 0])) {
|
||||
assert.equal(typeof item.multiMem, 'number');
|
||||
assert.equal(typeof item.resp, 'number');
|
||||
|
||||
if (testUtils.isVersionGreaterThan([7, 0, 3])) {
|
||||
assert.equal(typeof item.ssub, 'number');
|
||||
assert.equal(typeof item.ssub, 'number');
|
||||
}
|
||||
}
|
||||
}
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
}
|
||||
}
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
||||
|
@@ -1,43 +1,44 @@
|
||||
import { RedisCommandArguments, RedisCommandArgument } from '.';
|
||||
import { pushVerdictArguments } from './generic-transformers';
|
||||
import { transformReply as transformClientInfoReply, ClientInfoReply } from './CLIENT_INFO';
|
||||
import { RedisArgument, VerbatimStringReply, Command } from '../RESP/types';
|
||||
import { pushVariadicArguments } from './generic-transformers';
|
||||
import CLIENT_INFO, { ClientInfoReply } from './CLIENT_INFO';
|
||||
|
||||
interface ListFilterType {
|
||||
TYPE: 'NORMAL' | 'MASTER' | 'REPLICA' | 'PUBSUB';
|
||||
ID?: never;
|
||||
export interface ListFilterType {
|
||||
TYPE: 'NORMAL' | 'MASTER' | 'REPLICA' | 'PUBSUB';
|
||||
ID?: never;
|
||||
}
|
||||
|
||||
interface ListFilterId {
|
||||
ID: Array<RedisCommandArgument>;
|
||||
TYPE?: never;
|
||||
export interface ListFilterId {
|
||||
ID: Array<RedisArgument>;
|
||||
TYPE?: never;
|
||||
}
|
||||
|
||||
export type ListFilter = ListFilterType | ListFilterId;
|
||||
|
||||
export const IS_READ_ONLY = true;
|
||||
|
||||
export function transformArguments(filter?: ListFilter): RedisCommandArguments {
|
||||
let args: RedisCommandArguments = ['CLIENT', 'LIST'];
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments(filter?: ListFilter) {
|
||||
let args: Array<RedisArgument> = ['CLIENT', 'LIST'];
|
||||
|
||||
if (filter) {
|
||||
if (filter.TYPE !== undefined) {
|
||||
args.push('TYPE', filter.TYPE);
|
||||
} else {
|
||||
args.push('ID');
|
||||
args = pushVerdictArguments(args, filter.ID);
|
||||
}
|
||||
if (filter.TYPE !== undefined) {
|
||||
args.push('TYPE', filter.TYPE);
|
||||
} else {
|
||||
args.push('ID');
|
||||
args = pushVariadicArguments(args, filter.ID);
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
export function transformReply(rawReply: string): Array<ClientInfoReply> {
|
||||
const split = rawReply.split('\n'),
|
||||
length = split.length - 1,
|
||||
reply: Array<ClientInfoReply> = [];
|
||||
},
|
||||
transformReply(rawReply: VerbatimStringReply): Array<ClientInfoReply> {
|
||||
const split = rawReply.toString().split('\n'),
|
||||
length = split.length - 1,
|
||||
reply: Array<ClientInfoReply> = [];
|
||||
for (let i = 0; i < length; i++) {
|
||||
reply.push(transformClientInfoReply(split[i]));
|
||||
reply.push(CLIENT_INFO.transformReply(split[i] as unknown as VerbatimStringReply));
|
||||
}
|
||||
|
||||
|
||||
return reply;
|
||||
}
|
||||
}
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,30 +1,30 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments } from './CLIENT_NO-EVICT';
|
||||
import CLIENT_NO_EVICT from './CLIENT_NO-EVICT';
|
||||
|
||||
describe('CLIENT NO-EVICT', () => {
|
||||
testUtils.isVersionGreaterThanHook([7]);
|
||||
testUtils.isVersionGreaterThanHook([7]);
|
||||
|
||||
describe('transformArguments', () => {
|
||||
it('true', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(true),
|
||||
['CLIENT', 'NO-EVICT', 'ON']
|
||||
);
|
||||
});
|
||||
|
||||
it('false', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(false),
|
||||
['CLIENT', 'NO-EVICT', 'OFF']
|
||||
);
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
it('true', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_NO_EVICT.transformArguments(true),
|
||||
['CLIENT', 'NO-EVICT', 'ON']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.clientNoEvict', async client => {
|
||||
assert.equal(
|
||||
await client.clientNoEvict(true),
|
||||
'OK'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
it('false', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_NO_EVICT.transformArguments(false),
|
||||
['CLIENT', 'NO-EVICT', 'OFF']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.clientNoEvict', async client => {
|
||||
assert.equal(
|
||||
await client.clientNoEvict(true),
|
||||
'OK'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
||||
|
@@ -1,11 +1,14 @@
|
||||
import { RedisCommandArguments } from '.';
|
||||
import { SimpleStringReply, Command } from '../RESP/types';
|
||||
|
||||
export function transformArguments(value: boolean): RedisCommandArguments {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments(value: boolean) {
|
||||
return [
|
||||
'CLIENT',
|
||||
'NO-EVICT',
|
||||
value ? 'ON' : 'OFF'
|
||||
'CLIENT',
|
||||
'NO-EVICT',
|
||||
value ? 'ON' : 'OFF'
|
||||
];
|
||||
}
|
||||
|
||||
export declare function transformReply(): 'OK' | Buffer;
|
||||
},
|
||||
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,30 +1,30 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments } from './CLIENT_NO-TOUCH';
|
||||
import CLIENT_NO_TOUCH from './CLIENT_NO-TOUCH';
|
||||
|
||||
describe('CLIENT NO-TOUCH', () => {
|
||||
testUtils.isVersionGreaterThanHook([7, 2]);
|
||||
testUtils.isVersionGreaterThanHook([7, 2]);
|
||||
|
||||
describe('transformArguments', () => {
|
||||
it('true', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(true),
|
||||
['CLIENT', 'NO-TOUCH', 'ON']
|
||||
);
|
||||
});
|
||||
|
||||
it('false', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(false),
|
||||
['CLIENT', 'NO-TOUCH', 'OFF']
|
||||
);
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
it('true', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_NO_TOUCH.transformArguments(true),
|
||||
['CLIENT', 'NO-TOUCH', 'ON']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.clientNoTouch', async client => {
|
||||
assert.equal(
|
||||
await client.clientNoTouch(true),
|
||||
'OK'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
it('false', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_NO_TOUCH.transformArguments(false),
|
||||
['CLIENT', 'NO-TOUCH', 'OFF']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.clientNoTouch', async client => {
|
||||
assert.equal(
|
||||
await client.clientNoTouch(true),
|
||||
'OK'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
||||
|
@@ -1,11 +1,15 @@
|
||||
import { RedisCommandArguments } from '.';
|
||||
import { SimpleStringReply, Command } from '../RESP/types';
|
||||
|
||||
export function transformArguments(value: boolean): RedisCommandArguments {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments(value: boolean) {
|
||||
return [
|
||||
'CLIENT',
|
||||
'NO-TOUCH',
|
||||
value ? 'ON' : 'OFF'
|
||||
'CLIENT',
|
||||
'NO-TOUCH',
|
||||
value ? 'ON' : 'OFF'
|
||||
];
|
||||
}
|
||||
},
|
||||
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||
} as const satisfies Command;
|
||||
|
||||
export declare function transformReply(): 'OK' | Buffer;
|
||||
|
@@ -1,28 +1,28 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments } from './CLIENT_PAUSE';
|
||||
import CLIENT_PAUSE from './CLIENT_PAUSE';
|
||||
|
||||
describe('CLIENT PAUSE', () => {
|
||||
describe('transformArguments', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(0),
|
||||
['CLIENT', 'PAUSE', '0']
|
||||
);
|
||||
});
|
||||
|
||||
it('with mode', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(0, 'ALL'),
|
||||
['CLIENT', 'PAUSE', '0', 'ALL']
|
||||
);
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_PAUSE.transformArguments(0),
|
||||
['CLIENT', 'PAUSE', '0']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.clientPause', async client => {
|
||||
assert.equal(
|
||||
await client.clientPause(0),
|
||||
'OK'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
it('with mode', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_PAUSE.transformArguments(0, 'ALL'),
|
||||
['CLIENT', 'PAUSE', '0', 'ALL']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.clientPause', async client => {
|
||||
assert.equal(
|
||||
await client.clientPause(0),
|
||||
'OK'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
||||
|
@@ -1,20 +1,20 @@
|
||||
import { RedisCommandArguments } from '.';
|
||||
import { SimpleStringReply, Command } from '../RESP/types';
|
||||
|
||||
export function transformArguments(
|
||||
timeout: number,
|
||||
mode?: 'WRITE' | 'ALL'
|
||||
): RedisCommandArguments {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments(timeout: number, mode?: 'WRITE' | 'ALL') {
|
||||
const args = [
|
||||
'CLIENT',
|
||||
'PAUSE',
|
||||
timeout.toString()
|
||||
'CLIENT',
|
||||
'PAUSE',
|
||||
timeout.toString()
|
||||
];
|
||||
|
||||
if (mode) {
|
||||
args.push(mode);
|
||||
args.push(mode);
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
export declare function transformReply(): 'OK' | Buffer;
|
||||
},
|
||||
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,11 +1,20 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { transformArguments } from './CLIENT_SETNAME';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
|
||||
import CLIENT_SETNAME from './CLIENT_SETNAME';
|
||||
|
||||
describe('CLIENT SETNAME', () => {
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('name'),
|
||||
['CLIENT', 'SETNAME', 'name']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_SETNAME.transformArguments('name'),
|
||||
['CLIENT', 'SETNAME', 'name']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.clientSetName', async client => {
|
||||
assert.equal(
|
||||
await client.clientSetName('name'),
|
||||
'OK'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
||||
|
@@ -1,7 +1,10 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { RedisArgument, SimpleStringReply, Command } from '../RESP/types';
|
||||
|
||||
export function transformArguments(name: RedisCommandArgument): RedisCommandArguments {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments(name: RedisArgument) {
|
||||
return ['CLIENT', 'SETNAME', name];
|
||||
}
|
||||
|
||||
export declare function transformReply(): RedisCommandArgument;
|
||||
},
|
||||
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,101 +1,101 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments } from './CLIENT_TRACKING';
|
||||
import CLIENT_TRACKING from './CLIENT_TRACKING';
|
||||
|
||||
describe('CLIENT TRACKING', () => {
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
testUtils.isVersionGreaterThanHook([6]);
|
||||
|
||||
describe('transformArguments', () => {
|
||||
describe('true', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(true),
|
||||
['CLIENT', 'TRACKING', 'ON']
|
||||
);
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
describe('true', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_TRACKING.transformArguments(true),
|
||||
['CLIENT', 'TRACKING', 'ON']
|
||||
);
|
||||
});
|
||||
|
||||
it('with REDIRECT', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(true, {
|
||||
REDIRECT: 1
|
||||
}),
|
||||
['CLIENT', 'TRACKING', 'ON', 'REDIRECT', '1']
|
||||
);
|
||||
});
|
||||
it('with REDIRECT', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_TRACKING.transformArguments(true, {
|
||||
REDIRECT: 1
|
||||
}),
|
||||
['CLIENT', 'TRACKING', 'ON', 'REDIRECT', '1']
|
||||
);
|
||||
});
|
||||
|
||||
describe('with BCAST', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(true, {
|
||||
BCAST: true
|
||||
}),
|
||||
['CLIENT', 'TRACKING', 'ON', 'BCAST']
|
||||
);
|
||||
});
|
||||
|
||||
describe('with PREFIX', () => {
|
||||
it('string', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(true, {
|
||||
BCAST: true,
|
||||
PREFIX: 'prefix'
|
||||
}),
|
||||
['CLIENT', 'TRACKING', 'ON', 'BCAST', 'PREFIX', 'prefix']
|
||||
);
|
||||
});
|
||||
|
||||
it('array', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(true, {
|
||||
BCAST: true,
|
||||
PREFIX: ['1', '2']
|
||||
}),
|
||||
['CLIENT', 'TRACKING', 'ON', 'BCAST', 'PREFIX', '1', 'PREFIX', '2']
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('with OPTIN', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(true, {
|
||||
OPTIN: true
|
||||
}),
|
||||
['CLIENT', 'TRACKING', 'ON', 'OPTIN']
|
||||
);
|
||||
});
|
||||
|
||||
it('with OPTOUT', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(true, {
|
||||
OPTOUT: true
|
||||
}),
|
||||
['CLIENT', 'TRACKING', 'ON', 'OPTOUT']
|
||||
);
|
||||
});
|
||||
|
||||
it('with NOLOOP', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(true, {
|
||||
NOLOOP: true
|
||||
}),
|
||||
['CLIENT', 'TRACKING', 'ON', 'NOLOOP']
|
||||
);
|
||||
});
|
||||
describe('with BCAST', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_TRACKING.transformArguments(true, {
|
||||
BCAST: true
|
||||
}),
|
||||
['CLIENT', 'TRACKING', 'ON', 'BCAST']
|
||||
);
|
||||
});
|
||||
|
||||
it('false', () => {
|
||||
describe('with PREFIX', () => {
|
||||
it('string', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(false),
|
||||
['CLIENT', 'TRACKING', 'OFF']
|
||||
CLIENT_TRACKING.transformArguments(true, {
|
||||
BCAST: true,
|
||||
PREFIX: 'prefix'
|
||||
}),
|
||||
['CLIENT', 'TRACKING', 'ON', 'BCAST', 'PREFIX', 'prefix']
|
||||
);
|
||||
});
|
||||
|
||||
it('array', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_TRACKING.transformArguments(true, {
|
||||
BCAST: true,
|
||||
PREFIX: ['1', '2']
|
||||
}),
|
||||
['CLIENT', 'TRACKING', 'ON', 'BCAST', 'PREFIX', '1', 'PREFIX', '2']
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('with OPTIN', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_TRACKING.transformArguments(true, {
|
||||
OPTIN: true
|
||||
}),
|
||||
['CLIENT', 'TRACKING', 'ON', 'OPTIN']
|
||||
);
|
||||
});
|
||||
|
||||
it('with OPTOUT', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_TRACKING.transformArguments(true, {
|
||||
OPTOUT: true
|
||||
}),
|
||||
['CLIENT', 'TRACKING', 'ON', 'OPTOUT']
|
||||
);
|
||||
});
|
||||
|
||||
it('with NOLOOP', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_TRACKING.transformArguments(true, {
|
||||
NOLOOP: true
|
||||
}),
|
||||
['CLIENT', 'TRACKING', 'ON', 'NOLOOP']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.clientTracking', async client => {
|
||||
assert.equal(
|
||||
await client.clientTracking(false),
|
||||
'OK'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
it('false', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_TRACKING.transformArguments(false),
|
||||
['CLIENT', 'TRACKING', 'OFF']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.clientTracking', async client => {
|
||||
assert.equal(
|
||||
await client.clientTracking(false),
|
||||
'OK'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
||||
|
@@ -1,83 +1,87 @@
|
||||
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||
import { RedisArgument, SimpleStringReply, Command } from '../RESP/types';
|
||||
import { RedisVariadicArgument } from './generic-transformers';
|
||||
|
||||
interface CommonOptions {
|
||||
REDIRECT?: number;
|
||||
NOLOOP?: boolean;
|
||||
REDIRECT?: number;
|
||||
NOLOOP?: boolean;
|
||||
}
|
||||
|
||||
interface BroadcastOptions {
|
||||
BCAST?: boolean;
|
||||
PREFIX?: RedisCommandArgument | Array<RedisCommandArgument>;
|
||||
BCAST?: boolean;
|
||||
PREFIX?: RedisVariadicArgument;
|
||||
}
|
||||
|
||||
interface OptInOptions {
|
||||
OPTIN?: boolean;
|
||||
OPTIN?: boolean;
|
||||
}
|
||||
|
||||
interface OptOutOptions {
|
||||
OPTOUT?: boolean;
|
||||
OPTOUT?: boolean;
|
||||
}
|
||||
|
||||
type ClientTrackingOptions = CommonOptions & (
|
||||
BroadcastOptions |
|
||||
OptInOptions |
|
||||
OptOutOptions
|
||||
export type ClientTrackingOptions = CommonOptions & (
|
||||
BroadcastOptions |
|
||||
OptInOptions |
|
||||
OptOutOptions
|
||||
);
|
||||
|
||||
export function transformArguments<M extends boolean>(
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments<M extends boolean>(
|
||||
mode: M,
|
||||
options?: M extends true ? ClientTrackingOptions : undefined
|
||||
): RedisCommandArguments {
|
||||
const args: RedisCommandArguments = [
|
||||
'CLIENT',
|
||||
'TRACKING',
|
||||
mode ? 'ON' : 'OFF'
|
||||
options?: M extends true ? ClientTrackingOptions : never
|
||||
) {
|
||||
const args: Array<RedisArgument> = [
|
||||
'CLIENT',
|
||||
'TRACKING',
|
||||
mode ? 'ON' : 'OFF'
|
||||
];
|
||||
|
||||
if (mode) {
|
||||
if (options?.REDIRECT) {
|
||||
args.push(
|
||||
'REDIRECT',
|
||||
options.REDIRECT.toString()
|
||||
);
|
||||
}
|
||||
if (options?.REDIRECT) {
|
||||
args.push(
|
||||
'REDIRECT',
|
||||
options.REDIRECT.toString()
|
||||
);
|
||||
}
|
||||
|
||||
if (isBroadcast(options)) {
|
||||
args.push('BCAST');
|
||||
if (isBroadcast(options)) {
|
||||
args.push('BCAST');
|
||||
|
||||
if (options?.PREFIX) {
|
||||
if (Array.isArray(options.PREFIX)) {
|
||||
for (const prefix of options.PREFIX) {
|
||||
args.push('PREFIX', prefix);
|
||||
}
|
||||
} else {
|
||||
args.push('PREFIX', options.PREFIX);
|
||||
}
|
||||
if (options?.PREFIX) {
|
||||
if (Array.isArray(options.PREFIX)) {
|
||||
for (const prefix of options.PREFIX) {
|
||||
args.push('PREFIX', prefix);
|
||||
}
|
||||
} else if (isOptIn(options)) {
|
||||
args.push('OPTIN');
|
||||
} else if (isOptOut(options)) {
|
||||
args.push('OPTOUT');
|
||||
} else {
|
||||
args.push('PREFIX', options.PREFIX);
|
||||
}
|
||||
}
|
||||
} else if (isOptIn(options)) {
|
||||
args.push('OPTIN');
|
||||
} else if (isOptOut(options)) {
|
||||
args.push('OPTOUT');
|
||||
}
|
||||
|
||||
if (options?.NOLOOP) {
|
||||
args.push('NOLOOP');
|
||||
}
|
||||
if (options?.NOLOOP) {
|
||||
args.push('NOLOOP');
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
},
|
||||
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||
} as const satisfies Command;
|
||||
|
||||
function isBroadcast(options?: ClientTrackingOptions): options is BroadcastOptions {
|
||||
return (options as BroadcastOptions)?.BCAST === true;
|
||||
return (options as BroadcastOptions)?.BCAST === true;
|
||||
}
|
||||
|
||||
function isOptIn(options?: ClientTrackingOptions): options is OptInOptions {
|
||||
return (options as OptInOptions)?.OPTIN === true;
|
||||
return (options as OptInOptions)?.OPTIN === true;
|
||||
}
|
||||
|
||||
function isOptOut(options?: ClientTrackingOptions): options is OptOutOptions {
|
||||
return (options as OptOutOptions)?.OPTOUT === true;
|
||||
return (options as OptOutOptions)?.OPTOUT === true;
|
||||
}
|
||||
|
||||
export declare function transformReply(): 'OK' | Buffer;
|
||||
|
@@ -1,25 +1,25 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments } from './CLIENT_TRACKINGINFO';
|
||||
import CLIENT_TRACKINGINFO from './CLIENT_TRACKINGINFO';
|
||||
|
||||
describe('CLIENT TRACKINGINFO', () => {
|
||||
testUtils.isVersionGreaterThanHook([6, 2]);
|
||||
testUtils.isVersionGreaterThanHook([6, 2]);
|
||||
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(),
|
||||
['CLIENT', 'TRACKINGINFO']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_TRACKINGINFO.transformArguments(),
|
||||
['CLIENT', 'TRACKINGINFO']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.clientTrackingInfo', async client => {
|
||||
assert.deepEqual(
|
||||
await client.clientTrackingInfo(),
|
||||
{
|
||||
flags: new Set(['off']),
|
||||
redirect: -1,
|
||||
prefixes: []
|
||||
}
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
testUtils.testWithClient('client.clientTrackingInfo', async client => {
|
||||
assert.deepEqual(
|
||||
await client.clientTrackingInfo(),
|
||||
{
|
||||
flags: ['off'],
|
||||
redirect: -1,
|
||||
prefixes: []
|
||||
}
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
||||
|
@@ -1,28 +1,23 @@
|
||||
import { RedisCommandArguments } from '.';
|
||||
import { TuplesToMapReply, BlobStringReply, SetReply, NumberReply, ArrayReply, UnwrapReply, Resp2Reply, Command } from '../RESP/types';
|
||||
|
||||
export function transformArguments(): RedisCommandArguments {
|
||||
type TrackingInfo = TuplesToMapReply<[
|
||||
[BlobStringReply<'flags'>, SetReply<BlobStringReply>],
|
||||
[BlobStringReply<'redirect'>, NumberReply],
|
||||
[BlobStringReply<'prefixes'>, ArrayReply<BlobStringReply>]
|
||||
]>;
|
||||
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments() {
|
||||
return ['CLIENT', 'TRACKINGINFO'];
|
||||
}
|
||||
|
||||
type RawReply = [
|
||||
'flags',
|
||||
Array<string>,
|
||||
'redirect',
|
||||
number,
|
||||
'prefixes',
|
||||
Array<string>
|
||||
];
|
||||
|
||||
interface Reply {
|
||||
flags: Set<string>;
|
||||
redirect: number;
|
||||
prefixes: Array<string>;
|
||||
}
|
||||
|
||||
export function transformReply(reply: RawReply): Reply {
|
||||
return {
|
||||
flags: new Set(reply[1]),
|
||||
redirect: reply[3],
|
||||
prefixes: reply[5]
|
||||
};
|
||||
}
|
||||
},
|
||||
transformReply: {
|
||||
2: (reply: UnwrapReply<Resp2Reply<TrackingInfo>>) => ({
|
||||
flags: reply[1],
|
||||
redirect: reply[3],
|
||||
prefixes: reply[5]
|
||||
}),
|
||||
3: undefined as unknown as () => TrackingInfo
|
||||
}
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,21 +1,21 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments } from './CLIENT_UNPAUSE';
|
||||
import CLIENT_UNPAUSE from './CLIENT_UNPAUSE';
|
||||
|
||||
describe('CLIENT UNPAUSE', () => {
|
||||
testUtils.isVersionGreaterThanHook([6, 2]);
|
||||
testUtils.isVersionGreaterThanHook([6, 2]);
|
||||
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(),
|
||||
['CLIENT', 'UNPAUSE']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
CLIENT_UNPAUSE.transformArguments(),
|
||||
['CLIENT', 'UNPAUSE']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithClient('client.unpause', async client => {
|
||||
assert.equal(
|
||||
await client.clientUnpause(),
|
||||
'OK'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
testUtils.testWithClient('client.clientUnpause', async client => {
|
||||
assert.equal(
|
||||
await client.clientUnpause(),
|
||||
'OK'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
||||
|
@@ -1,7 +1,10 @@
|
||||
import { RedisCommandArguments } from '.';
|
||||
import { SimpleStringReply, Command } from '../RESP/types';
|
||||
|
||||
export function transformArguments(): RedisCommandArguments {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments() {
|
||||
return ['CLIENT', 'UNPAUSE'];
|
||||
}
|
||||
|
||||
export declare function transformReply(): 'OK' | Buffer;
|
||||
},
|
||||
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,20 +1,20 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { transformArguments } from './CLUSTER_ADDSLOTS';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import CLUSTER_ADDSLOTS from './CLUSTER_ADDSLOTS';
|
||||
|
||||
describe('CLUSTER ADDSLOTS', () => {
|
||||
describe('transformArguments', () => {
|
||||
it('single', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(0),
|
||||
['CLUSTER', 'ADDSLOTS', '0']
|
||||
);
|
||||
});
|
||||
|
||||
it('multiple', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments([0, 1]),
|
||||
['CLUSTER', 'ADDSLOTS', '0', '1']
|
||||
);
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
it('single', () => {
|
||||
assert.deepEqual(
|
||||
CLUSTER_ADDSLOTS.transformArguments(0),
|
||||
['CLUSTER', 'ADDSLOTS', '0']
|
||||
);
|
||||
});
|
||||
|
||||
it('multiple', () => {
|
||||
assert.deepEqual(
|
||||
CLUSTER_ADDSLOTS.transformArguments([0, 1]),
|
||||
['CLUSTER', 'ADDSLOTS', '0', '1']
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,11 +1,14 @@
|
||||
import { RedisCommandArguments } from '.';
|
||||
import { pushVerdictNumberArguments } from './generic-transformers';
|
||||
import { SimpleStringReply, Command } from '../RESP/types';
|
||||
import { pushVariadicNumberArguments } from './generic-transformers';
|
||||
|
||||
export function transformArguments(slots: number | Array<number>): RedisCommandArguments {
|
||||
return pushVerdictNumberArguments(
|
||||
['CLUSTER', 'ADDSLOTS'],
|
||||
slots
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments(slots: number | Array<number>) {
|
||||
return pushVariadicNumberArguments(
|
||||
['CLUSTER', 'ADDSLOTS'],
|
||||
slots
|
||||
);
|
||||
}
|
||||
|
||||
export declare function transformReply(): string;
|
||||
},
|
||||
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,29 +1,32 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { transformArguments } from './CLUSTER_ADDSLOTSRANGE';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils from '../test-utils';
|
||||
import CLUSTER_ADDSLOTSRANGE from './CLUSTER_ADDSLOTSRANGE';
|
||||
|
||||
describe('CLUSTER ADDSLOTSRANGE', () => {
|
||||
describe('transformArguments', () => {
|
||||
it('single', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments({
|
||||
start: 0,
|
||||
end: 1
|
||||
}),
|
||||
['CLUSTER', 'ADDSLOTSRANGE', '0', '1']
|
||||
);
|
||||
});
|
||||
testUtils.isVersionGreaterThanHook([7, 0]);
|
||||
|
||||
it('multiple', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments([{
|
||||
start: 0,
|
||||
end: 1
|
||||
}, {
|
||||
start: 2,
|
||||
end: 3
|
||||
}]),
|
||||
['CLUSTER', 'ADDSLOTSRANGE', '0', '1', '2', '3']
|
||||
);
|
||||
});
|
||||
describe('transformArguments', () => {
|
||||
it('single', () => {
|
||||
assert.deepEqual(
|
||||
CLUSTER_ADDSLOTSRANGE.transformArguments({
|
||||
start: 0,
|
||||
end: 1
|
||||
}),
|
||||
['CLUSTER', 'ADDSLOTSRANGE', '0', '1']
|
||||
);
|
||||
});
|
||||
|
||||
it('multiple', () => {
|
||||
assert.deepEqual(
|
||||
CLUSTER_ADDSLOTSRANGE.transformArguments([{
|
||||
start: 0,
|
||||
end: 1
|
||||
}, {
|
||||
start: 2,
|
||||
end: 3
|
||||
}]),
|
||||
['CLUSTER', 'ADDSLOTSRANGE', '0', '1', '2', '3']
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,13 +1,14 @@
|
||||
import { RedisCommandArguments } from '.';
|
||||
import { SimpleStringReply, Command } from '../RESP/types';
|
||||
import { pushSlotRangesArguments, SlotRange } from './generic-transformers';
|
||||
|
||||
export function transformArguments(
|
||||
ranges: SlotRange | Array<SlotRange>
|
||||
): RedisCommandArguments {
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments(ranges: SlotRange | Array<SlotRange>) {
|
||||
return pushSlotRangesArguments(
|
||||
['CLUSTER', 'ADDSLOTSRANGE'],
|
||||
ranges
|
||||
['CLUSTER', 'ADDSLOTSRANGE'],
|
||||
ranges
|
||||
);
|
||||
}
|
||||
|
||||
export declare function transformReply(): 'OK';
|
||||
},
|
||||
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,20 +1,20 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments } from './CLUSTER_BUMPEPOCH';
|
||||
import CLUSTER_BUMPEPOCH from './CLUSTER_BUMPEPOCH';
|
||||
|
||||
describe('CLUSTER BUMPEPOCH', () => {
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(),
|
||||
['CLUSTER', 'BUMPEPOCH']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
CLUSTER_BUMPEPOCH.transformArguments(),
|
||||
['CLUSTER', 'BUMPEPOCH']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithCluster('clusterNode.clusterBumpEpoch', async cluster => {
|
||||
const client = await cluster.nodeClient(cluster.masters[0]);
|
||||
assert.equal(
|
||||
typeof await client.clusterBumpEpoch(),
|
||||
'string'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
testUtils.testWithCluster('clusterNode.clusterBumpEpoch', async cluster => {
|
||||
const client = await cluster.nodeClient(cluster.masters[0]);
|
||||
assert.equal(
|
||||
typeof await client.clusterBumpEpoch(),
|
||||
'string'
|
||||
);
|
||||
}, GLOBAL.SERVERS.OPEN);
|
||||
});
|
||||
|
@@ -1,5 +1,10 @@
|
||||
export function transformArguments(): Array<string> {
|
||||
return ['CLUSTER', 'BUMPEPOCH'];
|
||||
}
|
||||
import { SimpleStringReply, Command } from '../RESP/types';
|
||||
|
||||
export declare function transformReply(): 'BUMPED' | 'STILL';
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments() {
|
||||
return ['CLUSTER', 'BUMPEPOCH'];
|
||||
},
|
||||
transformReply: undefined as unknown as () => SimpleStringReply<'BUMPED' | 'STILL'>
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,22 +1,21 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments } from './CLUSTER_COUNT-FAILURE-REPORTS';
|
||||
import CLUSTER_COUNT_FAILURE_REPORTS from './CLUSTER_COUNT-FAILURE-REPORTS';
|
||||
|
||||
describe('CLUSTER COUNT-FAILURE-REPORTS', () => {
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('0'),
|
||||
['CLUSTER', 'COUNT-FAILURE-REPORTS', '0']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
CLUSTER_COUNT_FAILURE_REPORTS.transformArguments('0'),
|
||||
['CLUSTER', 'COUNT-FAILURE-REPORTS', '0']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithCluster('clusterNode.clusterCountFailureReports', async cluster => {
|
||||
const client = await cluster.nodeClient(cluster.masters[0]);
|
||||
assert.equal(
|
||||
typeof await client.clusterCountFailureReports(
|
||||
await client.clusterMyId()
|
||||
),
|
||||
'number'
|
||||
);
|
||||
}, GLOBAL.CLUSTERS.OPEN);
|
||||
testUtils.testWithCluster('clusterNode.clusterCountFailureReports', async cluster => {
|
||||
const [master] = cluster.masters,
|
||||
client = await cluster.nodeClient(master);
|
||||
assert.equal(
|
||||
typeof await client.clusterCountFailureReports(master.id),
|
||||
'number'
|
||||
);
|
||||
}, GLOBAL.CLUSTERS.OPEN);
|
||||
});
|
||||
|
@@ -1,5 +1,10 @@
|
||||
export function transformArguments(nodeId: string): Array<string> {
|
||||
return ['CLUSTER', 'COUNT-FAILURE-REPORTS', nodeId];
|
||||
}
|
||||
import { RedisArgument, NumberReply, Command } from '../RESP/types';
|
||||
|
||||
export declare function transformReply(): number;
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments(nodeId: RedisArgument) {
|
||||
return ['CLUSTER', 'COUNT-FAILURE-REPORTS', nodeId];
|
||||
},
|
||||
transformReply: undefined as unknown as () => NumberReply
|
||||
} as const satisfies Command;
|
||||
|
@@ -1,20 +1,20 @@
|
||||
import { strict as assert } from 'assert';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import testUtils, { GLOBAL } from '../test-utils';
|
||||
import { transformArguments } from './CLUSTER_COUNTKEYSINSLOT';
|
||||
import CLUSTER_COUNTKEYSINSLOT from './CLUSTER_COUNTKEYSINSLOT';
|
||||
|
||||
describe('CLUSTER COUNTKEYSINSLOT', () => {
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments(0),
|
||||
['CLUSTER', 'COUNTKEYSINSLOT', '0']
|
||||
);
|
||||
});
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
CLUSTER_COUNTKEYSINSLOT.transformArguments(0),
|
||||
['CLUSTER', 'COUNTKEYSINSLOT', '0']
|
||||
);
|
||||
});
|
||||
|
||||
testUtils.testWithCluster('clusterNode.clusterCountKeysInSlot', async cluster => {
|
||||
const client = await cluster.nodeClient(cluster.masters[0]);
|
||||
assert.equal(
|
||||
typeof await client.clusterCountKeysInSlot(0),
|
||||
'number'
|
||||
);
|
||||
}, GLOBAL.CLUSTERS.OPEN);
|
||||
testUtils.testWithCluster('clusterNode.clusterCountKeysInSlot', async cluster => {
|
||||
const client = await cluster.nodeClient(cluster.masters[0]);
|
||||
assert.equal(
|
||||
typeof await client.clusterCountKeysInSlot(0),
|
||||
'number'
|
||||
);
|
||||
}, GLOBAL.CLUSTERS.OPEN);
|
||||
});
|
||||
|
@@ -1,5 +1,10 @@
|
||||
export function transformArguments(slot: number): Array<string> {
|
||||
return ['CLUSTER', 'COUNTKEYSINSLOT', slot.toString()];
|
||||
}
|
||||
import { NumberReply, Command } from '../RESP/types';
|
||||
|
||||
export declare function transformReply(): number;
|
||||
export default {
|
||||
FIRST_KEY_INDEX: undefined,
|
||||
IS_READ_ONLY: true,
|
||||
transformArguments(slot: number) {
|
||||
return ['CLUSTER', 'COUNTKEYSINSLOT', slot.toString()];
|
||||
},
|
||||
transformReply: undefined as unknown as () => NumberReply
|
||||
} as const satisfies Command;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user