diff --git a/packages/client/lib/commands/SDIFFCARD.spec.ts b/packages/client/lib/commands/SDIFFCARD.spec.ts new file mode 100644 index 0000000000..9b3b78906e --- /dev/null +++ b/packages/client/lib/commands/SDIFFCARD.spec.ts @@ -0,0 +1,36 @@ +import { strict as assert } from 'node:assert'; +import testUtils, { GLOBAL } from '../test-utils'; +import SDIFFCARD from './SDIFFCARD'; +import { parseArgs } from './generic-transformers'; + +describe('SDIFFCARD', () => { + testUtils.isVersionGreaterThanHook([8, 10]); + + describe('transformArguments', () => { + it('simple', () => { + assert.deepEqual( + parseArgs(SDIFFCARD, ['1', '2']), + ['SDIFFCARD', '2', '1', '2'] + ); + }); + + it('with LIMIT', () => { + assert.deepEqual( + parseArgs(SDIFFCARD, ['1', '2'], { + LIMIT: 3 + }), + ['SDIFFCARD', '2', '1', '2', 'LIMIT', '3'] + ); + }); + }); + + testUtils.testAll('sDiffCard', async client => { + assert.equal( + await client.sDiffCard('key'), + 0 + ); + }, { + client: GLOBAL.SERVERS.OPEN, + cluster: GLOBAL.CLUSTERS.OPEN + }); +}); diff --git a/packages/client/lib/commands/SDIFFCARD.ts b/packages/client/lib/commands/SDIFFCARD.ts new file mode 100644 index 0000000000..2e07d1b5f6 --- /dev/null +++ b/packages/client/lib/commands/SDIFFCARD.ts @@ -0,0 +1,25 @@ +import { CommandParser } from '../client/parser'; +import { NumberReply, Command } from '../RESP/types'; +import { RedisVariadicArgument } from './generic-transformers'; + +/** + * Options for the SDIFFCARD command + * + * @property LIMIT - Cap the returned cardinality at this value; `LIMIT 0` means no limit + */ +export interface SDiffCardOptions { + LIMIT?: number; +} + +export default { + IS_READ_ONLY: true, + parseCommand(parser: CommandParser, keys: RedisVariadicArgument, options?: SDiffCardOptions) { + parser.push('SDIFFCARD'); + parser.pushKeysLength(keys); + + if (options?.LIMIT !== undefined) { + parser.push('LIMIT', options.LIMIT.toString()); + } + }, + transformReply: undefined as unknown as () => NumberReply +} as const satisfies Command; diff --git a/packages/client/lib/commands/SUNIONCARD.spec.ts b/packages/client/lib/commands/SUNIONCARD.spec.ts new file mode 100644 index 0000000000..8f558ba8e6 --- /dev/null +++ b/packages/client/lib/commands/SUNIONCARD.spec.ts @@ -0,0 +1,55 @@ +import { strict as assert } from 'node:assert'; +import testUtils, { GLOBAL } from '../test-utils'; +import SUNIONCARD from './SUNIONCARD'; +import { parseArgs } from './generic-transformers'; + +describe('SUNIONCARD', () => { + testUtils.isVersionGreaterThanHook([8, 10]); + + describe('transformArguments', () => { + it('simple', () => { + assert.deepEqual( + parseArgs(SUNIONCARD, ['1', '2']), + ['SUNIONCARD', '2', '1', '2'] + ); + }); + + it('with APPROX', () => { + assert.deepEqual( + parseArgs(SUNIONCARD, ['1', '2'], { + APPROX: true + }), + ['SUNIONCARD', '2', '1', '2', 'APPROX'] + ); + }); + + it('with LIMIT', () => { + assert.deepEqual( + parseArgs(SUNIONCARD, ['1', '2'], { + LIMIT: 3 + }), + ['SUNIONCARD', '2', '1', '2', 'LIMIT', '3'] + ); + }); + + it('with APPROX and LIMIT', () => { + assert.deepEqual( + parseArgs(SUNIONCARD, ['1', '2'], { + APPROX: true, + LIMIT: 3 + }), + ['SUNIONCARD', '2', '1', '2', 'APPROX', 'LIMIT', '3'] + ); + }); + }); + + testUtils.testAll('sUnionCard', async client => { + assert.equal( + await client.sUnionCard('key'), + 0 + ); + }, { + client: GLOBAL.SERVERS.OPEN, + cluster: GLOBAL.CLUSTERS.OPEN + }); +}); diff --git a/packages/client/lib/commands/SUNIONCARD.ts b/packages/client/lib/commands/SUNIONCARD.ts new file mode 100644 index 0000000000..7bba2c30b4 --- /dev/null +++ b/packages/client/lib/commands/SUNIONCARD.ts @@ -0,0 +1,31 @@ +import { CommandParser } from '../client/parser'; +import { NumberReply, Command } from '../RESP/types'; +import { RedisVariadicArgument } from './generic-transformers'; + +/** + * Options for the SUNIONCARD command + * + * @property APPROX - When true, return an approximate cardinality using HyperLogLog + * @property LIMIT - Cap the returned cardinality at this value; `LIMIT 0` means no limit + */ +export interface SUnionCardOptions { + APPROX?: boolean; + LIMIT?: number; +} + +export default { + IS_READ_ONLY: true, + parseCommand(parser: CommandParser, keys: RedisVariadicArgument, options?: SUnionCardOptions) { + parser.push('SUNIONCARD'); + parser.pushKeysLength(keys); + + if (options?.APPROX) { + parser.push('APPROX'); + } + + if (options?.LIMIT !== undefined) { + parser.push('LIMIT', options.LIMIT.toString()); + } + }, + transformReply: undefined as unknown as () => NumberReply +} as const satisfies Command; diff --git a/packages/client/lib/commands/index.ts b/packages/client/lib/commands/index.ts index 6e0afc385a..3ae4f4485f 100644 --- a/packages/client/lib/commands/index.ts +++ b/packages/client/lib/commands/index.ts @@ -276,6 +276,7 @@ import SCRIPT_FLUSH from './SCRIPT_FLUSH'; import SCRIPT_KILL from './SCRIPT_KILL'; import SCRIPT_LOAD from './SCRIPT_LOAD'; import SDIFF from './SDIFF'; +import SDIFFCARD from './SDIFFCARD'; import SDIFFSTORE from './SDIFFSTORE'; import SET from './SET'; import SETBIT from './SETBIT'; @@ -301,6 +302,7 @@ import SREM from './SREM'; import SSCAN from './SSCAN'; import STRLEN from './STRLEN'; import SUNION from './SUNION'; +import SUNIONCARD from './SUNIONCARD'; import SUNIONSTORE from './SUNIONSTORE'; import SWAPDB from './SWAPDB'; import TIME from './TIME'; @@ -4055,6 +4057,24 @@ export default { * @see https://redis.io/commands/sdiff/ */ sDiff: SDIFF, + /** + * Constructs the SDIFFCARD command to return the cardinality of the difference between the first set and all successive sets + * Added since Redis 8.10. + * + * @param keys - One or more set keys; the first is the minuend, the rest are subtrahends + * @param options - Options for the SDIFFCARD command + * @see https://redis.io/commands/sdiffcard/ + */ + SDIFFCARD, + /** + * Constructs the SDIFFCARD command to return the cardinality of the difference between the first set and all successive sets + * Added since Redis 8.10. + * + * @param keys - One or more set keys; the first is the minuend, the rest are subtrahends + * @param options - Options for the SDIFFCARD command + * @see https://redis.io/commands/sdiffcard/ + */ + sDiffCard: SDIFFCARD, /** * Constructs the SDIFFSTORE command * @@ -4455,6 +4475,24 @@ export default { * @see https://redis.io/commands/sunion/ */ sUnion: SUNION, + /** + * Constructs the SUNIONCARD command to return the cardinality of the union of all the given sets + * Added since Redis 8.10. + * + * @param keys - One or more set keys to union + * @param options - Options for the SUNIONCARD command (APPROX, LIMIT) + * @see https://redis.io/commands/sunioncard/ + */ + SUNIONCARD, + /** + * Constructs the SUNIONCARD command to return the cardinality of the union of all the given sets + * Added since Redis 8.10. + * + * @param keys - One or more set keys to union + * @param options - Options for the SUNIONCARD command (APPROX, LIMIT) + * @see https://redis.io/commands/sunioncard/ + */ + sUnionCard: SUNIONCARD, /** * Constructs the SUNIONSTORE command to store the union of multiple sets into a destination set *