/
_utils.ts
131 lines (120 loc) · 4.16 KB
/
_utils.ts
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
122
123
124
125
126
127
128
129
130
131
export function notImplemented(msg?: string): never {
const message = msg ? `Not implemented: ${msg}` : "Not implemented";
throw new Error(message);
}
export type _TextDecoder = typeof TextDecoder.prototype;
export const _TextDecoder = TextDecoder;
export type _TextEncoder = typeof TextEncoder.prototype;
export const _TextEncoder = TextEncoder;
// API helpers
export type MaybeNull<T> = T | null;
export type MaybeDefined<T> = T | undefined;
export type MaybeEmpty<T> = T | null | undefined;
export function intoCallbackAPI<T>(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
func: (...args: any[]) => Promise<T>,
cb: MaybeEmpty<(err: MaybeNull<Error>, value: MaybeEmpty<T>) => void>,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
...args: any[]
): void {
func(...args)
.then((value) => cb && cb(null, value))
.catch((err) => cb && cb(err, null));
}
export function intoCallbackAPIWithIntercept<T1, T2>(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
func: (...args: any[]) => Promise<T1>,
interceptor: (v: T1) => T2,
cb: MaybeEmpty<(err: MaybeNull<Error>, value: MaybeEmpty<T2>) => void>,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
...args: any[]
): void {
func(...args)
.then((value) => cb && cb(null, interceptor(value)))
.catch((err) => cb && cb(err, null));
}
export function spliceOne(list: string[], index: number): void {
for (; index + 1 < list.length; index++) list[index] = list[index + 1];
list.pop();
}
// Taken from: https://github.com/nodejs/node/blob/ba684805b6c0eded76e5cd89ee00328ac7a59365/lib/internal/util.js#L125
// Return undefined if there is no match.
// Move the "slow cases" to a separate function to make sure this function gets
// inlined properly. That prioritizes the common case.
export function normalizeEncoding(enc: string | null): string | undefined {
if (enc == null || enc === "utf8" || enc === "utf-8") return "utf8";
return slowCases(enc);
}
// https://github.com/nodejs/node/blob/ba684805b6c0eded76e5cd89ee00328ac7a59365/lib/internal/util.js#L130
function slowCases(enc: string): string | undefined {
switch (enc.length) {
case 4:
if (enc === "UTF8") return "utf8";
if (enc === "ucs2" || enc === "UCS2") return "utf16le";
enc = `${enc}`.toLowerCase();
if (enc === "utf8") return "utf8";
if (enc === "ucs2") return "utf16le";
break;
case 3:
if (enc === "hex" || enc === "HEX" || `${enc}`.toLowerCase() === "hex") {
return "hex";
}
break;
case 5:
if (enc === "ascii") return "ascii";
if (enc === "ucs-2") return "utf16le";
if (enc === "UTF-8") return "utf8";
if (enc === "ASCII") return "ascii";
if (enc === "UCS-2") return "utf16le";
enc = `${enc}`.toLowerCase();
if (enc === "utf-8") return "utf8";
if (enc === "ascii") return "ascii";
if (enc === "ucs-2") return "utf16le";
break;
case 6:
if (enc === "base64") return "base64";
if (enc === "latin1" || enc === "binary") return "latin1";
if (enc === "BASE64") return "base64";
if (enc === "LATIN1" || enc === "BINARY") return "latin1";
enc = `${enc}`.toLowerCase();
if (enc === "base64") return "base64";
if (enc === "latin1" || enc === "binary") return "latin1";
break;
case 7:
if (
enc === "utf16le" ||
enc === "UTF16LE" ||
`${enc}`.toLowerCase() === "utf16le"
) {
return "utf16le";
}
break;
case 8:
if (
enc === "utf-16le" ||
enc === "UTF-16LE" ||
`${enc}`.toLowerCase() === "utf-16le"
) {
return "utf16le";
}
break;
default:
if (enc === "") return "utf8";
}
}
export function validateIntegerRange(
value: number,
name: string,
min = -2147483648,
max = 2147483647,
): void {
// The defaults for min and max correspond to the limits of 32-bit integers.
if (!Number.isInteger(value)) {
throw new Error(`${name} must be 'an integer' but was ${value}`);
}
if (value < min || value > max) {
throw new Error(
`${name} must be >= ${min} && <= ${max}. Value was ${value}`,
);
}
}