diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ba2b03a88..e2919287f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ #### Changes * Node: Added binary variant to HSCAN command ([#2240](https://github.com/valkey-io/valkey-glide/pull/2240)) +* Node: replace decoder by DecoderOption and route by RouteOption in API([#2234](https://github.com/valkey-io/valkey-glide/pull/2234/)) * Node: Added binary variant to sorted set commands ([#2190](https://github.com/valkey-io/valkey-glide/pull/2190), [#2210](https://github.com/valkey-io/valkey-glide/pull/2210)) * Node: Added binary variant for MSET, MSETNX commands ([#2229](https://github.com/valkey-io/valkey-glide/pull/2229)) * Node: Added binary variant to HASH commands ([#2194](https://github.com/valkey-io/valkey-glide/pull/2194)) diff --git a/node/src/BaseClient.ts b/node/src/BaseClient.ts index eed9a59c95..51c906a328 100644 --- a/node/src/BaseClient.ts +++ b/node/src/BaseClient.ts @@ -235,7 +235,11 @@ import { TimeoutError, } from "./Errors"; import { GlideClientConfiguration } from "./GlideClient"; -import { GlideClusterClientConfiguration } from "./GlideClusterClient"; +import { + GlideClusterClientConfiguration, + RouteOption, + Routes, +} from "./GlideClusterClient"; import { Logger } from "./Logger"; import { command_request, @@ -502,10 +506,6 @@ export type ScriptOptions = { * The arguments for the script. */ args?: GlideString[]; - /** - * {@link Decoder} type which defines how to handle the responses. If not set, the default decoder from the client config will be used. - */ - decoder?: Decoder; }; function getRequestErrorClass( @@ -530,16 +530,93 @@ function getRequestErrorClass( return RequestError; } +/** + * @internal + */ +function toProtobufRoute( + route: Routes | undefined, +): command_request.Routes | undefined { + if (!route) { + return undefined; + } + + if (route === "allPrimaries") { + return command_request.Routes.create({ + simpleRoutes: command_request.SimpleRoutes.AllPrimaries, + }); + } else if (route === "allNodes") { + return command_request.Routes.create({ + simpleRoutes: command_request.SimpleRoutes.AllNodes, + }); + } else if (route === "randomNode") { + return command_request.Routes.create({ + simpleRoutes: command_request.SimpleRoutes.Random, + }); + } else if (route.type === "primarySlotKey") { + return command_request.Routes.create({ + slotKeyRoute: command_request.SlotKeyRoute.create({ + slotType: command_request.SlotTypes.Primary, + slotKey: route.key, + }), + }); + } else if (route.type === "replicaSlotKey") { + return command_request.Routes.create({ + slotKeyRoute: command_request.SlotKeyRoute.create({ + slotType: command_request.SlotTypes.Replica, + slotKey: route.key, + }), + }); + } else if (route.type === "primarySlotId") { + return command_request.Routes.create({ + slotKeyRoute: command_request.SlotIdRoute.create({ + slotType: command_request.SlotTypes.Primary, + slotId: route.id, + }), + }); + } else if (route.type === "replicaSlotId") { + return command_request.Routes.create({ + slotKeyRoute: command_request.SlotIdRoute.create({ + slotType: command_request.SlotTypes.Replica, + slotId: route.id, + }), + }); + } else if (route.type === "routeByAddress") { + let port = route.port; + let host = route.host; + + if (port === undefined) { + const split = host.split(":"); + + if (split.length !== 2) { + throw new RequestError( + "No port provided, expected host to be formatted as `{hostname}:{port}`. Received " + + host, + ); + } + + host = split[0]; + port = Number(split[1]); + } + + return command_request.Routes.create({ + byAddressRoute: { host, port }, + }); + } +} + export type PubSubMsg = { message: string; channel: string; pattern?: string | null; }; -export type WritePromiseOptions = { - decoder?: Decoder; - route?: command_request.Routes; -}; +/** + * @internal + * A type to combine RouterOption and DecoderOption to be used for creating write promises for the command. + * See - {@link DecoderOption} and {@link RouteOption} + */ +export type WritePromiseOptions = RouteOption & DecoderOption; + export class BaseClient { private socket: net.Socket; private readonly promiseCallbackFunctions: [ @@ -754,8 +831,9 @@ export class BaseClient { | command_request.ScriptInvocation, options: WritePromiseOptions = {}, ): Promise { - const { decoder = this.defaultDecoder, route } = options; - const stringDecoder = decoder === Decoder.String ? true : false; + const route = toProtobufRoute(options?.route); + const stringDecoder: boolean = + (options?.decoder ?? this.defaultDecoder) === Decoder.String; if (this.isClosed) { throw new ClosingError( @@ -1046,8 +1124,7 @@ export class BaseClient { * @see {@link https://valkey.io/commands/get/|valkey.io} for details. * * @param key - The key to retrieve from the database. - * @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. - * If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used. + * @param options - (Optional) See {@link DecoderOption}. * @returns If `key` exists, returns the value of `key`. Otherwise, return null. * * @example @@ -1062,9 +1139,9 @@ export class BaseClient { */ public async get( key: GlideString, - decoder?: Decoder, + options?: DecoderOption, ): Promise { - return this.createWritePromise(createGet(key), { decoder: decoder }); + return this.createWritePromise(createGet(key), options); } /** @@ -1093,9 +1170,10 @@ export class BaseClient { expiry: "persist" | { type: TimeUnit; duration: number }; } & DecoderOption, ): Promise { - return this.createWritePromise(createGetEx(key, options?.expiry), { - decoder: options?.decoder, - }); + return this.createWritePromise( + createGetEx(key, options?.expiry), + options, + ); } /** @@ -1104,8 +1182,7 @@ export class BaseClient { * @see {@link https://valkey.io/commands/getdel/|valkey.io} for details. * * @param key - The key to retrieve from the database. - * @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. - * If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used. + * @param options - (Optional) See {@link DecoderOption}. * @returns If `key` exists, returns the `value` of `key`. Otherwise, return `null`. * * @example @@ -1118,9 +1195,9 @@ export class BaseClient { */ public async getdel( key: GlideString, - decoder?: Decoder, + options?: DecoderOption, ): Promise { - return this.createWritePromise(createGetDel(key), { decoder: decoder }); + return this.createWritePromise(createGetDel(key), options); } /** @@ -1135,8 +1212,7 @@ export class BaseClient { * @param key - The key of the string. * @param start - The starting offset. * @param end - The ending offset. - * @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. - * If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used. + * @param options - (Optional) See {@link DecoderOption}. * @returns A substring extracted from the value stored at `key`. * * @example @@ -1156,11 +1232,12 @@ export class BaseClient { key: GlideString, start: number, end: number, - decoder?: Decoder, + options?: DecoderOption, ): Promise { - return this.createWritePromise(createGetRange(key, start, end), { - decoder: decoder, - }); + return this.createWritePromise( + createGetRange(key, start, end), + options, + ); } /** Set the given key with the given value. Return value is dependent on the passed options. @@ -1198,9 +1275,7 @@ export class BaseClient { value: GlideString, options?: SetOptions & DecoderOption, ): Promise<"OK" | GlideString | null> { - return this.createWritePromise(createSet(key, value, options), { - decoder: options?.decoder, - }); + return this.createWritePromise(createSet(key, value, options), options); } /** @@ -1311,8 +1386,7 @@ export class BaseClient { * @remarks When in cluster mode, the command may route to multiple nodes when `keys` map to different hash slots. * * @param keys - A list of keys to retrieve values for. - * @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. - * If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used. + * @param options - (Optional) See {@link DecoderOption}. * @returns A list of values corresponding to the provided keys. If a key is not found, * its corresponding value in the list will be null. * @@ -1327,9 +1401,9 @@ export class BaseClient { */ public async mget( keys: GlideString[], - decoder?: Decoder, + options?: DecoderOption, ): Promise<(GlideString | null)[]> { - return this.createWritePromise(createMGet(keys), { decoder: decoder }); + return this.createWritePromise(createMGet(keys), options); } /** Set multiple keys to multiple values in a single operation. @@ -2264,8 +2338,7 @@ export class BaseClient { * @see {@link https://valkey.io/commands/lpop/|valkey.io} for details. * * @param key - The key of the list. - * @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. - * If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used. + * @param options - (Optional) See {@link DecoderOption}. * @returns The value of the first element. * If `key` does not exist null will be returned. * @@ -2285,9 +2358,9 @@ export class BaseClient { */ public async lpop( key: GlideString, - decoder?: Decoder, + options?: DecoderOption, ): Promise { - return this.createWritePromise(createLPop(key), { decoder: decoder }); + return this.createWritePromise(createLPop(key), options); } /** Removes and returns up to `count` elements of the list stored at `key`, depending on the list's length. @@ -2296,8 +2369,7 @@ export class BaseClient { * * @param key - The key of the list. * @param count - The count of the elements to pop from the list. - * @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. - * If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used. + * @param options - (Optional) See {@link DecoderOption}. * @returns A list of the popped elements will be returned depending on the list's length. * If `key` does not exist null will be returned. * @@ -2318,11 +2390,9 @@ export class BaseClient { public async lpopCount( key: GlideString, count: number, - decoder?: Decoder, + options?: DecoderOption, ): Promise { - return this.createWritePromise(createLPop(key, count), { - decoder: decoder, - }); + return this.createWritePromise(createLPop(key, count), options); } /** Returns the specified elements of the list stored at `key`. @@ -2335,8 +2405,7 @@ export class BaseClient { * @param key - The key of the list. * @param start - The starting point of the range. * @param end - The end of the range. - * @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. - * If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used. + * @param options - (Optional) See {@link DecoderOption}. * @returns list of elements in the specified range. * If `start` exceeds the end of the list, or if `start` is greater than `end`, an empty list will be returned. * If `end` exceeds the actual end of the list, the range will stop at the actual end of the list. @@ -2367,11 +2436,9 @@ export class BaseClient { key: GlideString, start: number, end: number, - decoder?: Decoder, + options?: DecoderOption, ): Promise { - return this.createWritePromise(createLRange(key, start, end), { - decoder: decoder, - }); + return this.createWritePromise(createLRange(key, start, end), options); } /** Returns the length of the list stored at `key`. @@ -2405,8 +2472,7 @@ export class BaseClient { * @param destination - The key to the destination list. * @param whereFrom - The {@link ListDirection} to remove the element from. * @param whereTo - The {@link ListDirection} to add the element to. - * @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. - * If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used. + * @param options - (Optional) See {@link DecoderOption}. * @returns The popped element, or `null` if `source` does not exist. * * @example @@ -2429,11 +2495,11 @@ export class BaseClient { destination: GlideString, whereFrom: ListDirection, whereTo: ListDirection, - decoder?: Decoder, + options?: DecoderOption, ): Promise { return this.createWritePromise( createLMove(source, destination, whereFrom, whereTo), - { decoder: decoder }, + options, ); } @@ -2453,8 +2519,7 @@ export class BaseClient { * @param whereFrom - The {@link ListDirection} to remove the element from. * @param whereTo - The {@link ListDirection} to add the element to. * @param timeout - The number of seconds to wait for a blocking operation to complete. A value of `0` will block indefinitely. - * @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. - * If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used. + * @param options - (Optional) See {@link DecoderOption}. * @returns The popped element, or `null` if `source` does not exist or if the operation timed-out. * * @example @@ -2477,11 +2542,11 @@ export class BaseClient { whereFrom: ListDirection, whereTo: ListDirection, timeout: number, - decoder?: Decoder, + options?: DecoderOption, ): Promise { return this.createWritePromise( createBLMove(source, destination, whereFrom, whereTo, timeout), - { decoder: decoder }, + options, ); } @@ -2632,8 +2697,7 @@ export class BaseClient { * @see {@link https://valkey.io/commands/rpop/|valkey.io} for details. * * @param key - The key of the list. - * @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. - * If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used. + * @param options - (Optional) See {@link DecoderOption}. * @returns The value of the last element. * If `key` does not exist null will be returned. * @@ -2653,9 +2717,9 @@ export class BaseClient { */ public async rpop( key: GlideString, - decoder?: Decoder, + options?: DecoderOption, ): Promise { - return this.createWritePromise(createRPop(key), { decoder: decoder }); + return this.createWritePromise(createRPop(key), options); } /** Removes and returns up to `count` elements from the list stored at `key`, depending on the list's length. @@ -2664,8 +2728,7 @@ export class BaseClient { * * @param key - The key of the list. * @param count - The count of the elements to pop from the list. - * @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. - * If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used. + * @param options - (Optional) See {@link DecoderOption}. * @returns A list of popped elements will be returned depending on the list's length. * If `key` does not exist null will be returned. * @@ -2686,11 +2749,9 @@ export class BaseClient { public async rpopCount( key: GlideString, count: number, - decoder?: Decoder, + options?: DecoderOption, ): Promise { - return this.createWritePromise(createRPop(key, count), { - decoder: decoder, - }); + return this.createWritePromise(createRPop(key, count), options); } /** Adds the specified members to the set stored at `key`. Specified members that are already a member of this set are ignored. @@ -3023,9 +3084,10 @@ export class BaseClient { keys: GlideString[], options?: DecoderOption, ): Promise> { - return this.createWritePromise(createSUnion(keys), { - decoder: options?.decoder, - }).then((sunion) => new Set(sunion)); + return this.createWritePromise( + createSUnion(keys), + options, + ).then((sunion) => new Set(sunion)); } /** @@ -3502,7 +3564,7 @@ export class BaseClient { * @see {@link https://valkey.io/commands/script-load/|SCRIPT LOAD} and {@link https://valkey.io/commands/evalsha/|EVALSHA} on valkey.io for details. * * @param script - The Lua script to execute. - * @param options - The script option that contains keys and arguments for the script. + * @param options - (Optional) See {@link ScriptOptions} and {@link DecoderOption}. * @returns A value that depends on the script that was executed. * * @example @@ -3518,11 +3580,11 @@ export class BaseClient { */ public async invokeScript( script: Script, - option?: ScriptOptions, + options?: ScriptOptions & DecoderOption, ): Promise { const scriptInvocation = command_request.ScriptInvocation.create({ hash: script.getHash(), - keys: option?.keys?.map((item) => { + keys: options?.keys?.map((item) => { if (typeof item === "string") { // Convert the string to a Buffer return Buffer.from(item); @@ -3531,7 +3593,7 @@ export class BaseClient { return item; } }), - args: option?.args?.map((item) => { + args: options?.args?.map((item) => { if (typeof item === "string") { // Convert the string to a Buffer return Buffer.from(item); @@ -3541,9 +3603,7 @@ export class BaseClient { } }), }); - return this.createWritePromise(scriptInvocation, { - decoder: option?.decoder, - }); + return this.createWritePromise(scriptInvocation, options); } /** @@ -5685,8 +5745,7 @@ export class BaseClient { * * @param key - The `key` of the list. * @param index - The `index` of the element in the list to retrieve. - * @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. - * If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used. + * @param options - (Optional) See {@link DecoderOption}. * @returns - The element at `index` in the list stored at `key`. * If `index` is out of range or if `key` does not exist, null is returned. * @@ -5707,11 +5766,9 @@ export class BaseClient { public async lindex( key: GlideString, index: number, - decoder?: Decoder, + options?: DecoderOption, ): Promise { - return this.createWritePromise(createLIndex(key, index), { - decoder: decoder, - }); + return this.createWritePromise(createLIndex(key, index), options); } /** @@ -5827,8 +5884,7 @@ export class BaseClient { * * @param keys - The `keys` of the lists to pop from. * @param timeout - The `timeout` in seconds. - * @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. - * If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used. + * @param options - (Optional) See {@link DecoderOption}. * @returns - An `array` containing the `key` from which the element was popped and the value of the popped element, * formatted as [key, value]. If no element could be popped and the timeout expired, returns `null`. * @@ -5842,11 +5898,9 @@ export class BaseClient { public async brpop( keys: GlideString[], timeout: number, - decoder?: Decoder, + options?: DecoderOption, ): Promise<[GlideString, GlideString] | null> { - return this.createWritePromise(createBRPop(keys, timeout), { - decoder: decoder, - }); + return this.createWritePromise(createBRPop(keys, timeout), options); } /** Blocking list pop primitive. @@ -5860,8 +5914,7 @@ export class BaseClient { * * @param keys - The `keys` of the lists to pop from. * @param timeout - The `timeout` in seconds. - * @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. - * If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used. + * @param options - (Optional) See {@link DecoderOption}. * @returns - An `array` containing the `key` from which the element was popped and the value of the popped element, * formatted as [key, value]. If no element could be popped and the timeout expired, returns `null`. * @@ -5874,11 +5927,9 @@ export class BaseClient { public async blpop( keys: GlideString[], timeout: number, - decoder?: Decoder, + options?: DecoderOption, ): Promise<[GlideString, GlideString] | null> { - return this.createWritePromise(createBLPop(keys, timeout), { - decoder: decoder, - }); + return this.createWritePromise(createBLPop(keys, timeout), options); } /** Adds all elements to the HyperLogLog data structure stored at the specified `key`. @@ -6043,8 +6094,7 @@ export class BaseClient { * @param keys - A list of `keys` accessed by the function. To ensure the correct execution of functions, * all names of keys that a function accesses must be explicitly provided as `keys`. * @param args - A list of `function` arguments and it should not represent names of keys. - * @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. - * If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used. + * @param options - (Optional) See {@link DecoderOption}. * @returns The invoked function's return value. * * @example @@ -6057,11 +6107,9 @@ export class BaseClient { func: GlideString, keys: GlideString[], args: GlideString[], - decoder?: Decoder, + options?: DecoderOption, ): Promise { - return this.createWritePromise(createFCall(func, keys, args), { - decoder, - }); + return this.createWritePromise(createFCall(func, keys, args), options); } /** @@ -6075,8 +6123,7 @@ export class BaseClient { * @param keys - A list of `keys` accessed by the function. To ensure the correct execution of functions, * all names of keys that a function accesses must be explicitly provided as `keys`. * @param args - A list of `function` arguments and it should not represent names of keys. - * @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. - * If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used. + * @param options - (Optional) See {@link DecoderOption}. * @returns The invoked function's return value. * * @example @@ -6090,11 +6137,12 @@ export class BaseClient { func: GlideString, keys: GlideString[], args: GlideString[], - decoder?: Decoder, + options?: DecoderOption, ): Promise { - return this.createWritePromise(createFCallReadOnly(func, keys, args), { - decoder, - }); + return this.createWritePromise( + createFCallReadOnly(func, keys, args), + options, + ); } /** @@ -6262,7 +6310,7 @@ export class BaseClient { ): Promise<[GlideString, [number?, number?, [number, number]?]?][]> { return this.createWritePromise( createGeoSearch(key, searchFrom, searchBy, options), - { decoder: options?.decoder }, + options, ); } @@ -6957,9 +7005,10 @@ export class BaseClient { public async pubsubChannels( options?: { pattern?: GlideString } & DecoderOption, ): Promise { - return this.createWritePromise(createPubSubChannels(options?.pattern), { - decoder: options?.decoder, - }); + return this.createWritePromise( + createPubSubChannels(options?.pattern), + options, + ); } /** diff --git a/node/src/GlideClient.ts b/node/src/GlideClient.ts index 3492fd715e..a72766502c 100644 --- a/node/src/GlideClient.ts +++ b/node/src/GlideClient.ts @@ -179,8 +179,7 @@ export class GlideClient extends BaseClient { * @see {@link https://github.com/valkey-io/valkey-glide/wiki/NodeJS-wrapper#transaction|Valkey Glide Wiki} for details on Valkey Transactions. * * @param transaction - A {@link Transaction} object containing a list of commands to be executed. - * @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. - * If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used. + * @param options - (Optional) See {@link DecoderOption}. * @returns A list of results corresponding to the execution of each command in the transaction. * If a command returns a value, it will be included in the list. If a command doesn't return a value, * the list entry will be `null`. @@ -188,11 +187,11 @@ export class GlideClient extends BaseClient { */ public async exec( transaction: Transaction, - decoder?: Decoder, + options?: DecoderOption, ): Promise { return this.createWritePromise( transaction.commands, - { decoder: decoder }, + options, ).then((result) => this.processResultWithSetCommands( result, @@ -208,6 +207,10 @@ export class GlideClient extends BaseClient { * * @see {@link https://github.com/valkey-io/valkey-glide/wiki/General-Concepts#custom-command|Valkey Glide Wiki} for details on the restrictions and limitations of the custom command API. * + * @param args - A list including the command name and arguments for the custom command. + * @param options - (Optional) See {@link DecoderOption}. + * @returns The executed custom command return value. + * * @example * ```typescript * // Example usage of customCommand method to retrieve pub/sub clients @@ -217,11 +220,9 @@ export class GlideClient extends BaseClient { */ public async customCommand( args: GlideString[], - decoder?: Decoder, + options?: DecoderOption, ): Promise { - return this.createWritePromise(createCustomCommand(args), { - decoder: decoder, - }); + return this.createWritePromise(createCustomCommand(args), options); } /** @@ -255,9 +256,7 @@ export class GlideClient extends BaseClient { message?: GlideString; } & DecoderOption, ): Promise { - return this.createWritePromise(createPing(options?.message), { - decoder: options?.decoder, - }); + return this.createWritePromise(createPing(options?.message), options); } /** @@ -301,8 +300,7 @@ export class GlideClient extends BaseClient { * * @see {@link https://valkey.io/commands/client-getname/|valkey.io} for more details. * - * @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. - * If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used. + * @param options - (Optional) See {@link DecoderOption}. * @returns The name of the client connection as a string if a name is set, or `null` if no name is assigned. * * @example @@ -312,10 +310,10 @@ export class GlideClient extends BaseClient { * console.log(result); // Output: 'Client Name' * ``` */ - public async clientGetName(decoder?: Decoder): Promise { - return this.createWritePromise(createClientGetName(), { - decoder: decoder, - }); + public async clientGetName( + options?: DecoderOption, + ): Promise { + return this.createWritePromise(createClientGetName(), options); } /** @@ -381,8 +379,7 @@ export class GlideClient extends BaseClient { * @see {@link https://valkey.io/commands/config-get/|valkey.io} for details. * * @param parameters - A list of configuration parameter names to retrieve values for. - * @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. - * If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used. + * @param options - (Optional) See {@link DecoderOption}. * * @returns A map of values corresponding to the configuration parameters. * @@ -395,11 +392,9 @@ export class GlideClient extends BaseClient { */ public async configGet( parameters: string[], - decoder?: Decoder, + options?: DecoderOption, ): Promise> { - return this.createWritePromise(createConfigGet(parameters), { - decoder: decoder, - }); + return this.createWritePromise(createConfigGet(parameters), options); } /** @@ -430,8 +425,7 @@ export class GlideClient extends BaseClient { * @see {@link https://valkey.io/commands/echo|valkey.io} for more details. * * @param message - The message to be echoed back. - * @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. - * If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used. + * @param options - (Optional) See {@link DecoderOption}. * @returns The provided `message`. * * @example @@ -443,11 +437,9 @@ export class GlideClient extends BaseClient { */ public async echo( message: GlideString, - decoder?: Decoder, + options?: DecoderOption, ): Promise { - return this.createWritePromise(createEcho(message), { - decoder, - }); + return this.createWritePromise(createEcho(message), options); } /** @@ -598,7 +590,7 @@ export class GlideClient extends BaseClient { ): Promise { return this.createWritePromise( createFunctionLoad(libraryCode, options?.replace), - { decoder: options?.decoder }, + options, ); } @@ -654,9 +646,7 @@ export class GlideClient extends BaseClient { public async functionList( options?: FunctionListOptions & DecoderOption, ): Promise { - return this.createWritePromise(createFunctionList(options), { - decoder: options?.decoder, - }); + return this.createWritePromise(createFunctionList(options), options); } /** @@ -669,8 +659,7 @@ export class GlideClient extends BaseClient { * @see {@link https://valkey.io/commands/function-stats/|valkey.io} for details. * @remarks Since Valkey version 7.0.0. * - * @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. - * If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used. + * @param options - (Optional) See {@link DecoderOption}. * @returns A Record where the key is the node address and the value is a Record with two keys: * - `"running_script"`: Information about the running script, or `null` if no script is running. * - `"engines"`: Information about available engines and their stats. @@ -706,11 +695,9 @@ export class GlideClient extends BaseClient { * ``` */ public async functionStats( - decoder?: Decoder, + options?: DecoderOption, ): Promise { - return this.createWritePromise(createFunctionStats(), { - decoder, - }); + return this.createWritePromise(createFunctionStats(), options); } /** @@ -886,9 +873,7 @@ export class GlideClient extends BaseClient { key: GlideString, options?: SortOptions & DecoderOption, ): Promise<(GlideString | null)[]> { - return this.createWritePromise(createSort(key, options), { - decoder: options?.decoder, - }); + return this.createWritePromise(createSort(key, options), options); } /** @@ -919,9 +904,10 @@ export class GlideClient extends BaseClient { key: GlideString, options?: SortOptions & DecoderOption, ): Promise<(GlideString | null)[]> { - return this.createWritePromise(createSortReadOnly(key, options), { - decoder: options?.decoder, - }); + return this.createWritePromise( + createSortReadOnly(key, options), + options, + ); } /** @@ -981,9 +967,7 @@ export class GlideClient extends BaseClient { * Returns a random existing key name from the currently selected database. * * @see {@link https://valkey.io/commands/randomkey/|valkey.io} for more details. - * - * @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. - * If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used. + * @param options - (Optional) See {@link DecoderOption}. * @returns A random existing key name from the currently selected database. * * @example @@ -992,8 +976,10 @@ export class GlideClient extends BaseClient { * console.log(result); // Output: "key12" - "key12" is a random existing key name from the currently selected database. * ``` */ - public async randomKey(decoder?: Decoder): Promise { - return this.createWritePromise(createRandomKey(), { decoder: decoder }); + public async randomKey( + options?: DecoderOption, + ): Promise { + return this.createWritePromise(createRandomKey(), options); } /** diff --git a/node/src/GlideClusterClient.ts b/node/src/GlideClusterClient.ts index 0cb43f00a4..a8826ef4ed 100644 --- a/node/src/GlideClusterClient.ts +++ b/node/src/GlideClusterClient.ts @@ -57,8 +57,7 @@ import { createTime, createUnWatch, } from "./Commands"; -import { RequestError } from "./Errors"; -import { command_request, connection_request } from "./ProtobufMessage"; +import { connection_request } from "./ProtobufMessage"; import { ClusterTransaction } from "./Transaction"; /** An extension to command option types with {@link Routes}. */ @@ -225,77 +224,6 @@ export type SingleNodeRoute = | SlotKeyTypes | RouteByAddress; -function toProtobufRoute( - route: Routes | undefined, -): command_request.Routes | undefined { - if (route === undefined) { - return undefined; - } - - if (route === "allPrimaries") { - return command_request.Routes.create({ - simpleRoutes: command_request.SimpleRoutes.AllPrimaries, - }); - } else if (route === "allNodes") { - return command_request.Routes.create({ - simpleRoutes: command_request.SimpleRoutes.AllNodes, - }); - } else if (route === "randomNode") { - return command_request.Routes.create({ - simpleRoutes: command_request.SimpleRoutes.Random, - }); - } else if (route.type === "primarySlotKey") { - return command_request.Routes.create({ - slotKeyRoute: command_request.SlotKeyRoute.create({ - slotType: command_request.SlotTypes.Primary, - slotKey: route.key, - }), - }); - } else if (route.type === "replicaSlotKey") { - return command_request.Routes.create({ - slotKeyRoute: command_request.SlotKeyRoute.create({ - slotType: command_request.SlotTypes.Replica, - slotKey: route.key, - }), - }); - } else if (route.type === "primarySlotId") { - return command_request.Routes.create({ - slotKeyRoute: command_request.SlotIdRoute.create({ - slotType: command_request.SlotTypes.Primary, - slotId: route.id, - }), - }); - } else if (route.type === "replicaSlotId") { - return command_request.Routes.create({ - slotKeyRoute: command_request.SlotIdRoute.create({ - slotType: command_request.SlotTypes.Replica, - slotId: route.id, - }), - }); - } else if (route.type === "routeByAddress") { - let port = route.port; - let host = route.host; - - if (port === undefined) { - const split = host.split(":"); - - if (split.length !== 2) { - throw new RequestError( - "No port provided, expected host to be formatted as `{hostname}:{port}`. Received " + - host, - ); - } - - host = split[0]; - port = Number(split[1]); - } - - return command_request.Routes.create({ - byAddressRoute: { host, port }, - }); - } -} - /** * Client used for connection to cluster Redis servers. * @@ -361,6 +289,10 @@ export class GlideClusterClient extends BaseClient { * * @see {@link https://github.com/valkey-io/valkey-glide/wiki/General-Concepts#custom-command|Glide for Valkey Wiki} for details on the restrictions and limitations of the custom command API. * + * @param args - A list including the command name and arguments for the custom command. + * @param options - (Optional) See {@link RouteOption} and {@link DecoderOption} + * @returns The executed custom command return value. + * * @example * ```typescript * // Example usage of customCommand method to retrieve pub/sub clients with routing to all primary nodes @@ -370,13 +302,10 @@ export class GlideClusterClient extends BaseClient { */ public async customCommand( args: GlideString[], - options?: { route?: Routes; decoder?: Decoder }, + options?: RouteOption & DecoderOption, ): Promise> { const command = createCustomCommand(args); - return super.createWritePromise(command, { - route: toProtobufRoute(options?.route), - decoder: options?.decoder, - }); + return super.createWritePromise(command, options); } /** @@ -385,11 +314,12 @@ export class GlideClusterClient extends BaseClient { * @see {@link https://github.com/valkey-io/valkey-glide/wiki/NodeJS-wrapper#transaction|Valkey Glide Wiki} for details on Valkey Transactions. * * @param transaction - A {@link ClusterTransaction} object containing a list of commands to be executed. - * @param route - (Optional) If `route` is not provided, the transaction will be routed to the slot owner of the first key found in the transaction. + * + * @param options - (Optional) Additional parameters: + * - (Optional) `route`: If `route` is not provided, the transaction will be routed to the slot owner of the first key found in the transaction. * If no key is found, the command will be sent to a random node. * If `route` is provided, the client will route the command to the nodes defined by `route`. - * @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. - * If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used. + * - (Optional) `decoder`: See {@link DecoderOption}. * @returns A list of results corresponding to the execution of each command in the transaction. * If a command returns a value, it will be included in the list. If a command doesn't return a value, * the list entry will be `null`. @@ -399,15 +329,11 @@ export class GlideClusterClient extends BaseClient { transaction: ClusterTransaction, options?: { route?: SingleNodeRoute; - decoder?: Decoder; - }, + } & DecoderOption, ): Promise { return this.createWritePromise( transaction.commands, - { - route: toProtobufRoute(options?.route), - decoder: options?.decoder, - }, + options, ).then((result) => this.processResultWithSetCommands( result, @@ -451,10 +377,7 @@ export class GlideClusterClient extends BaseClient { } & RouteOption & DecoderOption, ): Promise { - return this.createWritePromise(createPing(options?.message), { - route: toProtobufRoute(options?.route), - decoder: options?.decoder, - }); + return this.createWritePromise(createPing(options?.message), options); } /** @@ -477,7 +400,7 @@ export class GlideClusterClient extends BaseClient { ): Promise> { return this.createWritePromise>( createInfo(options?.sections), - { route: toProtobufRoute(options?.route), decoder: Decoder.String }, + { decoder: Decoder.String, ...options }, ); } @@ -513,10 +436,7 @@ export class GlideClusterClient extends BaseClient { ): Promise> { return this.createWritePromise>( createClientGetName(), - { - route: toProtobufRoute(options?.route), - decoder: options?.decoder, - }, + options, ); } @@ -527,8 +447,7 @@ export class GlideClusterClient extends BaseClient { * * @see {@link https://valkey.io/commands/config-rewrite/|valkey.io} for details. * - * @param route - (Optional) Specifies the routing configuration for the command. - * The client will route the command to the nodes defined by `route`. + * @param options - (Optional) See {@link RouteOption}. * @returns `"OK"` when the configuration was rewritten properly. Otherwise, an error is thrown. * * @example @@ -538,10 +457,10 @@ export class GlideClusterClient extends BaseClient { * console.log(result); // Output: 'OK' * ``` */ - public async configRewrite(route?: Routes): Promise<"OK"> { + public async configRewrite(options?: RouteOption): Promise<"OK"> { return this.createWritePromise(createConfigRewrite(), { - route: toProtobufRoute(route), decoder: Decoder.String, + ...options, }); } @@ -552,8 +471,7 @@ export class GlideClusterClient extends BaseClient { * * @see {@link https://valkey.io/commands/config-resetstat/|valkey.io} for details. * - * @param route - (Optional) Specifies the routing configuration for the command. - * The client will route the command to the nodes defined by `route`. + * @param options - (Optional) See {@link RouteOption}. * @returns always `"OK"`. * * @example @@ -563,10 +481,10 @@ export class GlideClusterClient extends BaseClient { * console.log(result); // Output: 'OK' * ``` */ - public async configResetStat(route?: Routes): Promise<"OK"> { + public async configResetStat(options?: RouteOption): Promise<"OK"> { return this.createWritePromise(createConfigResetStat(), { - route: toProtobufRoute(route), decoder: Decoder.String, + ...options, }); } @@ -592,7 +510,7 @@ export class GlideClusterClient extends BaseClient { ): Promise> { return this.createWritePromise>( createClientId(), - { route: toProtobufRoute(options?.route) }, + options, ); } @@ -627,10 +545,7 @@ export class GlideClusterClient extends BaseClient { parameters: string[], options?: RouteOption & DecoderOption, ): Promise>> { - return this.createWritePromise(createConfigGet(parameters), { - route: toProtobufRoute(options?.route), - decoder: options?.decoder, - }); + return this.createWritePromise(createConfigGet(parameters), options); } /** @@ -656,8 +571,8 @@ export class GlideClusterClient extends BaseClient { options?: RouteOption, ): Promise<"OK"> { return this.createWritePromise(createConfigSet(parameters), { - route: toProtobufRoute(options?.route), decoder: Decoder.String, + ...options, }); } @@ -690,10 +605,7 @@ export class GlideClusterClient extends BaseClient { message: GlideString, options?: RouteOption & DecoderOption, ): Promise> { - return this.createWritePromise(createEcho(message), { - route: toProtobufRoute(options?.route), - decoder: options?.decoder, - }); + return this.createWritePromise(createEcho(message), options); } /** @@ -730,8 +642,8 @@ export class GlideClusterClient extends BaseClient { options?: RouteOption, ): Promise> { return this.createWritePromise(createTime(), { - route: toProtobufRoute(options?.route), decoder: Decoder.String, + ...options, }); } @@ -785,8 +697,8 @@ export class GlideClusterClient extends BaseClient { options?: LolwutOptions & RouteOption, ): Promise> { return this.createWritePromise(createLolwut(options), { - route: toProtobufRoute(options?.route), decoder: Decoder.String, + ...options, }); } @@ -812,10 +724,7 @@ export class GlideClusterClient extends BaseClient { args: GlideString[], options?: RouteOption & DecoderOption, ): Promise> { - return this.createWritePromise(createFCall(func, [], args), { - route: toProtobufRoute(options?.route), - decoder: options?.decoder, - }); + return this.createWritePromise(createFCall(func, [], args), options); } /** @@ -841,10 +750,10 @@ export class GlideClusterClient extends BaseClient { args: GlideString[], options?: RouteOption & DecoderOption, ): Promise> { - return this.createWritePromise(createFCallReadOnly(func, [], args), { - route: toProtobufRoute(options?.route), - decoder: options?.decoder, - }); + return this.createWritePromise( + createFCallReadOnly(func, [], args), + options, + ); } /** @@ -866,11 +775,11 @@ export class GlideClusterClient extends BaseClient { */ public async functionDelete( libraryCode: GlideString, - route?: Routes, + options?: RouteOption, ): Promise<"OK"> { return this.createWritePromise(createFunctionDelete(libraryCode), { - route: toProtobufRoute(route), decoder: Decoder.String, + ...options, }); } @@ -904,10 +813,7 @@ export class GlideClusterClient extends BaseClient { ): Promise { return this.createWritePromise( createFunctionLoad(libraryCode, options?.replace), - { - route: toProtobufRoute(options?.route), - decoder: options?.decoder, - }, + options, ); } @@ -934,8 +840,8 @@ export class GlideClusterClient extends BaseClient { } & RouteOption, ): Promise<"OK"> { return this.createWritePromise(createFunctionFlush(options?.mode), { - route: toProtobufRoute(options?.route), decoder: Decoder.String, + ...options, }); } @@ -970,10 +876,7 @@ export class GlideClusterClient extends BaseClient { public async functionList( options?: FunctionListOptions & DecoderOption & RouteOption, ): Promise> { - return this.createWritePromise(createFunctionList(options), { - route: toProtobufRoute(options?.route), - decoder: options?.decoder, - }); + return this.createWritePromise(createFunctionList(options), options); } /** @@ -1026,10 +929,7 @@ export class GlideClusterClient extends BaseClient { public async functionStats( options?: RouteOption & DecoderOption, ): Promise> { - return this.createWritePromise(createFunctionStats(), { - route: toProtobufRoute(options?.route), - decoder: options?.decoder, - }); + return this.createWritePromise(createFunctionStats(), options); } /** @@ -1039,8 +939,7 @@ export class GlideClusterClient extends BaseClient { * @see {@link https://valkey.io/commands/function-kill/|valkey.io} for details. * @remarks Since Valkey version 7.0.0. * - * @param route - (Optional) The client will route the command to the nodes defined by `route`. - * If not defined, the command will be routed to all nodes. + * @param options - (Optional) See {@link RouteOption}. * @returns `"OK"` if function is terminated. Otherwise, throws an error. * * @example @@ -1048,10 +947,10 @@ export class GlideClusterClient extends BaseClient { * await client.functionKill(); * ``` */ - public async functionKill(route?: Routes): Promise<"OK"> { + public async functionKill(options?: RouteOption): Promise<"OK"> { return this.createWritePromise(createFunctionKill(), { - route: toProtobufRoute(route), decoder: Decoder.String, + ...options, }); } @@ -1061,8 +960,7 @@ export class GlideClusterClient extends BaseClient { * @see {@link https://valkey.io/commands/function-dump/|valkey.io} for details. * @remarks Since Valkey version 7.0.0. * - * @param route - (Optional) The client will route the command to the nodes defined by `route`. - * If not defined, the command will be routed a random node. + * @param options - (Optional) See {@link RouteOption}. * @returns The serialized payload of all loaded libraries. * * @example @@ -1072,11 +970,11 @@ export class GlideClusterClient extends BaseClient { * ``` */ public async functionDump( - route?: Routes, + options?: RouteOption, ): Promise> { return this.createWritePromise(createFunctionDump(), { - route: toProtobufRoute(route), decoder: Decoder.Bytes, + ...options, }); } @@ -1104,10 +1002,7 @@ export class GlideClusterClient extends BaseClient { ): Promise<"OK"> { return this.createWritePromise( createFunctionRestore(payload, options?.policy), - { - route: toProtobufRoute(options?.route), - decoder: Decoder.String, - }, + { decoder: Decoder.String, ...options }, ); } @@ -1135,8 +1030,8 @@ export class GlideClusterClient extends BaseClient { } & RouteOption, ): Promise<"OK"> { return this.createWritePromise(createFlushAll(options?.mode), { - route: toProtobufRoute(options?.route), decoder: Decoder.String, + ...options, }); } @@ -1164,8 +1059,8 @@ export class GlideClusterClient extends BaseClient { } & RouteOption, ): Promise<"OK"> { return this.createWritePromise(createFlushDB(options?.mode), { - route: toProtobufRoute(options?.route), decoder: Decoder.String, + ...options, }); } @@ -1189,9 +1084,7 @@ export class GlideClusterClient extends BaseClient { public async dbsize( options?: RouteOption, ): Promise> { - return this.createWritePromise(createDBSize(), { - route: toProtobufRoute(options?.route), - }); + return this.createWritePromise(createDBSize(), options); } /** Publish a message on pubsub channel. @@ -1259,7 +1152,7 @@ export class GlideClusterClient extends BaseClient { ): Promise { return this.createWritePromise( createPubsubShardChannels(options?.pattern), - { decoder: options?.decoder }, + options, ); } @@ -1315,9 +1208,7 @@ export class GlideClusterClient extends BaseClient { key: GlideString, options?: SortClusterOptions & DecoderOption, ): Promise { - return this.createWritePromise(createSort(key, options), { - decoder: options?.decoder, - }); + return this.createWritePromise(createSort(key, options), options); } /** @@ -1345,9 +1236,10 @@ export class GlideClusterClient extends BaseClient { key: GlideString, options?: SortClusterOptions & DecoderOption, ): Promise { - return this.createWritePromise(createSortReadOnly(key, options), { - decoder: options?.decoder, - }); + return this.createWritePromise( + createSortReadOnly(key, options), + options, + ); } /** @@ -1403,9 +1295,7 @@ export class GlideClusterClient extends BaseClient { public async lastsave( options?: RouteOption, ): Promise> { - return this.createWritePromise(createLastSave(), { - route: toProtobufRoute(options?.route), - }); + return this.createWritePromise(createLastSave(), options); } /** @@ -1427,10 +1317,7 @@ export class GlideClusterClient extends BaseClient { public async randomKey( options?: DecoderOption & RouteOption, ): Promise { - return this.createWritePromise(createRandomKey(), { - route: toProtobufRoute(options?.route), - decoder: options?.decoder, - }); + return this.createWritePromise(createRandomKey(), options); } /** @@ -1454,8 +1341,8 @@ export class GlideClusterClient extends BaseClient { */ public async unwatch(options?: RouteOption): Promise<"OK"> { return this.createWritePromise(createUnWatch(), { - route: toProtobufRoute(options?.route), decoder: Decoder.String, + ...options, }); } } diff --git a/node/tests/GlideClient.test.ts b/node/tests/GlideClient.test.ts index 8efc797900..a56484f6fb 100644 --- a/node/tests/GlideClient.test.ts +++ b/node/tests/GlideClient.test.ts @@ -177,8 +177,12 @@ describe("GlideClient", () => { expect(result).toEqual("OK"); expect(await client.get(key)).toEqual(valueEncoded); - expect(await client.get(key, Decoder.String)).toEqual(value); - expect(await client.get(key, Decoder.Bytes)).toEqual(valueEncoded); + expect(await client.get(key, { decoder: Decoder.String })).toEqual( + value, + ); + expect(await client.get(key, { decoder: Decoder.Bytes })).toEqual( + valueEncoded, + ); client.close(); }, ); @@ -201,8 +205,12 @@ describe("GlideClient", () => { expect(result).toEqual("OK"); expect(await client.get(key)).toEqual(value); - expect(await client.get(key, Decoder.String)).toEqual(value); - expect(await client.get(key, Decoder.Bytes)).toEqual(valueEncoded); + expect(await client.get(key, { decoder: Decoder.String })).toEqual( + value, + ); + expect(await client.get(key, { decoder: Decoder.Bytes })).toEqual( + valueEncoded, + ); client.close(); }, ); @@ -236,7 +244,9 @@ describe("GlideClient", () => { const transaction = new Transaction(); const expectedRes = await encodedTransactionTest(transaction); transaction.select(0); - const result = await client.exec(transaction, Decoder.Bytes); + const result = await client.exec(transaction, { + decoder: Decoder.Bytes, + }); expectedRes.push(["select(0)", "OK"]); validateTransactionResponse(result, expectedRes); @@ -256,7 +266,9 @@ describe("GlideClient", () => { Buffer.from("value"), ); bytesTransaction.select(0); - const result = await client.exec(bytesTransaction, Decoder.Bytes); + const result = await client.exec(bytesTransaction, { + decoder: Decoder.Bytes, + }); expectedBytesRes.push(["select(0)", "OK"]); validateTransactionResponse(result, expectedBytesRes); @@ -267,7 +279,7 @@ describe("GlideClient", () => { // Since DUMP gets binary results, we cannot use the string decoder here, so we expected to get an error. await expect( - client.exec(stringTransaction, Decoder.String), + client.exec(stringTransaction, { decoder: Decoder.String }), ).rejects.toThrowError( "invalid utf-8 sequence of 1 bytes from index 9", ); @@ -671,7 +683,7 @@ describe("GlideClient", () => { Buffer.from(funcName), [], [Buffer.from("one"), "two"], - Decoder.Bytes, + { decoder: Decoder.Bytes }, ), ).toEqual(Buffer.from("one")); expect( @@ -679,7 +691,7 @@ describe("GlideClient", () => { Buffer.from(funcName), [], ["one", Buffer.from("two")], - Decoder.Bytes, + { decoder: Decoder.Bytes }, ), ).toEqual(Buffer.from("one")); @@ -1137,7 +1149,9 @@ describe("GlideClient", () => { // Verify functionDump let transaction = new Transaction().functionDump(); - const result = await client.exec(transaction, Decoder.Bytes); + const result = await client.exec(transaction, { + decoder: Decoder.Bytes, + }); const data = result?.[0] as Buffer; // Verify functionRestore @@ -1424,7 +1438,7 @@ describe("GlideClient", () => { // `key` should be the only key in the database expect(await client.randomKey()).toEqual(key); // test binary decoder - expect(await client.randomKey(Decoder.Bytes)).toEqual( + expect(await client.randomKey({ decoder: Decoder.Bytes })).toEqual( Buffer.from(key), ); diff --git a/node/tests/GlideClientInternals.test.ts b/node/tests/GlideClientInternals.test.ts index b2025b0cc8..84b4669808 100644 --- a/node/tests/GlideClientInternals.test.ts +++ b/node/tests/GlideClientInternals.test.ts @@ -310,7 +310,9 @@ describe("SocketConnectionInternals", () => { }, ); }); - const result = await connection.get("foo", Decoder.String); + const result = await connection.get("foo", { + decoder: Decoder.String, + }); expect(result).toEqual(expected); }); }; diff --git a/node/tests/GlideClusterClient.test.ts b/node/tests/GlideClusterClient.test.ts index d938d20c2b..59e4ed3ba6 100644 --- a/node/tests/GlideClusterClient.test.ts +++ b/node/tests/GlideClusterClient.test.ts @@ -260,9 +260,9 @@ describe("GlideClusterClient", () => { ).toEqual("OK"); // check the restore expect(await client.get(key)).toEqual(value); - expect(await client.get(key, Decoder.Bytes)).toEqual( - valueEncoded, - ); + expect( + await client.get(key, { decoder: Decoder.Bytes }), + ).toEqual(valueEncoded); } }, TIMEOUT, @@ -1182,7 +1182,9 @@ describe("GlideClusterClient", () => { // Delete the function expect( - await client.functionDelete(libName, route), + await client.functionDelete(libName, { + route, + }), ).toEqual("OK"); functionList = await client.functionList({ @@ -1198,7 +1200,7 @@ describe("GlideClusterClient", () => { // Delete a non-existing library await expect( - client.functionDelete(libName, route), + client.functionDelete(libName, { route }), ).rejects.toThrow(`Library not found`); } finally { expect(await client.functionFlush()).toEqual( @@ -1247,7 +1249,7 @@ describe("GlideClusterClient", () => { // nothing to kill await expect( - client.functionKill(route), + client.functionKill({ route }), ).rejects.toThrow(/notbusy/i); // load the lib @@ -1279,9 +1281,9 @@ describe("GlideClusterClient", () => { while (timeout >= 0) { try { expect( - await client.functionKill( + await client.functionKill({ route, - ), + }), ).toEqual("OK"); killed = true; break; @@ -1333,7 +1335,7 @@ describe("GlideClusterClient", () => { try { // dumping an empty lib - let response = await client.functionDump(route); + let response = await client.functionDump({ route }); if (singleNodeRoute) { expect(response.byteLength).toBeGreaterThan(0); @@ -1365,7 +1367,7 @@ describe("GlideClusterClient", () => { withCode: true, route: route, }); - response = await client.functionDump(route); + response = await client.functionDump({ route }); const dump = ( singleNodeRoute ? response @@ -1519,7 +1521,7 @@ describe("GlideClusterClient", () => { // nothing to kill await expect( - client.functionKill(route), + client.functionKill({ route }), ).rejects.toThrow(/notbusy/i); // load the lib @@ -1546,7 +1548,7 @@ describe("GlideClusterClient", () => { try { // valkey kills a function with 5 sec delay // but this will always throw an error in the test - await client.functionKill(route); + await client.functionKill({ route }); } catch (err) { // looking for an error with "unkillable" in the message // at that point we can break the loop diff --git a/node/tests/SharedTests.ts b/node/tests/SharedTests.ts index 31f756e93a..9892292d46 100644 --- a/node/tests/SharedTests.ts +++ b/node/tests/SharedTests.ts @@ -169,7 +169,9 @@ export function runBaseTests(config: { if (client instanceof GlideClient) { expect( - await client.clientGetName(Decoder.Bytes), + await client.clientGetName({ + decoder: Decoder.Bytes, + }), ).toEqual(Buffer.from("TEST_CLIENT")); } else { expect( @@ -396,7 +398,9 @@ export function runBaseTests(config: { expect( await client.mget( [key1Encoded, key2, "nonExistingKey", key3Encoded], - Decoder.Bytes, + { + decoder: Decoder.Bytes, + }, ), ).toEqual([valueEncoded, valueEncoded, null, valueEncoded]); }, protocol); @@ -1266,10 +1270,12 @@ export function runBaseTests(config: { expect(await client.getdel(key1)).toEqual(null); expect(await client.set(key1, value1)).toEqual("OK"); - expect(await client.getdel(key1, Decoder.Bytes)).toEqual( - value1Encoded, - ); - expect(await client.getdel(key1, Decoder.Bytes)).toEqual(null); + expect( + await client.getdel(key1, { decoder: Decoder.Bytes }), + ).toEqual(value1Encoded); + expect( + await client.getdel(key1, { decoder: Decoder.Bytes }), + ).toEqual(null); // key isn't a string expect(await client.sadd(key2, ["a"])).toEqual(1); @@ -1296,14 +1302,20 @@ export function runBaseTests(config: { // range of binary buffer expect(await client.set(key, "This is a string")).toEqual("OK"); - expect(await client.getrange(key, 0, 3, Decoder.Bytes)).toEqual( - valueEncoded.subarray(0, 4), - ); expect( - await client.getrange(key, -3, -1, Decoder.Bytes), + await client.getrange(key, 0, 3, { + decoder: Decoder.Bytes, + }), + ).toEqual(valueEncoded.subarray(0, 4)); + expect( + await client.getrange(key, -3, -1, { + decoder: Decoder.Bytes, + }), ).toEqual(valueEncoded.subarray(-3, valueEncoded.length)); expect( - await client.getrange(key, 0, -1, Decoder.Bytes), + await client.getrange(key, 0, -1, { + decoder: Decoder.Bytes, + }), ).toEqual(valueEncoded.subarray(0, valueEncoded.length)); // out of range @@ -1684,18 +1696,22 @@ export function runBaseTests(config: { expect(await client.set(key, value)).toEqual("OK"); expect(await client.get(key)).toEqual(value); - expect(await client.get(key, Decoder.Bytes)).toEqual( - valueEncoded, - ); - expect(await client.get(key, Decoder.String)).toEqual(value); + expect( + await client.get(key, { decoder: Decoder.Bytes }), + ).toEqual(valueEncoded); + expect( + await client.get(key, { decoder: Decoder.String }), + ).toEqual(value); // Setting the encoded value. Should behave as the previous test since the default is String decoding. expect(await client.set(key, valueEncoded)).toEqual("OK"); expect(await client.get(key)).toEqual(value); - expect(await client.get(key, Decoder.Bytes)).toEqual( - valueEncoded, - ); - expect(await client.get(key, Decoder.String)).toEqual(value); + expect( + await client.get(key, { decoder: Decoder.Bytes }), + ).toEqual(valueEncoded); + expect( + await client.get(key, { decoder: Decoder.String }), + ).toEqual(value); }, protocol); }, config.timeout, @@ -2121,21 +2137,23 @@ export function runBaseTests(config: { ); expect(await client.lpop("nonExistingKey")).toEqual(null); expect(await client.lpush(key2, valueList2)).toEqual(3); - expect(await client.lpop(key2, Decoder.Bytes)).toEqual( - Buffer.from("value5"), - ); - expect(await client.lrange(key2, 0, -1, Decoder.Bytes)).toEqual( - encodedValues, - ); - expect(await client.lpopCount(key2, 2, Decoder.Bytes)).toEqual( - encodedValues, - ); + expect( + await client.lpop(key2, { decoder: Decoder.Bytes }), + ).toEqual(Buffer.from("value5")); + expect( + await client.lrange(key2, 0, -1, { + decoder: Decoder.Bytes, + }), + ).toEqual(encodedValues); + expect( + await client.lpopCount(key2, 2, { decoder: Decoder.Bytes }), + ).toEqual(encodedValues); expect( await client.lpush(key2, [Buffer.from("value8")]), ).toEqual(1); - expect(await client.lpop(key2, Decoder.Bytes)).toEqual( - Buffer.from("value8"), - ); + expect( + await client.lpop(key2, { decoder: Decoder.Bytes }), + ).toEqual(Buffer.from("value8")); }, protocol); }, config.timeout, @@ -2333,7 +2351,7 @@ export function runBaseTests(config: { key2, ListDirection.RIGHT, ListDirection.LEFT, - Decoder.Bytes, + { decoder: Decoder.Bytes }, ), ).toEqual(Buffer.from("4")); @@ -2474,7 +2492,7 @@ export function runBaseTests(config: { ListDirection.RIGHT, ListDirection.LEFT, 0.1, - Decoder.Bytes, + { decoder: Decoder.Bytes }, ), ).toEqual(Buffer.from("4")); @@ -2700,19 +2718,18 @@ export function runBaseTests(config: { expect(await client.rpop("nonExistingKey")).toEqual(null); expect(await client.rpush(key2, valueList2)).toEqual(3); - expect(await client.rpop(key2, Decoder.Bytes)).toEqual( - Buffer.from("value7"), - ); - expect(await client.rpopCount(key2, 2, Decoder.Bytes)).toEqual([ - Buffer.from("value6"), - Buffer.from("value5"), - ]); + expect( + await client.rpop(key2, { decoder: Decoder.Bytes }), + ).toEqual(Buffer.from("value7")); + expect( + await client.rpopCount(key2, 2, { decoder: Decoder.Bytes }), + ).toEqual([Buffer.from("value6"), Buffer.from("value5")]); expect( await client.rpush(key2, [Buffer.from("value8")]), ).toEqual(1); - expect(await client.rpop(key2, Decoder.Bytes)).toEqual( - Buffer.from("value8"), - ); + expect( + await client.rpop(key2, { decoder: Decoder.Bytes }), + ).toEqual(Buffer.from("value8")); }, protocol); }, config.timeout, @@ -5844,24 +5861,25 @@ export function runBaseTests(config: { expect(await client.echo(message)).toEqual(message); expect( client instanceof GlideClient - ? await client.echo(message, Decoder.String) + ? await client.echo(message, { + decoder: Decoder.String, + }) : await client.echo(message, { decoder: Decoder.String, }), ).toEqual(message); expect( client instanceof GlideClient - ? await client.echo(message, Decoder.Bytes) + ? await client.echo(message, { decoder: Decoder.Bytes }) : await client.echo(message, { decoder: Decoder.Bytes, }), ).toEqual(Buffer.from(message)); expect( client instanceof GlideClient - ? await client.echo( - Buffer.from(message), - Decoder.String, - ) + ? await client.echo(Buffer.from(message), { + decoder: Decoder.String, + }) : await client.echo(Buffer.from(message), { decoder: Decoder.String, }), @@ -5929,12 +5947,16 @@ export function runBaseTests(config: { expect(await client.lindex(listName, 1)).toEqual(listKey1Value); expect(await client.lindex("notExsitingList", 1)).toEqual(null); expect(await client.lindex(listName, 3)).toEqual(null); - expect(await client.lindex(listName, 0, Decoder.Bytes)).toEqual( - Buffer.from(listKey2Value), - ); - expect(await client.lindex(listName, 1, Decoder.Bytes)).toEqual( - Buffer.from(listKey1Value), - ); + expect( + await client.lindex(listName, 0, { + decoder: Decoder.Bytes, + }), + ).toEqual(Buffer.from(listKey2Value)); + expect( + await client.lindex(listName, 1, { + decoder: Decoder.Bytes, + }), + ).toEqual(Buffer.from(listKey1Value)); expect(await client.lindex(encodedListName, 0)).toEqual( listKey2Value, ); @@ -6353,7 +6375,9 @@ export function runBaseTests(config: { ]); // Test encoded value expect( - await client.brpop(["brpop-test"], 0.1, Decoder.Bytes), + await client.brpop(["brpop-test"], 0.1, { + decoder: Decoder.Bytes, + }), ).toEqual([Buffer.from("brpop-test"), Buffer.from("bar")]); // Delete all values from list expect(await client.del(["brpop-test"])).toEqual(1); @@ -6394,7 +6418,9 @@ export function runBaseTests(config: { ]); // Test decoded value expect( - await client.blpop(["blpop-test"], 0.1, Decoder.Bytes), + await client.blpop(["blpop-test"], 0.1, { + decoder: Decoder.Bytes, + }), ).toEqual([Buffer.from("blpop-test"), Buffer.from("bar")]); // Delete all values from list expect(await client.del(["blpop-test"])).toEqual(1); @@ -7444,10 +7470,12 @@ export function runBaseTests(config: { // Restore to a new key without option expect(await client.restore(key2, 0, data)).toEqual("OK"); - expect(await client.get(key2, Decoder.String)).toEqual(value); - expect(await client.get(key2, Decoder.Bytes)).toEqual( - valueEncode, - ); + expect( + await client.get(key2, { decoder: Decoder.String }), + ).toEqual(value); + expect( + await client.get(key2, { decoder: Decoder.Bytes }), + ).toEqual(valueEncode); // Restore to an existing key await expect(client.restore(key2, 0, data)).rejects.toThrow( @@ -7531,10 +7559,9 @@ export function runBaseTests(config: { // Transaction tests let response = client instanceof GlideClient - ? await client.exec( - new Transaction().dump(key1), - Decoder.Bytes, - ) + ? await client.exec(new Transaction().dump(key1), { + decoder: Decoder.Bytes, + }) : await client.exec( new ClusterTransaction().dump(key1), { decoder: Decoder.Bytes }, @@ -7549,7 +7576,7 @@ export function runBaseTests(config: { new Transaction() .restore(key4, 0, data) .get(key4), - Decoder.String, + { decoder: Decoder.String }, ) : await client.exec( new ClusterTransaction() @@ -7567,7 +7594,7 @@ export function runBaseTests(config: { new Transaction() .restore(key5, 0, data) .get(key5), - Decoder.Bytes, + { decoder: Decoder.Bytes }, ) : await client.exec( new ClusterTransaction() @@ -7750,9 +7777,9 @@ export function runBaseTests(config: { expect(await client.append(key3, valueEncoded)).toBe( valueEncoded.length * 2, ); - expect(await client.get(key3, Decoder.Bytes)).toEqual( - Buffer.concat([valueEncoded, valueEncoded]), - ); + expect( + await client.get(key3, { decoder: Decoder.Bytes }), + ).toEqual(Buffer.concat([valueEncoded, valueEncoded])); }, protocol); }, config.timeout,