forked from microsoft/rushstack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLegacyAdapters.ts
More file actions
121 lines (114 loc) · 4.27 KB
/
LegacyAdapters.ts
File metadata and controls
121 lines (114 loc) · 4.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
import { sort as timsort } from 'timsort';
import * as semver from 'semver';
/**
* Callback used by {@link LegacyAdapters}.
* @public
*/
export type LegacyCallback<TResult, TError> = (error: TError | null | undefined, result: TResult) => void;
/**
* Helper functions used when interacting with APIs that do not follow modern coding practices.
* @public
*/
export class LegacyAdapters {
private static _useTimsort: boolean | undefined = undefined;
/**
* This function wraps a function with a callback in a promise.
*/
public static convertCallbackToPromise<TResult, TError>(
fn: (cb: LegacyCallback<TResult, TError>) => void
): Promise<TResult>;
public static convertCallbackToPromise<TResult, TError, TArg1>(
fn: (arg1: TArg1, cb: LegacyCallback<TResult, TError>) => void,
arg1: TArg1
): Promise<TResult>;
public static convertCallbackToPromise<TResult, TError, TArg1, TArg2>(
fn: (arg1: TArg1, arg2: TArg2, cb: LegacyCallback<TResult, TError>) => void,
arg1: TArg1,
arg2: TArg2
): Promise<TResult>;
public static convertCallbackToPromise<TResult, TError, TArg1, TArg2, TArg3>(
fn: (arg1: TArg1, arg2: TArg2, arg3: TArg3, cb: LegacyCallback<TResult, TError>) => void,
arg1: TArg1,
arg2: TArg2,
arg3: TArg3
): Promise<TResult>;
public static convertCallbackToPromise<TResult, TError, TArg1, TArg2, TArg3, TArg4>(
fn: (arg1: TArg1, arg2: TArg2, arg3: TArg3, arg4: TArg4, cb: LegacyCallback<TResult, TError>) => void,
arg1: TArg1,
arg2: TArg2,
arg3: TArg3,
arg4: TArg4
): Promise<TResult>;
public static convertCallbackToPromise<TResult, TError, TArg1, TArg2, TArg3, TArg4>(
fn: (
a: TArg1 | LegacyCallback<TResult, TError>,
b?: TArg2 | LegacyCallback<TResult, TError>,
c?: TArg3 | LegacyCallback<TResult, TError>,
d?: TArg4 | LegacyCallback<TResult, TError>,
e?: TArg4 | LegacyCallback<TResult, TError>
) => void,
arg1?: TArg1,
arg2?: TArg2,
arg3?: TArg3,
arg4?: TArg4
): Promise<TResult> {
return new Promise((resolve: (result: TResult) => void, reject: (error: Error) => void) => {
const cb: LegacyCallback<TResult, TError> = (error: TError | null | undefined, result: TResult) => {
if (error) {
reject(LegacyAdapters.scrubError(error));
} else {
resolve(result);
}
};
try {
if (arg1 !== undefined && arg2 !== undefined && arg3 !== undefined && arg4 !== undefined) {
fn(arg1, arg2, arg3, arg4, cb);
} else if (arg1 !== undefined && arg2 !== undefined && arg3 !== undefined) {
fn(arg1, arg2, arg3, cb);
} else if (arg1 !== undefined && arg2 !== undefined ) {
fn(arg1, arg2, cb);
} else if (arg1 !== undefined ) {
fn(arg1, cb);
} else {
fn(cb);
}
} catch (e) {
reject(e);
}
});
}
/**
* Normalizes an object into an `Error` object.
*/
public static scrubError(error: Error | string | any): Error { // eslint-disable-line @typescript-eslint/no-explicit-any
if (error instanceof Error) {
return error;
} else if (typeof error === 'string') {
return new Error(error);
} else {
const errorObject: Error = new Error('An error occurred.');
(errorObject as any).errorData = error; // eslint-disable-line @typescript-eslint/no-explicit-any
return errorObject;
}
}
/**
* Prior to Node 11.x, the `Array.sort()` algorithm is not guaranteed to be stable.
* If you need a stable sort, you can use `sortStable()` as a workaround.
*
* @remarks
* On NodeJS 11.x and later, this method simply calls the native `Array.sort()`.
* For earlier versions, it uses an implementation of Timsort, which is the same algorithm used by modern NodeJS.
*/
public static sortStable<T>(array: T[], compare?: (a: T, b: T) => number): void {
if (LegacyAdapters._useTimsort === undefined) {
LegacyAdapters._useTimsort = semver.major(process.versions.node) < 11;
}
if (LegacyAdapters._useTimsort) {
timsort(array, compare);
} else {
Array.prototype.sort.call(array, compare);
}
}
}