diff --git a/packages/client/lib/commands/ECHO.spec.ts b/packages/client/lib/commands/ECHO.spec.ts index 27f6b2a17d..04ce759b1f 100644 --- a/packages/client/lib/commands/ECHO.spec.ts +++ b/packages/client/lib/commands/ECHO.spec.ts @@ -1,19 +1,19 @@ import { strict as assert } from 'assert'; import testUtils, { GLOBAL } from '../test-utils'; -import { transformArguments } from './ECHO'; +import ECHO from './ECHO'; describe('ECHO', () => { - it('transformArguments', () => { - assert.deepEqual( - transformArguments('message'), - ['ECHO', 'message'] - ); - }); + it('transformArguments', () => { + assert.deepEqual( + ECHO.transformArguments('message'), + ['ECHO', 'message'] + ); + }); - testUtils.testWithClient('client.echo', async client => { - assert.equal( - await client.echo('message'), - 'message' - ); - }, GLOBAL.SERVERS.OPEN); + testUtils.testWithClient('client.echo', async client => { + assert.equal( + await client.echo('message'), + 'message' + ); + }, GLOBAL.SERVERS.OPEN); }); diff --git a/packages/client/lib/commands/EVAL.spec.ts b/packages/client/lib/commands/EVAL.spec.ts index 7aa029362f..e131cd79ab 100644 --- a/packages/client/lib/commands/EVAL.spec.ts +++ b/packages/client/lib/commands/EVAL.spec.ts @@ -1,29 +1,25 @@ import { strict as assert } from 'assert'; import testUtils, { GLOBAL } from '../test-utils'; -import { transformArguments } from './EVAL'; +import EVAL from './EVAL'; describe('EVAL', () => { - it('transformArguments', () => { - assert.deepEqual( - transformArguments('return KEYS[1] + ARGV[1]', { - keys: ['key'], - arguments: ['argument'] - }), - ['EVAL', 'return KEYS[1] + ARGV[1]', '1', 'key', 'argument'] - ); - }); + it('transformArguments', () => { + assert.deepEqual( + EVAL.transformArguments('return KEYS[1] + ARGV[1]', { + keys: ['key'], + arguments: ['argument'] + }), + ['EVAL', 'return KEYS[1] + ARGV[1]', '1', 'key', 'argument'] + ); + }); - testUtils.testWithClient('client.eval', async client => { - assert.equal( - await client.eval('return 1'), - 1 - ); - }, GLOBAL.SERVERS.OPEN); - - testUtils.testWithCluster('cluster.eval', async cluster => { - assert.equal( - await cluster.eval('return 1'), - 1 - ); - }, GLOBAL.CLUSTERS.OPEN); + testUtils.testAll('eval', async client => { + assert.equal( + await client.eval('return 1'), + 1 + ); + }, { + client: GLOBAL.SERVERS.OPEN, + cluster: GLOBAL.CLUSTERS.OPEN + }); }); diff --git a/packages/client/lib/commands/EVAL.ts b/packages/client/lib/commands/EVAL.ts index a82f8bf0aa..21684e7a31 100644 --- a/packages/client/lib/commands/EVAL.ts +++ b/packages/client/lib/commands/EVAL.ts @@ -1,7 +1,33 @@ -import { evalFirstKeyIndex, EvalOptions, pushEvalArguments } from './generic-transformers'; +import { RedisArgument, ReplyUnion, Command } from '../RESP/types'; -export const FIRST_KEY_INDEX = evalFirstKeyIndex; - -export function transformArguments(script: string, options?: EvalOptions): Array { - return pushEvalArguments(['EVAL', script], options); +export interface EvalOptions { + keys?: Array; + arguments?: Array; } + +export function transformEvalArguments( + command: RedisArgument, + script: RedisArgument, + options?: EvalOptions +) { + const args = [command, script]; + + if (options?.keys) { + args.push(options.keys.length.toString(), ...options.keys); + } else { + args.push('0'); + } + + if (options?.arguments) { + args.push(...options.arguments); + } + + return args; +} + +export default { + FIRST_KEY_INDEX: (_, options?: EvalOptions) => options?.keys?.[0], + IS_READ_ONLY: false, + transformArguments: transformEvalArguments.bind(undefined, 'EVAL'), + transformReply: undefined as unknown as () => ReplyUnion +} as const satisfies Command; diff --git a/packages/client/lib/commands/EVALSHA.spec.ts b/packages/client/lib/commands/EVALSHA.spec.ts index 08b330ac4f..ce08ec89c8 100644 --- a/packages/client/lib/commands/EVALSHA.spec.ts +++ b/packages/client/lib/commands/EVALSHA.spec.ts @@ -1,14 +1,14 @@ import { strict as assert } from 'assert'; -import { transformArguments } from './EVALSHA'; +import EVALSHA from './EVALSHA'; describe('EVALSHA', () => { - it('transformArguments', () => { - assert.deepEqual( - transformArguments('sha1', { - keys: ['key'], - arguments: ['argument'] - }), - ['EVALSHA', 'sha1', '1', 'key', 'argument'] - ); - }); + it('transformArguments', () => { + assert.deepEqual( + EVALSHA.transformArguments('sha1', { + keys: ['key'], + arguments: ['argument'] + }), + ['EVALSHA', 'sha1', '1', 'key', 'argument'] + ); + }); }); diff --git a/packages/client/lib/commands/EVALSHA.ts b/packages/client/lib/commands/EVALSHA.ts index 24f7060a05..dc4127f90d 100644 --- a/packages/client/lib/commands/EVALSHA.ts +++ b/packages/client/lib/commands/EVALSHA.ts @@ -1,7 +1,9 @@ -import { evalFirstKeyIndex, EvalOptions, pushEvalArguments } from './generic-transformers'; +import { Command } from '../RESP/types'; +import EVAL, { transformEvalArguments } from './EVAL'; -export const FIRST_KEY_INDEX = evalFirstKeyIndex; - -export function transformArguments(sha1: string, options?: EvalOptions): Array { - return pushEvalArguments(['EVALSHA', sha1], options); -} +export default { + FIRST_KEY_INDEX: EVAL.FIRST_KEY_INDEX, + IS_READ_ONLY: false, + transformArguments: transformEvalArguments.bind(undefined, 'EVALSHA'), + transformReply: EVAL.transformReply +} as const satisfies Command; diff --git a/packages/client/lib/commands/EVALSHA_RO.spec.ts b/packages/client/lib/commands/EVALSHA_RO.spec.ts index 939a4a209c..0afd5d1803 100644 --- a/packages/client/lib/commands/EVALSHA_RO.spec.ts +++ b/packages/client/lib/commands/EVALSHA_RO.spec.ts @@ -1,17 +1,17 @@ import { strict as assert } from 'assert'; import testUtils from '../test-utils'; -import { transformArguments } from './EVALSHA_RO'; +import EVALSHA_RO from './EVALSHA_RO'; describe('EVALSHA_RO', () => { - testUtils.isVersionGreaterThanHook([7]); + testUtils.isVersionGreaterThanHook([7]); - it('transformArguments', () => { - assert.deepEqual( - transformArguments('sha1', { - keys: ['key'], - arguments: ['argument'] - }), - ['EVALSHA_RO', 'sha1', '1', 'key', 'argument'] - ); - }); + it('transformArguments', () => { + assert.deepEqual( + EVALSHA_RO.transformArguments('sha1', { + keys: ['key'], + arguments: ['argument'] + }), + ['EVALSHA_RO', 'sha1', '1', 'key', 'argument'] + ); + }); }); diff --git a/packages/client/lib/commands/EVALSHA_RO.ts b/packages/client/lib/commands/EVALSHA_RO.ts index c3fcc3dc9c..fe9042bd5f 100644 --- a/packages/client/lib/commands/EVALSHA_RO.ts +++ b/packages/client/lib/commands/EVALSHA_RO.ts @@ -1,9 +1,9 @@ -import { evalFirstKeyIndex, EvalOptions, pushEvalArguments } from './generic-transformers'; +import { Command } from '../RESP/types'; +import EVAL, { transformEvalArguments } from './EVAL'; -export const FIRST_KEY_INDEX = evalFirstKeyIndex; - -export const IS_READ_ONLY = true; - -export function transformArguments(sha1: string, options?: EvalOptions): Array { - return pushEvalArguments(['EVALSHA_RO', sha1], options); -} +export default { + FIRST_KEY_INDEX: EVAL.FIRST_KEY_INDEX, + IS_READ_ONLY: true, + transformArguments: transformEvalArguments.bind(undefined, 'EVALSHA_RO'), + transformReply: EVAL.transformReply +} as const satisfies Command; diff --git a/packages/client/lib/commands/EVAL_RO.spec.ts b/packages/client/lib/commands/EVAL_RO.spec.ts index f71d0b2b24..06ae6c6409 100644 --- a/packages/client/lib/commands/EVAL_RO.spec.ts +++ b/packages/client/lib/commands/EVAL_RO.spec.ts @@ -1,31 +1,27 @@ import { strict as assert } from 'assert'; import testUtils, { GLOBAL } from '../test-utils'; -import { transformArguments } from './EVAL_RO'; +import EVAL_RO from './EVAL_RO'; describe('EVAL_RO', () => { - testUtils.isVersionGreaterThanHook([7]); + testUtils.isVersionGreaterThanHook([7]); - it('transformArguments', () => { - assert.deepEqual( - transformArguments('return KEYS[1] + ARGV[1]', { - keys: ['key'], - arguments: ['argument'] - }), - ['EVAL_RO', 'return KEYS[1] + ARGV[1]', '1', 'key', 'argument'] - ); - }); + it('transformArguments', () => { + assert.deepEqual( + EVAL_RO.transformArguments('return KEYS[1] + ARGV[1]', { + keys: ['key'], + arguments: ['argument'] + }), + ['EVAL_RO', 'return KEYS[1] + ARGV[1]', '1', 'key', 'argument'] + ); + }); - testUtils.testWithClient('client.evalRo', async client => { - assert.equal( - await client.evalRo('return 1'), - 1 - ); - }, GLOBAL.SERVERS.OPEN); - - testUtils.testWithCluster('cluster.evalRo', async cluster => { - assert.equal( - await cluster.evalRo('return 1'), - 1 - ); - }, GLOBAL.CLUSTERS.OPEN); + testUtils.testAll('evalRo', async cluster => { + assert.equal( + await cluster.evalRo('return 1'), + 1 + ); + }, { + client: GLOBAL.SERVERS.OPEN, + cluster: GLOBAL.CLUSTERS.OPEN + }); }); diff --git a/packages/client/lib/commands/EVAL_RO.ts b/packages/client/lib/commands/EVAL_RO.ts index 590c3af04f..2608e28f78 100644 --- a/packages/client/lib/commands/EVAL_RO.ts +++ b/packages/client/lib/commands/EVAL_RO.ts @@ -1,9 +1,9 @@ -import { evalFirstKeyIndex, EvalOptions, pushEvalArguments } from './generic-transformers'; +import { Command } from '../RESP/types'; +import EVAL, { transformEvalArguments } from './EVAL'; -export const FIRST_KEY_INDEX = evalFirstKeyIndex; - -export const IS_READ_ONLY = true; - -export function transformArguments(script: string, options?: EvalOptions): Array { - return pushEvalArguments(['EVAL_RO', script], options); -} +export default { + FIRST_KEY_INDEX: EVAL.FIRST_KEY_INDEX, + IS_READ_ONLY: true, + transformArguments: transformEvalArguments.bind(undefined, 'EVAL_RO'), + transformReply: EVAL.transformReply +} as const satisfies Command; diff --git a/packages/client/lib/commands/FCALL.ts b/packages/client/lib/commands/FCALL.ts index a4cadedb6f..a2411f62dc 100644 --- a/packages/client/lib/commands/FCALL.ts +++ b/packages/client/lib/commands/FCALL.ts @@ -5,3 +5,15 @@ export const FIRST_KEY_INDEX = evalFirstKeyIndex; export function transformArguments(fn: string, options?: EvalOptions): Array { return pushEvalArguments(['FCALL', fn], options); } + +import { SimpleStringReply, Command } from '../RESP/types'; + +export default { + FIRST_KEY_INDEX: undefined, + IS_READ_ONLY: false, + transformArguments() { + return ['FCALL']; + }, + transformReply: undefined as unknown as () => SimpleStringReply +} as const satisfies Command; + diff --git a/packages/client/lib/commands/HELLO.spec.ts b/packages/client/lib/commands/HELLO.spec.ts index 12d6d98c7c..0a60c7ae69 100644 --- a/packages/client/lib/commands/HELLO.spec.ts +++ b/packages/client/lib/commands/HELLO.spec.ts @@ -1,76 +1,71 @@ import { strict as assert } from 'assert'; import testUtils, { GLOBAL } from '../test-utils'; -import { transformArguments } from './HELLO'; +import HELLO from './HELLO'; describe('HELLO', () => { - testUtils.isVersionGreaterThanHook([6]); + testUtils.isVersionGreaterThanHook([6]); - describe('transformArguments', () => { - it('simple', () => { - assert.deepEqual( - transformArguments(), - ['HELLO'] - ); - }); - - it('with protover', () => { - assert.deepEqual( - transformArguments({ - protover: 3 - }), - ['HELLO', '3'] - ); - }); - - it('with protover, auth', () => { - assert.deepEqual( - transformArguments({ - protover: 3, - auth: { - username: 'username', - password: 'password' - } - }), - ['HELLO', '3', 'AUTH', 'username', 'password'] - ); - }); - - it('with protover, clientName', () => { - assert.deepEqual( - transformArguments({ - protover: 3, - clientName: 'clientName' - }), - ['HELLO', '3', 'SETNAME', 'clientName'] - ); - }); - - it('with protover, auth, clientName', () => { - assert.deepEqual( - transformArguments({ - protover: 3, - auth: { - username: 'username', - password: 'password' - }, - clientName: 'clientName' - }), - ['HELLO', '3', 'AUTH', 'username', 'password', 'SETNAME', 'clientName'] - ); - }); + describe('transformArguments', () => { + it('simple', () => { + assert.deepEqual( + HELLO.transformArguments(), + ['HELLO'] + ); }); - testUtils.testWithClient('client.hello', async client => { - const reply = await client.hello(); - assert.equal(reply.server, 'redis'); - assert.equal(typeof reply.version, 'string'); - assert.equal(reply.proto, 2); - assert.equal(typeof reply.id, 'number'); - assert.equal(reply.mode, 'standalone'); - assert.equal(reply.role, 'master'); - assert.deepEqual(reply.modules, []); - }, { - ...GLOBAL.SERVERS.OPEN, - minimumDockerVersion: [6, 2] + it('with protover', () => { + assert.deepEqual( + HELLO.transformArguments(3), + ['HELLO', '3'] + ); }); + + it('with protover, AUTH', () => { + assert.deepEqual( + HELLO.transformArguments(3, { + AUTH: { + username: 'username', + password: 'password' + } + }), + ['HELLO', '3', 'AUTH', 'username', 'password'] + ); + }); + + it('with protover, SETNAME', () => { + assert.deepEqual( + HELLO.transformArguments(3, { + SETNAME: 'name' + }), + ['HELLO', '3', 'SETNAME', 'name'] + ); + }); + + it('with protover, AUTH, SETNAME', () => { + assert.deepEqual( + HELLO.transformArguments(3, { + AUTH: { + username: 'username', + password: 'password' + }, + SETNAME: 'name' + }), + ['HELLO', '3', 'AUTH', 'username', 'password', 'SETNAME', 'name'] + ); + }); + }); + + testUtils.testWithClient('client.hello', async client => { + const reply = await client.hello(); + assert.equal(reply.server, 'redis'); + assert.equal(typeof reply.version, 'string'); + assert.equal(reply.proto, 2); + assert.equal(typeof reply.id, 'number'); + assert.equal(reply.mode, 'standalone'); + assert.equal(reply.role, 'master'); + assert.deepEqual(reply.modules, []); + }, { + ...GLOBAL.SERVERS.OPEN, + minimumDockerVersion: [6, 2] + }); }); diff --git a/packages/client/lib/commands/HELLO.ts b/packages/client/lib/commands/HELLO.ts index d4784b67c4..717ee05130 100644 --- a/packages/client/lib/commands/HELLO.ts +++ b/packages/client/lib/commands/HELLO.ts @@ -1,6 +1,7 @@ import { RedisArgument, ArrayReply, BlobStringReply, Command, NumberReply, Resp2Reply, RespVersions, TuplesToMapReply } from '../RESP/types'; export interface HelloOptions { + protover?: RespVersions; AUTH?: { username: RedisArgument; password: RedisArgument; @@ -19,22 +20,26 @@ export type HelloReply = TuplesToMapReply<[ ]>; export default { - transformArguments(protoover: RespVersions, options?: HelloOptions) { - const args: Array = ['HELLO', protoover.toString()]; + transformArguments(protover?: RespVersions, options?: HelloOptions) { + const args: Array = ['HELLO']; - if (options?.AUTH) { - args.push( - 'AUTH', - options.AUTH.username, - options.AUTH.password - ); - } + if (protover) { + args.push(protover.toString()); - if (options?.SETNAME) { - args.push( - 'SETNAME', - options.SETNAME - ); + if (options?.AUTH) { + args.push( + 'AUTH', + options.AUTH.username, + options.AUTH.password + ); + } + + if (options?.SETNAME) { + args.push( + 'SETNAME', + options.SETNAME + ); + } } return args; diff --git a/packages/client/lib/commands/LASTSAVE.spec.ts b/packages/client/lib/commands/LASTSAVE.spec.ts index a6b4863f39..db282374a9 100644 --- a/packages/client/lib/commands/LASTSAVE.spec.ts +++ b/packages/client/lib/commands/LASTSAVE.spec.ts @@ -1,16 +1,16 @@ import { strict as assert } from 'assert'; import testUtils, { GLOBAL } from '../test-utils'; -import { transformArguments } from './LASTSAVE'; +import LASTSAVE from './LASTSAVE'; describe('LASTSAVE', () => { - it('transformArguments', () => { - assert.deepEqual( - transformArguments(), - ['LASTSAVE'] - ); - }); + it('transformArguments', () => { + assert.deepEqual( + LASTSAVE.transformArguments(), + ['LASTSAVE'] + ); + }); - testUtils.testWithClient('client.lastSave', async client => { - assert.ok((await client.lastSave()) instanceof Date); - }, GLOBAL.SERVERS.OPEN); + testUtils.testWithClient('client.lastSave', async client => { + assert.ok(typeof await client.lastSave() === 'number'); + }, GLOBAL.SERVERS.OPEN); }); diff --git a/packages/client/lib/commands/LASTSAVE.ts b/packages/client/lib/commands/LASTSAVE.ts index 76944d3548..a65161f78b 100644 --- a/packages/client/lib/commands/LASTSAVE.ts +++ b/packages/client/lib/commands/LASTSAVE.ts @@ -1,9 +1,10 @@ -export const IS_READ_ONLY = true; +import { NumberReply, Command } from '../RESP/types'; -export function transformArguments(): Array { +export default { + FIRST_KEY_INDEX: undefined, + IS_READ_ONLY: true, + transformArguments() { return ['LASTSAVE']; -} - -export function transformReply(reply: number): Date { - return new Date(reply); -} + }, + transformReply: undefined as unknown as () => NumberReply +} as const satisfies Command; diff --git a/packages/client/lib/commands/LCS_LEN.spec.ts b/packages/client/lib/commands/LCS_LEN.spec.ts index c3cffb0937..0ad10b3ed8 100644 --- a/packages/client/lib/commands/LCS_LEN.spec.ts +++ b/packages/client/lib/commands/LCS_LEN.spec.ts @@ -14,7 +14,7 @@ describe('LCS_LEN', () => { testUtils.testAll('lcsLen', async client => { assert.equal( - await client.lcsLen('1', '2'), + await client.lcsLen('{tag}1', '{tag}2'), 0 ); }, { diff --git a/packages/client/lib/commands/MOVE.spec.ts b/packages/client/lib/commands/MOVE.spec.ts index 929fd2dfd4..e0ca4ec797 100644 --- a/packages/client/lib/commands/MOVE.spec.ts +++ b/packages/client/lib/commands/MOVE.spec.ts @@ -10,13 +10,10 @@ describe('MOVE', () => { ); }); - testUtils.testAll('move', async client => { + testUtils.testWithClient('client.move', async client => { assert.equal( await client.move('key', 1), 0 ); - }, { - client: GLOBAL.SERVERS.OPEN, - cluster: GLOBAL.CLUSTERS.OPEN - }); + }, GLOBAL.SERVERS.OPEN); }); diff --git a/packages/client/lib/commands/PUBLISH.spec.ts b/packages/client/lib/commands/PUBLISH.spec.ts index b2084e668b..e965781291 100644 --- a/packages/client/lib/commands/PUBLISH.spec.ts +++ b/packages/client/lib/commands/PUBLISH.spec.ts @@ -1,19 +1,19 @@ import { strict as assert } from 'assert'; import testUtils, { GLOBAL } from '../test-utils'; -import { transformArguments } from './PUBLISH'; +import PUBLISH from './PUBLISH'; describe('PUBLISH', () => { - it('transformArguments', () => { - assert.deepEqual( - transformArguments('channel', 'message'), - ['PUBLISH', 'channel', 'message'] - ); - }); + it('transformArguments', () => { + assert.deepEqual( + PUBLISH.transformArguments('channel', 'message'), + ['PUBLISH', 'channel', 'message'] + ); + }); - testUtils.testWithClient('client.publish', async client => { - assert.equal( - await client.publish('channel', 'message'), - 0 - ); - }, GLOBAL.SERVERS.OPEN); + testUtils.testWithClient('client.publish', async client => { + assert.equal( + await client.publish('channel', 'message'), + 0 + ); + }, GLOBAL.SERVERS.OPEN); }); diff --git a/packages/client/lib/commands/index.ts b/packages/client/lib/commands/index.ts index c96883ae49..8f66b1cab0 100644 --- a/packages/client/lib/commands/index.ts +++ b/packages/client/lib/commands/index.ts @@ -45,6 +45,11 @@ import DECR from './DECR'; import DECRBY from './DECRBY'; import DEL from './DEL'; import DUMP from './DUMP'; +import ECHO from './ECHO'; +import EVAL_RO from './EVAL_RO'; +import EVAL from './EVAL'; +import EVALSHA_RO from './EVALSHA_RO'; +import EVALSHA from './EVALSHA'; import GEOADD from './GEOADD'; import GEODIST from './GEODIST'; import GEOHASH from './GEOHASH'; @@ -75,6 +80,7 @@ import EXPIRETIME from './EXPIRETIME'; import FLUSHALL from './FLUSHALL'; import FLUSHDB from './FLUSHDB'; import HDEL from './HDEL'; +import HELLO from './HELLO'; import HEXISTS from './HEXISTS'; import HGET from './HGET'; import HGETALL from './HGETALL'; @@ -96,6 +102,7 @@ import INCRBY from './INCRBY'; import INCRBYFLOAT from './INCRBYFLOAT'; import INFO from './INFO'; import KEYS from './KEYS'; +import LASTSAVE from './LASTSAVE'; // import LCS_IDX_WITHMATCHLEN from './LCS_IDX_WITHMATCHLEN'; // import LCS_IDX from './LCS_IDX'; import LCS_LEN from './LCS_LEN'; @@ -320,6 +327,16 @@ export default { del: DEL, DUMP, dump: DUMP, + ECHO, + echo: ECHO, + EVAL_RO, + evalRo: EVAL_RO, + EVAL, + eval: EVAL, + EVALSHA_RO, + evalShaRo: EVALSHA_RO, + EVALSHA, + evalSha: EVALSHA, EXISTS, exists: EXISTS, EXPIRE, @@ -380,6 +397,8 @@ export default { getSet: GETSET, HDEL, hDel: HDEL, + HELLO, + hello: HELLO, HEXISTS, hExists: HEXISTS, HGET, @@ -422,6 +441,8 @@ export default { info: INFO, KEYS, keys: KEYS, + LASTSAVE, + lastSave: LASTSAVE, // LCS_IDX_WITHMATCHLEN, // LCS_IDX, LCS_LEN,