You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-06 02:15:48 +03:00
Merge branch 'master' of github.com:redis/node-redis into COMMAND_DOCS
This commit is contained in:
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
node-version: ['12', '14', '16']
|
node-version: ['12', '14', '16']
|
||||||
redis-version: ['5', '6.0', '6.2']
|
redis-version: ['5', '6.0', '6.2', '7.0-rc2']
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2.3.4
|
- uses: actions/checkout@v2.3.4
|
||||||
with:
|
with:
|
||||||
|
1367
package-lock.json
generated
1367
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "redis",
|
"name": "redis",
|
||||||
"description": "A modern, high performance Redis client",
|
"description": "A modern, high performance Redis client",
|
||||||
"version": "4.0.4",
|
"version": "4.0.6",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
@@ -24,17 +24,17 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@node-redis/bloom": "1.0.1",
|
"@node-redis/bloom": "1.0.1",
|
||||||
"@node-redis/client": "1.0.4",
|
"@node-redis/client": "1.0.5",
|
||||||
"@node-redis/graph": "1.0.0",
|
"@node-redis/graph": "1.0.0",
|
||||||
"@node-redis/json": "1.0.2",
|
"@node-redis/json": "1.0.2",
|
||||||
"@node-redis/search": "1.0.3",
|
"@node-redis/search": "1.0.5",
|
||||||
"@node-redis/time-series": "1.0.2"
|
"@node-redis/time-series": "1.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tsconfig/node12": "^1.0.9",
|
"@tsconfig/node12": "^1.0.9",
|
||||||
"gh-pages": "^3.2.3",
|
"gh-pages": "^3.2.3",
|
||||||
"release-it": "^14.12.1",
|
"release-it": "^14.13.1",
|
||||||
"typescript": "^4.5.4"
|
"typescript": "^4.6.3"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@@ -18,12 +18,12 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
||||||
"@node-redis/test-utils": "*",
|
"@node-redis/test-utils": "*",
|
||||||
"@types/node": "^17.0.13",
|
"@types/node": "^17.0.23",
|
||||||
"nyc": "^15.1.0",
|
"nyc": "^15.1.0",
|
||||||
"release-it": "^14.12.4",
|
"release-it": "^14.13.1",
|
||||||
"source-map-support": "^0.5.21",
|
"source-map-support": "^0.5.21",
|
||||||
"ts-node": "^10.4.0",
|
"ts-node": "^10.7.0",
|
||||||
"typedoc": "^0.22.11",
|
"typedoc": "^0.22.13",
|
||||||
"typescript": "^4.5.5"
|
"typescript": "^4.6.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -23,16 +23,33 @@ import * as CLIENT_KILL from '../commands/CLIENT_KILL';
|
|||||||
import * as CLIENT_SETNAME from '../commands/CLIENT_SETNAME';
|
import * as CLIENT_SETNAME from '../commands/CLIENT_SETNAME';
|
||||||
import * as CLIENT_INFO from '../commands/CLIENT_INFO';
|
import * as CLIENT_INFO from '../commands/CLIENT_INFO';
|
||||||
import * as CLUSTER_ADDSLOTS from '../commands/CLUSTER_ADDSLOTS';
|
import * as CLUSTER_ADDSLOTS from '../commands/CLUSTER_ADDSLOTS';
|
||||||
|
import * as CLUSTER_ADDSLOTSRANGE from '../commands/CLUSTER_ADDSLOTSRANGE';
|
||||||
|
import * as CLUSTER_BUMPEPOCH from '../commands/CLUSTER_BUMPEPOCH';
|
||||||
|
import * as CLUSTER_COUNT_FAILURE_REPORTS from '../commands/CLUSTER_COUNT-FAILURE-REPORTS';
|
||||||
|
import * as CLUSTER_COUNTKEYSINSLOT from '../commands/CLUSTER_COUNTKEYSINSLOT';
|
||||||
|
import * as CLUSTER_DELSLOTS from '../commands/CLUSTER_DELSLOTS';
|
||||||
|
import * as CLUSTER_DELSLOTSRANGE from '../commands/CLUSTER_DELSLOTSRANGE';
|
||||||
|
import * as CLUSTER_FAILOVER from '../commands/CLUSTER_FAILOVER';
|
||||||
import * as CLUSTER_FLUSHSLOTS from '../commands/CLUSTER_FLUSHSLOTS';
|
import * as CLUSTER_FLUSHSLOTS from '../commands/CLUSTER_FLUSHSLOTS';
|
||||||
|
import * as CLUSTER_FORGET from '../commands/CLUSTER_FORGET';
|
||||||
|
import * as CLUSTER_GETKEYSINSLOT from '../commands/CLUSTER_GETKEYSINSLOT';
|
||||||
import * as CLUSTER_INFO from '../commands/CLUSTER_INFO';
|
import * as CLUSTER_INFO from '../commands/CLUSTER_INFO';
|
||||||
import * as CLUSTER_NODES from '../commands/CLUSTER_NODES';
|
import * as CLUSTER_KEYSLOT from '../commands/CLUSTER_KEYSLOT';
|
||||||
|
import * as CLUSTER_LINKS from '../commands/CLUSTER_LINKS';
|
||||||
import * as CLUSTER_MEET from '../commands/CLUSTER_MEET';
|
import * as CLUSTER_MEET from '../commands/CLUSTER_MEET';
|
||||||
|
import * as CLUSTER_MYID from '../commands/CLUSTER_MYID';
|
||||||
|
import * as CLUSTER_NODES from '../commands/CLUSTER_NODES';
|
||||||
|
import * as CLUSTER_REPLICAS from '../commands/CLUSTER_REPLICAS';
|
||||||
|
import * as CLUSTER_REPLICATE from '../commands/CLUSTER_REPLICATE';
|
||||||
import * as CLUSTER_RESET from '../commands/CLUSTER_RESET';
|
import * as CLUSTER_RESET from '../commands/CLUSTER_RESET';
|
||||||
|
import * as CLUSTER_SAVECONFIG from '../commands/CLUSTER_SAVECONFIG';
|
||||||
|
import * as CLUSTER_SET_CONFIG_EPOCH from '../commands/CLUSTER_SET-CONFIG-EPOCH';
|
||||||
import * as CLUSTER_SETSLOT from '../commands/CLUSTER_SETSLOT';
|
import * as CLUSTER_SETSLOT from '../commands/CLUSTER_SETSLOT';
|
||||||
import * as CLUSTER_SLOTS from '../commands/CLUSTER_SLOTS';
|
import * as CLUSTER_SLOTS from '../commands/CLUSTER_SLOTS';
|
||||||
import * as COMMAND_COUNT from '../commands/COMMAND_COUNT';
|
import * as COMMAND_COUNT from '../commands/COMMAND_COUNT';
|
||||||
import * as COMMAND_DOCS from '../commands/COMMAND_DOCS';
|
import * as COMMAND_DOCS from '../commands/COMMAND_DOCS';
|
||||||
import * as COMMAND_GETKEYS from '../commands/COMMAND_GETKEYS';
|
import * as COMMAND_GETKEYS from '../commands/COMMAND_GETKEYS';
|
||||||
|
import * as COMMAND_GETKEYSANDFLAGS from '../commands/COMMAND_GETKEYSANDFLAGS';
|
||||||
import * as COMMAND_INFO from '../commands/COMMAND_INFO';
|
import * as COMMAND_INFO from '../commands/COMMAND_INFO';
|
||||||
import * as COMMAND_LIST from '../commands/COMMAND_LIST';
|
import * as COMMAND_LIST from '../commands/COMMAND_LIST';
|
||||||
import * as COMMAND from '../commands/COMMAND';
|
import * as COMMAND from '../commands/COMMAND';
|
||||||
@@ -82,6 +99,7 @@ import * as SWAPDB from '../commands/SWAPDB';
|
|||||||
import * as TIME from '../commands/TIME';
|
import * as TIME from '../commands/TIME';
|
||||||
import * as UNWATCH from '../commands/UNWATCH';
|
import * as UNWATCH from '../commands/UNWATCH';
|
||||||
import * as WAIT from '../commands/WAIT';
|
import * as WAIT from '../commands/WAIT';
|
||||||
|
import * as LATENCY_DOCTOR from '../commands/LATENCY_DOCTOR';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
...CLUSTER_COMMANDS,
|
...CLUSTER_COMMANDS,
|
||||||
@@ -133,16 +151,48 @@ export default {
|
|||||||
clientInfo: CLIENT_INFO,
|
clientInfo: CLIENT_INFO,
|
||||||
CLUSTER_ADDSLOTS,
|
CLUSTER_ADDSLOTS,
|
||||||
clusterAddSlots: CLUSTER_ADDSLOTS,
|
clusterAddSlots: CLUSTER_ADDSLOTS,
|
||||||
|
CLUSTER_ADDSLOTSRANGE,
|
||||||
|
clusterAddSlotsRange: CLUSTER_ADDSLOTSRANGE,
|
||||||
|
CLUSTER_BUMPEPOCH,
|
||||||
|
clusterBumpEpoch: CLUSTER_BUMPEPOCH,
|
||||||
|
CLUSTER_COUNT_FAILURE_REPORTS,
|
||||||
|
clusterCountFailureReports: CLUSTER_COUNT_FAILURE_REPORTS,
|
||||||
|
CLUSTER_COUNTKEYSINSLOT,
|
||||||
|
clusterCountKeysInSlot: CLUSTER_COUNTKEYSINSLOT,
|
||||||
|
CLUSTER_DELSLOTS,
|
||||||
|
clusterDelSlots: CLUSTER_DELSLOTS,
|
||||||
|
CLUSTER_DELSLOTSRANGE,
|
||||||
|
clusterDelSlotsRange: CLUSTER_DELSLOTSRANGE,
|
||||||
|
CLUSTER_FAILOVER,
|
||||||
|
clusterFailover: CLUSTER_FAILOVER,
|
||||||
CLUSTER_FLUSHSLOTS,
|
CLUSTER_FLUSHSLOTS,
|
||||||
clusterFlushSlots: CLUSTER_FLUSHSLOTS,
|
clusterFlushSlots: CLUSTER_FLUSHSLOTS,
|
||||||
|
CLUSTER_FORGET,
|
||||||
|
clusterForget: CLUSTER_FORGET,
|
||||||
|
CLUSTER_GETKEYSINSLOT,
|
||||||
|
clusterGetKeysInSlot: CLUSTER_GETKEYSINSLOT,
|
||||||
CLUSTER_INFO,
|
CLUSTER_INFO,
|
||||||
clusterInfo: CLUSTER_INFO,
|
clusterInfo: CLUSTER_INFO,
|
||||||
CLUSTER_NODES,
|
CLUSTER_KEYSLOT,
|
||||||
clusterNodes: CLUSTER_NODES,
|
clusterKeySlot: CLUSTER_KEYSLOT,
|
||||||
|
CLUSTER_LINKS,
|
||||||
|
clusterLinks: CLUSTER_LINKS,
|
||||||
CLUSTER_MEET,
|
CLUSTER_MEET,
|
||||||
clusterMeet: CLUSTER_MEET,
|
clusterMeet: CLUSTER_MEET,
|
||||||
|
CLUSTER_MYID,
|
||||||
|
clusterMyId: CLUSTER_MYID,
|
||||||
|
CLUSTER_NODES,
|
||||||
|
clusterNodes: CLUSTER_NODES,
|
||||||
|
CLUSTER_REPLICAS,
|
||||||
|
clusterReplicas: CLUSTER_REPLICAS,
|
||||||
|
CLUSTER_REPLICATE,
|
||||||
|
clusterReplicate: CLUSTER_REPLICATE,
|
||||||
CLUSTER_RESET,
|
CLUSTER_RESET,
|
||||||
clusterReset: CLUSTER_RESET,
|
clusterReset: CLUSTER_RESET,
|
||||||
|
CLUSTER_SAVECONFIG,
|
||||||
|
clusterSaveConfig: CLUSTER_SAVECONFIG,
|
||||||
|
CLUSTER_SET_CONFIG_EPOCH,
|
||||||
|
clusterSetConfigEpoch: CLUSTER_SET_CONFIG_EPOCH,
|
||||||
CLUSTER_SETSLOT,
|
CLUSTER_SETSLOT,
|
||||||
clusterSetSlot: CLUSTER_SETSLOT,
|
clusterSetSlot: CLUSTER_SETSLOT,
|
||||||
CLUSTER_SLOTS,
|
CLUSTER_SLOTS,
|
||||||
@@ -153,6 +203,8 @@ export default {
|
|||||||
commandDocs: COMMAND_DOCS,
|
commandDocs: COMMAND_DOCS,
|
||||||
COMMAND_GETKEYS,
|
COMMAND_GETKEYS,
|
||||||
commandGetKeys: COMMAND_GETKEYS,
|
commandGetKeys: COMMAND_GETKEYS,
|
||||||
|
COMMAND_GETKEYSANDFLAGS,
|
||||||
|
commandGetKeysAndFlags: COMMAND_GETKEYSANDFLAGS,
|
||||||
COMMAND_INFO,
|
COMMAND_INFO,
|
||||||
commandInfo: COMMAND_INFO,
|
commandInfo: COMMAND_INFO,
|
||||||
COMMAND_LIST,
|
COMMAND_LIST,
|
||||||
@@ -187,6 +239,8 @@ export default {
|
|||||||
keys: KEYS,
|
keys: KEYS,
|
||||||
LASTSAVE,
|
LASTSAVE,
|
||||||
lastSave: LASTSAVE,
|
lastSave: LASTSAVE,
|
||||||
|
LATENCY_DOCTOR,
|
||||||
|
latencyDoctor: LATENCY_DOCTOR,
|
||||||
LOLWUT,
|
LOLWUT,
|
||||||
lolwut: LOLWUT,
|
lolwut: LOLWUT,
|
||||||
MEMOERY_DOCTOR,
|
MEMOERY_DOCTOR,
|
||||||
|
@@ -477,8 +477,11 @@ describe('Client', () => {
|
|||||||
assert.ok(id !== isolatedId);
|
assert.ok(id !== isolatedId);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
|
|
||||||
async function killClient<M extends RedisModules, S extends RedisScripts>(client: RedisClientType<M, S>): Promise<void> {
|
async function killClient<M extends RedisModules, S extends RedisScripts>(
|
||||||
const onceErrorPromise = once(client, 'error');
|
client: RedisClientType<M, S>,
|
||||||
|
errorClient: RedisClientType<M, S> = client
|
||||||
|
): Promise<void> {
|
||||||
|
const onceErrorPromise = once(errorClient, 'error');
|
||||||
await client.sendCommand(['QUIT']);
|
await client.sendCommand(['QUIT']);
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
onceErrorPromise,
|
onceErrorPromise,
|
||||||
@@ -503,6 +506,10 @@ describe('Client', () => {
|
|||||||
minimumDockerVersion: [6, 2] // CLIENT INFO
|
minimumDockerVersion: [6, 2] // CLIENT INFO
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testUtils.testWithClient('should propagated errors from "isolated" clients', client => {
|
||||||
|
return client.executeIsolated(isolated => killClient(isolated, client));
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
|
|
||||||
testUtils.testWithClient('scanIterator', async client => {
|
testUtils.testWithClient('scanIterator', async client => {
|
||||||
const promises = [],
|
const promises = [],
|
||||||
keys = new Set();
|
keys = new Set();
|
||||||
|
@@ -189,7 +189,7 @@ export default class RedisClient<M extends RedisModules, S extends RedisScripts>
|
|||||||
create: async () => {
|
create: async () => {
|
||||||
const duplicate = this.duplicate({
|
const duplicate = this.duplicate({
|
||||||
isolationPoolOptions: undefined
|
isolationPoolOptions: undefined
|
||||||
});
|
}).on('error', err => this.emit('error', err));
|
||||||
await duplicate.connect();
|
await duplicate.connect();
|
||||||
return duplicate;
|
return duplicate;
|
||||||
},
|
},
|
||||||
|
@@ -6,7 +6,7 @@ describe('Socket', () => {
|
|||||||
describe('reconnectStrategy', () => {
|
describe('reconnectStrategy', () => {
|
||||||
let clock: SinonFakeTimers;
|
let clock: SinonFakeTimers;
|
||||||
beforeEach(() => clock = useFakeTimers());
|
beforeEach(() => clock = useFakeTimers());
|
||||||
afterEach(() => clock.uninstall());
|
afterEach(() => clock.restore());
|
||||||
|
|
||||||
it('custom strategy', () => {
|
it('custom strategy', () => {
|
||||||
const reconnectStrategy = spy((retries: number): number | Error => {
|
const reconnectStrategy = spy((retries: number): number | Error => {
|
||||||
|
@@ -21,6 +21,7 @@ import * as EVALSHA from '../commands/EVALSHA';
|
|||||||
import * as EXISTS from '../commands/EXISTS';
|
import * as EXISTS from '../commands/EXISTS';
|
||||||
import * as EXPIRE from '../commands/EXPIRE';
|
import * as EXPIRE from '../commands/EXPIRE';
|
||||||
import * as EXPIREAT from '../commands/EXPIREAT';
|
import * as EXPIREAT from '../commands/EXPIREAT';
|
||||||
|
import * as EXPIRETIME from '../commands/EXPIRETIME';
|
||||||
import * as GEOADD from '../commands/GEOADD';
|
import * as GEOADD from '../commands/GEOADD';
|
||||||
import * as GEODIST from '../commands/GEODIST';
|
import * as GEODIST from '../commands/GEODIST';
|
||||||
import * as GEOHASH from '../commands/GEOHASH';
|
import * as GEOHASH from '../commands/GEOHASH';
|
||||||
@@ -72,9 +73,14 @@ import * as MGET from '../commands/MGET';
|
|||||||
import * as MIGRATE from '../commands/MIGRATE';
|
import * as MIGRATE from '../commands/MIGRATE';
|
||||||
import * as MSET from '../commands/MSET';
|
import * as MSET from '../commands/MSET';
|
||||||
import * as MSETNX from '../commands/MSETNX';
|
import * as MSETNX from '../commands/MSETNX';
|
||||||
|
import * as OBJECT_ENCODING from '../commands/OBJECT_ENCODING';
|
||||||
|
import * as OBJECT_FREQ from '../commands/OBJECT_FREQ';
|
||||||
|
import * as OBJECT_IDLETIME from '../commands/OBJECT_IDLETIME';
|
||||||
|
import * as OBJECT_REFCOUNT from '../commands/OBJECT_REFCOUNT';
|
||||||
import * as PERSIST from '../commands/PERSIST';
|
import * as PERSIST from '../commands/PERSIST';
|
||||||
import * as PEXPIRE from '../commands/PEXPIRE';
|
import * as PEXPIRE from '../commands/PEXPIRE';
|
||||||
import * as PEXPIREAT from '../commands/PEXPIREAT';
|
import * as PEXPIREAT from '../commands/PEXPIREAT';
|
||||||
|
import * as PEXPIRETIME from '../commands/PEXPIRETIME';
|
||||||
import * as PFADD from '../commands/PFADD';
|
import * as PFADD from '../commands/PFADD';
|
||||||
import * as PFCOUNT from '../commands/PFCOUNT';
|
import * as PFCOUNT from '../commands/PFCOUNT';
|
||||||
import * as PFMERGE from '../commands/PFMERGE';
|
import * as PFMERGE from '../commands/PFMERGE';
|
||||||
@@ -98,11 +104,14 @@ import * as SETEX from '../commands/SETEX';
|
|||||||
import * as SETNX from '../commands/SETNX';
|
import * as SETNX from '../commands/SETNX';
|
||||||
import * as SETRANGE from '../commands/SETRANGE';
|
import * as SETRANGE from '../commands/SETRANGE';
|
||||||
import * as SINTER from '../commands/SINTER';
|
import * as SINTER from '../commands/SINTER';
|
||||||
|
import * as SINTERCARD from '../commands/SINTERCARD';
|
||||||
import * as SINTERSTORE from '../commands/SINTERSTORE';
|
import * as SINTERSTORE from '../commands/SINTERSTORE';
|
||||||
import * as SISMEMBER from '../commands/SISMEMBER';
|
import * as SISMEMBER from '../commands/SISMEMBER';
|
||||||
import * as SMEMBERS from '../commands/SMEMBERS';
|
import * as SMEMBERS from '../commands/SMEMBERS';
|
||||||
import * as SMISMEMBER from '../commands/SMISMEMBER';
|
import * as SMISMEMBER from '../commands/SMISMEMBER';
|
||||||
import * as SMOVE from '../commands/SMOVE';
|
import * as SMOVE from '../commands/SMOVE';
|
||||||
|
import * as SORT_RO from '../commands/SORT_RO';
|
||||||
|
import * as SORT_STORE from '../commands/SORT_STORE';
|
||||||
import * as SORT from '../commands/SORT';
|
import * as SORT from '../commands/SORT';
|
||||||
import * as SPOP from '../commands/SPOP';
|
import * as SPOP from '../commands/SPOP';
|
||||||
import * as SRANDMEMBER_COUNT from '../commands/SRANDMEMBER_COUNT';
|
import * as SRANDMEMBER_COUNT from '../commands/SRANDMEMBER_COUNT';
|
||||||
@@ -149,6 +158,7 @@ import * as ZDIFFSTORE from '../commands/ZDIFFSTORE';
|
|||||||
import * as ZINCRBY from '../commands/ZINCRBY';
|
import * as ZINCRBY from '../commands/ZINCRBY';
|
||||||
import * as ZINTER_WITHSCORES from '../commands/ZINTER_WITHSCORES';
|
import * as ZINTER_WITHSCORES from '../commands/ZINTER_WITHSCORES';
|
||||||
import * as ZINTER from '../commands/ZINTER';
|
import * as ZINTER from '../commands/ZINTER';
|
||||||
|
import * as ZINTERCARD from '../commands/ZINTERCARD';
|
||||||
import * as ZINTERSTORE from '../commands/ZINTERSTORE';
|
import * as ZINTERSTORE from '../commands/ZINTERSTORE';
|
||||||
import * as ZLEXCOUNT from '../commands/ZLEXCOUNT';
|
import * as ZLEXCOUNT from '../commands/ZLEXCOUNT';
|
||||||
import * as ZMSCORE from '../commands/ZMSCORE';
|
import * as ZMSCORE from '../commands/ZMSCORE';
|
||||||
@@ -222,6 +232,8 @@ export default {
|
|||||||
expire: EXPIRE,
|
expire: EXPIRE,
|
||||||
EXPIREAT,
|
EXPIREAT,
|
||||||
expireAt: EXPIREAT,
|
expireAt: EXPIREAT,
|
||||||
|
EXPIRETIME,
|
||||||
|
expireTime: EXPIRETIME,
|
||||||
GEOADD,
|
GEOADD,
|
||||||
geoAdd: GEOADD,
|
geoAdd: GEOADD,
|
||||||
GEODIST,
|
GEODIST,
|
||||||
@@ -324,12 +336,22 @@ export default {
|
|||||||
mSet: MSET,
|
mSet: MSET,
|
||||||
MSETNX,
|
MSETNX,
|
||||||
mSetNX: MSETNX,
|
mSetNX: MSETNX,
|
||||||
|
OBJECT_ENCODING,
|
||||||
|
objectEncoding: OBJECT_ENCODING,
|
||||||
|
OBJECT_FREQ,
|
||||||
|
objectFreq: OBJECT_FREQ,
|
||||||
|
OBJECT_IDLETIME,
|
||||||
|
objectIdleTime: OBJECT_IDLETIME,
|
||||||
|
OBJECT_REFCOUNT,
|
||||||
|
objectRefCount: OBJECT_REFCOUNT,
|
||||||
PERSIST,
|
PERSIST,
|
||||||
persist: PERSIST,
|
persist: PERSIST,
|
||||||
PEXPIRE,
|
PEXPIRE,
|
||||||
pExpire: PEXPIRE,
|
pExpire: PEXPIRE,
|
||||||
PEXPIREAT,
|
PEXPIREAT,
|
||||||
pExpireAt: PEXPIREAT,
|
pExpireAt: PEXPIREAT,
|
||||||
|
PEXPIRETIME,
|
||||||
|
pExpireTime: PEXPIRETIME,
|
||||||
PFADD,
|
PFADD,
|
||||||
pfAdd: PFADD,
|
pfAdd: PFADD,
|
||||||
PFCOUNT,
|
PFCOUNT,
|
||||||
@@ -366,6 +388,8 @@ export default {
|
|||||||
sDiffStore: SDIFFSTORE,
|
sDiffStore: SDIFFSTORE,
|
||||||
SINTER,
|
SINTER,
|
||||||
sInter: SINTER,
|
sInter: SINTER,
|
||||||
|
SINTERCARD,
|
||||||
|
sInterCard: SINTERCARD,
|
||||||
SINTERSTORE,
|
SINTERSTORE,
|
||||||
sInterStore: SINTERSTORE,
|
sInterStore: SINTERSTORE,
|
||||||
SET,
|
SET,
|
||||||
@@ -386,6 +410,10 @@ export default {
|
|||||||
smIsMember: SMISMEMBER,
|
smIsMember: SMISMEMBER,
|
||||||
SMOVE,
|
SMOVE,
|
||||||
sMove: SMOVE,
|
sMove: SMOVE,
|
||||||
|
SORT_RO,
|
||||||
|
sortRo: SORT_RO,
|
||||||
|
SORT_STORE,
|
||||||
|
sortStore: SORT_STORE,
|
||||||
SORT,
|
SORT,
|
||||||
sort: SORT,
|
sort: SORT,
|
||||||
SPOP,
|
SPOP,
|
||||||
@@ -478,6 +506,8 @@ export default {
|
|||||||
zInterWithScores: ZINTER_WITHSCORES,
|
zInterWithScores: ZINTER_WITHSCORES,
|
||||||
ZINTER,
|
ZINTER,
|
||||||
zInter: ZINTER,
|
zInter: ZINTER,
|
||||||
|
ZINTERCARD,
|
||||||
|
zInterCard: ZINTERCARD,
|
||||||
ZINTERSTORE,
|
ZINTERSTORE,
|
||||||
zInterStore: ZINTERSTORE,
|
zInterStore: ZINTERSTORE,
|
||||||
ZLEXCOUNT,
|
ZLEXCOUNT,
|
||||||
|
@@ -13,20 +13,32 @@ describe('ACL GETUSER', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.aclGetUser', async client => {
|
testUtils.testWithClient('client.aclGetUser', async client => {
|
||||||
|
const expectedReply: any = {
|
||||||
|
passwords: [],
|
||||||
|
commands: '+@all',
|
||||||
|
};
|
||||||
|
|
||||||
|
if (testUtils.isVersionGreaterThan([7])) {
|
||||||
|
expectedReply.flags = ['on', 'nopass'];
|
||||||
|
expectedReply.keys = '~*';
|
||||||
|
expectedReply.channels = '&*';
|
||||||
|
expectedReply.selectors = [];
|
||||||
|
} else {
|
||||||
|
expectedReply.keys = ['*'];
|
||||||
|
expectedReply.selectors = undefined;
|
||||||
|
|
||||||
|
if (testUtils.isVersionGreaterThan([6, 2])) {
|
||||||
|
expectedReply.flags = ['on', 'allkeys', 'allchannels', 'allcommands', 'nopass'];
|
||||||
|
expectedReply.channels = ['*'];
|
||||||
|
} else {
|
||||||
|
expectedReply.flags = ['on', 'allkeys', 'allcommands', 'nopass'];
|
||||||
|
expectedReply.channels = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
await client.aclGetUser('default'),
|
await client.aclGetUser('default'),
|
||||||
{
|
expectedReply
|
||||||
passwords: [],
|
|
||||||
commands: '+@all',
|
|
||||||
keys: ['*'],
|
|
||||||
...(testUtils.isVersionGreaterThan([6, 2]) ? {
|
|
||||||
flags: ['on', 'allkeys', 'allchannels', 'allcommands', 'nopass'],
|
|
||||||
channels: ['*']
|
|
||||||
} : {
|
|
||||||
flags: ['on', 'allkeys', 'allcommands', 'nopass'],
|
|
||||||
channels: undefined
|
|
||||||
})
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -5,24 +5,27 @@ export function transformArguments(username: RedisCommandArgument): RedisCommand
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AclGetUserRawReply = [
|
type AclGetUserRawReply = [
|
||||||
_: RedisCommandArgument,
|
'flags',
|
||||||
flags: Array<RedisCommandArgument>,
|
Array<RedisCommandArgument>,
|
||||||
_: RedisCommandArgument,
|
'passwords',
|
||||||
passwords: Array<RedisCommandArgument>,
|
Array<RedisCommandArgument>,
|
||||||
_: RedisCommandArgument,
|
'commands',
|
||||||
commands: RedisCommandArgument,
|
RedisCommandArgument,
|
||||||
_: RedisCommandArgument,
|
'keys',
|
||||||
keys: Array<RedisCommandArgument>,
|
Array<RedisCommandArgument> | RedisCommandArgument,
|
||||||
_: RedisCommandArgument,
|
'channels',
|
||||||
channels: Array<RedisCommandArgument>
|
Array<RedisCommandArgument> | RedisCommandArgument,
|
||||||
|
'selectors' | undefined,
|
||||||
|
Array<Array<string>> | undefined
|
||||||
];
|
];
|
||||||
|
|
||||||
interface AclUser {
|
interface AclUser {
|
||||||
flags: Array<RedisCommandArgument>;
|
flags: Array<RedisCommandArgument>;
|
||||||
passwords: Array<RedisCommandArgument>;
|
passwords: Array<RedisCommandArgument>;
|
||||||
commands: RedisCommandArgument;
|
commands: RedisCommandArgument;
|
||||||
keys: Array<RedisCommandArgument>;
|
keys: Array<RedisCommandArgument> | RedisCommandArgument;
|
||||||
channels: Array<RedisCommandArgument>
|
channels: Array<RedisCommandArgument> | RedisCommandArgument;
|
||||||
|
selectors?: Array<Array<string>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function transformReply(reply: AclGetUserRawReply): AclUser {
|
export function transformReply(reply: AclGetUserRawReply): AclUser {
|
||||||
@@ -31,6 +34,7 @@ export function transformReply(reply: AclGetUserRawReply): AclUser {
|
|||||||
passwords: reply[3],
|
passwords: reply[3],
|
||||||
commands: reply[5],
|
commands: reply[5],
|
||||||
keys: reply[7],
|
keys: reply[7],
|
||||||
channels: reply[9]
|
channels: reply[9],
|
||||||
|
selectors: reply[11]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -11,14 +11,27 @@ describe('BITCOUNT', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('with range', () => {
|
describe('with range', () => {
|
||||||
assert.deepEqual(
|
it('simple', () => {
|
||||||
transformArguments('key', {
|
assert.deepEqual(
|
||||||
start: 0,
|
transformArguments('key', {
|
||||||
end: 1
|
start: 0,
|
||||||
}),
|
end: 1
|
||||||
['BITCOUNT', 'key', '0', '1']
|
}),
|
||||||
);
|
['BITCOUNT', 'key', '0', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with mode', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('key', {
|
||||||
|
start: 0,
|
||||||
|
end: 1,
|
||||||
|
mode: 'BIT'
|
||||||
|
}),
|
||||||
|
['BITCOUNT', 'key', '0', '1', 'BIT']
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -7,6 +7,7 @@ export const IS_READ_ONLY = true;
|
|||||||
interface BitCountRange {
|
interface BitCountRange {
|
||||||
start: number;
|
start: number;
|
||||||
end: number;
|
end: number;
|
||||||
|
mode?: 'BYTE' | 'BIT';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function transformArguments(
|
export function transformArguments(
|
||||||
@@ -20,6 +21,10 @@ export function transformArguments(
|
|||||||
range.start.toString(),
|
range.start.toString(),
|
||||||
range.end.toString()
|
range.end.toString()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (range.mode) {
|
||||||
|
args.push(range.mode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
|
@@ -18,12 +18,19 @@ describe('BITPOS', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('with start, end', () => {
|
it('with start and end', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', 1, 1, -1),
|
transformArguments('key', 1, 1, -1),
|
||||||
['BITPOS', 'key', '1', '1', '-1']
|
['BITPOS', 'key', '1', '1', '-1']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('with start, end and mode', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('key', 1, 1, -1, 'BIT'),
|
||||||
|
['BITPOS', 'key', '1', '1', '-1', 'BIT']
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.bitPos', async client => {
|
testUtils.testWithClient('client.bitPos', async client => {
|
||||||
|
@@ -9,7 +9,8 @@ export function transformArguments(
|
|||||||
key: RedisCommandArgument,
|
key: RedisCommandArgument,
|
||||||
bit: BitValue,
|
bit: BitValue,
|
||||||
start?: number,
|
start?: number,
|
||||||
end?: number
|
end?: number,
|
||||||
|
mode?: 'BYTE' | 'BIT'
|
||||||
): RedisCommandArguments {
|
): RedisCommandArguments {
|
||||||
const args = ['BITPOS', key, bit.toString()];
|
const args = ['BITPOS', key, bit.toString()];
|
||||||
|
|
||||||
@@ -21,6 +22,10 @@ export function transformArguments(
|
|||||||
args.push(end.toString());
|
args.push(end.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mode) {
|
||||||
|
args.push(mode);
|
||||||
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,13 +1,11 @@
|
|||||||
export function transformArguments(slots: number | Array<number>): Array<string> {
|
import { RedisCommandArguments } from '.';
|
||||||
const args = ['CLUSTER', 'ADDSLOTS'];
|
import { pushVerdictNumberArguments } from './generic-transformers';
|
||||||
|
|
||||||
if (typeof slots === 'number') {
|
export function transformArguments(slots: number | Array<number>): RedisCommandArguments {
|
||||||
args.push(slots.toString());
|
return pushVerdictNumberArguments(
|
||||||
} else {
|
['CLUSTER', 'ADDSLOTS'],
|
||||||
args.push(...slots.map(String));
|
slots
|
||||||
}
|
);
|
||||||
|
|
||||||
return args;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export declare function transformReply(): string;
|
export declare function transformReply(): string;
|
||||||
|
29
packages/client/lib/commands/CLUSTER_ADDSLOTSRANGE.spec.ts
Normal file
29
packages/client/lib/commands/CLUSTER_ADDSLOTSRANGE.spec.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import { transformArguments } from './CLUSTER_ADDSLOTSRANGE';
|
||||||
|
|
||||||
|
describe('CLUSTER ADDSLOTSRANGE', () => {
|
||||||
|
describe('transformArguments', () => {
|
||||||
|
it('single', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments({
|
||||||
|
start: 0,
|
||||||
|
end: 1
|
||||||
|
}),
|
||||||
|
['CLUSTER', 'ADDSLOTSRANGE', '0', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('multiple', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments([{
|
||||||
|
start: 0,
|
||||||
|
end: 1
|
||||||
|
}, {
|
||||||
|
start: 2,
|
||||||
|
end: 3
|
||||||
|
}]),
|
||||||
|
['CLUSTER', 'ADDSLOTSRANGE', '0', '1', '2', '3']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
13
packages/client/lib/commands/CLUSTER_ADDSLOTSRANGE.ts
Normal file
13
packages/client/lib/commands/CLUSTER_ADDSLOTSRANGE.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { RedisCommandArguments } from '.';
|
||||||
|
import { pushSlotRangesArguments, SlotRange } from './generic-transformers';
|
||||||
|
|
||||||
|
export function transformArguments(
|
||||||
|
ranges: SlotRange | Array<SlotRange>
|
||||||
|
): RedisCommandArguments {
|
||||||
|
return pushSlotRangesArguments(
|
||||||
|
['CLUSTER', 'ADDSLOTSRANGE'],
|
||||||
|
ranges
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): 'OK';
|
19
packages/client/lib/commands/CLUSTER_BUMPEPOCH.spec.ts
Normal file
19
packages/client/lib/commands/CLUSTER_BUMPEPOCH.spec.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
|
import { transformArguments } from './CLUSTER_BUMPEPOCH';
|
||||||
|
|
||||||
|
describe('CLUSTER BUMPEPOCH', () => {
|
||||||
|
it('transformArguments', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments(),
|
||||||
|
['CLUSTER', 'BUMPEPOCH']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithCluster('clusterNode.clusterBumpEpoch', async cluster => {
|
||||||
|
assert.equal(
|
||||||
|
typeof await cluster.getSlotMaster(0).client.clusterBumpEpoch(),
|
||||||
|
'string'
|
||||||
|
);
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
|
});
|
5
packages/client/lib/commands/CLUSTER_BUMPEPOCH.ts
Normal file
5
packages/client/lib/commands/CLUSTER_BUMPEPOCH.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export function transformArguments(): Array<string> {
|
||||||
|
return ['CLUSTER', 'BUMPEPOCH'];
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): 'BUMPED' | 'STILL';
|
@@ -0,0 +1,22 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
|
import { transformArguments } from './CLUSTER_COUNT-FAILURE-REPORTS';
|
||||||
|
|
||||||
|
describe('CLUSTER COUNT-FAILURE-REPORTS', () => {
|
||||||
|
it('transformArguments', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('0'),
|
||||||
|
['CLUSTER', 'COUNT-FAILURE-REPORTS', '0']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithCluster('clusterNode.clusterCountFailureReports', async cluster => {
|
||||||
|
const { client } = cluster.getSlotMaster(0);
|
||||||
|
assert.equal(
|
||||||
|
typeof await client.clusterCountFailureReports(
|
||||||
|
await client.clusterMyId()
|
||||||
|
),
|
||||||
|
'number'
|
||||||
|
);
|
||||||
|
}, GLOBAL.CLUSTERS.OPEN);
|
||||||
|
});
|
@@ -0,0 +1,5 @@
|
|||||||
|
export function transformArguments(nodeId: string): Array<string> {
|
||||||
|
return ['CLUSTER', 'COUNT-FAILURE-REPORTS', nodeId];
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): number;
|
19
packages/client/lib/commands/CLUSTER_COUNTKEYSINSLOT.spec.ts
Normal file
19
packages/client/lib/commands/CLUSTER_COUNTKEYSINSLOT.spec.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
|
import { transformArguments } from './CLUSTER_COUNTKEYSINSLOT';
|
||||||
|
|
||||||
|
describe('CLUSTER COUNTKEYSINSLOT', () => {
|
||||||
|
it('transformArguments', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments(0),
|
||||||
|
['CLUSTER', 'COUNTKEYSINSLOT', '0']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithCluster('clusterNode.clusterCountKeysInSlot', async cluster => {
|
||||||
|
assert.equal(
|
||||||
|
typeof await cluster.getSlotMaster(0).client.clusterCountKeysInSlot(0),
|
||||||
|
'number'
|
||||||
|
);
|
||||||
|
}, GLOBAL.CLUSTERS.OPEN);
|
||||||
|
});
|
5
packages/client/lib/commands/CLUSTER_COUNTKEYSINSLOT.ts
Normal file
5
packages/client/lib/commands/CLUSTER_COUNTKEYSINSLOT.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export function transformArguments(slot: number): Array<string> {
|
||||||
|
return ['CLUSTER', 'COUNTKEYSINSLOT', slot.toString()];
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): number;
|
20
packages/client/lib/commands/CLUSTER_DELSLOTS.spec.ts
Normal file
20
packages/client/lib/commands/CLUSTER_DELSLOTS.spec.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import { transformArguments } from './CLUSTER_DELSLOTS';
|
||||||
|
|
||||||
|
describe('CLUSTER DELSLOTS', () => {
|
||||||
|
describe('transformArguments', () => {
|
||||||
|
it('single', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments(0),
|
||||||
|
['CLUSTER', 'DELSLOTS', '0']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('multiple', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments([0, 1]),
|
||||||
|
['CLUSTER', 'DELSLOTS', '0', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
11
packages/client/lib/commands/CLUSTER_DELSLOTS.ts
Normal file
11
packages/client/lib/commands/CLUSTER_DELSLOTS.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { RedisCommandArguments } from '.';
|
||||||
|
import { pushVerdictNumberArguments } from './generic-transformers';
|
||||||
|
|
||||||
|
export function transformArguments(slots: number | Array<number>): RedisCommandArguments {
|
||||||
|
return pushVerdictNumberArguments(
|
||||||
|
['CLUSTER', 'DELSLOTS'],
|
||||||
|
slots
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): 'OK';
|
29
packages/client/lib/commands/CLUSTER_DELSLOTSRANGE.spec.ts
Normal file
29
packages/client/lib/commands/CLUSTER_DELSLOTSRANGE.spec.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import { transformArguments } from './CLUSTER_DELSLOTSRANGE';
|
||||||
|
|
||||||
|
describe('CLUSTER DELSLOTSRANGE', () => {
|
||||||
|
describe('transformArguments', () => {
|
||||||
|
it('single', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments({
|
||||||
|
start: 0,
|
||||||
|
end: 1
|
||||||
|
}),
|
||||||
|
['CLUSTER', 'DELSLOTSRANGE', '0', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('multiple', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments([{
|
||||||
|
start: 0,
|
||||||
|
end: 1
|
||||||
|
}, {
|
||||||
|
start: 2,
|
||||||
|
end: 3
|
||||||
|
}]),
|
||||||
|
['CLUSTER', 'DELSLOTSRANGE', '0', '1', '2', '3']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
13
packages/client/lib/commands/CLUSTER_DELSLOTSRANGE.ts
Normal file
13
packages/client/lib/commands/CLUSTER_DELSLOTSRANGE.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { RedisCommandArguments } from '.';
|
||||||
|
import { pushSlotRangesArguments, SlotRange } from './generic-transformers';
|
||||||
|
|
||||||
|
export function transformArguments(
|
||||||
|
ranges: SlotRange | Array<SlotRange>
|
||||||
|
): RedisCommandArguments {
|
||||||
|
return pushSlotRangesArguments(
|
||||||
|
['CLUSTER', 'DELSLOTSRANGE'],
|
||||||
|
ranges
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): 'OK';
|
20
packages/client/lib/commands/CLUSTER_FAILOVER.spec.ts
Normal file
20
packages/client/lib/commands/CLUSTER_FAILOVER.spec.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import { FailoverModes, transformArguments } from './CLUSTER_FAILOVER';
|
||||||
|
|
||||||
|
describe('CLUSTER FAILOVER', () => {
|
||||||
|
describe('transformArguments', () => {
|
||||||
|
it('simple', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments(),
|
||||||
|
['CLUSTER', 'FAILOVER']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with mode', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments(FailoverModes.FORCE),
|
||||||
|
['CLUSTER', 'FAILOVER', 'FORCE']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
16
packages/client/lib/commands/CLUSTER_FAILOVER.ts
Normal file
16
packages/client/lib/commands/CLUSTER_FAILOVER.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
export enum FailoverModes {
|
||||||
|
FORCE = 'FORCE',
|
||||||
|
TAKEOVER = 'TAKEOVER'
|
||||||
|
}
|
||||||
|
|
||||||
|
export function transformArguments(mode?: FailoverModes): Array<string> {
|
||||||
|
const args = ['CLUSTER', 'FAILOVER'];
|
||||||
|
|
||||||
|
if (mode) {
|
||||||
|
args.push(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): 'OK';
|
@@ -2,4 +2,4 @@ export function transformArguments(): Array<string> {
|
|||||||
return ['CLUSTER', 'FLUSHSLOTS'];
|
return ['CLUSTER', 'FLUSHSLOTS'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export declare function transformReply(): string;
|
export declare function transformReply(): 'OK';
|
||||||
|
11
packages/client/lib/commands/CLUSTER_FORGET.spec.ts
Normal file
11
packages/client/lib/commands/CLUSTER_FORGET.spec.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import { transformArguments } from './CLUSTER_FORGET';
|
||||||
|
|
||||||
|
describe('CLUSTER FORGET', () => {
|
||||||
|
it('transformArguments', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('0'),
|
||||||
|
['CLUSTER', 'FORGET', '0']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
5
packages/client/lib/commands/CLUSTER_FORGET.ts
Normal file
5
packages/client/lib/commands/CLUSTER_FORGET.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export function transformArguments(nodeId: string): Array<string> {
|
||||||
|
return ['CLUSTER', 'FORGET', nodeId];
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): 'OK';
|
@@ -1,4 +1,5 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
import { transformArguments } from './CLUSTER_GETKEYSINSLOT';
|
import { transformArguments } from './CLUSTER_GETKEYSINSLOT';
|
||||||
|
|
||||||
describe('CLUSTER GETKEYSINSLOT', () => {
|
describe('CLUSTER GETKEYSINSLOT', () => {
|
||||||
@@ -8,4 +9,12 @@ describe('CLUSTER GETKEYSINSLOT', () => {
|
|||||||
['CLUSTER', 'GETKEYSINSLOT', '0', '10']
|
['CLUSTER', 'GETKEYSINSLOT', '0', '10']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testUtils.testWithCluster('clusterNode.clusterGetKeysInSlot', async cluster => {
|
||||||
|
const reply = await cluster.getSlotMaster(0).client.clusterGetKeysInSlot(0, 1);
|
||||||
|
assert.ok(Array.isArray(reply));
|
||||||
|
for (const item of reply) {
|
||||||
|
assert.equal(typeof item, 'string');
|
||||||
|
}
|
||||||
|
}, GLOBAL.CLUSTERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -2,4 +2,4 @@ export function transformArguments(slot: number, count: number): Array<string> {
|
|||||||
return ['CLUSTER', 'GETKEYSINSLOT', slot.toString(), count.toString()];
|
return ['CLUSTER', 'GETKEYSINSLOT', slot.toString(), count.toString()];
|
||||||
}
|
}
|
||||||
|
|
||||||
export declare function transformReply(): string;
|
export declare function transformReply(): Array<string>;
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
import { transformArguments, transformReply } from './CLUSTER_INFO';
|
import { transformArguments, transformReply } from './CLUSTER_INFO';
|
||||||
|
|
||||||
describe('CLUSTER INFO', () => {
|
describe('CLUSTER INFO', () => {
|
||||||
@@ -43,4 +44,11 @@ describe('CLUSTER INFO', () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testUtils.testWithCluster('clusterNode.clusterInfo', async cluster => {
|
||||||
|
assert.notEqual(
|
||||||
|
await cluster.getSlotMaster(0).client.clusterInfo(),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}, GLOBAL.CLUSTERS.OPEN);
|
||||||
});
|
});
|
||||||
|
19
packages/client/lib/commands/CLUSTER_KEYSLOT.spec.ts
Normal file
19
packages/client/lib/commands/CLUSTER_KEYSLOT.spec.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
|
import { transformArguments } from './CLUSTER_KEYSLOT';
|
||||||
|
|
||||||
|
describe('CLUSTER KEYSLOT', () => {
|
||||||
|
it('transformArguments', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('key'),
|
||||||
|
['CLUSTER', 'KEYSLOT', 'key']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithCluster('clusterNode.clusterKeySlot', async cluster => {
|
||||||
|
assert.equal(
|
||||||
|
typeof await cluster.getSlotMaster(0).client.clusterKeySlot('key'),
|
||||||
|
'number'
|
||||||
|
);
|
||||||
|
}, GLOBAL.CLUSTERS.OPEN);
|
||||||
|
});
|
5
packages/client/lib/commands/CLUSTER_KEYSLOT.ts
Normal file
5
packages/client/lib/commands/CLUSTER_KEYSLOT.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export function transformArguments(key: string): Array<string> {
|
||||||
|
return ['CLUSTER', 'KEYSLOT', key];
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): number;
|
27
packages/client/lib/commands/CLUSTER_LINKS.spec.ts
Normal file
27
packages/client/lib/commands/CLUSTER_LINKS.spec.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
|
import { transformArguments } from './CLUSTER_LINKS';
|
||||||
|
|
||||||
|
describe('CLUSTER LINKS', () => {
|
||||||
|
testUtils.isVersionGreaterThanHook([7, 0]);
|
||||||
|
|
||||||
|
it('transformArguments', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments(),
|
||||||
|
['CLUSTER', 'LINKS']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithCluster('clusterNode.clusterLinks', async cluster => {
|
||||||
|
const links = await cluster.getSlotMaster(0).client.clusterLinks();
|
||||||
|
assert.ok(Array.isArray(links));
|
||||||
|
for (const link of links) {
|
||||||
|
assert.equal(typeof link.direction, 'string');
|
||||||
|
assert.equal(typeof link.node, 'string');
|
||||||
|
assert.equal(typeof link.createTime, 'number');
|
||||||
|
assert.equal(typeof link.events, 'string');
|
||||||
|
assert.equal(typeof link.sendBufferAllocated, 'number');
|
||||||
|
assert.equal(typeof link.sendBufferUsed, 'number');
|
||||||
|
}
|
||||||
|
}, GLOBAL.CLUSTERS.OPEN);
|
||||||
|
});
|
38
packages/client/lib/commands/CLUSTER_LINKS.ts
Normal file
38
packages/client/lib/commands/CLUSTER_LINKS.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
export function transformArguments(): Array<string> {
|
||||||
|
return ['CLUSTER', 'LINKS'];
|
||||||
|
}
|
||||||
|
|
||||||
|
type ClusterLinksRawReply = Array<[
|
||||||
|
'direction',
|
||||||
|
string,
|
||||||
|
'node',
|
||||||
|
string,
|
||||||
|
'createTime',
|
||||||
|
number,
|
||||||
|
'events',
|
||||||
|
string,
|
||||||
|
'send-buffer-allocated',
|
||||||
|
number,
|
||||||
|
'send-buffer-used',
|
||||||
|
number
|
||||||
|
]>;
|
||||||
|
|
||||||
|
type ClusterLinksReply = Array<{
|
||||||
|
direction: string;
|
||||||
|
node: string;
|
||||||
|
createTime: number;
|
||||||
|
events: string;
|
||||||
|
sendBufferAllocated: number;
|
||||||
|
sendBufferUsed: number;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
export function transformReply(reply: ClusterLinksRawReply): ClusterLinksReply {
|
||||||
|
return reply.map(peerLink => ({
|
||||||
|
direction: peerLink[1],
|
||||||
|
node: peerLink[3],
|
||||||
|
createTime: Number(peerLink[5]),
|
||||||
|
events: peerLink[7],
|
||||||
|
sendBufferAllocated: Number(peerLink[9]),
|
||||||
|
sendBufferUsed: Number(peerLink[11])
|
||||||
|
}));
|
||||||
|
}
|
@@ -2,4 +2,4 @@ export function transformArguments(ip: string, port: number): Array<string> {
|
|||||||
return ['CLUSTER', 'MEET', ip, port.toString()];
|
return ['CLUSTER', 'MEET', ip, port.toString()];
|
||||||
}
|
}
|
||||||
|
|
||||||
export declare function transformReply(): string;
|
export declare function transformReply(): 'OK';
|
||||||
|
19
packages/client/lib/commands/CLUSTER_MYID.spec.ts
Normal file
19
packages/client/lib/commands/CLUSTER_MYID.spec.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
|
import { transformArguments } from './CLUSTER_MYID';
|
||||||
|
|
||||||
|
describe('CLUSTER MYID', () => {
|
||||||
|
it('transformArguments', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments(),
|
||||||
|
['CLUSTER', 'MYID']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithCluster('clusterNode.clusterMyId', async cluster => {
|
||||||
|
assert.equal(
|
||||||
|
typeof await cluster.getSlotMaster(0).client.clusterMyId(),
|
||||||
|
'string'
|
||||||
|
);
|
||||||
|
}, GLOBAL.CLUSTERS.OPEN);
|
||||||
|
});
|
5
packages/client/lib/commands/CLUSTER_MYID.ts
Normal file
5
packages/client/lib/commands/CLUSTER_MYID.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export function transformArguments(): Array<string> {
|
||||||
|
return ['CLUSTER', 'MYID'];
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): string;
|
11
packages/client/lib/commands/CLUSTER_REPLICAS.spec.ts
Normal file
11
packages/client/lib/commands/CLUSTER_REPLICAS.spec.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import { transformArguments } from './CLUSTER_REPLICAS';
|
||||||
|
|
||||||
|
describe('CLUSTER REPLICAS', () => {
|
||||||
|
it('transformArguments', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('0'),
|
||||||
|
['CLUSTER', 'REPLICAS', '0']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
5
packages/client/lib/commands/CLUSTER_REPLICAS.ts
Normal file
5
packages/client/lib/commands/CLUSTER_REPLICAS.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export function transformArguments(nodeId: string): Array<string> {
|
||||||
|
return ['CLUSTER', 'REPLICAS', nodeId];
|
||||||
|
}
|
||||||
|
|
||||||
|
export { transformReply } from './CLUSTER_NODES';
|
11
packages/client/lib/commands/CLUSTER_REPLICATE.spec.ts
Normal file
11
packages/client/lib/commands/CLUSTER_REPLICATE.spec.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import { transformArguments } from './CLUSTER_REPLICATE';
|
||||||
|
|
||||||
|
describe('CLUSTER REPLICATE', () => {
|
||||||
|
it('transformArguments', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('0'),
|
||||||
|
['CLUSTER', 'REPLICATE', '0']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
5
packages/client/lib/commands/CLUSTER_REPLICATE.ts
Normal file
5
packages/client/lib/commands/CLUSTER_REPLICATE.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export function transformArguments(nodeId: string): Array<string> {
|
||||||
|
return ['CLUSTER', 'REPLICATE', nodeId];
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): 'OK';
|
@@ -10,18 +10,11 @@ describe('CLUSTER RESET', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('HARD', () => {
|
it('with mode', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('HARD'),
|
transformArguments('HARD'),
|
||||||
['CLUSTER', 'RESET', 'HARD']
|
['CLUSTER', 'RESET', 'HARD']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('SOFT', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('SOFT'),
|
|
||||||
['CLUSTER', 'RESET', 'SOFT']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -1,6 +1,4 @@
|
|||||||
export type ClusterResetModes = 'HARD' | 'SOFT';
|
export function transformArguments(mode?: 'HARD' | 'SOFT'): Array<string> {
|
||||||
|
|
||||||
export function transformArguments(mode?: ClusterResetModes): Array<string> {
|
|
||||||
const args = ['CLUSTER', 'RESET'];
|
const args = ['CLUSTER', 'RESET'];
|
||||||
|
|
||||||
if (mode) {
|
if (mode) {
|
||||||
|
19
packages/client/lib/commands/CLUSTER_SAVECONFIG.spec.ts
Normal file
19
packages/client/lib/commands/CLUSTER_SAVECONFIG.spec.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
|
import { transformArguments } from './CLUSTER_SAVECONFIG';
|
||||||
|
|
||||||
|
describe('CLUSTER SAVECONFIG', () => {
|
||||||
|
it('transformArguments', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments(),
|
||||||
|
['CLUSTER', 'SAVECONFIG']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithCluster('clusterNode.clusterSaveConfig', async cluster => {
|
||||||
|
assert.equal(
|
||||||
|
await cluster.getSlotMaster(0).client.clusterSaveConfig(),
|
||||||
|
'OK'
|
||||||
|
);
|
||||||
|
}, GLOBAL.CLUSTERS.OPEN);
|
||||||
|
});
|
5
packages/client/lib/commands/CLUSTER_SAVECONFIG.ts
Normal file
5
packages/client/lib/commands/CLUSTER_SAVECONFIG.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export function transformArguments(): Array<string> {
|
||||||
|
return ['CLUSTER', 'SAVECONFIG'];
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): 'OK';
|
@@ -0,0 +1,11 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import { transformArguments } from './CLUSTER_SET-CONFIG-EPOCH';
|
||||||
|
|
||||||
|
describe('CLUSTER SET-CONFIG-EPOCH', () => {
|
||||||
|
it('transformArguments', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments(0),
|
||||||
|
['CLUSTER', 'SET-CONFIG-EPOCH', '0']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
5
packages/client/lib/commands/CLUSTER_SET-CONFIG-EPOCH.ts
Normal file
5
packages/client/lib/commands/CLUSTER_SET-CONFIG-EPOCH.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export function transformArguments(configEpoch: number): Array<string> {
|
||||||
|
return ['CLUSTER', 'SET-CONFIG-EPOCH', configEpoch.toString()];
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): 'OK';
|
@@ -5,7 +5,11 @@ export enum ClusterSlotStates {
|
|||||||
NODE = 'NODE'
|
NODE = 'NODE'
|
||||||
}
|
}
|
||||||
|
|
||||||
export function transformArguments(slot: number, state: ClusterSlotStates, nodeId?: string): Array<string> {
|
export function transformArguments(
|
||||||
|
slot: number,
|
||||||
|
state: ClusterSlotStates,
|
||||||
|
nodeId?: string
|
||||||
|
): Array<string> {
|
||||||
const args = ['CLUSTER', 'SETSLOT', slot.toString(), state];
|
const args = ['CLUSTER', 'SETSLOT', slot.toString(), state];
|
||||||
|
|
||||||
if (nodeId) {
|
if (nodeId) {
|
||||||
@@ -15,4 +19,4 @@ export function transformArguments(slot: number, state: ClusterSlotStates, nodeI
|
|||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
export declare function transformReply(): string;
|
export declare function transformReply(): 'OK';
|
||||||
|
@@ -6,7 +6,12 @@ export function transformArguments(): RedisCommandArguments {
|
|||||||
|
|
||||||
type ClusterSlotsRawNode = [ip: string, port: number, id: string];
|
type ClusterSlotsRawNode = [ip: string, port: number, id: string];
|
||||||
|
|
||||||
type ClusterSlotsRawReply = Array<[from: number, to: number, master: ClusterSlotsRawNode, ...replicas: Array<ClusterSlotsRawNode>]>;
|
type ClusterSlotsRawReply = Array<[
|
||||||
|
from: number,
|
||||||
|
to: number,
|
||||||
|
master: ClusterSlotsRawNode,
|
||||||
|
...replicas: Array<ClusterSlotsRawNode>
|
||||||
|
]>;
|
||||||
|
|
||||||
type ClusterSlotsNode = {
|
type ClusterSlotsNode = {
|
||||||
ip: string;
|
ip: string;
|
||||||
|
24
packages/client/lib/commands/COMMAND_GETKEYSANDFLAGS.spec.ts
Normal file
24
packages/client/lib/commands/COMMAND_GETKEYSANDFLAGS.spec.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
|
import { transformArguments } from './COMMAND_GETKEYSANDFLAGS';
|
||||||
|
|
||||||
|
describe('COMMAND GETKEYSANDFLAGS', () => {
|
||||||
|
testUtils.isVersionGreaterThanHook([7, 0]);
|
||||||
|
|
||||||
|
it('transformArguments', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments(['GET', 'key']),
|
||||||
|
['COMMAND', 'GETKEYSANDFLAGS', 'GET', 'key']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithClient('client.commandGetKeysAndFlags', async client => {
|
||||||
|
assert.deepEqual(
|
||||||
|
await client.commandGetKeysAndFlags(['GET', 'key']),
|
||||||
|
[{
|
||||||
|
key: 'key',
|
||||||
|
flags: ['RO', 'access']
|
||||||
|
}]
|
||||||
|
);
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
|
});
|
24
packages/client/lib/commands/COMMAND_GETKEYSANDFLAGS.ts
Normal file
24
packages/client/lib/commands/COMMAND_GETKEYSANDFLAGS.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||||
|
|
||||||
|
export const IS_READ_ONLY = true;
|
||||||
|
|
||||||
|
export function transformArguments(args: Array<RedisCommandArgument>): RedisCommandArguments {
|
||||||
|
return ['COMMAND', 'GETKEYSANDFLAGS', ...args];
|
||||||
|
}
|
||||||
|
|
||||||
|
type KeysAndFlagsRawReply = Array<[
|
||||||
|
RedisCommandArgument,
|
||||||
|
RedisCommandArguments
|
||||||
|
]>;
|
||||||
|
|
||||||
|
type KeysAndFlagsReply = Array<{
|
||||||
|
key: RedisCommandArgument;
|
||||||
|
flags: RedisCommandArguments;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
export function transformReply(reply: KeysAndFlagsRawReply): KeysAndFlagsReply {
|
||||||
|
return reply.map(([key, flags]) => ({
|
||||||
|
key,
|
||||||
|
flags
|
||||||
|
}));
|
||||||
|
}
|
@@ -9,7 +9,11 @@ export function assertPingCommand(commandInfo: CommandReply | null | undefined):
|
|||||||
{
|
{
|
||||||
name: 'ping',
|
name: 'ping',
|
||||||
arity: -1,
|
arity: -1,
|
||||||
flags: new Set([CommandFlags.STALE, CommandFlags.FAST]),
|
flags: new Set(
|
||||||
|
testUtils.isVersionGreaterThan([7]) ?
|
||||||
|
[CommandFlags.FAST] :
|
||||||
|
[CommandFlags.STALE, CommandFlags.FAST]
|
||||||
|
),
|
||||||
firstKeyIndex: 0,
|
firstKeyIndex: 0,
|
||||||
lastKeyIndex: 0,
|
lastKeyIndex: 0,
|
||||||
step: 0,
|
step: 0,
|
||||||
|
@@ -2,10 +2,23 @@ import { strict as assert } from 'assert';
|
|||||||
import { transformArguments } from './CONFIG_SET';
|
import { transformArguments } from './CONFIG_SET';
|
||||||
|
|
||||||
describe('CONFIG SET', () => {
|
describe('CONFIG SET', () => {
|
||||||
it('transformArguments', () => {
|
describe('transformArguments', () => {
|
||||||
assert.deepEqual(
|
it('set one parameter (old version)', () => {
|
||||||
transformArguments('parameter', 'value'),
|
assert.deepEqual(
|
||||||
['CONFIG', 'SET', 'parameter', 'value']
|
transformArguments('parameter', 'value'),
|
||||||
);
|
['CONFIG', 'SET', 'parameter', 'value']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('set muiltiple parameters', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments({
|
||||||
|
1: 'a',
|
||||||
|
2: 'b',
|
||||||
|
3: 'c'
|
||||||
|
}),
|
||||||
|
['CONFIG', 'SET', '1', 'a', '2', 'b', '3', 'c']
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -1,5 +1,23 @@
|
|||||||
export function transformArguments(parameter: string, value: string): Array<string> {
|
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||||
return ['CONFIG', 'SET', parameter, value];
|
|
||||||
|
type SingleParameter = [parameter: RedisCommandArgument, value: RedisCommandArgument];
|
||||||
|
|
||||||
|
type MultipleParameters = [config: Record<string, RedisCommandArgument>];
|
||||||
|
|
||||||
|
export function transformArguments(
|
||||||
|
...[parameterOrConfig, value]: SingleParameter | MultipleParameters
|
||||||
|
): RedisCommandArguments {
|
||||||
|
const args: RedisCommandArguments = ['CONFIG', 'SET'];
|
||||||
|
|
||||||
|
if (typeof parameterOrConfig === 'string') {
|
||||||
|
args.push(parameterOrConfig, value!);
|
||||||
|
} else {
|
||||||
|
for (const [key, value] of Object.entries(parameterOrConfig)) {
|
||||||
|
args.push(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
export declare function transformReply(): string;
|
export declare function transformReply(): string;
|
||||||
|
@@ -3,11 +3,20 @@ import testUtils, { GLOBAL } from '../test-utils';
|
|||||||
import { transformArguments } from './EXPIRE';
|
import { transformArguments } from './EXPIRE';
|
||||||
|
|
||||||
describe('EXPIRE', () => {
|
describe('EXPIRE', () => {
|
||||||
it('transformArguments', () => {
|
describe('transformArguments', () => {
|
||||||
assert.deepEqual(
|
it('simple', () => {
|
||||||
transformArguments('key', 1),
|
assert.deepEqual(
|
||||||
['EXPIRE', 'key', '1']
|
transformArguments('key', 1),
|
||||||
);
|
['EXPIRE', 'key', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with set option', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('key', 1, 'NX'),
|
||||||
|
['EXPIRE', 'key', '1', 'NX']
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.expire', async client => {
|
testUtils.testWithClient('client.expire', async client => {
|
||||||
|
@@ -4,9 +4,16 @@ export const FIRST_KEY_INDEX = 1;
|
|||||||
|
|
||||||
export function transformArguments(
|
export function transformArguments(
|
||||||
key: RedisCommandArgument,
|
key: RedisCommandArgument,
|
||||||
seconds: number
|
seconds: number,
|
||||||
|
mode?: 'NX' | 'XX' | 'GT' | 'LT'
|
||||||
): RedisCommandArguments {
|
): RedisCommandArguments {
|
||||||
return ['EXPIRE', key, seconds.toString()];
|
const args = ['EXPIRE', key, seconds.toString()];
|
||||||
|
|
||||||
|
if (mode) {
|
||||||
|
args.push(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { transformBooleanReply as transformReply } from './generic-transformers';
|
export { transformBooleanReply as transformReply } from './generic-transformers';
|
||||||
|
@@ -18,6 +18,13 @@ describe('EXPIREAT', () => {
|
|||||||
['EXPIREAT', 'key', Math.floor(d.getTime() / 1000).toString()]
|
['EXPIREAT', 'key', Math.floor(d.getTime() / 1000).toString()]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('with set option', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('key', 1, 'GT'),
|
||||||
|
['EXPIREAT', 'key', '1', 'GT']
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.expireAt', async client => {
|
testUtils.testWithClient('client.expireAt', async client => {
|
||||||
|
@@ -5,13 +5,20 @@ export const FIRST_KEY_INDEX = 1;
|
|||||||
|
|
||||||
export function transformArguments(
|
export function transformArguments(
|
||||||
key: RedisCommandArgument,
|
key: RedisCommandArgument,
|
||||||
timestamp: number | Date
|
timestamp: number | Date,
|
||||||
|
mode?: 'NX' | 'XX' | 'GT' | 'LT'
|
||||||
): RedisCommandArguments {
|
): RedisCommandArguments {
|
||||||
return [
|
const args = [
|
||||||
'EXPIREAT',
|
'EXPIREAT',
|
||||||
key,
|
key,
|
||||||
transformEXAT(timestamp)
|
transformEXAT(timestamp)
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if (mode) {
|
||||||
|
args.push(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { transformBooleanReply as transformReply } from './generic-transformers';
|
export { transformBooleanReply as transformReply } from './generic-transformers';
|
||||||
|
21
packages/client/lib/commands/EXPIRETIME.spec.ts
Normal file
21
packages/client/lib/commands/EXPIRETIME.spec.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
|
import { transformArguments } from './EXPIRETIME';
|
||||||
|
|
||||||
|
describe('EXPIRETIME', () => {
|
||||||
|
testUtils.isVersionGreaterThanHook([7, 0]);
|
||||||
|
|
||||||
|
it('transformArguments', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('key'),
|
||||||
|
['EXPIRETIME', 'key']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithClient('client.expireTime', async client => {
|
||||||
|
assert.equal(
|
||||||
|
await client.expireTime('key'),
|
||||||
|
-2
|
||||||
|
);
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
|
});
|
9
packages/client/lib/commands/EXPIRETIME.ts
Normal file
9
packages/client/lib/commands/EXPIRETIME.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||||
|
|
||||||
|
export const FIRST_KEY_INDEX = 1;
|
||||||
|
|
||||||
|
export function transformArguments(key: RedisCommandArgument): RedisCommandArguments {
|
||||||
|
return ['EXPIRETIME', key];
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): number;
|
19
packages/client/lib/commands/LATENCY_DOCTOR.spec.ts
Normal file
19
packages/client/lib/commands/LATENCY_DOCTOR.spec.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import {strict as assert} from 'assert';
|
||||||
|
import testUtils, {GLOBAL} from '../test-utils';
|
||||||
|
import { transformArguments } from './LATENCY_DOCTOR';
|
||||||
|
|
||||||
|
describe('LATENCY DOCTOR', () => {
|
||||||
|
it('transformArguments', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments(),
|
||||||
|
['LATENCY', 'DOCTOR']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithClient('client.latencyDoctor', async client => {
|
||||||
|
assert.equal(
|
||||||
|
typeof (await client.latencyDoctor()),
|
||||||
|
'string'
|
||||||
|
);
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
|
});
|
5
packages/client/lib/commands/LATENCY_DOCTOR.ts
Normal file
5
packages/client/lib/commands/LATENCY_DOCTOR.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export function transformArguments(): Array<string> {
|
||||||
|
return ['LATENCY', 'DOCTOR'];
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): string;
|
19
packages/client/lib/commands/OBJECT_ENCODING.spec.ts
Normal file
19
packages/client/lib/commands/OBJECT_ENCODING.spec.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
|
import { transformArguments } from './OBJECT_ENCODING';
|
||||||
|
|
||||||
|
describe('OBJECT ENCODING', () => {
|
||||||
|
it('transformArguments', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('key'),
|
||||||
|
['OBJECT', 'ENCODING', 'key']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithClient('client.objectEncoding', async client => {
|
||||||
|
assert.equal(
|
||||||
|
await client.objectEncoding('key'),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
|
});
|
11
packages/client/lib/commands/OBJECT_ENCODING.ts
Normal file
11
packages/client/lib/commands/OBJECT_ENCODING.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||||
|
|
||||||
|
export const FIRST_KEY_INDEX = 2;
|
||||||
|
|
||||||
|
export const IS_READ_ONLY = true;
|
||||||
|
|
||||||
|
export function transformArguments(key: RedisCommandArgument): RedisCommandArguments {
|
||||||
|
return ['OBJECT', 'ENCODING', key];
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): string | null;
|
19
packages/client/lib/commands/OBJECT_FREQ.spec.ts
Normal file
19
packages/client/lib/commands/OBJECT_FREQ.spec.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
|
import { transformArguments } from './OBJECT_FREQ';
|
||||||
|
|
||||||
|
describe('OBJECT FREQ', () => {
|
||||||
|
it('transformArguments', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('key'),
|
||||||
|
['OBJECT', 'FREQ', 'key']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithClient('client.objectFreq', async client => {
|
||||||
|
assert.equal(
|
||||||
|
await client.objectFreq('key'),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
|
});
|
11
packages/client/lib/commands/OBJECT_FREQ.ts
Normal file
11
packages/client/lib/commands/OBJECT_FREQ.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||||
|
|
||||||
|
export const FIRST_KEY_INDEX = 2;
|
||||||
|
|
||||||
|
export const IS_READ_ONLY = true;
|
||||||
|
|
||||||
|
export function transformArguments(key: RedisCommandArgument): RedisCommandArguments {
|
||||||
|
return ['OBJECT', 'FREQ', key];
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): number | null;
|
19
packages/client/lib/commands/OBJECT_IDLETIME.spec.ts
Normal file
19
packages/client/lib/commands/OBJECT_IDLETIME.spec.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
|
import { transformArguments } from './OBJECT_IDLETIME';
|
||||||
|
|
||||||
|
describe('OBJECT IDLETIME', () => {
|
||||||
|
it('transformArguments', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('key'),
|
||||||
|
['OBJECT', 'IDLETIME', 'key']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithClient('client.objectIdleTime', async client => {
|
||||||
|
assert.equal(
|
||||||
|
await client.objectIdleTime('key'),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
|
});
|
11
packages/client/lib/commands/OBJECT_IDLETIME.ts
Normal file
11
packages/client/lib/commands/OBJECT_IDLETIME.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||||
|
|
||||||
|
export const FIRST_KEY_INDEX = 2;
|
||||||
|
|
||||||
|
export const IS_READ_ONLY = true;
|
||||||
|
|
||||||
|
export function transformArguments(key: RedisCommandArgument): RedisCommandArguments {
|
||||||
|
return ['OBJECT', 'IDLETIME', key];
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): number | null;
|
19
packages/client/lib/commands/OBJECT_REFCOUNT.spec.ts
Normal file
19
packages/client/lib/commands/OBJECT_REFCOUNT.spec.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
|
import { transformArguments } from './OBJECT_REFCOUNT';
|
||||||
|
|
||||||
|
describe('OBJECT REFCOUNT', () => {
|
||||||
|
it('transformArguments', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('key'),
|
||||||
|
['OBJECT', 'REFCOUNT', 'key']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithClient('client.objectRefCount', async client => {
|
||||||
|
assert.equal(
|
||||||
|
await client.objectRefCount('key'),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
|
});
|
11
packages/client/lib/commands/OBJECT_REFCOUNT.ts
Normal file
11
packages/client/lib/commands/OBJECT_REFCOUNT.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||||
|
|
||||||
|
export const FIRST_KEY_INDEX = 2;
|
||||||
|
|
||||||
|
export const IS_READ_ONLY = true;
|
||||||
|
|
||||||
|
export function transformArguments(key: RedisCommandArgument): RedisCommandArguments {
|
||||||
|
return ['OBJECT', 'REFCOUNT', key];
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): number | null;
|
@@ -3,11 +3,20 @@ import testUtils, { GLOBAL } from '../test-utils';
|
|||||||
import { transformArguments } from './PEXPIRE';
|
import { transformArguments } from './PEXPIRE';
|
||||||
|
|
||||||
describe('PEXPIRE', () => {
|
describe('PEXPIRE', () => {
|
||||||
it('transformArguments', () => {
|
describe('transformArguments', () => {
|
||||||
assert.deepEqual(
|
it('simple', () => {
|
||||||
transformArguments('key', 1),
|
assert.deepEqual(
|
||||||
['PEXPIRE', 'key', '1']
|
transformArguments('key', 1),
|
||||||
);
|
['PEXPIRE', 'key', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with set option', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('key', 1, 'GT'),
|
||||||
|
['PEXPIRE', 'key', '1', 'GT']
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.pExpire', async client => {
|
testUtils.testWithClient('client.pExpire', async client => {
|
||||||
|
@@ -4,9 +4,16 @@ export const FIRST_KEY_INDEX = 1;
|
|||||||
|
|
||||||
export function transformArguments(
|
export function transformArguments(
|
||||||
key: RedisCommandArgument,
|
key: RedisCommandArgument,
|
||||||
milliseconds: number
|
milliseconds: number,
|
||||||
|
mode?: 'NX' | 'XX' | 'GT' | 'LT'
|
||||||
): RedisCommandArguments {
|
): RedisCommandArguments {
|
||||||
return ['PEXPIRE', key, milliseconds.toString()];
|
const args = ['PEXPIRE', key, milliseconds.toString()];
|
||||||
|
|
||||||
|
if (mode) {
|
||||||
|
args.push(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { transformBooleanReply as transformReply } from './generic-transformers';
|
export { transformBooleanReply as transformReply } from './generic-transformers';
|
||||||
|
@@ -18,6 +18,13 @@ describe('PEXPIREAT', () => {
|
|||||||
['PEXPIREAT', 'key', d.getTime().toString()]
|
['PEXPIREAT', 'key', d.getTime().toString()]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('with set option', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('key', 1, 'XX'),
|
||||||
|
['PEXPIREAT', 'key', '1', 'XX']
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.pExpireAt', async client => {
|
testUtils.testWithClient('client.pExpireAt', async client => {
|
||||||
|
@@ -5,13 +5,20 @@ export const FIRST_KEY_INDEX = 1;
|
|||||||
|
|
||||||
export function transformArguments(
|
export function transformArguments(
|
||||||
key: RedisCommandArgument,
|
key: RedisCommandArgument,
|
||||||
millisecondsTimestamp: number | Date
|
millisecondsTimestamp: number | Date,
|
||||||
|
mode?: 'NX' | 'XX' | 'GT' | 'LT'
|
||||||
): RedisCommandArguments {
|
): RedisCommandArguments {
|
||||||
return [
|
const args = [
|
||||||
'PEXPIREAT',
|
'PEXPIREAT',
|
||||||
key,
|
key,
|
||||||
transformPXAT(millisecondsTimestamp)
|
transformPXAT(millisecondsTimestamp)
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if (mode) {
|
||||||
|
args.push(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { transformBooleanReply as transformReply } from './generic-transformers';
|
export { transformBooleanReply as transformReply } from './generic-transformers';
|
||||||
|
21
packages/client/lib/commands/PEXPIRETIME.spec.ts
Normal file
21
packages/client/lib/commands/PEXPIRETIME.spec.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
|
import { transformArguments } from './PEXPIRETIME';
|
||||||
|
|
||||||
|
describe('PEXPIRETIME', () => {
|
||||||
|
testUtils.isVersionGreaterThanHook([7, 0]);
|
||||||
|
|
||||||
|
it('transformArguments', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('key'),
|
||||||
|
['PEXPIRETIME', 'key']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithClient('client.pExpireTime', async client => {
|
||||||
|
assert.equal(
|
||||||
|
await client.pExpireTime('key'),
|
||||||
|
-2
|
||||||
|
);
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
|
});
|
9
packages/client/lib/commands/PEXPIRETIME.ts
Normal file
9
packages/client/lib/commands/PEXPIRETIME.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||||
|
|
||||||
|
export const FIRST_KEY_INDEX = 1;
|
||||||
|
|
||||||
|
export function transformArguments(key: RedisCommandArgument): RedisCommandArguments {
|
||||||
|
return ['PEXPIRETIME', key];
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): number;
|
30
packages/client/lib/commands/SINTERCARD.spec.ts
Normal file
30
packages/client/lib/commands/SINTERCARD.spec.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
|
import { transformArguments } from './SINTERCARD';
|
||||||
|
|
||||||
|
describe('SINTERCARD', () => {
|
||||||
|
testUtils.isVersionGreaterThanHook([7, 0]);
|
||||||
|
|
||||||
|
describe('transformArguments', () => {
|
||||||
|
it('simple', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments(['1', '2']),
|
||||||
|
['SINTERCARD', '2', '1', '2']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with limit', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments(['1', '2'], 1),
|
||||||
|
['SINTERCARD', '2', '1', '2', 'LIMIT', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithClient('client.sInterCard', async client => {
|
||||||
|
assert.deepEqual(
|
||||||
|
await client.sInterCard('key'),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
|
});
|
21
packages/client/lib/commands/SINTERCARD.ts
Normal file
21
packages/client/lib/commands/SINTERCARD.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||||
|
import { pushVerdictArgument } from './generic-transformers';
|
||||||
|
|
||||||
|
export const FIRST_KEY_INDEX = 2;
|
||||||
|
|
||||||
|
export const IS_READ_ONLY = true;
|
||||||
|
|
||||||
|
export function transformArguments(
|
||||||
|
keys: Array<RedisCommandArgument> | RedisCommandArgument,
|
||||||
|
limit?: number
|
||||||
|
): RedisCommandArguments {
|
||||||
|
const args = pushVerdictArgument(['SINTERCARD'], keys);
|
||||||
|
|
||||||
|
if (limit) {
|
||||||
|
args.push('LIMIT', limit.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): number;
|
@@ -70,16 +70,7 @@ describe('SORT', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('with STORE', () => {
|
it('with BY, LIMIT, GET, DIRECTION, ALPHA', () => {
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('key', {
|
|
||||||
STORE: 'destination'
|
|
||||||
}),
|
|
||||||
['SORT', 'key', 'STORE', 'destination']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with BY, LIMIT, GET, DIRECTION, ALPHA, STORE', () => {
|
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', {
|
transformArguments('key', {
|
||||||
BY: 'pattern',
|
BY: 'pattern',
|
||||||
@@ -89,10 +80,9 @@ describe('SORT', () => {
|
|||||||
},
|
},
|
||||||
GET: 'pattern',
|
GET: 'pattern',
|
||||||
DIRECTION: 'ASC',
|
DIRECTION: 'ASC',
|
||||||
ALPHA: true,
|
ALPHA: true
|
||||||
STORE: 'destination'
|
|
||||||
}),
|
}),
|
||||||
['SORT', 'key', 'BY', 'pattern', 'LIMIT', '0', '1', 'GET', 'pattern', 'ASC', 'ALPHA', 'STORE', 'destination']
|
['SORT', 'key', 'BY', 'pattern', 'LIMIT', '0', '1', 'GET', 'pattern', 'ASC', 'ALPHA']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -1,56 +1,13 @@
|
|||||||
|
import { RedisCommandArguments } from '.';
|
||||||
|
import { pushSortArguments, SortOptions } from './generic-transformers';
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
export const FIRST_KEY_INDEX = 1;
|
||||||
|
|
||||||
export const IS_READ_ONLY = true;
|
export function transformArguments(
|
||||||
|
key: string,
|
||||||
interface SortOptions {
|
options?: SortOptions
|
||||||
BY?: string;
|
): RedisCommandArguments {
|
||||||
LIMIT?: {
|
return pushSortArguments(['SORT', key], options);
|
||||||
offset: number;
|
|
||||||
count: number;
|
|
||||||
},
|
|
||||||
GET?: string | Array<string>;
|
|
||||||
DIRECTION?: 'ASC' | 'DESC';
|
|
||||||
ALPHA?: true;
|
|
||||||
STORE?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function transformArguments(key: string, options?: SortOptions): Array<string> {
|
export declare function transformReply(): Array<string>;
|
||||||
const args = ['SORT', key];
|
|
||||||
|
|
||||||
if (options?.BY) {
|
|
||||||
args.push('BY', options.BY);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options?.LIMIT) {
|
|
||||||
args.push(
|
|
||||||
'LIMIT',
|
|
||||||
options.LIMIT.offset.toString(),
|
|
||||||
options.LIMIT.count.toString()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options?.GET) {
|
|
||||||
for (const pattern of (typeof options.GET === 'string' ? [options.GET] : options.GET)) {
|
|
||||||
args.push('GET', pattern);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options?.DIRECTION) {
|
|
||||||
args.push(options.DIRECTION);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options?.ALPHA) {
|
|
||||||
args.push('ALPHA');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options?.STORE) {
|
|
||||||
args.push('STORE', options.STORE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
// integer when using `STORE`
|
|
||||||
export function transformReply(reply: Array<string> | number): Array<string> | number {
|
|
||||||
return reply;
|
|
||||||
}
|
|
||||||
|
98
packages/client/lib/commands/SORT_RO.spec.ts
Normal file
98
packages/client/lib/commands/SORT_RO.spec.ts
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
|
import { transformArguments } from './SORT_RO';
|
||||||
|
|
||||||
|
describe('SORT_RO', () => {
|
||||||
|
testUtils.isVersionGreaterThanHook([7, 0]);
|
||||||
|
|
||||||
|
describe('transformArguments', () => {
|
||||||
|
it('simple', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('key'),
|
||||||
|
['SORT_RO', 'key']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with BY', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('key', {
|
||||||
|
BY: 'pattern'
|
||||||
|
}),
|
||||||
|
['SORT_RO', 'key', 'BY', 'pattern']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with LIMIT', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('key', {
|
||||||
|
LIMIT: {
|
||||||
|
offset: 0,
|
||||||
|
count: 1
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
['SORT_RO', 'key', 'LIMIT', '0', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with GET', () => {
|
||||||
|
it('string', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('key', {
|
||||||
|
GET: 'pattern'
|
||||||
|
}),
|
||||||
|
['SORT_RO', 'key', 'GET', 'pattern']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('array', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('key', {
|
||||||
|
GET: ['1', '2']
|
||||||
|
}),
|
||||||
|
['SORT_RO', 'key', 'GET', '1', 'GET', '2']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with DIRECTION', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('key', {
|
||||||
|
DIRECTION: 'ASC'
|
||||||
|
}),
|
||||||
|
['SORT_RO', 'key', 'ASC']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with ALPHA', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('key', {
|
||||||
|
ALPHA: true
|
||||||
|
}),
|
||||||
|
['SORT_RO', 'key', 'ALPHA']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with BY, LIMIT, GET, DIRECTION, ALPHA', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('key', {
|
||||||
|
BY: 'pattern',
|
||||||
|
LIMIT: {
|
||||||
|
offset: 0,
|
||||||
|
count: 1
|
||||||
|
},
|
||||||
|
GET: 'pattern',
|
||||||
|
DIRECTION: 'ASC',
|
||||||
|
ALPHA: true,
|
||||||
|
}),
|
||||||
|
['SORT_RO', 'key', 'BY', 'pattern', 'LIMIT', '0', '1', 'GET', 'pattern', 'ASC', 'ALPHA']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithClient('client.sortRo', async client => {
|
||||||
|
assert.deepEqual(
|
||||||
|
await client.sortRo('key'),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
|
});
|
15
packages/client/lib/commands/SORT_RO.ts
Normal file
15
packages/client/lib/commands/SORT_RO.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { RedisCommandArguments } from '.';
|
||||||
|
import { pushSortArguments, SortOptions } from "./generic-transformers";
|
||||||
|
|
||||||
|
export const FIRST_KEY_INDEX = 1;
|
||||||
|
|
||||||
|
export const IS_READ_ONLY = true;
|
||||||
|
|
||||||
|
export function transformArguments(
|
||||||
|
key: string,
|
||||||
|
options?: SortOptions
|
||||||
|
): RedisCommandArguments {
|
||||||
|
return pushSortArguments(['SORT_RO', key], options);
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): Array<string>;
|
96
packages/client/lib/commands/SORT_STORE.spec.ts
Normal file
96
packages/client/lib/commands/SORT_STORE.spec.ts
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
|
import { transformArguments } from './SORT_STORE';
|
||||||
|
|
||||||
|
describe('SORT STORE', () => {
|
||||||
|
describe('transformArguments', () => {
|
||||||
|
it('simple', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('source', 'destination'),
|
||||||
|
['SORT', 'source', 'STORE', 'destination']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with BY', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('source', 'destination', {
|
||||||
|
BY: 'pattern'
|
||||||
|
}),
|
||||||
|
['SORT', 'source', 'BY', 'pattern', 'STORE', 'destination']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with LIMIT', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('source', 'destination', {
|
||||||
|
LIMIT: {
|
||||||
|
offset: 0,
|
||||||
|
count: 1
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
['SORT', 'source', 'LIMIT', '0', '1', 'STORE', 'destination']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with GET', () => {
|
||||||
|
it('string', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('source', 'destination', {
|
||||||
|
GET: 'pattern'
|
||||||
|
}),
|
||||||
|
['SORT', 'source', 'GET', 'pattern', 'STORE', 'destination']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('array', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('source', 'destination', {
|
||||||
|
GET: ['1', '2']
|
||||||
|
}),
|
||||||
|
['SORT', 'source', 'GET', '1', 'GET', '2', 'STORE', 'destination']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with DIRECTION', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('source', 'destination', {
|
||||||
|
DIRECTION: 'ASC'
|
||||||
|
}),
|
||||||
|
['SORT', 'source', 'ASC', 'STORE', 'destination']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with ALPHA', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('source', 'destination', {
|
||||||
|
ALPHA: true
|
||||||
|
}),
|
||||||
|
['SORT', 'source', 'ALPHA', 'STORE', 'destination']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with BY, LIMIT, GET, DIRECTION, ALPHA', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('source', 'destination', {
|
||||||
|
BY: 'pattern',
|
||||||
|
LIMIT: {
|
||||||
|
offset: 0,
|
||||||
|
count: 1
|
||||||
|
},
|
||||||
|
GET: 'pattern',
|
||||||
|
DIRECTION: 'ASC',
|
||||||
|
ALPHA: true
|
||||||
|
}),
|
||||||
|
['SORT', 'source', 'BY', 'pattern', 'LIMIT', '0', '1', 'GET', 'pattern', 'ASC', 'ALPHA', 'STORE', 'destination']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithClient('client.sortStore', async client => {
|
||||||
|
assert.equal(
|
||||||
|
await client.sortStore('source', 'destination'),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
|
});
|
17
packages/client/lib/commands/SORT_STORE.ts
Normal file
17
packages/client/lib/commands/SORT_STORE.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { RedisCommandArguments } from '.';
|
||||||
|
import { SortOptions } from './generic-transformers';
|
||||||
|
import { transformArguments as transformSortArguments } from './SORT';
|
||||||
|
|
||||||
|
export const FIRST_KEY_INDEX = 1;
|
||||||
|
|
||||||
|
export function transformArguments(
|
||||||
|
source: string,
|
||||||
|
destination: string,
|
||||||
|
options?: SortOptions
|
||||||
|
): RedisCommandArguments {
|
||||||
|
const args = transformSortArguments(source, options);
|
||||||
|
args.push('STORE', destination);
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): number;
|
30
packages/client/lib/commands/ZINTERCARD.spec.ts
Normal file
30
packages/client/lib/commands/ZINTERCARD.spec.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
|
import { transformArguments } from './ZINTERCARD';
|
||||||
|
|
||||||
|
describe('ZINTERCARD', () => {
|
||||||
|
testUtils.isVersionGreaterThanHook([7, 0]);
|
||||||
|
|
||||||
|
describe('transformArguments', () => {
|
||||||
|
it('simple', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments(['1', '2']),
|
||||||
|
['ZINTERCARD', '2', '1', '2']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with limit', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments(['1', '2'], 1),
|
||||||
|
['ZINTERCARD', '2', '1', '2', 'LIMIT', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithClient('client.zInterCard', async client => {
|
||||||
|
assert.deepEqual(
|
||||||
|
await client.zInterCard('key'),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
|
});
|
21
packages/client/lib/commands/ZINTERCARD.ts
Normal file
21
packages/client/lib/commands/ZINTERCARD.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { RedisCommandArgument, RedisCommandArguments } from '.';
|
||||||
|
import { pushVerdictArgument } from './generic-transformers';
|
||||||
|
|
||||||
|
export const FIRST_KEY_INDEX = 2;
|
||||||
|
|
||||||
|
export const IS_READ_ONLY = true;
|
||||||
|
|
||||||
|
export function transformArguments(
|
||||||
|
keys: Array<RedisCommandArgument> | RedisCommandArgument,
|
||||||
|
limit?: number
|
||||||
|
): RedisCommandArguments {
|
||||||
|
const args = pushVerdictArgument(['ZINTERCARD'], keys);
|
||||||
|
|
||||||
|
if (limit) {
|
||||||
|
args.push('LIMIT', limit.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): number;
|
@@ -19,11 +19,13 @@ import {
|
|||||||
transformPXAT,
|
transformPXAT,
|
||||||
pushEvalArguments,
|
pushEvalArguments,
|
||||||
pushVerdictArguments,
|
pushVerdictArguments,
|
||||||
|
pushVerdictNumberArguments,
|
||||||
pushVerdictArgument,
|
pushVerdictArgument,
|
||||||
pushOptionalVerdictArgument,
|
pushOptionalVerdictArgument,
|
||||||
transformCommandReply,
|
transformCommandReply,
|
||||||
CommandFlags,
|
CommandFlags,
|
||||||
CommandCategories
|
CommandCategories,
|
||||||
|
pushSlotRangesArguments
|
||||||
} from './generic-transformers';
|
} from './generic-transformers';
|
||||||
|
|
||||||
describe('Generic Transformers', () => {
|
describe('Generic Transformers', () => {
|
||||||
@@ -578,6 +580,22 @@ describe('Generic Transformers', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('pushVerdictNumberArguments', () => {
|
||||||
|
it('number', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
pushVerdictNumberArguments([], 0),
|
||||||
|
['0']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('array', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
pushVerdictNumberArguments([], [0, 1]),
|
||||||
|
['0', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('pushVerdictArgument', () => {
|
describe('pushVerdictArgument', () => {
|
||||||
it('string', () => {
|
it('string', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
@@ -639,4 +657,29 @@ describe('Generic Transformers', () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('pushSlotRangesArguments', () => {
|
||||||
|
it('single range', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
pushSlotRangesArguments([], {
|
||||||
|
start: 0,
|
||||||
|
end: 1
|
||||||
|
}),
|
||||||
|
['0', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('multiple ranges', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
pushSlotRangesArguments([], [{
|
||||||
|
start: 0,
|
||||||
|
end: 1
|
||||||
|
}, {
|
||||||
|
start: 2,
|
||||||
|
end: 3
|
||||||
|
}]),
|
||||||
|
['0', '1', '2', '3']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -322,6 +322,21 @@ export function pushVerdictArguments(args: RedisCommandArguments, value: RedisCo
|
|||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function pushVerdictNumberArguments(
|
||||||
|
args: RedisCommandArguments,
|
||||||
|
value: number | Array<number>
|
||||||
|
): RedisCommandArguments {
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
for (const item of value) {
|
||||||
|
args.push(item.toString());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
args.push(value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
export function pushVerdictArgument(
|
export function pushVerdictArgument(
|
||||||
args: RedisCommandArguments,
|
args: RedisCommandArguments,
|
||||||
value: RedisCommandArgument | Array<RedisCommandArgument>
|
value: RedisCommandArgument | Array<RedisCommandArgument>
|
||||||
@@ -422,3 +437,77 @@ export function transformCommandReply(
|
|||||||
categories: new Set(categories)
|
categories: new Set(categories)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SortOptions {
|
||||||
|
BY?: string;
|
||||||
|
LIMIT?: {
|
||||||
|
offset: number;
|
||||||
|
count: number;
|
||||||
|
},
|
||||||
|
GET?: string | Array<string>;
|
||||||
|
DIRECTION?: 'ASC' | 'DESC';
|
||||||
|
ALPHA?: true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function pushSortArguments(
|
||||||
|
args: RedisCommandArguments,
|
||||||
|
options?: SortOptions
|
||||||
|
): RedisCommandArguments {
|
||||||
|
if (options?.BY) {
|
||||||
|
args.push('BY', options.BY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options?.LIMIT) {
|
||||||
|
args.push(
|
||||||
|
'LIMIT',
|
||||||
|
options.LIMIT.offset.toString(),
|
||||||
|
options.LIMIT.count.toString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options?.GET) {
|
||||||
|
for (const pattern of (typeof options.GET === 'string' ? [options.GET] : options.GET)) {
|
||||||
|
args.push('GET', pattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options?.DIRECTION) {
|
||||||
|
args.push(options.DIRECTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options?.ALPHA) {
|
||||||
|
args.push('ALPHA');
|
||||||
|
}
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SlotRange {
|
||||||
|
start: number;
|
||||||
|
end: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function pushSlotRangeArguments(
|
||||||
|
args: RedisCommandArguments,
|
||||||
|
range: SlotRange
|
||||||
|
): void {
|
||||||
|
args.push(
|
||||||
|
range.start.toString(),
|
||||||
|
range.end.toString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function pushSlotRangesArguments(
|
||||||
|
args: RedisCommandArguments,
|
||||||
|
ranges: SlotRange | Array<SlotRange>
|
||||||
|
): RedisCommandArguments {
|
||||||
|
if (Array.isArray(ranges)) {
|
||||||
|
for (const range of ranges) {
|
||||||
|
pushSlotRangeArguments(args, range);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pushSlotRangeArguments(args, ranges);
|
||||||
|
}
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-redis/client",
|
"name": "@node-redis/client",
|
||||||
"version": "1.0.4",
|
"version": "1.0.5",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
@@ -22,20 +22,20 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
||||||
"@node-redis/test-utils": "*",
|
"@node-redis/test-utils": "*",
|
||||||
"@types/node": "^17.0.13",
|
"@types/node": "^17.0.23",
|
||||||
"@types/redis-parser": "^3.0.0",
|
"@types/redis-parser": "^3.0.0",
|
||||||
"@types/sinon": "^10.0.9",
|
"@types/sinon": "^10.0.11",
|
||||||
"@types/yallist": "^4.0.1",
|
"@types/yallist": "^4.0.1",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.10.1",
|
"@typescript-eslint/eslint-plugin": "^5.16.0",
|
||||||
"@typescript-eslint/parser": "^5.10.1",
|
"@typescript-eslint/parser": "^5.16.0",
|
||||||
"eslint": "^8.8.0",
|
"eslint": "^8.12.0",
|
||||||
"nyc": "^15.1.0",
|
"nyc": "^15.1.0",
|
||||||
"release-it": "^14.12.4",
|
"release-it": "^14.13.1",
|
||||||
"sinon": "^13.0.0",
|
"sinon": "^13.0.1",
|
||||||
"source-map-support": "^0.5.21",
|
"source-map-support": "^0.5.21",
|
||||||
"ts-node": "^10.4.0",
|
"ts-node": "^10.7.0",
|
||||||
"typedoc": "^0.22.11",
|
"typedoc": "^0.22.13",
|
||||||
"typescript": "^4.5.5"
|
"typescript": "^4.6.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
|
@@ -18,12 +18,12 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
||||||
"@node-redis/test-utils": "*",
|
"@node-redis/test-utils": "*",
|
||||||
"@types/node": "^17.0.13",
|
"@types/node": "^17.0.23",
|
||||||
"nyc": "^15.1.0",
|
"nyc": "^15.1.0",
|
||||||
"release-it": "^14.12.4",
|
"release-it": "^14.13.1",
|
||||||
"source-map-support": "^0.5.21",
|
"source-map-support": "^0.5.21",
|
||||||
"ts-node": "^10.4.0",
|
"ts-node": "^10.7.0",
|
||||||
"typedoc": "^0.22.11",
|
"typedoc": "^0.22.13",
|
||||||
"typescript": "^4.5.5"
|
"typescript": "^4.6.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,12 +18,12 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
||||||
"@node-redis/test-utils": "*",
|
"@node-redis/test-utils": "*",
|
||||||
"@types/node": "^17.0.13",
|
"@types/node": "^17.0.23",
|
||||||
"nyc": "^15.1.0",
|
"nyc": "^15.1.0",
|
||||||
"release-it": "^14.12.4",
|
"release-it": "^14.13.1",
|
||||||
"source-map-support": "^0.5.21",
|
"source-map-support": "^0.5.21",
|
||||||
"ts-node": "^10.4.0",
|
"ts-node": "^10.7.0",
|
||||||
"typedoc": "^0.22.11",
|
"typedoc": "^0.22.13",
|
||||||
"typescript": "^4.5.5"
|
"typescript": "^4.6.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -434,6 +434,26 @@ describe('AGGREGATE', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('with PARAMS', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('index', '*', {
|
||||||
|
PARAMS: {
|
||||||
|
param: 'value'
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'PARAMS', '2', 'param', 'value']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with DIALECT', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('index', '*', {
|
||||||
|
DIALECT: 1
|
||||||
|
}),
|
||||||
|
['FT.AGGREGATE', 'index', '*', 'DIALECT', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.ft.aggregate', async client => {
|
testUtils.testWithClient('client.ft.aggregate', async client => {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { RedisCommandArgument, RedisCommandArguments } from '@node-redis/client/dist/lib/commands';
|
import { RedisCommandArgument, RedisCommandArguments } from '@node-redis/client/dist/lib/commands';
|
||||||
import { pushVerdictArgument, transformTuplesReply } from '@node-redis/client/dist/lib/commands/generic-transformers';
|
import { pushVerdictArgument, transformTuplesReply } from '@node-redis/client/dist/lib/commands/generic-transformers';
|
||||||
import { PropertyName, pushArgumentsWithLength, pushSortByArguments, SortByProperty } from '.';
|
import { Params, PropertyName, pushArgumentsWithLength, pushParamsArgs, pushSortByArguments, SortByProperty } from '.';
|
||||||
|
|
||||||
export enum AggregateSteps {
|
export enum AggregateSteps {
|
||||||
GROUPBY = 'GROUPBY',
|
GROUPBY = 'GROUPBY',
|
||||||
@@ -122,6 +122,8 @@ export interface AggregateOptions {
|
|||||||
VERBATIM?: true;
|
VERBATIM?: true;
|
||||||
LOAD?: LoadField | Array<LoadField>;
|
LOAD?: LoadField | Array<LoadField>;
|
||||||
STEPS?: Array<GroupByStep | SortStep | ApplyStep | LimitStep | FilterStep>;
|
STEPS?: Array<GroupByStep | SortStep | ApplyStep | LimitStep | FilterStep>;
|
||||||
|
PARAMS?: Params;
|
||||||
|
DIALECT?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function transformArguments(
|
export function transformArguments(
|
||||||
@@ -129,17 +131,16 @@ export function transformArguments(
|
|||||||
query: string,
|
query: string,
|
||||||
options?: AggregateOptions
|
options?: AggregateOptions
|
||||||
): RedisCommandArguments {
|
): RedisCommandArguments {
|
||||||
|
return pushAggregatehOptions(
|
||||||
const args = ['FT.AGGREGATE', index, query];
|
['FT.AGGREGATE', index, query],
|
||||||
pushAggregatehOptions(args, options);
|
options
|
||||||
return args;
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function pushAggregatehOptions(
|
export function pushAggregatehOptions(
|
||||||
args: RedisCommandArguments,
|
args: RedisCommandArguments,
|
||||||
options?: AggregateOptions
|
options?: AggregateOptions
|
||||||
): RedisCommandArguments {
|
): RedisCommandArguments {
|
||||||
|
|
||||||
if (options?.VERBATIM) {
|
if (options?.VERBATIM) {
|
||||||
args.push('VERBATIM');
|
args.push('VERBATIM');
|
||||||
}
|
}
|
||||||
@@ -202,6 +203,12 @@ export function pushAggregatehOptions(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pushParamsArgs(args, options?.PARAMS);
|
||||||
|
|
||||||
|
if (options?.DIALECT) {
|
||||||
|
args.push('DIALECT', options.DIALECT.toString());
|
||||||
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,7 +264,6 @@ function pushGroupByReducer(args: RedisCommandArguments, reducer: GroupByReducer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../test-utils';
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
import { transformArguments } from './CREATE';
|
import { transformArguments } from './CREATE';
|
||||||
import { SchemaFieldTypes, SchemaTextFieldPhonetics, RedisSearchLanguages } from '.';
|
import { SchemaFieldTypes, SchemaTextFieldPhonetics, RedisSearchLanguages, VectorAlgorithms } from '.';
|
||||||
|
|
||||||
describe('CREATE', () => {
|
describe('CREATE', () => {
|
||||||
describe('transformArguments', () => {
|
describe('transformArguments', () => {
|
||||||
@@ -126,6 +126,52 @@ describe('CREATE', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('VECTOR', () => {
|
||||||
|
it('Flat algorithm', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('index', {
|
||||||
|
field: {
|
||||||
|
type: SchemaFieldTypes.VECTOR,
|
||||||
|
ALGORITHM: VectorAlgorithms.FLAT,
|
||||||
|
TYPE: 'FLOAT32',
|
||||||
|
DIM: 2,
|
||||||
|
DISTANCE_METRIC: 'L2',
|
||||||
|
INITIAL_CAP: 1000000,
|
||||||
|
BLOCK_SIZE: 1000
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
[
|
||||||
|
'FT.CREATE', 'index', 'SCHEMA', 'field', 'VECTOR', 'FLAT', '10', 'TYPE',
|
||||||
|
'FLOAT32', 'DIM', '2', 'DISTANCE_METRIC', 'L2', 'INITIAL_CAP', '1000000',
|
||||||
|
'BLOCK_SIZE', '1000'
|
||||||
|
]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('HNSW algorithm', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments('index', {
|
||||||
|
field: {
|
||||||
|
type: SchemaFieldTypes.VECTOR,
|
||||||
|
ALGORITHM: VectorAlgorithms.HNSW,
|
||||||
|
TYPE: 'FLOAT32',
|
||||||
|
DIM: 2,
|
||||||
|
DISTANCE_METRIC: 'L2',
|
||||||
|
INITIAL_CAP: 1000000,
|
||||||
|
M: 40,
|
||||||
|
EF_CONSTRUCTION: 250,
|
||||||
|
EF_RUNTIME: 20
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
[
|
||||||
|
'FT.CREATE', 'index', 'SCHEMA', 'field', 'VECTOR', 'HNSW', '14', 'TYPE',
|
||||||
|
'FLOAT32', 'DIM', '2', 'DISTANCE_METRIC', 'L2', 'INITIAL_CAP', '1000000',
|
||||||
|
'M', '40', 'EF_CONSTRUCTION', '250', 'EF_RUNTIME', '20'
|
||||||
|
]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('with generic options', () => {
|
describe('with generic options', () => {
|
||||||
it('with AS', () => {
|
it('with AS', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user