@metamask/utils 3.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,91 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [3.2.0]
10
+ ### Added
11
+ - Add `PendingJsonRpcResponse` type ([#43](https://github.com/MetaMask/utils/pull/43))
12
+ - Add utils for converting between numbers and hex ([#41](https://github.com/MetaMask/utils/pull/41))
13
+ - Add coercion utils ([#38](https://github.com/MetaMask/utils/pull/38))
14
+
15
+ ## [3.1.0]
16
+ ### Added
17
+ - Add assertion utils ([#33](https://github.com/MetaMask/utils/pull/33))
18
+ - Add util functions for encoding and decoding bytes ([#34](https://github.com/MetaMask/utils/pull/34))
19
+
20
+ ### Fixed
21
+ - Make JSON-RPC error `data` property optional ([#31](https://github.com/MetaMask/utils/pull/31))
22
+ - Don't include test files in dist folder ([#35](https://github.com/MetaMask/utils/pull/35))
23
+ - Fix typo in README ([#28](https://github.com/MetaMask/utils/pull/28))
24
+
25
+ ## [3.0.3]
26
+ ### Fixed
27
+ - Allow omitting JSON-RPC params when params can be undefined ([#29](https://github.com/MetaMask/utils/pull/29))
28
+
29
+ ## [3.0.2]
30
+ ### Fixed
31
+ - Bump `superstruct` to ^0.16.5 ([#26](https://github.com/MetaMask/utils/pull/26))
32
+ - `superstruct`s 0.16.1 through 0.16.4 were not compatible with Node 14; this restores that compatibility.
33
+
34
+ ## [3.0.1]
35
+ ### Fixed
36
+ - Promote `@types/debug` from development dependencies to production dependencies ([#23](https://github.com/MetaMask/utils/pull/23))
37
+
38
+ ## [3.0.0]
39
+ ### Added
40
+ - Add logging functions ([#20](https://github.com/MetaMask/utils/pull/20))
41
+ - Add frozen collections (implemented in [#5](https://github.com/MetaMask/utils/pull/5) but exported in [#19](https://github.com/MetaMask/utils/pull/19))
42
+
43
+ ### Changed
44
+ - **BREAKING:** Improve types and type validation ([#19](https://github.com/MetaMask/utils/pull/19))
45
+ - Various type changes have been made that might be breaking:
46
+ - The `JsonRpcRequest` and `JsonRpcNotification` types now include a generic constraint requiring that the `Params` type extends the `JsonRpcParams` type.
47
+ - The `JsonRpcSuccess` and `JsonRpcResponse` types now include a generic contraint for the `Result` type, requiring that it extends the `Json` type.
48
+ - Various validation functions now accept `unknown` parameters rather than specific types. This should not be breaking except that it may affect type inference for the parameters passed in.
49
+ - New JSON-related functions have been added:
50
+ - `assertIsJsonRpcResponse`
51
+ - `isJsonRpcResponse`
52
+ - `InferWithParams`
53
+ - `JsonRpcParams`
54
+ - New JSON Struct types have been added:
55
+ - `JsonRpcErrorStruct`
56
+ - `JsonRpcFailureStruct`
57
+ - `JsonRpcIdStruct`
58
+ - `JsonRpcParamsStruct`
59
+ - `JsonRpcRequestStruct`
60
+ - `JsonRpcResponseStruct`
61
+ - `JsonRpcSuccessStruct`
62
+ - `JsonRpcVersionStruct`
63
+ - `JsonStruct`
64
+
65
+ ## [2.1.0]
66
+ ### Added
67
+ - Add JSON storage validation and limit utilities ([#14](https://github.com/MetaMask/utils/pull/14))
68
+ - Adds a new function `validateJsonAndGetSize`.
69
+
70
+ ## [2.0.0]
71
+ ### Added
72
+ - Add more JSON utils ([#8](https://github.com/MetaMask/utils/pull/8))
73
+
74
+ ### Changed
75
+ - **BREAKING:** Refactor and expand time utils ([#9](https://github.com/MetaMask/utils/pull/9))
76
+ - Adds a new function, `inMilliseconds`, and moves the time constants into a TypeScript `enum`.
77
+
78
+ ## [1.0.0]
79
+ ### Added
80
+ - Initial release
81
+
82
+ [Unreleased]: https://github.com/MetaMask/utils/compare/v3.2.0...HEAD
83
+ [3.2.0]: https://github.com/MetaMask/utils/compare/v3.1.0...v3.2.0
84
+ [3.1.0]: https://github.com/MetaMask/utils/compare/v3.0.3...v3.1.0
85
+ [3.0.3]: https://github.com/MetaMask/utils/compare/v3.0.2...v3.0.3
86
+ [3.0.2]: https://github.com/MetaMask/utils/compare/v3.0.1...v3.0.2
87
+ [3.0.1]: https://github.com/MetaMask/utils/compare/v3.0.0...v3.0.1
88
+ [3.0.0]: https://github.com/MetaMask/utils/compare/v2.1.0...v3.0.0
89
+ [2.1.0]: https://github.com/MetaMask/utils/compare/v2.0.0...v2.1.0
90
+ [2.0.0]: https://github.com/MetaMask/utils/compare/v1.0.0...v2.0.0
91
+ [1.0.0]: https://github.com/MetaMask/utils/releases/tag/v1.0.0
package/dist/bytes.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { Hex } from './hex';
1
2
  export declare type Bytes = bigint | number | string | Uint8Array;
2
3
  /**
3
4
  * Check if a value is a `Uint8Array`.
@@ -19,7 +20,7 @@ export declare function assertIsBytes(value: unknown): asserts value is Uint8Arr
19
20
  * @param bytes - The bytes to convert to a hexadecimal string.
20
21
  * @returns The hexadecimal string.
21
22
  */
22
- export declare function bytesToHex(bytes: Uint8Array): string;
23
+ export declare function bytesToHex(bytes: Uint8Array): Hex;
23
24
  /**
24
25
  * Convert a `Uint8Array` to a `bigint`.
25
26
  *
@@ -64,6 +65,8 @@ export declare function bytesToString(bytes: Uint8Array): string;
64
65
  * Convert a hexadecimal string to a `Uint8Array`. The string can optionally be
65
66
  * prefixed with `0x`. It accepts even and odd length strings.
66
67
  *
68
+ * If the value is "0x", an empty `Uint8Array` is returned.
69
+ *
67
70
  * @param value - The hexadecimal string to convert to bytes.
68
71
  * @returns The bytes as `Uint8Array`.
69
72
  */
@@ -112,6 +115,10 @@ export declare function stringToBytes(value: string): Uint8Array;
112
115
  * Convert a byte-like value to a `Uint8Array`. The value can be a `Uint8Array`,
113
116
  * a `bigint`, a `number`, or a `string`.
114
117
  *
118
+ * This will attempt to guess the type of the value based on its type and
119
+ * contents. For more control over the conversion, use the more specific
120
+ * conversion functions, such as {@link hexToBytes} or {@link stringToBytes}.
121
+ *
115
122
  * If the value is a `string`, and it is prefixed with `0x`, it will be
116
123
  * interpreted as a hexadecimal string. Otherwise, it will be interpreted as a
117
124
  * UTF-8 string. To convert a hexadecimal string to bytes without interpreting
package/dist/bytes.js CHANGED
@@ -70,6 +70,9 @@ exports.assertIsBytes = assertIsBytes;
70
70
  */
71
71
  function bytesToHex(bytes) {
72
72
  assertIsBytes(bytes);
73
+ if (bytes.length === 0) {
74
+ return '0x';
75
+ }
73
76
  const lookupTable = getPrecomputedHexValues();
74
77
  const hex = new Array(bytes.length);
75
78
  for (let i = 0; i < bytes.length; i++) {
@@ -140,17 +143,24 @@ exports.bytesToNumber = bytesToNumber;
140
143
  */
141
144
  function bytesToString(bytes) {
142
145
  assertIsBytes(bytes);
143
- return new TextDecoder(undefined).decode(bytes);
146
+ return new TextDecoder().decode(bytes);
144
147
  }
145
148
  exports.bytesToString = bytesToString;
146
149
  /**
147
150
  * Convert a hexadecimal string to a `Uint8Array`. The string can optionally be
148
151
  * prefixed with `0x`. It accepts even and odd length strings.
149
152
  *
153
+ * If the value is "0x", an empty `Uint8Array` is returned.
154
+ *
150
155
  * @param value - The hexadecimal string to convert to bytes.
151
156
  * @returns The bytes as `Uint8Array`.
152
157
  */
153
158
  function hexToBytes(value) {
159
+ var _a;
160
+ // "0x" is often used as empty byte array.
161
+ if (((_a = value === null || value === void 0 ? void 0 : value.toLowerCase) === null || _a === void 0 ? void 0 : _a.call(value)) === '0x') {
162
+ return new Uint8Array();
163
+ }
154
164
  (0, hex_1.assertIsHexString)(value);
155
165
  // Remove the `0x` prefix if it exists, and pad the string to have an even
156
166
  // number of characters.
@@ -267,6 +277,10 @@ exports.stringToBytes = stringToBytes;
267
277
  * Convert a byte-like value to a `Uint8Array`. The value can be a `Uint8Array`,
268
278
  * a `bigint`, a `number`, or a `string`.
269
279
  *
280
+ * This will attempt to guess the type of the value based on its type and
281
+ * contents. For more control over the conversion, use the more specific
282
+ * conversion functions, such as {@link hexToBytes} or {@link stringToBytes}.
283
+ *
270
284
  * If the value is a `string`, and it is prefixed with `0x`, it will be
271
285
  * interpreted as a hexadecimal string. Otherwise, it will be interpreted as a
272
286
  * UTF-8 string. To convert a hexadecimal string to bytes without interpreting
package/dist/bytes.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bytes.js","sourceRoot":"","sources":["../src/bytes.ts"],"names":[],"mappings":"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","sourcesContent":["import { assert } from './assert';\nimport { add0x, assertIsHexString, remove0x } from './hex';\n\n// '0'.charCodeAt(0) === 48\nconst HEX_MINIMUM_NUMBER_CHARACTER = 48;\n\n// '9'.charCodeAt(0) === 57\nconst HEX_MAXIMUM_NUMBER_CHARACTER = 58;\nconst HEX_CHARACTER_OFFSET = 87;\n\nexport type Bytes = bigint | number | string | Uint8Array;\n\n/**\n * Memoized function that returns an array to be used as a lookup table for\n * converting bytes to hexadecimal values.\n *\n * The array is created lazily and then cached for future use. The benefit of\n * this approach is that the performance of converting bytes to hex is much\n * better than if we were to call `toString(16)` on each byte.\n *\n * The downside is that the array is created once and then never garbage\n * collected. This is not a problem in practice because the array is only 256\n * elements long.\n *\n * @returns A function that returns the lookup table.\n */\nfunction getPrecomputedHexValuesBuilder(): () => string[] {\n // To avoid issues with tree shaking, we need to use a function to return the\n // array. This is because the array is only used in the `bytesToHex` function\n // and if we were to use a global variable, the array might be removed by the\n // tree shaker.\n const lookupTable: string[] = [];\n\n return () => {\n if (lookupTable.length === 0) {\n for (let i = 0; i < 256; i++) {\n lookupTable.push(i.toString(16).padStart(2, '0'));\n }\n }\n\n return lookupTable;\n };\n}\n\n/**\n * Function implementation of the {@link getPrecomputedHexValuesBuilder}\n * function.\n */\nconst getPrecomputedHexValues = getPrecomputedHexValuesBuilder();\n\n/**\n * Check if a value is a `Uint8Array`.\n *\n * @param value - The value to check.\n * @returns Whether the value is a `Uint8Array`.\n */\nexport function isBytes(value: unknown): value is Uint8Array {\n return value instanceof Uint8Array;\n}\n\n/**\n * Assert that a value is a `Uint8Array`.\n *\n * @param value - The value to check.\n * @throws If the value is not a `Uint8Array`.\n */\nexport function assertIsBytes(value: unknown): asserts value is Uint8Array {\n assert(isBytes(value), 'Value must be a Uint8Array.');\n}\n\n/**\n * Convert a `Uint8Array` to a hexadecimal string.\n *\n * @param bytes - The bytes to convert to a hexadecimal string.\n * @returns The hexadecimal string.\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n assertIsBytes(bytes);\n\n const lookupTable = getPrecomputedHexValues();\n const hex = new Array(bytes.length);\n\n for (let i = 0; i < bytes.length; i++) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n hex[i] = lookupTable[bytes[i]!];\n }\n\n return add0x(hex.join(''));\n}\n\n/**\n * Convert a `Uint8Array` to a `bigint`.\n *\n * To convert a `Uint8Array` to a `number` instead, use {@link bytesToNumber}.\n * To convert a two's complement encoded `Uint8Array` to a `bigint`, use\n * {@link bytesToSignedBigInt}.\n *\n * @param bytes - The bytes to convert to a `bigint`.\n * @returns The `bigint`.\n */\nexport function bytesToBigInt(bytes: Uint8Array): bigint {\n assertIsBytes(bytes);\n\n const hex = bytesToHex(bytes);\n return BigInt(hex);\n}\n\n/**\n * Convert a `Uint8Array` to a signed `bigint`. This assumes that the bytes are\n * encoded in two's complement.\n *\n * To convert a `Uint8Array` to an unsigned `bigint` instead, use\n * {@link bytesToBigInt}.\n *\n * @see https://en.wikipedia.org/wiki/Two%27s_complement\n * @param bytes - The bytes to convert to a signed `bigint`.\n * @returns The signed `bigint`.\n */\nexport function bytesToSignedBigInt(bytes: Uint8Array): bigint {\n assertIsBytes(bytes);\n\n let value = BigInt(0);\n for (const byte of bytes) {\n // eslint-disable-next-line no-bitwise\n value = (value << BigInt(8)) + BigInt(byte);\n }\n\n return BigInt.asIntN(bytes.length * 8, value);\n}\n\n/**\n * Convert a `Uint8Array` to a `number`.\n *\n * To convert a `Uint8Array` to a `bigint` instead, use {@link bytesToBigInt}.\n *\n * @param bytes - The bytes to convert to a number.\n * @returns The number.\n * @throws If the resulting number is not a safe integer.\n */\nexport function bytesToNumber(bytes: Uint8Array): number {\n assertIsBytes(bytes);\n\n const bigint = bytesToBigInt(bytes);\n\n assert(\n bigint <= BigInt(Number.MAX_SAFE_INTEGER),\n 'Number is not a safe integer. Use `bytesToBigInt` instead.',\n );\n\n return Number(bigint);\n}\n\n/**\n * Convert a UTF-8 encoded `Uint8Array` to a `string`.\n *\n * @param bytes - The bytes to convert to a string.\n * @returns The string.\n */\nexport function bytesToString(bytes: Uint8Array): string {\n assertIsBytes(bytes);\n\n return new TextDecoder(undefined).decode(bytes);\n}\n\n/**\n * Convert a hexadecimal string to a `Uint8Array`. The string can optionally be\n * prefixed with `0x`. It accepts even and odd length strings.\n *\n * @param value - The hexadecimal string to convert to bytes.\n * @returns The bytes as `Uint8Array`.\n */\nexport function hexToBytes(value: string): Uint8Array {\n assertIsHexString(value);\n\n // Remove the `0x` prefix if it exists, and pad the string to have an even\n // number of characters.\n const strippedValue = remove0x(value).toLowerCase();\n const normalizedValue =\n strippedValue.length % 2 === 0 ? strippedValue : `0${strippedValue}`;\n const bytes = new Uint8Array(normalizedValue.length / 2);\n\n for (let i = 0; i < bytes.length; i++) {\n // While this is not the prettiest way to convert a hexadecimal string to a\n // `Uint8Array`, it is a lot faster than using `parseInt` to convert each\n // character.\n const c1 = normalizedValue.charCodeAt(i * 2);\n const c2 = normalizedValue.charCodeAt(i * 2 + 1);\n const n1 =\n c1 -\n (c1 < HEX_MAXIMUM_NUMBER_CHARACTER\n ? HEX_MINIMUM_NUMBER_CHARACTER\n : HEX_CHARACTER_OFFSET);\n const n2 =\n c2 -\n (c2 < HEX_MAXIMUM_NUMBER_CHARACTER\n ? HEX_MINIMUM_NUMBER_CHARACTER\n : HEX_CHARACTER_OFFSET);\n\n bytes[i] = n1 * 16 + n2;\n }\n\n return bytes;\n}\n\n/**\n * Convert a `bigint` to a `Uint8Array`.\n *\n * This assumes that the `bigint` is an unsigned integer. To convert a signed\n * `bigint` instead, use {@link signedBigIntToBytes}.\n *\n * @param value - The bigint to convert to bytes.\n * @returns The bytes as `Uint8Array`.\n */\nexport function bigIntToBytes(value: bigint): Uint8Array {\n assert(typeof value === 'bigint', 'Value must be a bigint.');\n assert(value >= BigInt(0), 'Value must be a non-negative bigint.');\n\n const hex = value.toString(16);\n return hexToBytes(hex);\n}\n\n/**\n * Check if a `bigint` fits in a certain number of bytes.\n *\n * @param value - The `bigint` to check.\n * @param bytes - The number of bytes.\n * @returns Whether the `bigint` fits in the number of bytes.\n */\nfunction bigIntFits(value: bigint, bytes: number): boolean {\n assert(bytes > 0);\n\n /* eslint-disable no-bitwise */\n const mask = value >> BigInt(31);\n return !(((~value & mask) + (value & ~mask)) >> BigInt(bytes * 8 + ~0));\n /* eslint-enable no-bitwise */\n}\n\n/**\n * Convert a signed `bigint` to a `Uint8Array`. This uses two's complement\n * encoding to represent negative numbers.\n *\n * To convert an unsigned `bigint` to a `Uint8Array` instead, use\n * {@link bigIntToBytes}.\n *\n * @see https://en.wikipedia.org/wiki/Two%27s_complement\n * @param value - The number to convert to bytes.\n * @param byteLength - The length of the resulting `Uint8Array`. If the number\n * is larger than the maximum value that can be represented by the given length,\n * an error is thrown.\n * @returns The bytes as `Uint8Array`.\n */\nexport function signedBigIntToBytes(\n value: bigint,\n byteLength: number,\n): Uint8Array {\n assert(typeof value === 'bigint', 'Value must be a bigint.');\n assert(typeof byteLength === 'number', 'Byte length must be a number.');\n assert(byteLength > 0, 'Byte length must be greater than 0.');\n assert(\n bigIntFits(value, byteLength),\n 'Byte length is too small to represent the given value.',\n );\n\n // ESLint doesn't like mutating function parameters, so to avoid having to\n // disable the rule, we create a new variable.\n let numberValue = value;\n const bytes = new Uint8Array(byteLength);\n\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Number(BigInt.asUintN(8, numberValue));\n // eslint-disable-next-line no-bitwise\n numberValue >>= BigInt(8);\n }\n\n return bytes.reverse();\n}\n\n/**\n * Convert a `number` to a `Uint8Array`.\n *\n * @param value - The number to convert to bytes.\n * @returns The bytes as `Uint8Array`.\n * @throws If the number is not a safe integer.\n */\nexport function numberToBytes(value: number): Uint8Array {\n assert(typeof value === 'number', 'Value must be a number.');\n assert(value >= 0, 'Value must be a non-negative number.');\n assert(\n Number.isSafeInteger(value),\n 'Value is not a safe integer. Use `bigIntToBytes` instead.',\n );\n\n const hex = value.toString(16);\n return hexToBytes(hex);\n}\n\n/**\n * Convert a `string` to a UTF-8 encoded `Uint8Array`.\n *\n * @param value - The string to convert to bytes.\n * @returns The bytes as `Uint8Array`.\n */\nexport function stringToBytes(value: string): Uint8Array {\n assert(typeof value === 'string', 'Value must be a string.');\n\n return new TextEncoder().encode(value);\n}\n\n/**\n * Convert a byte-like value to a `Uint8Array`. The value can be a `Uint8Array`,\n * a `bigint`, a `number`, or a `string`.\n *\n * If the value is a `string`, and it is prefixed with `0x`, it will be\n * interpreted as a hexadecimal string. Otherwise, it will be interpreted as a\n * UTF-8 string. To convert a hexadecimal string to bytes without interpreting\n * it as a UTF-8 string, use {@link hexToBytes} instead.\n *\n * If the value is a `bigint`, it is assumed to be unsigned. To convert a signed\n * `bigint` to bytes, use {@link signedBigIntToBytes} instead.\n *\n * If the value is a `Uint8Array`, it will be returned as-is.\n *\n * @param value - The value to convert to bytes.\n * @returns The bytes as `Uint8Array`.\n */\nexport function valueToBytes(value: Bytes): Uint8Array {\n if (typeof value === 'bigint') {\n return bigIntToBytes(value);\n }\n\n if (typeof value === 'number') {\n return numberToBytes(value);\n }\n\n if (typeof value === 'string') {\n if (value.startsWith('0x')) {\n return hexToBytes(value);\n }\n\n return stringToBytes(value);\n }\n\n if (isBytes(value)) {\n return value;\n }\n\n throw new TypeError(`Unsupported value type: \"${typeof value}\".`);\n}\n\n/**\n * Concatenate multiple byte-like values into a single `Uint8Array`. The values\n * can be `Uint8Array`, `bigint`, `number`, or `string`. This uses\n * {@link valueToBytes} under the hood to convert each value to bytes. Refer to\n * the documentation of that function for more information.\n *\n * @param values - The values to concatenate.\n * @returns The concatenated bytes as `Uint8Array`.\n */\nexport function concatBytes(values: Bytes[]): Uint8Array {\n const normalizedValues = new Array(values.length);\n let byteLength = 0;\n\n for (let i = 0; i < values.length; i++) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const value = valueToBytes(values[i]!);\n\n normalizedValues[i] = value;\n byteLength += value.length;\n }\n\n const bytes = new Uint8Array(byteLength);\n for (let i = 0, offset = 0; i < normalizedValues.length; i++) {\n // While we could simply spread the values into an array and use\n // `Uint8Array.from`, that is a lot slower than using `Uint8Array.set`.\n bytes.set(normalizedValues[i], offset);\n offset += normalizedValues[i].length;\n }\n\n return bytes;\n}\n"]}
1
+ {"version":3,"file":"bytes.js","sourceRoot":"","sources":["../src/bytes.ts"],"names":[],"mappings":"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","sourcesContent":["import { assert } from './assert';\nimport { add0x, assertIsHexString, Hex, remove0x } from './hex';\n\n// '0'.charCodeAt(0) === 48\nconst HEX_MINIMUM_NUMBER_CHARACTER = 48;\n\n// '9'.charCodeAt(0) === 57\nconst HEX_MAXIMUM_NUMBER_CHARACTER = 58;\nconst HEX_CHARACTER_OFFSET = 87;\n\nexport type Bytes = bigint | number | string | Uint8Array;\n\n/**\n * Memoized function that returns an array to be used as a lookup table for\n * converting bytes to hexadecimal values.\n *\n * The array is created lazily and then cached for future use. The benefit of\n * this approach is that the performance of converting bytes to hex is much\n * better than if we were to call `toString(16)` on each byte.\n *\n * The downside is that the array is created once and then never garbage\n * collected. This is not a problem in practice because the array is only 256\n * elements long.\n *\n * @returns A function that returns the lookup table.\n */\nfunction getPrecomputedHexValuesBuilder(): () => string[] {\n // To avoid issues with tree shaking, we need to use a function to return the\n // array. This is because the array is only used in the `bytesToHex` function\n // and if we were to use a global variable, the array might be removed by the\n // tree shaker.\n const lookupTable: string[] = [];\n\n return () => {\n if (lookupTable.length === 0) {\n for (let i = 0; i < 256; i++) {\n lookupTable.push(i.toString(16).padStart(2, '0'));\n }\n }\n\n return lookupTable;\n };\n}\n\n/**\n * Function implementation of the {@link getPrecomputedHexValuesBuilder}\n * function.\n */\nconst getPrecomputedHexValues = getPrecomputedHexValuesBuilder();\n\n/**\n * Check if a value is a `Uint8Array`.\n *\n * @param value - The value to check.\n * @returns Whether the value is a `Uint8Array`.\n */\nexport function isBytes(value: unknown): value is Uint8Array {\n return value instanceof Uint8Array;\n}\n\n/**\n * Assert that a value is a `Uint8Array`.\n *\n * @param value - The value to check.\n * @throws If the value is not a `Uint8Array`.\n */\nexport function assertIsBytes(value: unknown): asserts value is Uint8Array {\n assert(isBytes(value), 'Value must be a Uint8Array.');\n}\n\n/**\n * Convert a `Uint8Array` to a hexadecimal string.\n *\n * @param bytes - The bytes to convert to a hexadecimal string.\n * @returns The hexadecimal string.\n */\nexport function bytesToHex(bytes: Uint8Array): Hex {\n assertIsBytes(bytes);\n\n if (bytes.length === 0) {\n return '0x';\n }\n\n const lookupTable = getPrecomputedHexValues();\n const hex = new Array(bytes.length);\n\n for (let i = 0; i < bytes.length; i++) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n hex[i] = lookupTable[bytes[i]!];\n }\n\n return add0x(hex.join(''));\n}\n\n/**\n * Convert a `Uint8Array` to a `bigint`.\n *\n * To convert a `Uint8Array` to a `number` instead, use {@link bytesToNumber}.\n * To convert a two's complement encoded `Uint8Array` to a `bigint`, use\n * {@link bytesToSignedBigInt}.\n *\n * @param bytes - The bytes to convert to a `bigint`.\n * @returns The `bigint`.\n */\nexport function bytesToBigInt(bytes: Uint8Array): bigint {\n assertIsBytes(bytes);\n\n const hex = bytesToHex(bytes);\n return BigInt(hex);\n}\n\n/**\n * Convert a `Uint8Array` to a signed `bigint`. This assumes that the bytes are\n * encoded in two's complement.\n *\n * To convert a `Uint8Array` to an unsigned `bigint` instead, use\n * {@link bytesToBigInt}.\n *\n * @see https://en.wikipedia.org/wiki/Two%27s_complement\n * @param bytes - The bytes to convert to a signed `bigint`.\n * @returns The signed `bigint`.\n */\nexport function bytesToSignedBigInt(bytes: Uint8Array): bigint {\n assertIsBytes(bytes);\n\n let value = BigInt(0);\n for (const byte of bytes) {\n // eslint-disable-next-line no-bitwise\n value = (value << BigInt(8)) + BigInt(byte);\n }\n\n return BigInt.asIntN(bytes.length * 8, value);\n}\n\n/**\n * Convert a `Uint8Array` to a `number`.\n *\n * To convert a `Uint8Array` to a `bigint` instead, use {@link bytesToBigInt}.\n *\n * @param bytes - The bytes to convert to a number.\n * @returns The number.\n * @throws If the resulting number is not a safe integer.\n */\nexport function bytesToNumber(bytes: Uint8Array): number {\n assertIsBytes(bytes);\n\n const bigint = bytesToBigInt(bytes);\n\n assert(\n bigint <= BigInt(Number.MAX_SAFE_INTEGER),\n 'Number is not a safe integer. Use `bytesToBigInt` instead.',\n );\n\n return Number(bigint);\n}\n\n/**\n * Convert a UTF-8 encoded `Uint8Array` to a `string`.\n *\n * @param bytes - The bytes to convert to a string.\n * @returns The string.\n */\nexport function bytesToString(bytes: Uint8Array): string {\n assertIsBytes(bytes);\n\n return new TextDecoder().decode(bytes);\n}\n\n/**\n * Convert a hexadecimal string to a `Uint8Array`. The string can optionally be\n * prefixed with `0x`. It accepts even and odd length strings.\n *\n * If the value is \"0x\", an empty `Uint8Array` is returned.\n *\n * @param value - The hexadecimal string to convert to bytes.\n * @returns The bytes as `Uint8Array`.\n */\nexport function hexToBytes(value: string): Uint8Array {\n // \"0x\" is often used as empty byte array.\n if (value?.toLowerCase?.() === '0x') {\n return new Uint8Array();\n }\n\n assertIsHexString(value);\n\n // Remove the `0x` prefix if it exists, and pad the string to have an even\n // number of characters.\n const strippedValue = remove0x(value).toLowerCase();\n const normalizedValue =\n strippedValue.length % 2 === 0 ? strippedValue : `0${strippedValue}`;\n const bytes = new Uint8Array(normalizedValue.length / 2);\n\n for (let i = 0; i < bytes.length; i++) {\n // While this is not the prettiest way to convert a hexadecimal string to a\n // `Uint8Array`, it is a lot faster than using `parseInt` to convert each\n // character.\n const c1 = normalizedValue.charCodeAt(i * 2);\n const c2 = normalizedValue.charCodeAt(i * 2 + 1);\n const n1 =\n c1 -\n (c1 < HEX_MAXIMUM_NUMBER_CHARACTER\n ? HEX_MINIMUM_NUMBER_CHARACTER\n : HEX_CHARACTER_OFFSET);\n const n2 =\n c2 -\n (c2 < HEX_MAXIMUM_NUMBER_CHARACTER\n ? HEX_MINIMUM_NUMBER_CHARACTER\n : HEX_CHARACTER_OFFSET);\n\n bytes[i] = n1 * 16 + n2;\n }\n\n return bytes;\n}\n\n/**\n * Convert a `bigint` to a `Uint8Array`.\n *\n * This assumes that the `bigint` is an unsigned integer. To convert a signed\n * `bigint` instead, use {@link signedBigIntToBytes}.\n *\n * @param value - The bigint to convert to bytes.\n * @returns The bytes as `Uint8Array`.\n */\nexport function bigIntToBytes(value: bigint): Uint8Array {\n assert(typeof value === 'bigint', 'Value must be a bigint.');\n assert(value >= BigInt(0), 'Value must be a non-negative bigint.');\n\n const hex = value.toString(16);\n return hexToBytes(hex);\n}\n\n/**\n * Check if a `bigint` fits in a certain number of bytes.\n *\n * @param value - The `bigint` to check.\n * @param bytes - The number of bytes.\n * @returns Whether the `bigint` fits in the number of bytes.\n */\nfunction bigIntFits(value: bigint, bytes: number): boolean {\n assert(bytes > 0);\n\n /* eslint-disable no-bitwise */\n const mask = value >> BigInt(31);\n return !(((~value & mask) + (value & ~mask)) >> BigInt(bytes * 8 + ~0));\n /* eslint-enable no-bitwise */\n}\n\n/**\n * Convert a signed `bigint` to a `Uint8Array`. This uses two's complement\n * encoding to represent negative numbers.\n *\n * To convert an unsigned `bigint` to a `Uint8Array` instead, use\n * {@link bigIntToBytes}.\n *\n * @see https://en.wikipedia.org/wiki/Two%27s_complement\n * @param value - The number to convert to bytes.\n * @param byteLength - The length of the resulting `Uint8Array`. If the number\n * is larger than the maximum value that can be represented by the given length,\n * an error is thrown.\n * @returns The bytes as `Uint8Array`.\n */\nexport function signedBigIntToBytes(\n value: bigint,\n byteLength: number,\n): Uint8Array {\n assert(typeof value === 'bigint', 'Value must be a bigint.');\n assert(typeof byteLength === 'number', 'Byte length must be a number.');\n assert(byteLength > 0, 'Byte length must be greater than 0.');\n assert(\n bigIntFits(value, byteLength),\n 'Byte length is too small to represent the given value.',\n );\n\n // ESLint doesn't like mutating function parameters, so to avoid having to\n // disable the rule, we create a new variable.\n let numberValue = value;\n const bytes = new Uint8Array(byteLength);\n\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Number(BigInt.asUintN(8, numberValue));\n // eslint-disable-next-line no-bitwise\n numberValue >>= BigInt(8);\n }\n\n return bytes.reverse();\n}\n\n/**\n * Convert a `number` to a `Uint8Array`.\n *\n * @param value - The number to convert to bytes.\n * @returns The bytes as `Uint8Array`.\n * @throws If the number is not a safe integer.\n */\nexport function numberToBytes(value: number): Uint8Array {\n assert(typeof value === 'number', 'Value must be a number.');\n assert(value >= 0, 'Value must be a non-negative number.');\n assert(\n Number.isSafeInteger(value),\n 'Value is not a safe integer. Use `bigIntToBytes` instead.',\n );\n\n const hex = value.toString(16);\n return hexToBytes(hex);\n}\n\n/**\n * Convert a `string` to a UTF-8 encoded `Uint8Array`.\n *\n * @param value - The string to convert to bytes.\n * @returns The bytes as `Uint8Array`.\n */\nexport function stringToBytes(value: string): Uint8Array {\n assert(typeof value === 'string', 'Value must be a string.');\n\n return new TextEncoder().encode(value);\n}\n\n/**\n * Convert a byte-like value to a `Uint8Array`. The value can be a `Uint8Array`,\n * a `bigint`, a `number`, or a `string`.\n *\n * This will attempt to guess the type of the value based on its type and\n * contents. For more control over the conversion, use the more specific\n * conversion functions, such as {@link hexToBytes} or {@link stringToBytes}.\n *\n * If the value is a `string`, and it is prefixed with `0x`, it will be\n * interpreted as a hexadecimal string. Otherwise, it will be interpreted as a\n * UTF-8 string. To convert a hexadecimal string to bytes without interpreting\n * it as a UTF-8 string, use {@link hexToBytes} instead.\n *\n * If the value is a `bigint`, it is assumed to be unsigned. To convert a signed\n * `bigint` to bytes, use {@link signedBigIntToBytes} instead.\n *\n * If the value is a `Uint8Array`, it will be returned as-is.\n *\n * @param value - The value to convert to bytes.\n * @returns The bytes as `Uint8Array`.\n */\nexport function valueToBytes(value: Bytes): Uint8Array {\n if (typeof value === 'bigint') {\n return bigIntToBytes(value);\n }\n\n if (typeof value === 'number') {\n return numberToBytes(value);\n }\n\n if (typeof value === 'string') {\n if (value.startsWith('0x')) {\n return hexToBytes(value);\n }\n\n return stringToBytes(value);\n }\n\n if (isBytes(value)) {\n return value;\n }\n\n throw new TypeError(`Unsupported value type: \"${typeof value}\".`);\n}\n\n/**\n * Concatenate multiple byte-like values into a single `Uint8Array`. The values\n * can be `Uint8Array`, `bigint`, `number`, or `string`. This uses\n * {@link valueToBytes} under the hood to convert each value to bytes. Refer to\n * the documentation of that function for more information.\n *\n * @param values - The values to concatenate.\n * @returns The concatenated bytes as `Uint8Array`.\n */\nexport function concatBytes(values: Bytes[]): Uint8Array {\n const normalizedValues = new Array(values.length);\n let byteLength = 0;\n\n for (let i = 0; i < values.length; i++) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const value = valueToBytes(values[i]!);\n\n normalizedValues[i] = value;\n byteLength += value.length;\n }\n\n const bytes = new Uint8Array(byteLength);\n for (let i = 0, offset = 0; i < normalizedValues.length; i++) {\n // While we could simply spread the values into an array and use\n // `Uint8Array.from`, that is a lot slower than using `Uint8Array.set`.\n bytes.set(normalizedValues[i], offset);\n offset += normalizedValues[i].length;\n }\n\n return bytes;\n}\n"]}
@@ -0,0 +1,96 @@
1
+ import { Infer } from 'superstruct';
2
+ import { Hex } from './hex';
3
+ declare const NumberLikeStruct: import("superstruct").Struct<string | number | bigint, null>;
4
+ declare const BytesLikeStruct: import("superstruct").Struct<Uint8Array | `0x${string}`, null>;
5
+ export declare type NumberLike = Infer<typeof NumberLikeStruct>;
6
+ export declare type BytesLike = Infer<typeof BytesLikeStruct>;
7
+ /**
8
+ * Create a number from a number-like value.
9
+ *
10
+ * - If the value is a number, it is returned as-is.
11
+ * - If the value is a `bigint`, it is converted to a number.
12
+ * - If the value is a string, it is interpreted as a decimal number.
13
+ * - If the value is a hex string (i.e., it starts with "0x"), it is
14
+ * interpreted as a hexadecimal number.
15
+ *
16
+ * This validates that the value is a number-like value, and that the resulting
17
+ * number is not `NaN` or `Infinity`.
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * const value = createNumber('0x010203');
22
+ * console.log(value); // 66051
23
+ *
24
+ * const otherValue = createNumber(123n);
25
+ * console.log(otherValue); // 123
26
+ * ```
27
+ * @param value - The value to create the number from.
28
+ * @returns The created number.
29
+ * @throws If the value is not a number-like value, or if the resulting number
30
+ * is `NaN` or `Infinity`.
31
+ */
32
+ export declare function createNumber(value: NumberLike): number;
33
+ /**
34
+ * Create a `bigint` from a number-like value.
35
+ *
36
+ * - If the value is a number, it is converted to a `bigint`.
37
+ * - If the value is a `bigint`, it is returned as-is.
38
+ * - If the value is a string, it is interpreted as a decimal number and
39
+ * converted to a `bigint`.
40
+ * - If the value is a hex string (i.e., it starts with "0x"), it is
41
+ * interpreted as a hexadecimal number and converted to a `bigint`.
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * const value = createBigInt('0x010203');
46
+ * console.log(value); // 16909060n
47
+ *
48
+ * const otherValue = createBigInt(123);
49
+ * console.log(otherValue); // 123n
50
+ * ```
51
+ * @param value - The value to create the bigint from.
52
+ * @returns The created bigint.
53
+ * @throws If the value is not a number-like value.
54
+ */
55
+ export declare function createBigInt(value: NumberLike): bigint;
56
+ /**
57
+ * Create a byte array from a bytes-like value.
58
+ *
59
+ * - If the value is a byte array, it is returned as-is.
60
+ * - If the value is a hex string (i.e., it starts with "0x"), it is interpreted
61
+ * as a hexadecimal number and converted to a byte array.
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * const value = createBytes('0x010203');
66
+ * console.log(value); // Uint8Array [ 1, 2, 3 ]
67
+ *
68
+ * const otherValue = createBytes('0x010203');
69
+ * console.log(otherValue); // Uint8Array [ 1, 2, 3 ]
70
+ * ```
71
+ * @param value - The value to create the byte array from.
72
+ * @returns The created byte array.
73
+ * @throws If the value is not a bytes-like value.
74
+ */
75
+ export declare function createBytes(value: BytesLike): Uint8Array;
76
+ /**
77
+ * Create a hexadecimal string from a bytes-like value.
78
+ *
79
+ * - If the value is a hex string (i.e., it starts with "0x"), it is returned
80
+ * as-is.
81
+ * - If the value is a `Uint8Array`, it is converted to a hex string.
82
+ *
83
+ * @example
84
+ * ```typescript
85
+ * const value = createHex(new Uint8Array([1, 2, 3]));
86
+ * console.log(value); // '0x010203'
87
+ *
88
+ * const otherValue = createHex('0x010203');
89
+ * console.log(otherValue); // '0x010203'
90
+ * ```
91
+ * @param value - The value to create the hex string from.
92
+ * @returns The created hex string.
93
+ * @throws If the value is not a bytes-like value.
94
+ */
95
+ export declare function createHex(value: BytesLike): Hex;
96
+ export {};
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createHex = exports.createBytes = exports.createBigInt = exports.createNumber = void 0;
4
+ const superstruct_1 = require("superstruct");
5
+ const hex_1 = require("./hex");
6
+ const assert_1 = require("./assert");
7
+ const bytes_1 = require("./bytes");
8
+ const NumberLikeStruct = (0, superstruct_1.union)([(0, superstruct_1.number)(), (0, superstruct_1.bigint)(), (0, superstruct_1.string)(), hex_1.StrictHexStruct]);
9
+ const NumberCoercer = (0, superstruct_1.coerce)((0, superstruct_1.number)(), NumberLikeStruct, Number);
10
+ const BigIntCoercer = (0, superstruct_1.coerce)((0, superstruct_1.bigint)(), NumberLikeStruct, BigInt);
11
+ const BytesLikeStruct = (0, superstruct_1.union)([hex_1.StrictHexStruct, (0, superstruct_1.instance)(Uint8Array)]);
12
+ const BytesCoercer = (0, superstruct_1.coerce)((0, superstruct_1.instance)(Uint8Array), (0, superstruct_1.union)([hex_1.StrictHexStruct]), bytes_1.hexToBytes);
13
+ const HexCoercer = (0, superstruct_1.coerce)(hex_1.StrictHexStruct, (0, superstruct_1.instance)(Uint8Array), bytes_1.bytesToHex);
14
+ /**
15
+ * Create a number from a number-like value.
16
+ *
17
+ * - If the value is a number, it is returned as-is.
18
+ * - If the value is a `bigint`, it is converted to a number.
19
+ * - If the value is a string, it is interpreted as a decimal number.
20
+ * - If the value is a hex string (i.e., it starts with "0x"), it is
21
+ * interpreted as a hexadecimal number.
22
+ *
23
+ * This validates that the value is a number-like value, and that the resulting
24
+ * number is not `NaN` or `Infinity`.
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * const value = createNumber('0x010203');
29
+ * console.log(value); // 66051
30
+ *
31
+ * const otherValue = createNumber(123n);
32
+ * console.log(otherValue); // 123
33
+ * ```
34
+ * @param value - The value to create the number from.
35
+ * @returns The created number.
36
+ * @throws If the value is not a number-like value, or if the resulting number
37
+ * is `NaN` or `Infinity`.
38
+ */
39
+ function createNumber(value) {
40
+ try {
41
+ const result = (0, superstruct_1.create)(value, NumberCoercer);
42
+ (0, assert_1.assert)(Number.isFinite(result), `Expected a number-like value, got "${value}".`);
43
+ return result;
44
+ }
45
+ catch (error) {
46
+ if (error instanceof superstruct_1.StructError) {
47
+ throw new Error(`Expected a number-like value, got "${value}".`);
48
+ }
49
+ /* istanbul ignore next */
50
+ throw error;
51
+ }
52
+ }
53
+ exports.createNumber = createNumber;
54
+ /**
55
+ * Create a `bigint` from a number-like value.
56
+ *
57
+ * - If the value is a number, it is converted to a `bigint`.
58
+ * - If the value is a `bigint`, it is returned as-is.
59
+ * - If the value is a string, it is interpreted as a decimal number and
60
+ * converted to a `bigint`.
61
+ * - If the value is a hex string (i.e., it starts with "0x"), it is
62
+ * interpreted as a hexadecimal number and converted to a `bigint`.
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * const value = createBigInt('0x010203');
67
+ * console.log(value); // 16909060n
68
+ *
69
+ * const otherValue = createBigInt(123);
70
+ * console.log(otherValue); // 123n
71
+ * ```
72
+ * @param value - The value to create the bigint from.
73
+ * @returns The created bigint.
74
+ * @throws If the value is not a number-like value.
75
+ */
76
+ function createBigInt(value) {
77
+ try {
78
+ // The `BigInt` constructor throws if the value is not a number-like value.
79
+ // There is no need to validate the value manually.
80
+ return (0, superstruct_1.create)(value, BigIntCoercer);
81
+ }
82
+ catch (error) {
83
+ if (error instanceof superstruct_1.StructError) {
84
+ throw new Error(`Expected a number-like value, got "${error.value}".`);
85
+ }
86
+ /* istanbul ignore next */
87
+ throw error;
88
+ }
89
+ }
90
+ exports.createBigInt = createBigInt;
91
+ /**
92
+ * Create a byte array from a bytes-like value.
93
+ *
94
+ * - If the value is a byte array, it is returned as-is.
95
+ * - If the value is a hex string (i.e., it starts with "0x"), it is interpreted
96
+ * as a hexadecimal number and converted to a byte array.
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * const value = createBytes('0x010203');
101
+ * console.log(value); // Uint8Array [ 1, 2, 3 ]
102
+ *
103
+ * const otherValue = createBytes('0x010203');
104
+ * console.log(otherValue); // Uint8Array [ 1, 2, 3 ]
105
+ * ```
106
+ * @param value - The value to create the byte array from.
107
+ * @returns The created byte array.
108
+ * @throws If the value is not a bytes-like value.
109
+ */
110
+ function createBytes(value) {
111
+ if (typeof value === 'string' && value.toLowerCase() === '0x') {
112
+ return new Uint8Array();
113
+ }
114
+ try {
115
+ return (0, superstruct_1.create)(value, BytesCoercer);
116
+ }
117
+ catch (error) {
118
+ if (error instanceof superstruct_1.StructError) {
119
+ throw new Error(`Expected a bytes-like value, got "${error.value}".`);
120
+ }
121
+ /* istanbul ignore next */
122
+ throw error;
123
+ }
124
+ }
125
+ exports.createBytes = createBytes;
126
+ /**
127
+ * Create a hexadecimal string from a bytes-like value.
128
+ *
129
+ * - If the value is a hex string (i.e., it starts with "0x"), it is returned
130
+ * as-is.
131
+ * - If the value is a `Uint8Array`, it is converted to a hex string.
132
+ *
133
+ * @example
134
+ * ```typescript
135
+ * const value = createHex(new Uint8Array([1, 2, 3]));
136
+ * console.log(value); // '0x010203'
137
+ *
138
+ * const otherValue = createHex('0x010203');
139
+ * console.log(otherValue); // '0x010203'
140
+ * ```
141
+ * @param value - The value to create the hex string from.
142
+ * @returns The created hex string.
143
+ * @throws If the value is not a bytes-like value.
144
+ */
145
+ function createHex(value) {
146
+ if ((value instanceof Uint8Array && value.length === 0) ||
147
+ (typeof value === 'string' && value.toLowerCase() === '0x')) {
148
+ return '0x';
149
+ }
150
+ try {
151
+ return (0, superstruct_1.create)(value, HexCoercer);
152
+ }
153
+ catch (error) {
154
+ if (error instanceof superstruct_1.StructError) {
155
+ throw new Error(`Expected a bytes-like value, got "${error.value}".`);
156
+ }
157
+ /* istanbul ignore next */
158
+ throw error;
159
+ }
160
+ }
161
+ exports.createHex = createHex;
162
+ //# sourceMappingURL=coercers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coercers.js","sourceRoot":"","sources":["../src/coercers.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n bigint,\n coerce,\n create,\n Infer,\n instance,\n number,\n string,\n StructError,\n union,\n} from 'superstruct';\nimport { Hex, StrictHexStruct } from './hex';\nimport { assert } from './assert';\nimport { bytesToHex, hexToBytes } from './bytes';\n\nconst NumberLikeStruct = union([number(), bigint(), string(), StrictHexStruct]);\nconst NumberCoercer = coerce(number(), NumberLikeStruct, Number);\nconst BigIntCoercer = coerce(bigint(), NumberLikeStruct, BigInt);\n\nconst BytesLikeStruct = union([StrictHexStruct, instance(Uint8Array)]);\nconst BytesCoercer = coerce(\n instance(Uint8Array),\n union([StrictHexStruct]),\n hexToBytes,\n);\n\nconst HexCoercer = coerce(StrictHexStruct, instance(Uint8Array), bytesToHex);\n\nexport type NumberLike = Infer<typeof NumberLikeStruct>;\nexport type BytesLike = Infer<typeof BytesLikeStruct>;\n\n/**\n * Create a number from a number-like value.\n *\n * - If the value is a number, it is returned as-is.\n * - If the value is a `bigint`, it is converted to a number.\n * - If the value is a string, it is interpreted as a decimal number.\n * - If the value is a hex string (i.e., it starts with \"0x\"), it is\n * interpreted as a hexadecimal number.\n *\n * This validates that the value is a number-like value, and that the resulting\n * number is not `NaN` or `Infinity`.\n *\n * @example\n * ```typescript\n * const value = createNumber('0x010203');\n * console.log(value); // 66051\n *\n * const otherValue = createNumber(123n);\n * console.log(otherValue); // 123\n * ```\n * @param value - The value to create the number from.\n * @returns The created number.\n * @throws If the value is not a number-like value, or if the resulting number\n * is `NaN` or `Infinity`.\n */\nexport function createNumber(value: NumberLike): number {\n try {\n const result = create(value, NumberCoercer);\n\n assert(\n Number.isFinite(result),\n `Expected a number-like value, got \"${value}\".`,\n );\n\n return result;\n } catch (error) {\n if (error instanceof StructError) {\n throw new Error(`Expected a number-like value, got \"${value}\".`);\n }\n\n /* istanbul ignore next */\n throw error;\n }\n}\n\n/**\n * Create a `bigint` from a number-like value.\n *\n * - If the value is a number, it is converted to a `bigint`.\n * - If the value is a `bigint`, it is returned as-is.\n * - If the value is a string, it is interpreted as a decimal number and\n * converted to a `bigint`.\n * - If the value is a hex string (i.e., it starts with \"0x\"), it is\n * interpreted as a hexadecimal number and converted to a `bigint`.\n *\n * @example\n * ```typescript\n * const value = createBigInt('0x010203');\n * console.log(value); // 16909060n\n *\n * const otherValue = createBigInt(123);\n * console.log(otherValue); // 123n\n * ```\n * @param value - The value to create the bigint from.\n * @returns The created bigint.\n * @throws If the value is not a number-like value.\n */\nexport function createBigInt(value: NumberLike): bigint {\n try {\n // The `BigInt` constructor throws if the value is not a number-like value.\n // There is no need to validate the value manually.\n return create(value, BigIntCoercer);\n } catch (error) {\n if (error instanceof StructError) {\n throw new Error(`Expected a number-like value, got \"${error.value}\".`);\n }\n\n /* istanbul ignore next */\n throw error;\n }\n}\n\n/**\n * Create a byte array from a bytes-like value.\n *\n * - If the value is a byte array, it is returned as-is.\n * - If the value is a hex string (i.e., it starts with \"0x\"), it is interpreted\n * as a hexadecimal number and converted to a byte array.\n *\n * @example\n * ```typescript\n * const value = createBytes('0x010203');\n * console.log(value); // Uint8Array [ 1, 2, 3 ]\n *\n * const otherValue = createBytes('0x010203');\n * console.log(otherValue); // Uint8Array [ 1, 2, 3 ]\n * ```\n * @param value - The value to create the byte array from.\n * @returns The created byte array.\n * @throws If the value is not a bytes-like value.\n */\nexport function createBytes(value: BytesLike): Uint8Array {\n if (typeof value === 'string' && value.toLowerCase() === '0x') {\n return new Uint8Array();\n }\n\n try {\n return create(value, BytesCoercer);\n } catch (error) {\n if (error instanceof StructError) {\n throw new Error(`Expected a bytes-like value, got \"${error.value}\".`);\n }\n\n /* istanbul ignore next */\n throw error;\n }\n}\n\n/**\n * Create a hexadecimal string from a bytes-like value.\n *\n * - If the value is a hex string (i.e., it starts with \"0x\"), it is returned\n * as-is.\n * - If the value is a `Uint8Array`, it is converted to a hex string.\n *\n * @example\n * ```typescript\n * const value = createHex(new Uint8Array([1, 2, 3]));\n * console.log(value); // '0x010203'\n *\n * const otherValue = createHex('0x010203');\n * console.log(otherValue); // '0x010203'\n * ```\n * @param value - The value to create the hex string from.\n * @returns The created hex string.\n * @throws If the value is not a bytes-like value.\n */\nexport function createHex(value: BytesLike): Hex {\n if (\n (value instanceof Uint8Array && value.length === 0) ||\n (typeof value === 'string' && value.toLowerCase() === '0x')\n ) {\n return '0x';\n }\n\n try {\n return create(value, HexCoercer);\n } catch (error) {\n if (error instanceof StructError) {\n throw new Error(`Expected a bytes-like value, got \"${error.value}\".`);\n }\n\n /* istanbul ignore next */\n throw error;\n }\n}\n"]}
package/dist/hex.d.ts CHANGED
@@ -1,3 +1,7 @@
1
+ import { Struct } from 'superstruct';
2
+ export declare type Hex = `0x${string}`;
3
+ export declare const HexStruct: Struct<string, null>;
4
+ export declare const StrictHexStruct: Struct<`0x${string}`, null>;
1
5
  /**
2
6
  * Check if a string is a valid hex string.
3
7
  *
@@ -5,6 +9,14 @@
5
9
  * @returns Whether the value is a valid hex string.
6
10
  */
7
11
  export declare function isHexString(value: unknown): value is string;
12
+ /**
13
+ * Strictly check if a string is a valid hex string. A valid hex string must
14
+ * start with the "0x"-prefix.
15
+ *
16
+ * @param value - The value to check.
17
+ * @returns Whether the value is a valid hex string.
18
+ */
19
+ export declare function isStrictHexString(value: unknown): value is Hex;
8
20
  /**
9
21
  * Assert that a value is a valid hex string.
10
22
  *
@@ -12,6 +24,14 @@ export declare function isHexString(value: unknown): value is string;
12
24
  * @throws If the value is not a valid hex string.
13
25
  */
14
26
  export declare function assertIsHexString(value: unknown): asserts value is string;
27
+ /**
28
+ * Assert that a value is a valid hex string. A valid hex string must start with
29
+ * the "0x"-prefix.
30
+ *
31
+ * @param value - The value to check.
32
+ * @throws If the value is not a valid hex string.
33
+ */
34
+ export declare function assertIsStrictHexString(value: unknown): asserts value is Hex;
15
35
  /**
16
36
  * Add the `0x`-prefix to a hexadecimal string. If the string already has the
17
37
  * prefix, it is returned as-is.
@@ -19,7 +39,7 @@ export declare function assertIsHexString(value: unknown): asserts value is stri
19
39
  * @param hex - The hexadecimal string to add the prefix to.
20
40
  * @returns The prefixed hexadecimal string.
21
41
  */
22
- export declare function add0x(hex: string): string;
42
+ export declare function add0x(hex: string): Hex;
23
43
  /**
24
44
  * Remove the `0x`-prefix from a hexadecimal string. If the string doesn't have
25
45
  * the prefix, it is returned as-is.
package/dist/hex.js CHANGED
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.remove0x = exports.add0x = exports.assertIsHexString = exports.isHexString = void 0;
3
+ exports.remove0x = exports.add0x = exports.assertIsStrictHexString = exports.assertIsHexString = exports.isStrictHexString = exports.isHexString = exports.StrictHexStruct = exports.HexStruct = void 0;
4
4
  const superstruct_1 = require("superstruct");
5
5
  const assert_1 = require("./assert");
6
- const HexStruct = (0, superstruct_1.pattern)((0, superstruct_1.string)(), /^(?:0x)?[0-9a-f]+$/iu);
6
+ exports.HexStruct = (0, superstruct_1.pattern)((0, superstruct_1.string)(), /^(?:0x)?[0-9a-f]+$/iu);
7
+ exports.StrictHexStruct = (0, superstruct_1.pattern)((0, superstruct_1.string)(), /^0x[0-9a-f]+$/iu);
7
8
  /**
8
9
  * Check if a string is a valid hex string.
9
10
  *
@@ -11,9 +12,20 @@ const HexStruct = (0, superstruct_1.pattern)((0, superstruct_1.string)(), /^(?:0
11
12
  * @returns Whether the value is a valid hex string.
12
13
  */
13
14
  function isHexString(value) {
14
- return (0, superstruct_1.is)(value, HexStruct);
15
+ return (0, superstruct_1.is)(value, exports.HexStruct);
15
16
  }
16
17
  exports.isHexString = isHexString;
18
+ /**
19
+ * Strictly check if a string is a valid hex string. A valid hex string must
20
+ * start with the "0x"-prefix.
21
+ *
22
+ * @param value - The value to check.
23
+ * @returns Whether the value is a valid hex string.
24
+ */
25
+ function isStrictHexString(value) {
26
+ return (0, superstruct_1.is)(value, exports.StrictHexStruct);
27
+ }
28
+ exports.isStrictHexString = isStrictHexString;
17
29
  /**
18
30
  * Assert that a value is a valid hex string.
19
31
  *
@@ -24,6 +36,17 @@ function assertIsHexString(value) {
24
36
  (0, assert_1.assert)(isHexString(value), 'Value must be a hexadecimal string.');
25
37
  }
26
38
  exports.assertIsHexString = assertIsHexString;
39
+ /**
40
+ * Assert that a value is a valid hex string. A valid hex string must start with
41
+ * the "0x"-prefix.
42
+ *
43
+ * @param value - The value to check.
44
+ * @throws If the value is not a valid hex string.
45
+ */
46
+ function assertIsStrictHexString(value) {
47
+ (0, assert_1.assert)(isStrictHexString(value), 'Value must be a hexadecimal string, starting with "0x".');
48
+ }
49
+ exports.assertIsStrictHexString = assertIsStrictHexString;
27
50
  /**
28
51
  * Add the `0x`-prefix to a hexadecimal string. If the string already has the
29
52
  * prefix, it is returned as-is.
@@ -32,9 +55,12 @@ exports.assertIsHexString = assertIsHexString;
32
55
  * @returns The prefixed hexadecimal string.
33
56
  */
34
57
  function add0x(hex) {
35
- if (hex.startsWith('0x') || hex.startsWith('0X')) {
58
+ if (hex.startsWith('0x')) {
36
59
  return hex;
37
60
  }
61
+ if (hex.startsWith('0X')) {
62
+ return `0x${hex.substring(2)}`;
63
+ }
38
64
  return `0x${hex}`;
39
65
  }
40
66
  exports.add0x = add0x;