diff --git a/packages/client/lib/cluster/commands.ts b/packages/client/lib/cluster/commands.ts index dcce3629a1..8edbd1e389 100644 --- a/packages/client/lib/cluster/commands.ts +++ b/packages/client/lib/cluster/commands.ts @@ -71,6 +71,10 @@ import * as HVALS from '../commands/HVALS'; import * as INCR from '../commands/INCR'; import * as INCRBY from '../commands/INCRBY'; import * as INCRBYFLOAT from '../commands/INCRBYFLOAT'; +import * as LCS_IDX_WITHMATCHLEN from '../commands/LCS_IDX_WITHMATCHLEN'; +import * as LCS_IDX from '../commands/LCS_IDX'; +import * as LCS_LEN from '../commands/LCS_LEN'; +import * as LCS from '../commands/LCS'; import * as LINDEX from '../commands/LINDEX'; import * as LINSERT from '../commands/LINSERT'; import * as LLEN from '../commands/LLEN'; @@ -351,6 +355,14 @@ export default { incrBy: INCRBY, INCRBYFLOAT, incrByFloat: INCRBYFLOAT, + LCS_IDX_WITHMATCHLEN, + lcsIdxWithMatchLen: LCS_IDX_WITHMATCHLEN, + LCS_IDX, + lcsIdx: LCS_IDX, + LCS_LEN, + lcsLen: LCS_LEN, + LCS, + lcs: LCS, LINDEX, lIndex: LINDEX, LINSERT, diff --git a/packages/client/lib/commands/LCS.spec.ts b/packages/client/lib/commands/LCS.spec.ts new file mode 100644 index 0000000000..a4d9035571 --- /dev/null +++ b/packages/client/lib/commands/LCS.spec.ts @@ -0,0 +1,28 @@ +import { strict as assert } from 'assert'; +import testUtils, { GLOBAL } from '../test-utils'; +import { transformArguments } from './LCS'; + +describe('LCS', () => { + testUtils.isVersionGreaterThanHook([7]); + + it('transformArguments', () => { + assert.deepEqual( + transformArguments('1', '2'), + ['LCS', '1', '2'] + ); + }); + + testUtils.testWithClient('client.lcs', async client => { + assert.equal( + await client.lcs('1', '2'), + '' + ); + }, GLOBAL.SERVERS.OPEN); + + testUtils.testWithCluster('cluster.lcs', async cluster => { + assert.equal( + await cluster.lcs('{tag}1', '{tag}2'), + '' + ); + }, GLOBAL.CLUSTERS.OPEN); +}); diff --git a/packages/client/lib/commands/LCS.ts b/packages/client/lib/commands/LCS.ts new file mode 100644 index 0000000000..b075b73e8a --- /dev/null +++ b/packages/client/lib/commands/LCS.ts @@ -0,0 +1,18 @@ +import { RedisCommandArgument, RedisCommandArguments } from '.'; + +export const FIRST_KEY_INDEX = 1; + +export const IS_READ_ONLY = true; + +export function transformArguments( + key1: RedisCommandArgument, + key2: RedisCommandArgument +): RedisCommandArguments { + return [ + 'LCS', + key1, + key2 + ]; +} + +export declare function transformReply(): string | Buffer; diff --git a/packages/client/lib/commands/LCS_IDX.spec.ts b/packages/client/lib/commands/LCS_IDX.spec.ts new file mode 100644 index 0000000000..fc3ee54f7c --- /dev/null +++ b/packages/client/lib/commands/LCS_IDX.spec.ts @@ -0,0 +1,41 @@ +import { strict as assert } from 'assert'; +import testUtils, { GLOBAL } from '../test-utils'; +import { transformArguments } from './LCS_IDX'; + +describe('LCS_IDX', () => { + testUtils.isVersionGreaterThanHook([7]); + + it('transformArguments', () => { + assert.deepEqual( + transformArguments('1', '2'), + ['LCS', '1', '2', 'IDX'] + ); + }); + + testUtils.testWithClient('client.lcsIdx', async client => { + const [, reply] = await Promise.all([ + client.mSet({ + '1': 'abc', + '2': 'bc' + }), + client.lcsIdx('1', '2') + ]); + + assert.deepEqual( + reply, + { + matches: [{ + key1: { + start: 1, + end: 2 + }, + key2: { + start: 0, + end: 1 + } + }], + length: 2 + } + ); + }, GLOBAL.SERVERS.OPEN); +}); diff --git a/packages/client/lib/commands/LCS_IDX.ts b/packages/client/lib/commands/LCS_IDX.ts new file mode 100644 index 0000000000..262a02ba4c --- /dev/null +++ b/packages/client/lib/commands/LCS_IDX.ts @@ -0,0 +1,42 @@ +import { RedisCommandArgument, RedisCommandArguments } from '.'; +import { RangeReply, RawRangeReply, transformRangeReply } from './generic-transformers'; +import { transformArguments as transformLcsArguments } from './LCS'; + +export { FIRST_KEY_INDEX, IS_READ_ONLY } from './LCS'; + +export function transformArguments( + key1: RedisCommandArgument, + key2: RedisCommandArgument +): RedisCommandArguments { + const args = transformLcsArguments(key1, key2); + args.push('IDX'); + return args; +} + +type RawReply = [ + 'matches', + Array<[ + key1: RawRangeReply, + key2: RawRangeReply + ]>, + 'len', + number +]; + +interface Reply { + matches: Array<{ + key1: RangeReply; + key2: RangeReply; + }>; + length: number; +} + +export function transformReply(reply: RawReply): Reply { + return { + matches: reply[1].map(([key1, key2]) => ({ + key1: transformRangeReply(key1), + key2: transformRangeReply(key2) + })), + length: reply[3] + }; +} diff --git a/packages/client/lib/commands/LCS_IDX_WITHMATCHLEN.spec.ts b/packages/client/lib/commands/LCS_IDX_WITHMATCHLEN.spec.ts new file mode 100644 index 0000000000..8be9b99313 --- /dev/null +++ b/packages/client/lib/commands/LCS_IDX_WITHMATCHLEN.spec.ts @@ -0,0 +1,42 @@ +import { strict as assert } from 'assert'; +import testUtils, { GLOBAL } from '../test-utils'; +import { transformArguments } from './LCS_IDX_WITHMATCHLEN'; + +describe('LCS_IDX_WITHMATCHLEN', () => { + testUtils.isVersionGreaterThanHook([7]); + + it('transformArguments', () => { + assert.deepEqual( + transformArguments('1', '2'), + ['LCS', '1', '2', 'IDX', 'WITHMATCHLEN'] + ); + }); + + testUtils.testWithClient('client.lcsIdxWithMatchLen', async client => { + const [, reply] = await Promise.all([ + client.mSet({ + '1': 'abc', + '2': 'bc' + }), + client.lcsIdxWithMatchLen('1', '2') + ]); + + assert.deepEqual( + reply, + { + matches: [{ + key1: { + start: 1, + end: 2 + }, + key2: { + start: 0, + end: 1 + }, + length: 2 + }], + length: 2 + } + ); + }, GLOBAL.SERVERS.OPEN); +}); diff --git a/packages/client/lib/commands/LCS_IDX_WITHMATCHLEN.ts b/packages/client/lib/commands/LCS_IDX_WITHMATCHLEN.ts new file mode 100644 index 0000000000..989870d6ca --- /dev/null +++ b/packages/client/lib/commands/LCS_IDX_WITHMATCHLEN.ts @@ -0,0 +1,45 @@ +import { RedisCommandArgument, RedisCommandArguments } from '.'; +import { RangeReply, RawRangeReply, transformRangeReply } from './generic-transformers'; +import { transformArguments as transformLcsArguments } from './LCS'; + +export { FIRST_KEY_INDEX, IS_READ_ONLY } from './LCS'; + +export function transformArguments( + key1: RedisCommandArgument, + key2: RedisCommandArgument +): RedisCommandArguments { + const args = transformLcsArguments(key1, key2); + args.push('IDX', 'WITHMATCHLEN'); + return args; +} + +type RawReply = [ + 'matches', + Array<[ + key1: RawRangeReply, + key2: RawRangeReply, + length: number + ]>, + 'len', + number +]; + +interface Reply { + matches: Array<{ + key1: RangeReply; + key2: RangeReply; + length: number; + }>; + length: number; +} + +export function transformReply(reply: RawReply): Reply { + return { + matches: reply[1].map(([key1, key2, length]) => ({ + key1: transformRangeReply(key1), + key2: transformRangeReply(key2), + length + })), + length: reply[3] + }; +} diff --git a/packages/client/lib/commands/LCS_LEN.spec.ts b/packages/client/lib/commands/LCS_LEN.spec.ts new file mode 100644 index 0000000000..bf4eefd330 --- /dev/null +++ b/packages/client/lib/commands/LCS_LEN.spec.ts @@ -0,0 +1,28 @@ +import { strict as assert } from 'assert'; +import testUtils, { GLOBAL } from '../test-utils'; +import { transformArguments } from './LCS_LEN'; + +describe('LCS_LEN', () => { + testUtils.isVersionGreaterThanHook([7]); + + it('transformArguments', () => { + assert.deepEqual( + transformArguments('1', '2'), + ['LCS', '1', '2', 'LEN'] + ); + }); + + testUtils.testWithClient('client.lcsLen', async client => { + assert.equal( + await client.lcsLen('1', '2'), + 0 + ); + }, GLOBAL.SERVERS.OPEN); + + testUtils.testWithCluster('cluster.lcsLen', async cluster => { + assert.equal( + await cluster.lcsLen('{tag}1', '{tag}2'), + 0 + ); + }, GLOBAL.CLUSTERS.OPEN); +}); diff --git a/packages/client/lib/commands/LCS_LEN.ts b/packages/client/lib/commands/LCS_LEN.ts new file mode 100644 index 0000000000..a5121e4c13 --- /dev/null +++ b/packages/client/lib/commands/LCS_LEN.ts @@ -0,0 +1,15 @@ +import { RedisCommandArgument, RedisCommandArguments } from '.'; +import { transformArguments as transformLcsArguments } from './LCS'; + +export { FIRST_KEY_INDEX, IS_READ_ONLY } from './LCS'; + +export function transformArguments( + key1: RedisCommandArgument, + key2: RedisCommandArgument +): RedisCommandArguments { + const args = transformLcsArguments(key1, key2); + args.push('LEN'); + return args; +} + +export declare function transformReply(): number; diff --git a/packages/client/lib/commands/generic-transformers.ts b/packages/client/lib/commands/generic-transformers.ts index 697dbcfa4e..728378bb27 100644 --- a/packages/client/lib/commands/generic-transformers.ts +++ b/packages/client/lib/commands/generic-transformers.ts @@ -670,3 +670,20 @@ export function pushSlotRangesArguments( return args; } + +export type RawRangeReply = [ + start: number, + end: number +]; + +export interface RangeReply { + start: number; + end: number; +} + +export function transformRangeReply([start, end]: RawRangeReply): RangeReply { + return { + start, + end + }; +}