-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathvalues.ts
144 lines (134 loc) · 4.34 KB
/
values.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
132
133
134
135
136
137
138
139
140
141
142
143
144
import { createHash } from 'node:crypto';
import { isArrayBufferView } from 'node:util/types';
export const isDevEnv = process.env.NODE_ENV === 'development';
export const isTestEnv = process.env.NODE_ENV === 'test';
export const isProdEnv =
process.env.NODE_ENV === 'production' ||
process.env.NODE_ENV === 'prod' ||
!process.env.NODE_ENV ||
(!isTestEnv && !isDevEnv);
/**
* Digests a string value into a SHA256 hash.
* @param content - String input
* @returns Hashed value
*/
export function sha256(content: string) {
return createHash('sha256').update(content).digest('hex');
}
/**
* Parses a boolean string using conventions from CLI arguments, URL query params, and environmental
* variables. If the input is defined but empty string then true is returned. If the input is
* undefined or null than false is returned. For example, if the input comes from a CLI arg like
* `--enable_thing` or URL query param like `?enable_thing`, then this function expects to receive a
* defined but empty string, and returns true. Otherwise, it checks or values like `true`, `1`,
* `on`, `yes` (and the inverses). Throws if an unexpected input value is provided.
*/
export function parseBoolean(val: string | undefined | null): boolean {
if (typeof val === 'undefined' || val === null) {
return false;
}
switch (val.trim().toLowerCase()) {
case '':
case 'true':
case '1':
case 'on':
case 'yes':
return true;
case 'false':
case '0':
case 'off':
case 'no':
return false;
default:
throw new Error(`Cannot parse boolean`);
}
}
/**
* Encodes a buffer as a `0x` prefixed lower-case hex string. Returns an empty string if the buffer
* is zero length.
*/
export function bufferToHex(buff: Buffer, prefix: boolean = true): string {
return buff.length === 0 ? '' : (prefix ? '0x' : '') + buff.toString('hex');
}
/**
* Decodes a `0x` prefixed hex string to a buffer.
* @param hex - A hex string with a `0x` prefix.
*/
export function hexToBuffer(hex: string): Buffer {
if (hex.length === 0) {
return Buffer.alloc(0);
}
if (!hex.startsWith('0x')) {
throw new Error(`Hex string is missing the "0x" prefix`);
}
if (hex.length % 2 !== 0) {
throw new Error(`Hex string is an odd number of digits`);
}
return Buffer.from(hex.substring(2), 'hex');
}
/**
* Decodes a hex string to a Buffer, trims the 0x-prefix if exists.
* If already a buffer, returns the input immediately.
*/
export function coerceToBuffer(hex: string | Buffer | ArrayBufferView): Buffer {
if (typeof hex === 'string') {
if (hex.startsWith('0x')) {
hex = hex.substring(2);
}
if (hex.length % 2 !== 0) {
throw new Error(`Hex string is an odd number of characters`);
}
if (!/^[0-9a-fA-F]*$/.test(hex)) {
throw new Error(`Hex string contains non-hexadecimal characters`);
}
return Buffer.from(hex, 'hex');
} else if (Buffer.isBuffer(hex)) {
return hex;
} else if (isArrayBufferView(hex)) {
return Buffer.from(hex.buffer, hex.byteOffset, hex.byteLength);
} else {
throw new Error(`Cannot convert to Buffer, unexpected type: ${hex.constructor.name}`);
}
}
/**
* Converts a hex string into a UTF-8 string.
* @param hex - Hex string
* @returns UTF-8 string
*/
export function hexToUtf8String(hex: string): string {
const buffer = hexToBuffer(hex);
return buffer.toString('utf8');
}
/**
* Converts a number to a hex string.
* @param number - Number
* @param paddingBytes - Padding bytes
* @returns Hex string
*/
export function numberToHex(number: number, paddingBytes: number = 4): string {
let result = number.toString(16);
if (result.length % 2 > 0) {
result = '0' + result;
}
if (paddingBytes && result.length / 2 < paddingBytes) {
result = '00'.repeat(paddingBytes - result.length / 2) + result;
}
return '0x' + result;
}
/**
* Checks if a string has `0x` prefix.
* @param val - Hex string
* @returns Boolean
*/
export const has0xPrefix = (val: string) => val.substring(0, 2).toLowerCase() === '0x';
/**
* Converts a string to an enum value.
* @param enumType - The enum type
* @param value - The string value to convert
* @returns Enum item or undefined
*/
export function toEnumValue<T>(enm: { [s: string]: T }, value: string): T | undefined {
return (Object.values(enm) as unknown as string[]).includes(value)
? (value as unknown as T)
: undefined;
}