diff --git a/CHANGELOG.md b/CHANGELOG.md index 3bbfef3e09..ba0dca22b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ #### Changes +* Node: Added binary variant to bitmap commands ([#2178](https://github.com/valkey-io/valkey-glide/pull/2178)) * Node: Added binary variant to generic commands ([#2158](https://github.com/valkey-io/valkey-glide/pull/2158)) * Node: Added binary variant to geo commands ([#2149](https://github.com/valkey-io/valkey-glide/pull/2149)) * Node: Added binary variant to HYPERLOGLOG commands ([#2176](https://github.com/valkey-io/valkey-glide/pull/2176)) diff --git a/node/src/BaseClient.ts b/node/src/BaseClient.ts index f257705eee..9b2270961b 100644 --- a/node/src/BaseClient.ts +++ b/node/src/BaseClient.ts @@ -1383,8 +1383,8 @@ export class BaseClient { */ public async bitop( operation: BitwiseOperation, - destination: string, - keys: string[], + destination: GlideString, + keys: GlideString[], ): Promise { return this.createWritePromise( createBitOp(operation, destination, keys), @@ -1408,7 +1408,7 @@ export class BaseClient { * console.log(result); // Output: 1 - The second bit of the string stored at "key" is set to 1. * ``` */ - public async getbit(key: string, offset: number): Promise { + public async getbit(key: GlideString, offset: number): Promise { return this.createWritePromise(createGetBit(key, offset)); } @@ -1432,7 +1432,7 @@ export class BaseClient { * ``` */ public async setbit( - key: string, + key: GlideString, offset: number, value: number, ): Promise { @@ -1464,7 +1464,7 @@ export class BaseClient { * ``` */ public async bitpos( - key: string, + key: GlideString, bit: number, start?: number, ): Promise { @@ -1505,7 +1505,7 @@ export class BaseClient { * ``` */ public async bitposInterval( - key: string, + key: GlideString, bit: number, start: number, end: number, @@ -1548,7 +1548,7 @@ export class BaseClient { * ``` */ public async bitfield( - key: string, + key: GlideString, subcommands: BitFieldSubCommands[], ): Promise<(number | null)[]> { return this.createWritePromise(createBitField(key, subcommands)); @@ -1572,7 +1572,7 @@ export class BaseClient { * ``` */ public async bitfieldReadOnly( - key: string, + key: GlideString, subcommands: BitFieldGet[], ): Promise { return this.createWritePromise(createBitField(key, subcommands, true)); @@ -5760,7 +5760,7 @@ export class BaseClient { * ``` */ public async bitcount( - key: string, + key: GlideString, options?: BitOffsetOptions, ): Promise { return this.createWritePromise(createBitCount(key, options)); diff --git a/node/src/Commands.ts b/node/src/Commands.ts index 14f8b2ebf0..70fc4d7d3f 100644 --- a/node/src/Commands.ts +++ b/node/src/Commands.ts @@ -490,8 +490,8 @@ export enum BitwiseOperation { */ export function createBitOp( operation: BitwiseOperation, - destination: string, - keys: string[], + destination: GlideString, + keys: GlideString[], ): command_request.Command { return createCommand(RequestType.BitOp, [operation, destination, ...keys]); } @@ -500,7 +500,7 @@ export function createBitOp( * @internal */ export function createGetBit( - key: string, + key: GlideString, offset: number, ): command_request.Command { return createCommand(RequestType.GetBit, [key, offset.toString()]); @@ -510,7 +510,7 @@ export function createGetBit( * @internal */ export function createSetBit( - key: string, + key: GlideString, offset: number, value: number, ): command_request.Command { @@ -799,14 +799,14 @@ export class BitFieldOverflow implements BitFieldSubCommands { * @internal */ export function createBitField( - key: string, + key: GlideString, subcommands: BitFieldSubCommands[], readOnly: boolean = false, ): command_request.Command { const requestType = readOnly ? RequestType.BitFieldReadOnly : RequestType.BitField; - let args: string[] = [key]; + let args: GlideString[] = [key]; for (const subcommand of subcommands) { args = args.concat(subcommand.toArgs()); @@ -2439,7 +2439,7 @@ export type BitOffsetOptions = { * @internal */ export function createBitCount( - key: string, + key: GlideString, options?: BitOffsetOptions, ): command_request.Command { const args = [key]; @@ -2471,13 +2471,13 @@ export enum BitmapIndexType { * @internal */ export function createBitPos( - key: string, + key: GlideString, bit: number, start?: number, end?: number, indexType?: BitmapIndexType, ): command_request.Command { - const args = [key, bit.toString()]; + const args: GlideString[] = [key, bit.toString()]; if (start !== undefined) { args.push(start.toString()); diff --git a/node/src/Transaction.ts b/node/src/Transaction.ts index d35c23d7ec..20f54172fa 100644 --- a/node/src/Transaction.ts +++ b/node/src/Transaction.ts @@ -612,8 +612,8 @@ export class BaseTransaction> { */ public bitop( operation: BitwiseOperation, - destination: string, - keys: string[], + destination: GlideString, + keys: GlideString[], ): T { return this.addAndReturn(createBitOp(operation, destination, keys)); } @@ -630,7 +630,7 @@ export class BaseTransaction> { * Command Response - The bit at the given `offset` of the string. Returns `0` if the key is empty or if the * `offset` exceeds the length of the string. */ - public getbit(key: string, offset: number): T { + public getbit(key: GlideString, offset: number): T { return this.addAndReturn(createGetBit(key, offset)); } @@ -648,7 +648,7 @@ export class BaseTransaction> { * * Command Response - The bit value that was previously stored at `offset`. */ - public setbit(key: string, offset: number, value: number): T { + public setbit(key: GlideString, offset: number, value: number): T { return this.addAndReturn(createSetBit(key, offset, value)); } @@ -667,7 +667,7 @@ export class BaseTransaction> { * Command Response - The position of the first occurrence of `bit` in the binary value of the string held at `key`. * If `start` was provided, the search begins at the offset indicated by `start`. */ - public bitpos(key: string, bit: number, start?: number): T { + public bitpos(key: GlideString, bit: number, start?: number): T { return this.addAndReturn(createBitPos(key, bit, start)); } @@ -696,7 +696,7 @@ export class BaseTransaction> { * binary value of the string held at `key`. */ public bitposInterval( - key: string, + key: GlideString, bit: number, start: number, end: number, @@ -729,7 +729,7 @@ export class BaseTransaction> { * subcommands when an overflow or underflow occurs. {@link BitFieldOverflow} does not return a value and * does not contribute a value to the array response. */ - public bitfield(key: string, subcommands: BitFieldSubCommands[]): T { + public bitfield(key: GlideString, subcommands: BitFieldSubCommands[]): T { return this.addAndReturn(createBitField(key, subcommands)); } @@ -745,7 +745,7 @@ export class BaseTransaction> { * Command Response - An array of results from the {@link BitFieldGet} subcommands. * */ - public bitfieldReadOnly(key: string, subcommands: BitFieldGet[]): T { + public bitfieldReadOnly(key: GlideString, subcommands: BitFieldGet[]): T { return this.addAndReturn(createBitField(key, subcommands, true)); } @@ -3368,7 +3368,7 @@ export class BaseTransaction> { * If `options` is not provided, returns the number of set bits in the string stored at `key`. * Otherwise, if `key` is missing, returns `0` as it is treated as an empty string. */ - public bitcount(key: string, options?: BitOffsetOptions): T { + public bitcount(key: GlideString, options?: BitOffsetOptions): T { return this.addAndReturn(createBitCount(key, options)); } diff --git a/node/tests/SharedTests.ts b/node/tests/SharedTests.ts index b9409bf2e6..fb66c6965e 100644 --- a/node/tests/SharedTests.ts +++ b/node/tests/SharedTests.ts @@ -591,6 +591,7 @@ export function runBaseTests(config: { const key2 = `{key}-${uuidv4()}`; const key3 = `{key}-${uuidv4()}`; const keys = [key1, key2]; + const keysEncoded = [Buffer.from(key1), Buffer.from(key2)]; const destination = `{key}-${uuidv4()}`; const nonExistingKey1 = `{key}-${uuidv4()}`; const nonExistingKey2 = `{key}-${uuidv4()}`; @@ -611,7 +612,11 @@ export function runBaseTests(config: { ).toEqual(6); expect(await client.get(destination)).toEqual("`bc`ab"); expect( - await client.bitop(BitwiseOperation.OR, destination, keys), + await client.bitop( + BitwiseOperation.OR, + destination, + keysEncoded, + ), ).toEqual(6); expect(await client.get(destination)).toEqual("goofev"); @@ -725,7 +730,7 @@ export function runBaseTests(config: { expect(await client.set(key, "foo")).toEqual("OK"); expect(await client.getbit(key, 1)).toEqual(1); // When offset is beyond the string length, the string is assumed to be a contiguous space with 0 bits. - expect(await client.getbit(key, 1000)).toEqual(0); + expect(await client.getbit(Buffer.from(key), 1000)).toEqual(0); // When key does not exist it is assumed to be an empty string, so offset is always out of range and the // value is also assumed to be a contiguous space with 0 bits. expect(await client.getbit(nonExistingKey, 1)).toEqual(0); @@ -753,7 +758,7 @@ export function runBaseTests(config: { const setKey = `{key}-${uuidv4()}`; expect(await client.setbit(key, 1, 1)).toEqual(0); - expect(await client.setbit(key, 1, 0)).toEqual(1); + expect(await client.setbit(Buffer.from(key), 1, 0)).toEqual(1); // invalid argument - offset can't be negative await expect(client.setbit(key, -1, 1)).rejects.toThrow( @@ -786,9 +791,12 @@ export function runBaseTests(config: { expect(await client.set(key, value)).toEqual("OK"); expect(await client.bitpos(key, 0)).toEqual(0); - expect(await client.bitpos(key, 1)).toEqual(2); + expect(await client.bitpos(Buffer.from(key), 1)).toEqual(2); expect(await client.bitpos(key, 1, 1)).toEqual(9); expect(await client.bitposInterval(key, 0, 3, 5)).toEqual(24); + expect( + await client.bitposInterval(Buffer.from(key), 0, 3, 5), + ).toEqual(24); // -1 is returned if start > end expect(await client.bitposInterval(key, 0, 1, 0)).toEqual(-1); @@ -947,7 +955,7 @@ export function runBaseTests(config: { // INCRBY tests expect( - await client.bitfield(key1, [ + await client.bitfield(Buffer.from(key1), [ // binary value becomes: // 0(11)00011 01101111 01101111 01100010 01000001 01110010 00000000 00000000 00010100 new BitFieldIncrBy(u2, offset1, 1), @@ -1104,7 +1112,7 @@ export function runBaseTests(config: { // offset is greater than current length of string: the operation is performed like the missing part all // consists of bits set to 0. expect( - await client.bitfieldReadOnly(key, [ + await client.bitfieldReadOnly(Buffer.from(key), [ new BitFieldGet( new UnsignedEncoding(3), new BitOffset(100), @@ -7915,7 +7923,10 @@ export function runBaseTests(config: { expect(await client.set(key1, value)).toEqual("OK"); expect(await client.bitcount(key1)).toEqual(26); expect( - await client.bitcount(key1, { start: 1, end: 1 }), + await client.bitcount(Buffer.from(key1), { + start: 1, + end: 1, + }), ).toEqual(6); expect( await client.bitcount(key1, { start: 0, end: -5 }),