diff --git a/CHANGELOG.md b/CHANGELOG.md index 857f9725ca..aa2e4b5e71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,9 @@ * Node: Added ZMPOP command ([#1994](https://github.com/valkey-io/valkey-glide/pull/1994)) * Node: Added ZINCRBY command ([#2009](https://github.com/valkey-io/valkey-glide/pull/2009)) +#### Breaking Changes +* Node: (Refactor) Convert classes to types ([#2005](https://github.com/valkey-io/valkey-glide/pull/2005)) + #### Fixes * Java: Add overloads for XADD to allow duplicate entry keys ([#1970](https://github.com/valkey-io/valkey-glide/pull/1970)) * Node: Fix ZADD bug where command could not be called with only the `changed` optional parameter ([#1995](https://github.com/valkey-io/valkey-glide/pull/1995)) diff --git a/node/npm/glide/index.ts b/node/npm/glide/index.ts index 420529e0e7..16585715f3 100644 --- a/node/npm/glide/index.ts +++ b/node/npm/glide/index.ts @@ -101,6 +101,7 @@ function initialize() { SetOptions, ZaddOptions, ScoreBoundry, + UpdateOptions, RangeByIndex, RangeByScore, RangeByLex, @@ -157,6 +158,7 @@ function initialize() { SetOptions, ZaddOptions, ScoreBoundry, + UpdateOptions, RangeByIndex, RangeByScore, RangeByLex, diff --git a/node/src/BaseClient.ts b/node/src/BaseClient.ts index ac62c35bcd..87a2df8531 100644 --- a/node/src/BaseClient.ts +++ b/node/src/BaseClient.ts @@ -13,11 +13,15 @@ import { Buffer, BufferWriter, Reader, Writer } from "protobufjs"; import { AggregationType, BitmapIndexType, + BitOffsetOptions, BitwiseOperation, ExpireOptions, + GeoAddOptions, + GeospatialData, GeoUnit, InsertPosition, KeyWeight, + LPosOptions, ListDirection, RangeByIndex, RangeByLex, @@ -140,10 +144,6 @@ import { createZRevRankWithScore, createZScore, } from "./Commands"; -import { BitOffsetOptions } from "./commands/BitOffsetOptions"; -import { GeoAddOptions } from "./commands/geospatial/GeoAddOptions"; -import { GeospatialData } from "./commands/geospatial/GeospatialData"; -import { LPosOptions } from "./commands/LPosOptions"; import { ClosingError, ConfigurationError, @@ -2388,7 +2388,8 @@ export class BaseClient { * @example * ```typescript * // Example usage of the zadd method to update scores in an existing sorted set - * const result = await client.zadd("existing_sorted_set", { member1: 15.0, member2: 5.5 }, { conditionalChange: "onlyIfExists", changed: true }); + * const options = { conditionalChange: ConditionalChange.ONLY_IF_EXISTS, changed: true }; + * const result = await client.zadd("existing_sorted_set", { member1: 15.0, member2: 5.5 }, options); * console.log(result); // Output: 2 - Updates the scores of two existing members in the sorted set "existing_sorted_set." * ``` */ @@ -3567,8 +3568,8 @@ export class BaseClient { * @example * ```typescript * await client.rpush("myList", ["a", "b", "c", "d", "e", "e"]); - * console.log(await client.lpos("myList", "e", new LPosOptions({ rank: 2 }))); // Output: 5 - the second occurrence of "e" is at index 5. - * console.log(await client.lpos("myList", "e", new LPosOptions({ count: 3 }))); // Output: [ 4, 5 ] - indices for the occurrences of "e" in list "myList". + * console.log(await client.lpos("myList", "e", { rank: 2 })); // Output: 5 - the second occurrence of "e" is at index 5. + * console.log(await client.lpos("myList", "e", { count: 3 })); // Output: [ 4, 5 ] - indices for the occurrences of "e" in list "myList". * ``` */ public lpos( @@ -3594,9 +3595,9 @@ export class BaseClient { * @example * ```typescript * console.log(await client.bitcount("my_key1")); // Output: 2 - The string stored at "my_key1" contains 2 set bits. - * console.log(await client.bitcount("my_key2", OffsetOptions(1, 3))); // Output: 2 - The second to fourth bytes of the string stored at "my_key2" contain 2 set bits. - * console.log(await client.bitcount("my_key3", OffsetOptions(1, 1, BitmapIndexType.BIT))); // Output: 1 - Indicates that the second bit of the string stored at "my_key3" is set. - * console.log(await client.bitcount("my_key3", OffsetOptions(-1, -1, BitmapIndexType.BIT))); // Output: 1 - Indicates that the last bit of the string stored at "my_key3" is set. + * console.log(await client.bitcount("my_key2", { start: 1, end: 3 })); // Output: 2 - The second to fourth bytes of the string stored at "my_key2" contain 2 set bits. + * console.log(await client.bitcount("my_key3", { start: 1, end: 1, indexType: BitmapIndexType.BIT })); // Output: 1 - Indicates that the second bit of the string stored at "my_key3" is set. + * console.log(await client.bitcount("my_key3", { start: -1, end: -1, indexType: BitmapIndexType.BIT })); // Output: 1 - Indicates that the last bit of the string stored at "my_key3" is set. * ``` */ public bitcount(key: string, options?: BitOffsetOptions): Promise { @@ -3619,8 +3620,11 @@ export class BaseClient { * * @example * ```typescript - * const options = new GeoAddOptions({updateMode: ConditionalChange.ONLY_IF_EXISTS, changed: true}); - * const num = await client.geoadd("mySortedSet", new Map([["Palermo", new GeospatialData(13.361389, 38.115556)]]), options); + * const options = {updateMode: ConditionalChange.ONLY_IF_EXISTS, changed: true}; + * const membersToCoordinates = new Map([ + * ["Palermo", { longitude: 13.361389, latitude: 38.115556 }], + * ]); + * const num = await client.geoadd("mySortedSet", membersToCoordinates, options); * console.log(num); // Output: 1 - Indicates that the position of an existing member in the sorted set "mySortedSet" has been updated. * ``` */ @@ -3648,7 +3652,7 @@ export class BaseClient { * * @example * ```typescript - * const data = new Map([["Palermo", new GeospatialData(13.361389, 38.115556)], ["Catania", new GeospatialData(15.087269, 37.502669)]]); + * const data = new Map([["Palermo", { longitude: 13.361389, latitude: 38.115556 }], ["Catania", { longitude: 15.087269, latitude: 37.502669 }]]); * await client.geoadd("mySortedSet", data); * const result = await client.geopos("mySortedSet", ["Palermo", "Catania", "NonExisting"]); * // When added via GEOADD, the geospatial coordinates are converted into a 52 bit geohash, so the coordinates diff --git a/node/src/Commands.ts b/node/src/Commands.ts index 044ddc9759..ff4eac85ae 100644 --- a/node/src/Commands.ts +++ b/node/src/Commands.ts @@ -4,13 +4,14 @@ import { createLeakedStringVec, MAX_REQUEST_ARGS_LEN } from "glide-rs"; import Long from "long"; -import { FlushMode } from "./commands/FlushMode"; -import { LPosOptions } from "./commands/LPosOptions"; +/* eslint-disable-next-line @typescript-eslint/no-unused-vars */ +import { BaseClient } from "src/BaseClient"; +/* eslint-disable-next-line @typescript-eslint/no-unused-vars */ +import { GlideClient } from "src/GlideClient"; +/* eslint-disable-next-line @typescript-eslint/no-unused-vars */ +import { GlideClusterClient } from "src/GlideClusterClient"; import { command_request } from "./ProtobufMessage"; -import { BitOffsetOptions } from "./commands/BitOffsetOptions"; -import { GeoAddOptions } from "./commands/geospatial/GeoAddOptions"; -import { GeospatialData } from "./commands/geospatial/GeospatialData"; import RequestType = command_request.RequestType; @@ -976,21 +977,25 @@ export function createTTL(key: string): command_request.Command { return createCommand(RequestType.TTL, [key]); } +/** + * Options for updating elements of a sorted set key. + */ +export enum UpdateByScore { + /** Only update existing elements if the new score is less than the current score. */ + LESS_THAN = "LT", + /** Only update existing elements if the new score is greater than the current score. */ + GREATER_THAN = "GT", +} + export type ZAddOptions = { /** - * `onlyIfDoesNotExist` - Only add new elements. Don't update already existing - * elements. Equivalent to `NX` in the Redis API. `onlyIfExists` - Only update - * elements that already exist. Don't add new elements. Equivalent to `XX` in - * the Redis API. + * Options for handling existing members. */ - conditionalChange?: "onlyIfExists" | "onlyIfDoesNotExist"; + conditionalChange?: ConditionalChange; /** - * `scoreLessThanCurrent` - Only update existing elements if the new score is - * less than the current score. Equivalent to `LT` in the Redis API. - * `scoreGreaterThanCurrent` - Only update existing elements if the new score - * is greater than the current score. Equivalent to `GT` in the Redis API. + * Options for updating scores. */ - updateOptions?: "scoreLessThanCurrent" | "scoreGreaterThanCurrent"; + updateOptions?: UpdateByScore; /** * Modify the return value from the number of new elements added, to the total number of elements changed. */ @@ -1009,22 +1014,22 @@ export function createZAdd( let args = [key]; if (options) { - if (options.conditionalChange === "onlyIfExists") { - args.push("XX"); - } else if (options.conditionalChange === "onlyIfDoesNotExist") { - if (options.updateOptions) { + if (options.conditionalChange) { + if ( + options.conditionalChange === + ConditionalChange.ONLY_IF_DOES_NOT_EXIST && + options.updateOptions + ) { throw new Error( `The GT, LT, and NX options are mutually exclusive. Cannot choose both ${options.updateOptions} and NX.`, ); } - args.push("NX"); + args.push(options.conditionalChange); } - if (options.updateOptions === "scoreLessThanCurrent") { - args.push("LT"); - } else if (options.updateOptions === "scoreGreaterThanCurrent") { - args.push("GT"); + if (options.updateOptions) { + args.push(options.updateOptions); } if (options.changed) { @@ -1694,6 +1699,27 @@ export function createFunctionLoad( return createCommand(RequestType.FunctionLoad, args); } +/** + * Represents offsets specifying a string interval to analyze in the {@link BaseClient.bitcount|bitcount} 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. + * + * See https://valkey.io/commands/bitcount/ for more details. + */ +export type BitOffsetOptions = { + /** The starting offset index. */ + start: number; + /** The ending offset index. */ + 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}. + * If no index type is provided, the indexes will be assumed to be byte indexes. + */ + indexType?: BitmapIndexType; +}; + /** * @internal */ @@ -1702,7 +1728,13 @@ export function createBitCount( options?: BitOffsetOptions, ): command_request.Command { const args = [key]; - if (options) args.push(...options.toArgs()); + + if (options) { + args.push(options.start.toString()); + args.push(options.end.toString()); + if (options.indexType) args.push(options.indexType); + } + return createCommand(RequestType.BitCount, args); } @@ -1747,6 +1779,24 @@ export function createBitPos( return createCommand(RequestType.BitPos, args); } +/** + * Defines flushing mode for {@link GlideClient.flushall}, {@link GlideClusterClient.flushall}, + * {@link GlideClient.functionFlush}, {@link GlideClusterClient.functionFlush}, + * {@link GlideClient.flushdb} and {@link GlideClusterClient.flushdb} commands. + * + * See https://valkey.io/commands/flushall/ and https://valkey.io/commands/flushdb/ for details. + */ +export enum FlushMode { + /** + * Flushes synchronously. + * + * since Valkey version 6.2.0. + */ + SYNC = "SYNC", + /** Flushes asynchronously. */ + ASYNC = "ASYNC", +} + export type StreamReadOptions = { /** * If set, the read request will block for the set amount of milliseconds or @@ -1932,6 +1982,20 @@ export function createFlushDB(mode?: FlushMode): command_request.Command { } } +/** + * Optional arguments to LPOS command. + * + * See https://valkey.io/commands/lpos/ for more details. + */ +export type LPosOptions = { + /** The rank of the match to return. */ + rank?: number; + /** The specific number of matching indices from a list. */ + count?: number; + /** The maximum number of comparisons to make between the element and the items in the list. */ + maxLength?: number; +}; + /** * @internal */ @@ -1940,10 +2004,23 @@ export function createLPos( element: string, options?: LPosOptions, ): command_request.Command { - let args: string[] = [key, element]; + const args: string[] = [key, element]; if (options) { - args = args.concat(options.toArgs()); + if (options.rank !== undefined) { + args.push("RANK"); + args.push(options.rank.toString()); + } + + if (options.count !== undefined) { + args.push("COUNT"); + args.push(options.count.toString()); + } + + if (options.maxLength !== undefined) { + args.push("MAXLEN"); + args.push(options.maxLength.toString()); + } } return createCommand(RequestType.LPos, args); @@ -1956,6 +2033,48 @@ export function createDBSize(): command_request.Command { return createCommand(RequestType.DBSize, []); } +/** + * An optional condition to the {@link BaseClient.geoadd} command. + */ +export enum ConditionalChange { + /** + * Only update elements that already exist. Don't add new elements. Equivalent to `XX` in the Valkey API. + */ + ONLY_IF_EXISTS = "XX", + + /** + * Only add new elements. Don't update already existing elements. Equivalent to `NX` in the Valkey API. + */ + ONLY_IF_DOES_NOT_EXIST = "NX", +} + +/** + * Represents a geographic position defined by longitude and latitude. + * The exact limits, as specified by `EPSG:900913 / EPSG:3785 / OSGEO:41001` are the + * following: + * + * Valid longitudes are from `-180` to `180` degrees. + * Valid latitudes are from `-85.05112878` to `85.05112878` degrees. + */ +export type GeospatialData = { + /** The longitude coordinate. */ + longitude: number; + /** The latitude coordinate. */ + latitude: number; +}; + +/** + * Optional arguments for the GeoAdd command. + * + * See https://valkey.io/commands/geoadd/ for more details. + */ +export type GeoAddOptions = { + /** Options for handling existing members. See {@link ConditionalChange}. */ + updateMode?: ConditionalChange; + /** If `true`, returns the count of changed elements instead of new elements added. */ + changed?: boolean; +}; + /** * @internal */ @@ -1967,11 +2086,20 @@ export function createGeoAdd( let args: string[] = [key]; if (options) { - args = args.concat(options.toArgs()); + if (options.updateMode) { + args.push(options.updateMode); + } + + if (options.changed) { + args.push("CH"); + } } membersToGeospatialData.forEach((coord, member) => { - args = args.concat(coord.toArgs()); + args = args.concat([ + coord.longitude.toString(), + coord.latitude.toString(), + ]); args.push(member); }); return createCommand(RequestType.GeoAdd, args); diff --git a/node/src/GlideClient.ts b/node/src/GlideClient.ts index b89e39a6c4..c63715b6df 100644 --- a/node/src/GlideClient.ts +++ b/node/src/GlideClient.ts @@ -10,6 +10,7 @@ import { ReturnType, } from "./BaseClient"; import { + FlushMode, InfoOptions, LolwutOptions, createClientGetName, @@ -35,7 +36,6 @@ import { } from "./Commands"; import { connection_request } from "./ProtobufMessage"; import { Transaction } from "./Transaction"; -import { FlushMode } from "./commands/FlushMode"; /* eslint-disable-next-line @typescript-eslint/no-namespace */ export namespace GlideClientConfiguration { diff --git a/node/src/GlideClusterClient.ts b/node/src/GlideClusterClient.ts index 0cddacdb0f..632132a3e0 100644 --- a/node/src/GlideClusterClient.ts +++ b/node/src/GlideClusterClient.ts @@ -10,6 +10,7 @@ import { ReturnType, } from "./BaseClient"; import { + FlushMode, InfoOptions, LolwutOptions, createClientGetName, @@ -34,7 +35,6 @@ import { createPublish, createTime, } from "./Commands"; -import { FlushMode } from "./commands/FlushMode"; import { RequestError } from "./Errors"; import { command_request, connection_request } from "./ProtobufMessage"; import { ClusterTransaction } from "./Transaction"; diff --git a/node/src/Transaction.ts b/node/src/Transaction.ts index 9c4aaeb347..df3a75afd1 100644 --- a/node/src/Transaction.ts +++ b/node/src/Transaction.ts @@ -4,13 +4,18 @@ import { AggregationType, + BitOffsetOptions, BitmapIndexType, BitwiseOperation, ExpireOptions, + FlushMode, + GeoAddOptions, + GeospatialData, GeoUnit, InfoOptions, InsertPosition, KeyWeight, + LPosOptions, ListDirection, LolwutOptions, RangeByIndex, @@ -154,11 +159,6 @@ import { createZIncrBy, } from "./Commands"; import { command_request } from "./ProtobufMessage"; -import { BitOffsetOptions } from "./commands/BitOffsetOptions"; -import { FlushMode } from "./commands/FlushMode"; -import { LPosOptions } from "./commands/LPosOptions"; -import { GeoAddOptions } from "./commands/geospatial/GeoAddOptions"; -import { GeospatialData } from "./commands/geospatial/GeospatialData"; /** * Base class encompassing shared commands for both standalone and cluster mode implementations in a transaction. diff --git a/node/src/commands/BitOffsetOptions.ts b/node/src/commands/BitOffsetOptions.ts deleted file mode 100644 index 5f5d6800e6..0000000000 --- a/node/src/commands/BitOffsetOptions.ts +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0 - */ - -// Import below added to fix up the TSdoc link, but eslint blames for unused import. -/* eslint-disable-next-line @typescript-eslint/no-unused-vars */ -import { BaseClient } from "src/BaseClient"; -import { BitmapIndexType } from "src/Commands"; - -/** - * Represents offsets specifying a string interval to analyze in the {@link BaseClient.bitcount|bitcount} 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. - * - * See https://valkey.io/commands/bitcount/ for more details. - */ -export class BitOffsetOptions { - private start: number; - private end: number; - private indexType?: BitmapIndexType; - - /** - * @param start - The starting offset index. - * @param end - The ending offset index. - * @param indexType - 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}. - * If no index type is provided, the indexes will be assumed to be byte indexes. - */ - constructor(start: number, end: number, indexType?: BitmapIndexType) { - this.start = start; - this.end = end; - this.indexType = indexType; - } - - /** - * Converts BitOffsetOptions into a string[]. - * - * @returns string[] - */ - public toArgs(): string[] { - const args = [this.start.toString(), this.end.toString()]; - - if (this.indexType) args.push(this.indexType); - - return args; - } -} diff --git a/node/src/commands/ConditionalChange.ts b/node/src/commands/ConditionalChange.ts deleted file mode 100644 index 5904f90d32..0000000000 --- a/node/src/commands/ConditionalChange.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0 - */ - -/* eslint-disable-next-line @typescript-eslint/no-unused-vars */ -import { BaseClient } from "src/BaseClient"; - -/** - * An optional condition to the {@link BaseClient.geoadd} command. - */ -export enum ConditionalChange { - /** - * Only update elements that already exist. Don't add new elements. Equivalent to `XX` in the Valkey API. - */ - ONLY_IF_EXISTS = "XX", - - /** - * Only add new elements. Don't update already existing elements. Equivalent to `NX` in the Valkey API. - * */ - ONLY_IF_DOES_NOT_EXIST = "NX", -} diff --git a/node/src/commands/FlushMode.ts b/node/src/commands/FlushMode.ts deleted file mode 100644 index 78b9ca10c0..0000000000 --- a/node/src/commands/FlushMode.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0 - */ - -// Import below added to fix up the TSdoc link, but eslint blames for unused import. -/* eslint-disable-next-line @typescript-eslint/no-unused-vars */ -import { GlideClient } from "src/GlideClient"; - -/** - * Defines flushing mode for {@link GlideClient.flushall|flushall} and {@link GlideClient.flushdb|flushdb} commands. - * - * See https://valkey.io/commands/flushall/ and https://valkey.io/commands/flushdb/ for details. - */ -export enum FlushMode { - /** - * Flushes synchronously. - * - * since Valkey version 6.2.0. - */ - SYNC = "SYNC", - /** Flushes asynchronously. */ - ASYNC = "ASYNC", -} diff --git a/node/src/commands/LPosOptions.ts b/node/src/commands/LPosOptions.ts deleted file mode 100644 index de2c0bcc2a..0000000000 --- a/node/src/commands/LPosOptions.ts +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0 - */ - -/** - * Optional arguments to LPOS command. - * - * See https://valkey.io/commands/lpos/ for more details. - */ -export class LPosOptions { - /** Redis API keyword use to determine the rank of the match to return. */ - public static RANK_REDIS_API = "RANK"; - /** Redis API keyword used to extract specific number of matching indices from a list. */ - public static COUNT_REDIS_API = "COUNT"; - /** Redis API keyword used to determine the maximum number of list items to compare. */ - public static MAXLEN_REDIS_API = "MAXLEN"; - /** The rank of the match to return. */ - private rank?: number; - /** The specific number of matching indices from a list. */ - private count?: number; - /** The maximum number of comparisons to make between the element and the items in the list. */ - private maxLength?: number; - - constructor({ - rank, - count, - maxLength, - }: { - rank?: number; - count?: number; - maxLength?: number; - }) { - this.rank = rank; - this.count = count; - this.maxLength = maxLength; - } - - /** - * - * Converts LPosOptions into a string[]. - * - * @returns string[] - */ - public toArgs(): string[] { - const args: string[] = []; - - if (this.rank !== undefined) { - args.push(LPosOptions.RANK_REDIS_API); - args.push(this.rank.toString()); - } - - if (this.count !== undefined) { - args.push(LPosOptions.COUNT_REDIS_API); - args.push(this.count.toString()); - } - - if (this.maxLength !== undefined) { - args.push(LPosOptions.MAXLEN_REDIS_API); - args.push(this.maxLength.toString()); - } - - return args; - } -} diff --git a/node/src/commands/geospatial/GeoAddOptions.ts b/node/src/commands/geospatial/GeoAddOptions.ts deleted file mode 100644 index 220dff8e19..0000000000 --- a/node/src/commands/geospatial/GeoAddOptions.ts +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0 - */ - -import { ConditionalChange } from "../ConditionalChange"; - -/** - * Optional arguments for the GeoAdd command. - * - * See https://valkey.io/commands/geoadd/ for more details. - */ -export class GeoAddOptions { - /** Valkey API keyword use to modify the return value from the number of new elements added, to the total number of elements changed. */ - public static CHANGED_VALKEY_API = "CH"; - - private updateMode?: ConditionalChange; - - private changed?: boolean; - - /** - * Default constructor for GeoAddOptions. - * - * @param updateMode - Options for handling existing members. See {@link ConditionalChange}. - * @param latitude - If `true`, returns the count of changed elements instead of new elements added. - */ - constructor(options: { - updateMode?: ConditionalChange; - changed?: boolean; - }) { - this.updateMode = options.updateMode; - this.changed = options.changed; - } - - /** - * Converts GeoAddOptions into a string[]. - * - * @returns string[] - */ - public toArgs(): string[] { - const args: string[] = []; - - if (this.updateMode) { - args.push(this.updateMode); - } - - if (this.changed) { - args.push(GeoAddOptions.CHANGED_VALKEY_API); - } - - return args; - } -} diff --git a/node/src/commands/geospatial/GeospatialData.ts b/node/src/commands/geospatial/GeospatialData.ts deleted file mode 100644 index 63c15bdff0..0000000000 --- a/node/src/commands/geospatial/GeospatialData.ts +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0 - */ - -/** - * Represents a geographic position defined by longitude and latitude. - * The exact limits, as specified by `EPSG:900913 / EPSG:3785 / OSGEO:41001` are the - * following: - * - * Valid longitudes are from `-180` to `180` degrees. - * Valid latitudes are from `-85.05112878` to `85.05112878` degrees. - */ -export class GeospatialData { - private longitude: number; - - private latitude: number; - - /** - * Default constructor for GeospatialData. - * - * @param longitude - The longitude coordinate. - * @param latitude - The latitude coordinate. - */ - constructor(longitude: number, latitude: number) { - this.longitude = longitude; - this.latitude = latitude; - } - - /** - * Converts GeospatialData into a string[]. - * - * @returns string[] - */ - public toArgs(): string[] { - return [this.longitude.toString(), this.latitude.toString()]; - } -} diff --git a/node/tests/RedisClient.test.ts b/node/tests/RedisClient.test.ts index 09ac745aeb..e8326ab797 100644 --- a/node/tests/RedisClient.test.ts +++ b/node/tests/RedisClient.test.ts @@ -14,7 +14,7 @@ import { BufferReader, BufferWriter } from "protobufjs"; import { v4 as uuidv4 } from "uuid"; import { GlideClient, ProtocolVersion, Transaction } from ".."; import { RedisCluster } from "../../utils/TestUtils.js"; -import { FlushMode } from "../build-ts/src/commands/FlushMode.js"; +import { FlushMode } from "../build-ts/src/Commands"; import { command_request } from "../src/ProtobufMessage"; import { runBaseTests } from "./SharedTests"; import { diff --git a/node/tests/RedisClusterClient.test.ts b/node/tests/RedisClusterClient.test.ts index 75a68dcdd6..79713181a2 100644 --- a/node/tests/RedisClusterClient.test.ts +++ b/node/tests/RedisClusterClient.test.ts @@ -21,8 +21,8 @@ import { Routes, ScoreFilter, } from ".."; +import { FlushMode } from "../build-ts/src/Commands"; import { RedisCluster } from "../../utils/TestUtils.js"; -import { FlushMode } from "../build-ts/src/commands/FlushMode"; import { runBaseTests } from "./SharedTests"; import { checkClusterResponse, diff --git a/node/tests/SharedTests.ts b/node/tests/SharedTests.ts index e0bd789c40..12ba6d97cd 100644 --- a/node/tests/SharedTests.ts +++ b/node/tests/SharedTests.ts @@ -13,7 +13,11 @@ import { BitmapIndexType, BitwiseOperation, ClosingError, + ConditionalChange, ExpireOptions, + FlushMode, + GeoUnit, + GeospatialData, ListDirection, GlideClient, GlideClusterClient, @@ -23,9 +27,11 @@ import { RequestError, ScoreFilter, Script, + UpdateByScore, parseInfoResponse, - GeoUnit, } from "../"; +import { RedisCluster } from "../../utils/TestUtils"; +import { SingleNodeRoute } from "../build-ts/src/GlideClusterClient"; import { Client, GetAndSetRandomValue, @@ -35,14 +41,6 @@ import { intoArray, intoString, } from "./TestUtilities"; -import { SingleNodeRoute } from "../build-ts/src/GlideClusterClient"; -import { BitOffsetOptions } from "../build-ts/src/commands/BitOffsetOptions"; -import { LPosOptions } from "../build-ts/src/commands/LPosOptions"; -import { GeospatialData } from "../build-ts/src/commands/geospatial/GeospatialData"; -import { GeoAddOptions } from "../build-ts/src/commands/geospatial/GeoAddOptions"; -import { ConditionalChange } from "../build-ts/src/commands/ConditionalChange"; -import { FlushMode } from "../build-ts/src/commands/FlushMode"; -import { RedisCluster } from "../../utils/TestUtils"; export type BaseClient = GlideClient | GlideClusterClient; @@ -283,8 +281,6 @@ export function runBaseTests(config: { await client.set("foo", "bar"); const oldResult = await client.info([InfoOptions.Commandstats]); const oldResultAsString = intoString(oldResult); - console.log(oldResult); - console.log(oldResultAsString); expect(oldResultAsString).toContain("cmdstat_set"); checkSimple(await client.configResetStat()).toEqual("OK"); @@ -2450,25 +2446,27 @@ export function runBaseTests(config: { const membersScores = { one: 1, two: 2, three: 3 }; expect( await client.zadd(key, membersScores, { - conditionalChange: "onlyIfExists", + conditionalChange: ConditionalChange.ONLY_IF_EXISTS, }), ).toEqual(0); expect( await client.zadd(key, membersScores, { - conditionalChange: "onlyIfDoesNotExist", + conditionalChange: + ConditionalChange.ONLY_IF_DOES_NOT_EXIST, }), ).toEqual(3); expect( await client.zaddIncr(key, "one", 5.0, { - conditionalChange: "onlyIfDoesNotExist", + conditionalChange: + ConditionalChange.ONLY_IF_DOES_NOT_EXIST, }), ).toEqual(null); expect( await client.zaddIncr(key, "one", 5.0, { - conditionalChange: "onlyIfExists", + conditionalChange: ConditionalChange.ONLY_IF_EXISTS, }), ).toEqual(6.0); }, protocol); @@ -2488,27 +2486,27 @@ export function runBaseTests(config: { expect( await client.zadd(key, membersScores, { - updateOptions: "scoreGreaterThanCurrent", + updateOptions: UpdateByScore.GREATER_THAN, changed: true, }), ).toEqual(1); expect( await client.zadd(key, membersScores, { - updateOptions: "scoreLessThanCurrent", + updateOptions: UpdateByScore.LESS_THAN, changed: true, }), ).toEqual(0); expect( await client.zaddIncr(key, "one", -3.0, { - updateOptions: "scoreLessThanCurrent", + updateOptions: UpdateByScore.LESS_THAN, }), ).toEqual(7.0); expect( await client.zaddIncr(key, "one", -3.0, { - updateOptions: "scoreGreaterThanCurrent", + updateOptions: UpdateByScore.GREATER_THAN, }), ).toEqual(null); }, protocol); @@ -4540,44 +4538,32 @@ export function runBaseTests(config: { // simplest case expect(await client.lpos(key, "a")).toEqual(0); - expect( - await client.lpos(key, "b", new LPosOptions({ rank: 2 })), - ).toEqual(5); + expect(await client.lpos(key, "b", { rank: 2 })).toEqual(5); // element doesn't exist expect(await client.lpos(key, "e")).toBeNull(); // reverse traversal - expect( - await client.lpos(key, "b", new LPosOptions({ rank: -2 })), - ).toEqual(2); + expect(await client.lpos(key, "b", { rank: -2 })).toEqual(2); // unlimited comparisons expect( - await client.lpos( - key, - "a", - new LPosOptions({ rank: 1, maxLength: 0 }), - ), + await client.lpos(key, "a", { rank: 1, maxLength: 0 }), ).toEqual(0); // limited comparisons expect( - await client.lpos( - key, - "c", - new LPosOptions({ rank: 1, maxLength: 2 }), - ), + await client.lpos(key, "c", { rank: 1, maxLength: 2 }), ).toBeNull(); // invalid rank value await expect( - client.lpos(key, "a", new LPosOptions({ rank: 0 })), + client.lpos(key, "a", { rank: 0 }), ).rejects.toThrow(RequestError); // invalid maxlen value await expect( - client.lpos(key, "a", new LPosOptions({ maxLength: -1 })), + client.lpos(key, "a", { maxLength: -1 }), ).rejects.toThrow(RequestError); // non-existent key @@ -4593,45 +4579,29 @@ export function runBaseTests(config: { // invalid count value await expect( - client.lpos(key, "a", new LPosOptions({ count: -1 })), + client.lpos(key, "a", { count: -1 }), ).rejects.toThrow(RequestError); // with count + expect(await client.lpos(key, "a", { count: 2 })).toEqual([ + 0, 1, + ]); + expect(await client.lpos(key, "a", { count: 0 })).toEqual([ + 0, 1, 4, + ]); expect( - await client.lpos(key, "a", new LPosOptions({ count: 2 })), - ).toEqual([0, 1]); - expect( - await client.lpos(key, "a", new LPosOptions({ count: 0 })), + await client.lpos(key, "a", { rank: 1, count: 0 }), ).toEqual([0, 1, 4]); expect( - await client.lpos( - key, - "a", - new LPosOptions({ rank: 1, count: 0 }), - ), - ).toEqual([0, 1, 4]); - expect( - await client.lpos( - key, - "a", - new LPosOptions({ rank: 2, count: 0 }), - ), + await client.lpos(key, "a", { rank: 2, count: 0 }), ).toEqual([1, 4]); expect( - await client.lpos( - key, - "a", - new LPosOptions({ rank: 3, count: 0 }), - ), + await client.lpos(key, "a", { rank: 3, count: 0 }), ).toEqual([4]); // reverse traversal expect( - await client.lpos( - key, - "a", - new LPosOptions({ rank: -1, count: 0 }), - ), + await client.lpos(key, "a", { rank: -1, count: 0 }), ).toEqual([4, 1, 0]); }, protocol); }, @@ -4697,18 +4667,15 @@ export function runBaseTests(config: { checkSimple(await client.set(key1, value)).toEqual("OK"); expect(await client.bitcount(key1)).toEqual(26); expect( - await client.bitcount(key1, new BitOffsetOptions(1, 1)), + await client.bitcount(key1, { start: 1, end: 1 }), ).toEqual(6); expect( - await client.bitcount(key1, new BitOffsetOptions(0, -5)), + await client.bitcount(key1, { start: 0, end: -5 }), ).toEqual(10); // non-existing key expect(await client.bitcount(uuidv4())).toEqual(0); expect( - await client.bitcount( - uuidv4(), - new BitOffsetOptions(5, 30), - ), + await client.bitcount(uuidv4(), { start: 5, end: 30 }), ).toEqual(0); // key exists, but it is not a string expect(await client.sadd(key2, [value])).toEqual(1); @@ -4716,53 +4683,60 @@ export function runBaseTests(config: { RequestError, ); await expect( - client.bitcount(key2, new BitOffsetOptions(1, 1)), + client.bitcount(key2, { start: 1, end: 1 }), ).rejects.toThrow(RequestError); if (cluster.checkIfServerVersionLessThan("7.0.0")) { await expect( - client.bitcount( - key1, - new BitOffsetOptions(2, 5, BitmapIndexType.BIT), - ), + client.bitcount(key1, { + start: 2, + end: 5, + indexType: BitmapIndexType.BIT, + }), ).rejects.toThrow(); await expect( - client.bitcount( - key1, - new BitOffsetOptions(2, 5, BitmapIndexType.BYTE), - ), + client.bitcount(key1, { + start: 2, + end: 5, + indexType: BitmapIndexType.BYTE, + }), ).rejects.toThrow(); } else { expect( - await client.bitcount( - key1, - new BitOffsetOptions(2, 5, BitmapIndexType.BYTE), - ), + await client.bitcount(key1, { + start: 2, + end: 5, + indexType: BitmapIndexType.BYTE, + }), ).toEqual(16); expect( - await client.bitcount( - key1, - new BitOffsetOptions(5, 30, BitmapIndexType.BIT), - ), + await client.bitcount(key1, { + start: 5, + end: 30, + indexType: BitmapIndexType.BIT, + }), ).toEqual(17); expect( - await client.bitcount( - key1, - new BitOffsetOptions(5, -5, BitmapIndexType.BIT), - ), + await client.bitcount(key1, { + start: 5, + end: -5, + indexType: BitmapIndexType.BIT, + }), ).toEqual(23); expect( - await client.bitcount( - uuidv4(), - new BitOffsetOptions(2, 5, BitmapIndexType.BYTE), - ), + await client.bitcount(uuidv4(), { + start: 2, + end: 5, + indexType: BitmapIndexType.BYTE, + }), ).toEqual(0); // key exists, but it is not a string await expect( - client.bitcount( - key2, - new BitOffsetOptions(1, 1, BitmapIndexType.BYTE), - ), + client.bitcount(key2, { + start: 1, + end: 1, + indexType: BitmapIndexType.BYTE, + }), ).rejects.toThrow(RequestError); } }, protocol); @@ -4777,14 +4751,14 @@ export function runBaseTests(config: { const key1 = uuidv4(); const key2 = uuidv4(); const membersToCoordinates = new Map(); - membersToCoordinates.set( - "Palermo", - new GeospatialData(13.361389, 38.115556), - ); - membersToCoordinates.set( - "Catania", - new GeospatialData(15.087269, 37.502669), - ); + membersToCoordinates.set("Palermo", { + longitude: 13.361389, + latitude: 38.115556, + }); + membersToCoordinates.set("Catania", { + longitude: 15.087269, + latitude: 37.502669, + }); // default geoadd expect(await client.geoadd(key1, membersToCoordinates)).toBe(2); @@ -4812,45 +4786,34 @@ export function runBaseTests(config: { expect(geopos).toEqual([null]); // with update mode options - membersToCoordinates.set( - "Catania", - new GeospatialData(15.087269, 39), - ); + membersToCoordinates.set("Catania", { + longitude: 15.087269, + latitude: 39, + }); expect( - await client.geoadd( - key1, - membersToCoordinates, - new GeoAddOptions({ - updateMode: - ConditionalChange.ONLY_IF_DOES_NOT_EXIST, - }), - ), + await client.geoadd(key1, membersToCoordinates, { + updateMode: ConditionalChange.ONLY_IF_DOES_NOT_EXIST, + }), ).toBe(0); expect( - await client.geoadd( - key1, - membersToCoordinates, - new GeoAddOptions({ - updateMode: ConditionalChange.ONLY_IF_EXISTS, - }), - ), + await client.geoadd(key1, membersToCoordinates, { + updateMode: ConditionalChange.ONLY_IF_EXISTS, + }), ).toBe(0); // with changed option - membersToCoordinates.set( - "Catania", - new GeospatialData(15.087269, 40), - ); - membersToCoordinates.set( - "Tel-Aviv", - new GeospatialData(32.0853, 34.7818), - ); + membersToCoordinates.set("Catania", { + longitude: 15.087269, + latitude: 40, + }); + membersToCoordinates.set("Tel-Aviv", { + longitude: 32.0853, + latitude: 34.7818, + }); expect( - await client.geoadd( - key1, - membersToCoordinates, - new GeoAddOptions({ changed: true }), - ), + await client.geoadd(key1, membersToCoordinates, { + changed: true, + }), ).toBe(2); // key exists but holding non-zset value @@ -4877,25 +4840,25 @@ export function runBaseTests(config: { await expect( client.geoadd( key, - new Map([["Place", new GeospatialData(-181, 0)]]), + new Map([["Place", { longitude: -181, latitude: 0 }]]), ), ).rejects.toThrow(); await expect( client.geoadd( key, - new Map([["Place", new GeospatialData(181, 0)]]), + new Map([["Place", { longitude: 181, latitude: 0 }]]), ), ).rejects.toThrow(); await expect( client.geoadd( key, - new Map([["Place", new GeospatialData(0, 86)]]), + new Map([["Place", { longitude: 0, latitude: 86 }]]), ), ).rejects.toThrow(); await expect( client.geoadd( key, - new Map([["Place", new GeospatialData(0, -86)]]), + new Map([["Place", { longitude: 0, latitude: -86 }]]), ), ).rejects.toThrow(); }, protocol); @@ -5016,14 +4979,14 @@ export function runBaseTests(config: { // adding the geo locations const membersToCoordinates = new Map(); - membersToCoordinates.set( - member1, - new GeospatialData(13.361389, 38.115556), - ); - membersToCoordinates.set( - member2, - new GeospatialData(15.087269, 37.502669), - ); + membersToCoordinates.set(member1, { + longitude: 13.361389, + latitude: 38.115556, + }); + membersToCoordinates.set(member2, { + longitude: 15.087269, + latitude: 37.502669, + }); expect(await client.geoadd(key1, membersToCoordinates)).toBe(2); // checking result with default metric @@ -5068,14 +5031,14 @@ export function runBaseTests(config: { // adding the geo locations const membersToCoordinates = new Map(); - membersToCoordinates.set( - "Palermo", - new GeospatialData(13.361389, 38.115556), - ); - membersToCoordinates.set( - "Catania", - new GeospatialData(15.087269, 37.502669), - ); + membersToCoordinates.set("Palermo", { + longitude: 13.361389, + latitude: 38.115556, + }); + membersToCoordinates.set("Catania", { + longitude: 15.087269, + latitude: 37.502669, + }); expect(await client.geoadd(key1, membersToCoordinates)).toBe(2); // checking result with default metric diff --git a/node/tests/TestUtilities.ts b/node/tests/TestUtilities.ts index fbe9722921..9f23326bc6 100644 --- a/node/tests/TestUtilities.ts +++ b/node/tests/TestUtilities.ts @@ -13,7 +13,9 @@ import { BitmapIndexType, BitwiseOperation, ClusterTransaction, + FlushMode, GeoUnit, + GeospatialData, GlideClient, GlideClusterClient, InsertPosition, @@ -24,10 +26,6 @@ import { ScoreFilter, Transaction, } from ".."; -import { BitOffsetOptions } from "../build-ts/src/commands/BitOffsetOptions"; -import { FlushMode } from "../build-ts/src/commands/FlushMode"; -import { GeospatialData } from "../build-ts/src/commands/geospatial/GeospatialData"; -import { LPosOptions } from "../build-ts/src/commands/LPosOptions"; beforeAll(() => { Logger.init("info"); @@ -526,20 +524,10 @@ export async function transactionTest( field + "3", ]); responseData.push(["rpush(key16, [1, 1, 2, 3, 3,])", 5]); - baseTransaction.lpos(key16, field + "1", new LPosOptions({ rank: 2 })); - responseData.push([ - 'lpos(key16, field + "1", new LPosOptions({ rank: 2 }))', - 1, - ]); - baseTransaction.lpos( - key16, - field + "1", - new LPosOptions({ rank: 2, count: 0 }), - ); - responseData.push([ - 'lpos(key16, field + "1", new LPosOptions({ rank: 2, count: 0 }))', - [1], - ]); + baseTransaction.lpos(key16, field + "1", { rank: 2 }); + responseData.push(['lpos(key16, field + "1", { rank: 2 })', 1]); + baseTransaction.lpos(key16, field + "1", { rank: 2, count: 0 }); + responseData.push(['lpos(key16, field + "1", { rank: 2, count: 0 })', [1]]); baseTransaction.sadd(key7, ["bar", "foo"]); responseData.push(['sadd(key7, ["bar", "foo"])', 2]); baseTransaction.sunionstore(key7, [key7, key7]); @@ -743,8 +731,8 @@ export async function transactionTest( responseData.push(['set(key17, "foobar")', "OK"]); baseTransaction.bitcount(key17); responseData.push(["bitcount(key17)", 26]); - baseTransaction.bitcount(key17, new BitOffsetOptions(1, 1)); - responseData.push(["bitcount(key17, new BitOffsetOptions(1, 1))", 6]); + baseTransaction.bitcount(key17, { start: 1, end: 1 }); + responseData.push(["bitcount(key17, { start: 1, end: 1 })", 6]); baseTransaction.bitpos(key17, 1); responseData.push(["bitpos(key17, 1)", 1]); @@ -759,10 +747,11 @@ export async function transactionTest( responseData.push(["get(key19)", "`bc`ab"]); if (gte("7.0.0", version)) { - baseTransaction.bitcount( - key17, - new BitOffsetOptions(5, 30, BitmapIndexType.BIT), - ); + baseTransaction.bitcount(key17, { + start: 5, + end: 30, + indexType: BitmapIndexType.BIT, + }); responseData.push([ "bitcount(key17, new BitOffsetOptions(5, 30, BitmapIndexType.BIT))", 17, @@ -780,9 +769,9 @@ export async function transactionTest( responseData.push(["pfcount([key11])", 3]); baseTransaction.geoadd( key18, - new Map([ - ["Palermo", new GeospatialData(13.361389, 38.115556)], - ["Catania", new GeospatialData(15.087269, 37.502669)], + new Map([ + ["Palermo", { longitude: 13.361389, latitude: 38.115556 }], + ["Catania", { longitude: 15.087269, latitude: 37.502669 }], ]), ); responseData.push(["geoadd(key18, { Palermo: ..., Catania: ... })", 2]);