Skip to content

Commit 4e8c567

Browse files
committed
fix: improve typing for auto pipelining
1 parent 2001ec6 commit 4e8c567

File tree

5 files changed

+75
-125
lines changed

5 files changed

+75
-125
lines changed

Diff for: lib/autoPipelining.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { flatten, isArguments, noop } from "./utils/lodash";
22
import * as calculateSlot from "cluster-key-slot";
33
import asCallback from "standard-as-callback";
4+
import { ArgumentType } from "./command";
45

56
export const kExec = Symbol("exec");
67
export const kCallbacks = Symbol("callbacks");
@@ -92,7 +93,7 @@ export function shouldUseAutoPipelining(
9293
* @private
9394
*/
9495
export function getFirstValueInFlattenedArray(
95-
args: (string | string[])[]
96+
args: ArgumentType[]
9697
): string | undefined {
9798
for (let i = 0; i < args.length; i++) {
9899
const arg = args[i];
@@ -106,7 +107,7 @@ export function getFirstValueInFlattenedArray(
106107
}
107108
const flattened = flatten([arg]);
108109
if (flattened.length > 0) {
109-
return flattened[0];
110+
return String(flattened[0]);
110111
}
111112
}
112113
return undefined;
@@ -116,7 +117,7 @@ export function executeWithAutoPipelining(
116117
client,
117118
functionName: string,
118119
commandName: string,
119-
args: (string | string[])[],
120+
args: ArgumentType[],
120121
callback
121122
) {
122123
// On cluster mode let's wait for slots to be available

Diff for: lib/command.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ import {
1111
import { flatten } from "./utils/lodash";
1212
import { CallbackFunction, ICommand, CommandParameter } from "./types";
1313

14+
export type ArgumentType =
15+
| string
16+
| Buffer
17+
| number
18+
| (string | Buffer | number | any[])[];
19+
1420
interface ICommandOptions {
1521
/**
1622
* Set the encoding of the reply, by default buffer will be returned.
@@ -179,9 +185,7 @@ export default class Command implements ICommand {
179185
*/
180186
constructor(
181187
public name: string,
182-
args: Array<
183-
string | Buffer | number | Array<string | Buffer | number | any[]>
184-
> = [],
188+
args: Array<ArgumentType> = [],
185189
options: ICommandOptions = {},
186190
callback?: CallbackFunction
187191
) {

Diff for: lib/utils/Commander.ts

+17-16
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import {
33
executeWithAutoPipelining,
44
shouldUseAutoPipelining,
55
} from "../autoPipelining";
6-
import Command from "../command";
6+
import Command, { ArgumentType } from "../command";
77
import Script from "../script";
8-
import { NetStream } from "../types";
8+
import { CallbackFunction, NetStream } from "../types";
99

1010
export interface CommanderOptions {
1111
keyPrefix?: string;
@@ -33,18 +33,13 @@ class Commander {
3333

3434
/**
3535
* Return supported builtin commands
36-
*
37-
* @return {string[]} command list
3836
*/
3937
getBuiltinCommands() {
4038
return commands.slice(0);
4139
}
4240

4341
/**
4442
* Create a builtin command
45-
*
46-
* @param {string} commandName - command name
47-
* @return {object} functions
4843
*/
4944
createBuiltinCommand(commandName: string) {
5045
return {
@@ -69,14 +64,16 @@ class Commander {
6964
/**
7065
* Define a custom command using lua script
7166
*
72-
* @param {string} name - the command name
7367
* @param {object} definition
7468
* @param {string} definition.lua - the lua code
7569
* @param {number} [definition.numberOfKeys=null] - the number of keys.
7670
* @param {boolean} [definition.readOnly=false] - force this script to be readonly so it executes on slaves as well.
7771
* If omit, you have to pass the number of keys as the first argument every time you invoke the command
7872
*/
79-
defineCommand(name, definition) {
73+
defineCommand(
74+
name: string,
75+
definition: { lua: string; numberOfKeys?: number; readOnly?: boolean }
76+
) {
8077
const script = new Script(
8178
definition.lua,
8279
definition.numberOfKeys,
@@ -139,8 +136,10 @@ function generateFunction(
139136
_commandName = null;
140137
}
141138

142-
return function (...args) {
143-
const commandName = _commandName || args.shift();
139+
return function (
140+
...args: ArgumentType[] | [...ArgumentType[], CallbackFunction]
141+
) {
142+
const commandName = (_commandName || args.shift()) as string;
144143
let callback = args[args.length - 1];
145144

146145
if (typeof callback === "function") {
@@ -158,13 +157,14 @@ function generateFunction(
158157
if (this.options.dropBufferSupport && !_encoding) {
159158
return asCallback(
160159
Promise.reject(new Error(DROP_BUFFER_SUPPORT_ERROR)),
161-
callback
160+
callback as CallbackFunction | undefined
162161
);
163162
}
164163

165164
// No auto pipeline, use regular command sending
166165
if (!shouldUseAutoPipelining(this, functionName, commandName)) {
167166
return this.sendCommand(
167+
// @ts-expect-error
168168
new Command(commandName, args, options, callback)
169169
);
170170
}
@@ -174,17 +174,18 @@ function generateFunction(
174174
this,
175175
functionName,
176176
commandName,
177+
// @ts-expect-error
177178
args,
178179
callback
179180
);
180181
};
181182
}
182183

183184
function generateScriptingFunction(
184-
functionName,
185-
commandName,
186-
script,
187-
encoding
185+
functionName: string,
186+
commandName: string,
187+
script: Script,
188+
encoding: unknown
188189
) {
189190
return function () {
190191
let length = arguments.length;

Diff for: lib/utils/index.ts

+9-59
Original file line numberDiff line numberDiff line change
@@ -5,44 +5,15 @@ import Debug from "./debug";
55

66
import TLSProfiles from "../constants/TLSProfiles";
77

8-
/**
9-
* Test if two buffers are equal
10-
*
11-
* @export
12-
* @param {Buffer} a
13-
* @param {Buffer} b
14-
* @returns {boolean} Whether the two buffers are equal
15-
*/
16-
export function bufferEqual(a: Buffer, b: Buffer): boolean {
17-
if (typeof a.equals === "function") {
18-
return a.equals(b);
19-
}
20-
21-
if (a.length !== b.length) {
22-
return false;
23-
}
24-
25-
for (let i = 0; i < a.length; ++i) {
26-
if (a[i] !== b[i]) {
27-
return false;
28-
}
29-
}
30-
return true;
31-
}
32-
338
/**
349
* Convert a buffer to string, supports buffer array
3510
*
36-
* @param {*} value - The input value
37-
* @param {string} encoding - string encoding
38-
* @return {*} The result
3911
* @example
4012
* ```js
41-
* var input = [Buffer.from('foo'), [Buffer.from('bar')]]
42-
* var res = convertBufferToString(input, 'utf8')
13+
* const input = [Buffer.from('foo'), [Buffer.from('bar')]]
14+
* const res = convertBufferToString(input, 'utf8')
4315
* expect(res).to.eql(['foo', ['bar']])
4416
* ```
45-
* @private
4617
*/
4718
export function convertBufferToString(value: any, encoding?: string) {
4819
if (value instanceof Buffer) {
@@ -65,17 +36,14 @@ export function convertBufferToString(value: any, encoding?: string) {
6536
/**
6637
* Convert a list of results to node-style
6738
*
68-
* @param {Array} arr - The input value
69-
* @return {Array} The output value
7039
* @example
7140
* ```js
72-
* var input = ['a', 'b', new Error('c'), 'd']
73-
* var output = exports.wrapMultiResult(input)
41+
* const input = ['a', 'b', new Error('c'), 'd']
42+
* const output = exports.wrapMultiResult(input)
7443
* expect(output).to.eql([[null, 'a'], [null, 'b'], [new Error('c')], [null, 'd'])
7544
* ```
76-
* @private
7745
*/
78-
export function wrapMultiResult(arr: any[] | null): any[][] {
46+
export function wrapMultiResult(arr: unknown[] | null): unknown[][] {
7947
// When using WATCH/EXEC transactions, the EXEC will return
8048
// a null instead of an array
8149
if (!arr) {
@@ -96,9 +64,6 @@ export function wrapMultiResult(arr: any[] | null): any[][] {
9664

9765
/**
9866
* Detect if the argument is a int
99-
*
100-
* @param {string} value
101-
* @return {boolean} Whether the value is a int
10267
* @example
10368
* ```js
10469
* > isInt('123')
@@ -122,8 +87,6 @@ export function isInt(value: any): value is string {
12287
/**
12388
* Pack an array to an Object
12489
*
125-
* @param {array} array
126-
* @return {object}
12790
* @example
12891
* ```js
12992
* > packObject(['a', 'b', 'c', 'd'])
@@ -143,10 +106,6 @@ export function packObject(array: any[]): Record<string, any> {
143106

144107
/**
145108
* Return a callback with timeout
146-
*
147-
* @param {function} callback
148-
* @param {number} timeout
149-
* @return {function}
150109
*/
151110
export function timeout(callback: CallbackFunction, timeout: number) {
152111
let timer: NodeJS.Timeout;
@@ -163,9 +122,6 @@ export function timeout(callback: CallbackFunction, timeout: number) {
163122

164123
/**
165124
* Convert an object to an array
166-
*
167-
* @param {object} obj
168-
* @return {array}
169125
* @example
170126
* ```js
171127
* > convertObjectToArray({ a: '1' })
@@ -174,7 +130,7 @@ export function timeout(callback: CallbackFunction, timeout: number) {
174130
*/
175131
export function convertObjectToArray<T>(
176132
obj: Record<string, T>
177-
): Array<string | T> {
133+
): (string | T)[] {
178134
const result = [];
179135
const keys = Object.keys(obj); // Object.entries requires node 7+
180136

@@ -186,16 +142,13 @@ export function convertObjectToArray<T>(
186142

187143
/**
188144
* Convert a map to an array
189-
*
190-
* @param {Map} map
191-
* @return {array}
192145
* @example
193146
* ```js
194147
* > convertMapToArray(new Map([[1, '2']]))
195148
* [1, '2']
196149
* ```
197150
*/
198-
export function convertMapToArray<K, V>(map: Map<K, V>): Array<K | V> {
151+
export function convertMapToArray<K, V>(map: Map<K, V>): (K | V)[] {
199152
const result: Array<K | V> = [];
200153
let pos = 0;
201154
map.forEach(function (value, key) {
@@ -208,9 +161,6 @@ export function convertMapToArray<K, V>(map: Map<K, V>): Array<K | V> {
208161

209162
/**
210163
* Convert a non-string arg to a string
211-
*
212-
* @param {*} arg
213-
* @return {string}
214164
*/
215165
export function toArg(arg: any): string {
216166
if (arg === null || typeof arg === "undefined") {
@@ -298,7 +248,7 @@ export function parseURL(url: string) {
298248
return result;
299249
}
300250

301-
interface ITLSOptions {
251+
interface TLSOptions {
302252
port: number;
303253
host: string;
304254
[key: string]: any;
@@ -310,7 +260,7 @@ interface ITLSOptions {
310260
* @param {Object} options - the redis connection options
311261
* @return {Object}
312262
*/
313-
export function resolveTLSProfile(options: ITLSOptions): ITLSOptions {
263+
export function resolveTLSProfile(options: TLSOptions): TLSOptions {
314264
let tls = options?.tls;
315265

316266
if (typeof tls === "string") tls = { profile: tls };

0 commit comments

Comments
 (0)