diff --git a/node/src/BaseClient.ts b/node/src/BaseClient.ts index 2f1be67495..e88b820ebf 100644 --- a/node/src/BaseClient.ts +++ b/node/src/BaseClient.ts @@ -20,7 +20,6 @@ import { BitOffset, // eslint-disable-line @typescript-eslint/no-unused-vars BitOffsetMultiplier, // eslint-disable-line @typescript-eslint/no-unused-vars BitOffsetOptions, - BitmapIndexType, BitwiseOperation, Boundary, CoordOrigin, // eslint-disable-line @typescript-eslint/no-unused-vars @@ -1510,12 +1509,18 @@ export class BaseClient { * The offset can also be a negative number indicating an offset starting at the end of the list, with `-1` being * the last byte of the list, `-2` being the penultimate, and so on. * - * @see {@link https://valkey.io/commands/bitpos/|valkey.io} for more details. + * If you are using Valkey 7.0.0 or above, the optional `indexType` can also be provided to specify whether the + * `start` and `end` offsets specify BIT or BYTE offsets. If `indexType` is not provided, BYTE offsets + * are assumed. If BIT is specified, `start=0` and `end=2` means to look at the first three bits. If BYTE is + * specified, `start=0` and `end=2` means to look at the first three bytes. + * + * @see {@link https://valkey.io/commands/bitpos/|valkey.io} for details. * * @param key - The key of the string. * @param bit - The bit value to match. Must be `0` or `1`. - * @param start - (Optional) The starting offset. If not supplied, the search will start at the beginning of the string. - * @returns The position of the first occurrence of `bit` in the binary value of the string held at `key`. + * @param options - (Optional) The {@link BitOffsetOptions}. + * + * @returns 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`. * * @example @@ -1526,59 +1531,21 @@ export class BaseClient { * * const result2 = await client.bitpos("key1", 1, -1); * console.log(result2); // Output: 10 - The first occurrence of bit value 1, starting at the last byte in the string stored at "key1", is at the eleventh position. - * ``` - */ - public async bitpos( - key: GlideString, - bit: number, - start?: number, - ): Promise { - return this.createWritePromise(createBitPos(key, bit, start)); - } - - /** - * Returns the position of the first bit matching the given `bit` value. The offsets are zero-based indexes, with - * `0` being the first element of the list, `1` being the next, and so on. These offsets can also be negative - * numbers indicating offsets starting at the end of the list, with `-1` being the last element of the list, `-2` - * being the penultimate, and so on. - * - * If you are using Valkey 7.0.0 or above, the optional `indexType` can also be provided to specify whether the - * `start` and `end` offsets specify BIT or BYTE offsets. If `indexType` is not provided, BYTE offsets - * are assumed. If BIT is specified, `start=0` and `end=2` means to look at the first three bits. If BYTE is - * specified, `start=0` and `end=2` means to look at the first three bytes. - * - * @see {@link https://valkey.io/commands/bitpos/|valkey.io} for more details. - * - * @param key - The key of the string. - * @param bit - The bit value to match. Must be `0` or `1`. - * @param start - The starting offset. - * @param end - The ending offset. - * @param indexType - (Optional) The index offset type. This option can only be specified if you are using Valkey - * version 7.0.0 or above. Could be either {@link BitmapIndexType.BYTE} or {@link BitmapIndexType.BIT}. If no - * index type is provided, the indexes will be assumed to be byte indexes. - * @returns The position of the first occurrence from the `start` to the `end` offsets of the `bit` in the binary - * value of the string held at `key`. * - * @example - * ```typescript * await client.set("key1", "A12"); // "A12" has binary value 01000001 00110001 00110010 - * const result1 = await client.bitposInterval("key1", 1, 1, -1); - * console.log(result1); // Output: 10 - The first occurrence of bit value 1 in the second byte to the last byte of the string stored at "key1" is at the eleventh position. + * const result3 = await client.bitpos("key1", 1, {start: 1, end: -1}); + * console.log(result3); // Output: 10 - The first occurrence of bit value 1 in the second byte to the last byte of the string stored at "key1" is at the eleventh position. * - * const result2 = await client.bitposInterval("key1", 1, 2, 9, BitmapIndexType.BIT); - * console.log(result2); // Output: 7 - The first occurrence of bit value 1 in the third to tenth bits of the string stored at "key1" is at the eighth position. + * const result4 = await client.bitpos("key1", 1, {start: 2, end: 9, indexType: BitmapIndexType.BIT}); + * console.log(result4); // Output: 7 - The first occurrence of bit value 1 in the third to tenth bits of the string stored at "key1" is at the eighth position. * ``` */ - public async bitposInterval( + public async bitpos( key: GlideString, bit: number, - start: number, - end: number, - indexType?: BitmapIndexType, + options?: BitOffsetOptions, ): Promise { - return this.createWritePromise( - createBitPos(key, bit, start, end, indexType), - ); + return this.createWritePromise(createBitPos(key, bit, options)); } /** diff --git a/node/src/Commands.ts b/node/src/Commands.ts index e19888f629..fa922a6303 100644 --- a/node/src/Commands.ts +++ b/node/src/Commands.ts @@ -2416,7 +2416,7 @@ export function createFunctionRestore( } /** - * Represents offsets specifying a string interval to analyze in the {@link BaseClient.bitcount|bitcount} command. The offsets are + * Represents offsets specifying a string interval to analyze in the {@link BaseClient.bitcount|bitcount and @link BaseClient.bitpos} command. The offsets are * zero-based indexes, with `0` being the first index of the string, `1` being the next index and so on. * The offsets can also be negative numbers indicating offsets starting at the end of the string, with `-1` being * the last index of the string, `-2` being the penultimate, and so on. @@ -2425,9 +2425,9 @@ export function createFunctionRestore( */ export type BitOffsetOptions = { /** The starting offset index. */ - start: number; + start?: number; /** The ending offset index. */ - end: number; + end?: number; /** * The index offset type. This option can only be specified if you are using server version 7.0.0 or above. * Could be either {@link BitmapIndexType.BYTE} or {@link BitmapIndexType.BIT}. @@ -2446,8 +2446,8 @@ export function createBitCount( const args = [key]; if (options) { - args.push(options.start.toString()); - args.push(options.end.toString()); + if (options.start) args.push(options.start.toString()); + if (options.end) args.push(options.end.toString()); if (options.indexType) args.push(options.indexType); } @@ -2474,22 +2474,14 @@ export enum BitmapIndexType { export function createBitPos( key: GlideString, bit: number, - start?: number, - end?: number, - indexType?: BitmapIndexType, + options?: BitOffsetOptions, ): command_request.Command { const args: GlideString[] = [key, bit.toString()]; - if (start !== undefined) { - args.push(start.toString()); - } - - if (end !== undefined) { - args.push(end.toString()); - } - - if (indexType) { - args.push(indexType); + if (options) { + if (options.start != undefined) args.push(options.start.toString()); + if (options.end != undefined) args.push(options.end.toString()); + if (options.indexType) args.push(options.indexType); } return createCommand(RequestType.BitPos, args); diff --git a/node/src/Transaction.ts b/node/src/Transaction.ts index 1547f52c59..9fd0e4945a 100644 --- a/node/src/Transaction.ts +++ b/node/src/Transaction.ts @@ -20,7 +20,6 @@ import { BitOffset, // eslint-disable-line @typescript-eslint/no-unused-vars BitOffsetMultiplier, // eslint-disable-line @typescript-eslint/no-unused-vars BitOffsetOptions, - BitmapIndexType, BitwiseOperation, Boundary, CoordOrigin, // eslint-disable-line @typescript-eslint/no-unused-vars @@ -671,25 +670,6 @@ export class BaseTransaction> { * The offset can also be a negative number indicating an offset starting at the end of the list, with `-1` being * the last byte of the list, `-2` being the penultimate, and so on. * - * @see {@link https://valkey.io/commands/bitpos/|valkey.io} for details. - * - * @param key - The key of the string. - * @param bit - The bit value to match. Must be `0` or `1`. - * @param start - (Optional) The starting offset. If not supplied, the search will start at the beginning of the string. - * - * 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: GlideString, bit: number, start?: number): T { - return this.addAndReturn(createBitPos(key, bit, start)); - } - - /** - * Returns the position of the first bit matching the given `bit` value. The offsets are zero-based indexes, with - * `0` being the first element of the list, `1` being the next, and so on. These offsets can also be negative - * numbers indicating offsets starting at the end of the list, with `-1` being the last element of the list, `-2` - * being the penultimate, and so on. - * * If you are using Valkey 7.0.0 or above, the optional `indexType` can also be provided to specify whether the * `start` and `end` offsets specify BIT or BYTE offsets. If `indexType` is not provided, BYTE offsets * are assumed. If BIT is specified, `start=0` and `end=2` means to look at the first three bits. If BYTE is @@ -699,23 +679,17 @@ export class BaseTransaction> { * * @param key - The key of the string. * @param bit - The bit value to match. Must be `0` or `1`. - * @param start - The starting offset. - * @param end - The ending offset. - * @param indexType - (Optional) The index offset type. This option can only be specified if you are using Valkey - * version 7.0.0 or above. Could be either {@link BitmapIndexType.BYTE} or {@link BitmapIndexType.BIT}. If no - * index type is provided, the indexes will be assumed to be byte indexes. + * @param options - (Optional) The {@link BitOffsetOptions}. * - * Command Response - The position of the first occurrence from the `start` to the `end` offsets of the `bit` in the - * binary value of the string held at `key`. + * 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 bitposInterval( + public bitpos( key: GlideString, bit: number, - start: number, - end: number, - indexType?: BitmapIndexType, + options?: BitOffsetOptions, ): T { - return this.addAndReturn(createBitPos(key, bit, start, end, indexType)); + return this.addAndReturn(createBitPos(key, bit, options)); } /** diff --git a/node/tests/SharedTests.ts b/node/tests/SharedTests.ts index 25a44b5f92..1fb7961a11 100644 --- a/node/tests/SharedTests.ts +++ b/node/tests/SharedTests.ts @@ -811,7 +811,7 @@ export function runBaseTests(config: { ); it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])( - `bitpos and bitposInterval test_%p`, + `bitpos test_%p`, async (protocol) => { await runTest(async (client: BaseClient, cluster) => { const key = `{key}-${uuidv4()}`; @@ -822,19 +822,30 @@ export function runBaseTests(config: { expect(await client.set(key, value)).toEqual("OK"); expect(await client.bitpos(key, 0)).toEqual(0); 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.bitpos(key, 1, { start: 1 })).toEqual(9); expect( - await client.bitposInterval(Buffer.from(key), 0, 3, 5), + await client.bitpos(key, 0, { start: 3, end: 5 }), + ).toEqual(24); + + expect( + await client.bitpos(Buffer.from(key), 0, { + start: 3, + end: 5, + }), ).toEqual(24); // -1 is returned if start > end - expect(await client.bitposInterval(key, 0, 1, 0)).toEqual(-1); + expect( + await client.bitpos(key, 0, { start: 1, end: 0 }), + ).toEqual(-1); // `BITPOS` returns -1 for non-existing strings expect(await client.bitpos(nonExistingKey, 1)).toEqual(-1); expect( - await client.bitposInterval(nonExistingKey, 1, 3, 5), + await client.bitpos(nonExistingKey, 1, { + start: 3, + end: 5, + }), ).toEqual(-1); // invalid argument - bit value must be 0 or 1 @@ -842,7 +853,7 @@ export function runBaseTests(config: { RequestError, ); await expect( - client.bitposInterval(key, 2, 3, 5), + client.bitpos(key, 2, { start: 3, end: 5 }), ).rejects.toThrow(RequestError); // key exists, but it is not a string @@ -851,86 +862,70 @@ export function runBaseTests(config: { RequestError, ); await expect( - client.bitposInterval(setKey, 1, 1, -1), + client.bitpos(setKey, 1, { start: 1, end: -1 }), ).rejects.toThrow(RequestError); if (cluster.checkIfServerVersionLessThan("7.0.0")) { await expect( - client.bitposInterval( - key, - 1, - 1, - -1, - BitmapIndexType.BYTE, - ), + client.bitpos(key, 1, { + start: 1, + end: -1, + indexType: BitmapIndexType.BYTE, + }), ).rejects.toThrow(RequestError); await expect( - client.bitposInterval( - key, - 1, - 1, - -1, - BitmapIndexType.BIT, - ), + client.bitpos(key, 1, { + start: 1, + end: -1, + indexType: BitmapIndexType.BIT, + }), ).rejects.toThrow(RequestError); } else { expect( - await client.bitposInterval( - key, - 0, - 3, - 5, - BitmapIndexType.BYTE, - ), + await client.bitpos(key, 0, { + start: 3, + end: 5, + indexType: BitmapIndexType.BYTE, + }), ).toEqual(24); expect( - await client.bitposInterval( - key, - 1, - 43, - -2, - BitmapIndexType.BIT, - ), + await client.bitpos(key, 1, { + start: 43, + end: -2, + indexType: BitmapIndexType.BIT, + }), ).toEqual(47); expect( - await client.bitposInterval( - nonExistingKey, - 1, - 3, - 5, - BitmapIndexType.BYTE, - ), + await client.bitpos(nonExistingKey, 1, { + start: 3, + end: 5, + indexType: BitmapIndexType.BYTE, + }), ).toEqual(-1); expect( - await client.bitposInterval( - nonExistingKey, - 1, - 3, - 5, - BitmapIndexType.BIT, - ), + await client.bitpos(nonExistingKey, 1, { + start: 3, + end: 5, + indexType: BitmapIndexType.BIT, + }), ).toEqual(-1); // -1 is returned if the bit value wasn't found expect( - await client.bitposInterval( - key, - 1, - -1, - -1, - BitmapIndexType.BIT, - ), + await client.bitpos(key, 1, { + start: -1, + end: -1, + indexType: BitmapIndexType.BIT, + }), ).toEqual(-1); // key exists, but it is not a string await expect( - client.bitposInterval( - setKey, - 1, - 1, - -1, - BitmapIndexType.BIT, - ), + client.bitpos(setKey, 1, { + start: 1, + end: -1, + indexType: BitmapIndexType.BIT, + }), ).rejects.toThrow(RequestError); } }, protocol); diff --git a/node/tests/TestUtilities.ts b/node/tests/TestUtilities.ts index 7136c043ab..c02b28c2fd 100644 --- a/node/tests/TestUtilities.ts +++ b/node/tests/TestUtilities.ts @@ -1326,9 +1326,13 @@ export async function transactionTest( "bitcount(key17, new BitOffsetOptions(5, 30, BitmapIndexType.BIT))", 17, ]); - baseTransaction.bitposInterval(key17, 1, 44, 50, BitmapIndexType.BIT); + baseTransaction.bitpos(key17, 1, { + start: 44, + end: 50, + indexType: BitmapIndexType.BIT, + }); responseData.push([ - "bitposInterval(key17, 1, 44, 50, BitmapIndexType.BIT)", + "bitpos(key17, 1, {start: 44, end: 50, indexType: BitmapIndexType.BIT})", 46, ]); }