@pezkuwi/util 14.0.1
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/README.md +17 -0
- package/package.json +49 -0
- package/src/array/chunk.spec.ts +29 -0
- package/src/array/chunk.ts +35 -0
- package/src/array/filter.spec.ts +20 -0
- package/src/array/filter.ts +24 -0
- package/src/array/flatten.spec.ts +33 -0
- package/src/array/flatten.ts +51 -0
- package/src/array/index.ts +14 -0
- package/src/array/range.spec.ts +29 -0
- package/src/array/range.ts +31 -0
- package/src/array/shuffle.spec.ts +39 -0
- package/src/array/shuffle.ts +27 -0
- package/src/array/unzip.spec.ts +14 -0
- package/src/array/unzip.ts +18 -0
- package/src/array/zip.spec.ts +26 -0
- package/src/array/zip.ts +17 -0
- package/src/assert.spec.ts +40 -0
- package/src/assert.ts +50 -0
- package/src/bi/consts.ts +112 -0
- package/src/bi/helpers.ts +23 -0
- package/src/bi/index.ts +16 -0
- package/src/bi/max.spec.ts +32 -0
- package/src/bi/min.spec.ts +26 -0
- package/src/bi/min.ts +16 -0
- package/src/bi/sqrt.spec.ts +59 -0
- package/src/bi/sqrt.ts +43 -0
- package/src/bi/toBigInt.spec.ts +69 -0
- package/src/bi/toBigInt.ts +33 -0
- package/src/bi/toHex.spec.ts +56 -0
- package/src/bi/toHex.ts +16 -0
- package/src/bi/toU8a.spec.ts +99 -0
- package/src/bi/toU8a.ts +72 -0
- package/src/bn/bn.ts +6 -0
- package/src/bn/consts.spec.ts +38 -0
- package/src/bn/consts.ts +112 -0
- package/src/bn/fromHex.spec.ts +15 -0
- package/src/bn/fromHex.ts +4 -0
- package/src/bn/index.ts +18 -0
- package/src/bn/max.spec.ts +32 -0
- package/src/bn/min.spec.ts +26 -0
- package/src/bn/min.ts +36 -0
- package/src/bn/sqrt.spec.ts +37 -0
- package/src/bn/sqrt.ts +50 -0
- package/src/bn/toBn.spec.ts +53 -0
- package/src/bn/toBn.ts +43 -0
- package/src/bn/toHex.spec.ts +50 -0
- package/src/bn/toHex.ts +27 -0
- package/src/bn/toU8a.spec.ts +60 -0
- package/src/bn/toU8a.ts +45 -0
- package/src/buffer/index.ts +8 -0
- package/src/buffer/toU8a.spec.ts +20 -0
- package/src/buffer/toU8a.ts +20 -0
- package/src/bundle.ts +35 -0
- package/src/compact/addLength.spec.ts +14 -0
- package/src/compact/addLength.ts +24 -0
- package/src/compact/defaults.ts +7 -0
- package/src/compact/fromU8a.spec.ts +84 -0
- package/src/compact/fromU8a.ts +109 -0
- package/src/compact/index.ts +28 -0
- package/src/compact/stripLength.spec.ts +17 -0
- package/src/compact/stripLength.ts +26 -0
- package/src/compact/toU8a.spec.ts +59 -0
- package/src/compact/toU8a.ts +53 -0
- package/src/compact/types.ts +4 -0
- package/src/detectPackage.spec.ts +110 -0
- package/src/detectPackage.ts +138 -0
- package/src/extractTime.spec.ts +21 -0
- package/src/extractTime.ts +71 -0
- package/src/float/index.ts +4 -0
- package/src/float/toU8a.spec.ts +52 -0
- package/src/float/toU8a.ts +30 -0
- package/src/format/formatBalance.spec.ts +296 -0
- package/src/format/formatBalance.ts +177 -0
- package/src/format/formatDate.spec.ts +17 -0
- package/src/format/formatDate.ts +22 -0
- package/src/format/formatDecimal.spec.ts +28 -0
- package/src/format/formatDecimal.ts +22 -0
- package/src/format/formatElapsed.spec.ts +44 -0
- package/src/format/formatElapsed.ts +35 -0
- package/src/format/formatNumber.spec.ts +60 -0
- package/src/format/formatNumber.ts +29 -0
- package/src/format/getSeparator.spec.ts +53 -0
- package/src/format/getSeparator.ts +15 -0
- package/src/format/index.ts +9 -0
- package/src/format/si.ts +52 -0
- package/src/has.spec.ts +12 -0
- package/src/has.ts +38 -0
- package/src/hex/addPrefix.spec.ts +32 -0
- package/src/hex/addPrefix.ts +26 -0
- package/src/hex/fixLength.spec.ts +38 -0
- package/src/hex/fixLength.ts +36 -0
- package/src/hex/hasPrefix.spec.ts +32 -0
- package/src/hex/hasPrefix.ts +24 -0
- package/src/hex/index.ts +16 -0
- package/src/hex/stripPrefix.spec.ts +44 -0
- package/src/hex/stripPrefix.ts +30 -0
- package/src/hex/toBigInt.spec.ts +74 -0
- package/src/hex/toBigInt.ts +19 -0
- package/src/hex/toBn.spec.ts +74 -0
- package/src/hex/toBn.ts +40 -0
- package/src/hex/toNumber.spec.ts +20 -0
- package/src/hex/toNumber.ts +24 -0
- package/src/hex/toString.spec.ts +20 -0
- package/src/hex/toString.ts +25 -0
- package/src/hex/toU8a.spec.ts +76 -0
- package/src/hex/toU8a.ts +68 -0
- package/src/hex/toU8aBuffer.spec.ts +38 -0
- package/src/hex/toU8aBuffer.ts +52 -0
- package/src/index.spec.ts +12 -0
- package/src/index.ts +6 -0
- package/src/is/array.spec.ts +20 -0
- package/src/is/array.ts +10 -0
- package/src/is/ascii.spec.ts +49 -0
- package/src/is/ascii.ts +52 -0
- package/src/is/bigInt.spec.ts +26 -0
- package/src/is/bigInt.ts +20 -0
- package/src/is/bn.spec.ts +21 -0
- package/src/is/bn.ts +23 -0
- package/src/is/boolean.spec.ts +26 -0
- package/src/is/boolean.ts +20 -0
- package/src/is/buffer.spec.ts +26 -0
- package/src/is/buffer.ts +28 -0
- package/src/is/childClass.spec.ts +36 -0
- package/src/is/childClass.ts +29 -0
- package/src/is/class.spec.ts +37 -0
- package/src/is/class.ts +12 -0
- package/src/is/codec.spec.ts +52 -0
- package/src/is/codec.ts +26 -0
- package/src/is/compact.spec.ts +27 -0
- package/src/is/compact.ts +19 -0
- package/src/is/error.spec.ts +20 -0
- package/src/is/error.ts +23 -0
- package/src/is/function.spec.ts +20 -0
- package/src/is/function.ts +23 -0
- package/src/is/helpers.ts +23 -0
- package/src/is/hex.spec.ts +77 -0
- package/src/is/hex.ts +36 -0
- package/src/is/index.ts +36 -0
- package/src/is/instanceOf.spec.ts +48 -0
- package/src/is/instanceOf.ts +24 -0
- package/src/is/ip.spec.ts +50 -0
- package/src/is/ip.ts +56 -0
- package/src/is/jsonObject.spec.ts +51 -0
- package/src/is/jsonObject.ts +45 -0
- package/src/is/null.spec.ts +20 -0
- package/src/is/null.ts +20 -0
- package/src/is/number.spec.ts +20 -0
- package/src/is/number.ts +20 -0
- package/src/is/object.spec.ts +32 -0
- package/src/is/object.ts +24 -0
- package/src/is/observable.spec.ts +26 -0
- package/src/is/observable.ts +22 -0
- package/src/is/promise.spec.ts +32 -0
- package/src/is/promise.ts +6 -0
- package/src/is/riscv.spec.ts +36 -0
- package/src/is/riscv.ts +27 -0
- package/src/is/string.spec.ts +32 -0
- package/src/is/string.ts +22 -0
- package/src/is/testChain.spec.ts +25 -0
- package/src/is/testChain.ts +12 -0
- package/src/is/toBigInt.spec.ts +22 -0
- package/src/is/toBigInt.ts +8 -0
- package/src/is/toBn.spec.ts +25 -0
- package/src/is/toBn.ts +8 -0
- package/src/is/u8a.spec.ts +42 -0
- package/src/is/u8a.ts +25 -0
- package/src/is/undefined.spec.ts +23 -0
- package/src/is/undefined.ts +21 -0
- package/src/is/utf8.spec.ts +42 -0
- package/src/is/utf8.ts +207 -0
- package/src/is/wasm.spec.ts +20 -0
- package/src/is/wasm.ts +17 -0
- package/src/lazy.spec.ts +71 -0
- package/src/lazy.ts +63 -0
- package/src/logger.spec.ts +188 -0
- package/src/logger.ts +160 -0
- package/src/memoize.spec.ts +79 -0
- package/src/memoize.ts +49 -0
- package/src/mod.ts +4 -0
- package/src/nextTick.ts +26 -0
- package/src/noop.ts +16 -0
- package/src/number/index.ts +9 -0
- package/src/number/toHex.spec.ts +44 -0
- package/src/number/toHex.ts +27 -0
- package/src/number/toU8a.spec.ts +50 -0
- package/src/number/toU8a.ts +25 -0
- package/src/object/clear.spec.ts +14 -0
- package/src/object/clear.ts +16 -0
- package/src/object/copy.spec.ts +17 -0
- package/src/object/copy.ts +12 -0
- package/src/object/entries.spec.ts +20 -0
- package/src/object/entries.ts +12 -0
- package/src/object/index.ts +10 -0
- package/src/object/keys.spec.ts +19 -0
- package/src/object/keys.ts +10 -0
- package/src/object/property.spec.ts +149 -0
- package/src/object/property.ts +39 -0
- package/src/object/spread.spec.ts +36 -0
- package/src/object/spread.ts +38 -0
- package/src/object/values.spec.ts +19 -0
- package/src/object/values.ts +10 -0
- package/src/packageDetect.ts +13 -0
- package/src/packageInfo.ts +6 -0
- package/src/promisify.spec.ts +50 -0
- package/src/promisify.ts +30 -0
- package/src/string/camelCase.spec.ts +119 -0
- package/src/string/camelCase.ts +79 -0
- package/src/string/index.ts +12 -0
- package/src/string/lowerFirst.spec.ts +41 -0
- package/src/string/lowerFirst.ts +46 -0
- package/src/string/pascalCase.spec.ts +26 -0
- package/src/string/shorten.spec.ts +38 -0
- package/src/string/shorten.ts +24 -0
- package/src/string/toHex.spec.ts +26 -0
- package/src/string/toHex.ts +27 -0
- package/src/string/toU8a.spec.ts +31 -0
- package/src/string/toU8a.ts +28 -0
- package/src/string/upperFirst.spec.ts +41 -0
- package/src/stringify.spec.ts +33 -0
- package/src/stringify.ts +20 -0
- package/src/test/index.ts +4 -0
- package/src/test/performance.ts +92 -0
- package/src/types.ts +100 -0
- package/src/u8a/cmp.spec.ts +62 -0
- package/src/u8a/cmp.ts +50 -0
- package/src/u8a/concat.spec.ts +42 -0
- package/src/u8a/concat.ts +60 -0
- package/src/u8a/concatBuffer.ts +34 -0
- package/src/u8a/empty.spec.ts +46 -0
- package/src/u8a/empty.ts +22 -0
- package/src/u8a/eq.spec.ts +113 -0
- package/src/u8a/eq.ts +46 -0
- package/src/u8a/fixLength.spec.ts +34 -0
- package/src/u8a/fixLength.ts +34 -0
- package/src/u8a/index.ts +22 -0
- package/src/u8a/sorted.spec.ts +20 -0
- package/src/u8a/sorted.ts +22 -0
- package/src/u8a/toBigInt.spec.ts +106 -0
- package/src/u8a/toBigInt.ts +100 -0
- package/src/u8a/toBn.spec.ts +106 -0
- package/src/u8a/toBn.ts +101 -0
- package/src/u8a/toBuffer.spec.ts +20 -0
- package/src/u8a/toBuffer.ts +28 -0
- package/src/u8a/toFloat.spec.ts +86 -0
- package/src/u8a/toFloat.ts +26 -0
- package/src/u8a/toHex.spec.ts +94 -0
- package/src/u8a/toHex.ts +68 -0
- package/src/u8a/toHexBuffer.spec.ts +63 -0
- package/src/u8a/toHexBuffer.ts +30 -0
- package/src/u8a/toNumber.spec.ts +47 -0
- package/src/u8a/toNumber.ts +80 -0
- package/src/u8a/toString.spec.ts +36 -0
- package/src/u8a/toString.ts +26 -0
- package/src/u8a/toU8a.spec.ts +63 -0
- package/src/u8a/toU8a.ts +46 -0
- package/src/u8a/wrap.spec.ts +139 -0
- package/src/u8a/wrap.ts +65 -0
- package/tsconfig.build.json +19 -0
- package/tsconfig.spec.json +17 -0
package/src/is/utf8.ts
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
// Adapted from https://github.com/JulienPalard/is_utf8/blob/master/is_utf8.c
|
|
5
|
+
|
|
6
|
+
import { u8aToU8a } from '../u8a/toU8a.js';
|
|
7
|
+
import { isString } from './string.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @name isUtf8
|
|
11
|
+
* @summary Tests if the input is valid Utf8
|
|
12
|
+
* @description
|
|
13
|
+
* Checks to see if the input string or Uint8Array is valid Utf8
|
|
14
|
+
*/
|
|
15
|
+
export function isUtf8 (value?: number[] | Uint8Array | string | null): boolean {
|
|
16
|
+
if (!value) {
|
|
17
|
+
return isString(value);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const u8a = u8aToU8a(value);
|
|
21
|
+
const len = u8a.length;
|
|
22
|
+
let i = 0;
|
|
23
|
+
|
|
24
|
+
while (i < len) {
|
|
25
|
+
if (u8a[i] <= 0x7F) /* 00..7F */ {
|
|
26
|
+
i += 1;
|
|
27
|
+
} else if (u8a[i] >= 0xC2 && u8a[i] <= 0xDF) /* C2..DF 80..BF */ {
|
|
28
|
+
if (i + 1 < len) /* Expect a 2nd byte */ {
|
|
29
|
+
if (u8a[i + 1] < 0x80 || u8a[i + 1] > 0xBF) {
|
|
30
|
+
// *message = "After a first byte between C2 and DF, expecting a 2nd byte between 80 and BF";
|
|
31
|
+
// *faulty_bytes = 2;
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
} else {
|
|
35
|
+
// *message = "After a first byte between C2 and DF, expecting a 2nd byte.";
|
|
36
|
+
// *faulty_bytes = 1;
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
i += 2;
|
|
41
|
+
} else if (u8a[i] === 0xE0) /* E0 A0..BF 80..BF */ {
|
|
42
|
+
if (i + 2 < len) /* Expect a 2nd and 3rd byte */ {
|
|
43
|
+
if (u8a[i + 1] < 0xA0 || u8a[i + 1] > 0xBF) {
|
|
44
|
+
// *message = "After a first byte of E0, expecting a 2nd byte between A0 and BF.";
|
|
45
|
+
// *faulty_bytes = 2;
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) {
|
|
50
|
+
// *message = "After a first byte of E0, expecting a 3nd byte between 80 and BF.";
|
|
51
|
+
// *faulty_bytes = 3;
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
// *message = "After a first byte of E0, expecting two following bytes.";
|
|
56
|
+
// *faulty_bytes = 1;
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
i += 3;
|
|
61
|
+
} else if (u8a[i] >= 0xE1 && u8a[i] <= 0xEC) /* E1..EC 80..BF 80..BF */ {
|
|
62
|
+
if (i + 2 < len) /* Expect a 2nd and 3rd byte */ {
|
|
63
|
+
if (u8a[i + 1] < 0x80 || u8a[i + 1] > 0xBF) {
|
|
64
|
+
// *message = "After a first byte between E1 and EC, expecting the 2nd byte between 80 and BF.";
|
|
65
|
+
// *faulty_bytes = 2;
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) {
|
|
70
|
+
// *message = "After a first byte between E1 and EC, expecting the 3rd byte between 80 and BF.";
|
|
71
|
+
// *faulty_bytes = 3;
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
} else {
|
|
75
|
+
// *message = "After a first byte between E1 and EC, expecting two following bytes.";
|
|
76
|
+
// *faulty_bytes = 1;
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
i += 3;
|
|
81
|
+
} else if (u8a[i] === 0xED) /* ED 80..9F 80..BF */ {
|
|
82
|
+
if (i + 2 < len) /* Expect a 2nd and 3rd byte */ {
|
|
83
|
+
if (u8a[i + 1] < 0x80 || u8a[i + 1] > 0x9F) {
|
|
84
|
+
// *message = "After a first byte of ED, expecting 2nd byte between 80 and 9F.";
|
|
85
|
+
// *faulty_bytes = 2;
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) {
|
|
90
|
+
// *message = "After a first byte of ED, expecting 3rd byte between 80 and BF.";
|
|
91
|
+
// *faulty_bytes = 3;
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
} else {
|
|
95
|
+
// *message = "After a first byte of ED, expecting two following bytes.";
|
|
96
|
+
// *faulty_bytes = 1;
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
i += 3;
|
|
101
|
+
} else if (u8a[i] >= 0xEE && u8a[i] <= 0xEF) /* EE..EF 80..BF 80..BF */ {
|
|
102
|
+
if (i + 2 < len) /* Expect a 2nd and 3rd byte */ {
|
|
103
|
+
if (u8a[i + 1] < 0x80 || u8a[i + 1] > 0xBF) {
|
|
104
|
+
// *message = "After a first byte between EE and EF, expecting 2nd byte between 80 and BF.";
|
|
105
|
+
// *faulty_bytes = 2;
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) {
|
|
110
|
+
// *message = "After a first byte between EE and EF, expecting 3rd byte between 80 and BF.";
|
|
111
|
+
// *faulty_bytes = 3;
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
} else {
|
|
115
|
+
// *message = "After a first byte between EE and EF, two following bytes.";
|
|
116
|
+
// *faulty_bytes = 1;
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
i += 3;
|
|
121
|
+
} else if (u8a[i] === 0xF0) /* F0 90..BF 80..BF 80..BF */ {
|
|
122
|
+
if (i + 3 < len) /* Expect a 2nd, 3rd 3th byte */ {
|
|
123
|
+
if (u8a[i + 1] < 0x90 || u8a[i + 1] > 0xBF) {
|
|
124
|
+
// *message = "After a first byte of F0, expecting 2nd byte between 90 and BF.";
|
|
125
|
+
// *faulty_bytes = 2;
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) {
|
|
130
|
+
// *message = "After a first byte of F0, expecting 3rd byte between 80 and BF.";
|
|
131
|
+
// *faulty_bytes = 3;
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (u8a[i + 3] < 0x80 || u8a[i + 3] > 0xBF) {
|
|
136
|
+
// *message = "After a first byte of F0, expecting 4th byte between 80 and BF.";
|
|
137
|
+
// *faulty_bytes = 4;
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
} else {
|
|
141
|
+
// *message = "After a first byte of F0, expecting three following bytes.";
|
|
142
|
+
// *faulty_bytes = 1;
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
i += 4;
|
|
147
|
+
} else if (u8a[i] >= 0xF1 && u8a[i] <= 0xF3) /* F1..F3 80..BF 80..BF 80..BF */ {
|
|
148
|
+
if (i + 3 < len) /* Expect a 2nd, 3rd 3th byte */ {
|
|
149
|
+
if (u8a[i + 1] < 0x80 || u8a[i + 1] > 0xBF) {
|
|
150
|
+
// *message = "After a first byte of F1, F2, or F3, expecting a 2nd byte between 80 and BF.";
|
|
151
|
+
// *faulty_bytes = 2;
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) {
|
|
156
|
+
// *message = "After a first byte of F1, F2, or F3, expecting a 3rd byte between 80 and BF.";
|
|
157
|
+
// *faulty_bytes = 3;
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (u8a[i + 3] < 0x80 || u8a[i + 3] > 0xBF) {
|
|
162
|
+
// *message = "After a first byte of F1, F2, or F3, expecting a 4th byte between 80 and BF.";
|
|
163
|
+
// *faulty_bytes = 4;
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
} else {
|
|
167
|
+
// *message = "After a first byte of F1, F2, or F3, expecting three following bytes.";
|
|
168
|
+
// *faulty_bytes = 1;
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
i += 4;
|
|
173
|
+
} else if (u8a[i] === 0xF4) /* F4 80..8F 80..BF 80..BF */ {
|
|
174
|
+
if (i + 3 < len) /* Expect a 2nd, 3rd 3th byte */ {
|
|
175
|
+
if (u8a[i + 1] < 0x80 || u8a[i + 1] > 0x8F) {
|
|
176
|
+
// *message = "After a first byte of F4, expecting 2nd byte between 80 and 8F.";
|
|
177
|
+
// *faulty_bytes = 2;
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (u8a[i + 2] < 0x80 || u8a[i + 2] > 0xBF) {
|
|
182
|
+
// *message = "After a first byte of F4, expecting 3rd byte between 80 and BF.";
|
|
183
|
+
// *faulty_bytes = 3;
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (u8a[i + 3] < 0x80 || u8a[i + 3] > 0xBF) {
|
|
188
|
+
// *message = "After a first byte of F4, expecting 4th byte between 80 and BF.";
|
|
189
|
+
// *faulty_bytes = 4;
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
} else {
|
|
193
|
+
// *message = "After a first byte of F4, expecting three following bytes.";
|
|
194
|
+
// *faulty_bytes = 1;
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
i += 4;
|
|
199
|
+
} else {
|
|
200
|
+
// *message = "Expecting bytes in the following ranges: 00..7F C2..F4.";
|
|
201
|
+
// *faulty_bytes = 1;
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
|
5
|
+
|
|
6
|
+
import { isWasm } from './index.js';
|
|
7
|
+
|
|
8
|
+
describe('isWasm', (): void => {
|
|
9
|
+
it('is false on no value', (): void => {
|
|
10
|
+
expect(isWasm()).toEqual(false);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('is false on non-wasm header', (): void => {
|
|
14
|
+
expect(isWasm(new Uint8Array([1, 2, 3]))).toEqual(false);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('is true when a wasm header is found', (): void => {
|
|
18
|
+
expect(isWasm(new Uint8Array([0, 97, 115, 109, 1, 2, 3]))).toEqual(true);
|
|
19
|
+
});
|
|
20
|
+
});
|
package/src/is/wasm.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { u8aEq } from '../u8a/eq.js';
|
|
5
|
+
import { isU8a } from './u8a.js';
|
|
6
|
+
|
|
7
|
+
const WASM_MAGIC = new Uint8Array([0, 97, 115, 109]); // \0asm
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @name isWasm
|
|
11
|
+
* @summary Tests if the input has a WASM header
|
|
12
|
+
* @description
|
|
13
|
+
* Checks to see if the input Uint8Array contains a valid WASM header
|
|
14
|
+
*/
|
|
15
|
+
export function isWasm (value?: unknown): value is Uint8Array {
|
|
16
|
+
return isU8a(value) && u8aEq(value.subarray(0, 4), WASM_MAGIC);
|
|
17
|
+
}
|
package/src/lazy.spec.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
|
5
|
+
|
|
6
|
+
import { lazyMethod, lazyMethods } from './index.js';
|
|
7
|
+
|
|
8
|
+
describe('lazyMethod', (): void => {
|
|
9
|
+
it('adds a key on the object', (): void => {
|
|
10
|
+
const test: { a?: number } = {};
|
|
11
|
+
|
|
12
|
+
expect(test.a).not.toBeDefined();
|
|
13
|
+
|
|
14
|
+
lazyMethod(test, 'a', () => 123);
|
|
15
|
+
|
|
16
|
+
expect(test.a).toEqual(123);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('allows the name to be retrieved', (): void => {
|
|
20
|
+
const test: { a?: number } = {};
|
|
21
|
+
|
|
22
|
+
expect(test.a).not.toBeDefined();
|
|
23
|
+
|
|
24
|
+
lazyMethod(test, 456, () => 123, () => 'a');
|
|
25
|
+
|
|
26
|
+
expect(test.a).toEqual(123);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('calls the getter lazily', (): void => {
|
|
30
|
+
const test: { a?: number } = {};
|
|
31
|
+
const getter = jest.fn(() => 123);
|
|
32
|
+
|
|
33
|
+
expect(test.a).not.toBeDefined();
|
|
34
|
+
|
|
35
|
+
lazyMethod(test, 'a', getter);
|
|
36
|
+
|
|
37
|
+
expect(Object.prototype.hasOwnProperty.call(test, 'a')).toEqual(true);
|
|
38
|
+
expect(getter).not.toHaveBeenCalled();
|
|
39
|
+
expect(test.a).toEqual(123);
|
|
40
|
+
expect(getter).toHaveBeenCalledWith('a', 0, expect.objectContaining({}));
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('calls the getter a single time', (): void => {
|
|
44
|
+
const test: { a?: number } = {};
|
|
45
|
+
const getter = jest.fn(() => 123);
|
|
46
|
+
|
|
47
|
+
lazyMethod(test, 'a', getter);
|
|
48
|
+
|
|
49
|
+
expect(getter).not.toHaveBeenCalled();
|
|
50
|
+
expect(test.a).toEqual(123);
|
|
51
|
+
expect(getter).toHaveBeenCalledWith('a', 0, expect.objectContaining({}));
|
|
52
|
+
expect(test.a).toEqual(123);
|
|
53
|
+
expect(getter).toHaveBeenCalledTimes(1);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe('lazyMethods', (): void => {
|
|
58
|
+
it('sets multiple properties', (): void => {
|
|
59
|
+
const test: { a?: string; b?: string; c?: string } = {};
|
|
60
|
+
const getter = jest.fn((name: string) => name);
|
|
61
|
+
|
|
62
|
+
lazyMethods(test, ['a', 'b', 'c'], getter);
|
|
63
|
+
|
|
64
|
+
expect(test.a).toEqual('a');
|
|
65
|
+
expect(test.b).toEqual('b');
|
|
66
|
+
expect(getter).toHaveBeenCalledTimes(2);
|
|
67
|
+
expect(test.a).toEqual('a');
|
|
68
|
+
expect(test.b).toEqual('b');
|
|
69
|
+
expect(getter).toHaveBeenCalledTimes(2);
|
|
70
|
+
});
|
|
71
|
+
});
|
package/src/lazy.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
type AnyFn = (...args: unknown[]) => unknown;
|
|
5
|
+
|
|
6
|
+
interface WithToString { toString: () => string }
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @name lazyMethod
|
|
10
|
+
* @description
|
|
11
|
+
* Creates a lazy, on-demand getter for the specific value. Upon get the value will be evaluated.
|
|
12
|
+
*/
|
|
13
|
+
export function lazyMethod <T, K, S> (result: Record<string, T> | AnyFn, item: K, creator: (item: K, index: number, self: S) => T, getName?: (item: K, index: number) => string, index = 0): void {
|
|
14
|
+
const name = getName
|
|
15
|
+
? getName(item, index)
|
|
16
|
+
: (item as WithToString).toString();
|
|
17
|
+
let value: T | undefined;
|
|
18
|
+
|
|
19
|
+
Object.defineProperty(result, name, {
|
|
20
|
+
// This allows for re-configuration with the embedded defineProperty below
|
|
21
|
+
// and ensures that on tested browsers and Node, it _will_ be redefined
|
|
22
|
+
// and thus short-circuited for future access
|
|
23
|
+
configurable: true,
|
|
24
|
+
enumerable: true,
|
|
25
|
+
|
|
26
|
+
// Use a function here, we don't want to capture the outer this, i.e.
|
|
27
|
+
// don't use arrow functions in this context since we have a this inside
|
|
28
|
+
get: function (): T {
|
|
29
|
+
// This check should _always_ be false and unneeded, since we override
|
|
30
|
+
// with a value below ... however we ensure we are quire vigilant against
|
|
31
|
+
// all environment failures, so we are rather be safe than sorry
|
|
32
|
+
if (value === undefined) {
|
|
33
|
+
value = creator(item, index, this as S);
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
// re-define the property as a value, next time around this
|
|
37
|
+
// getter will only return the computed value
|
|
38
|
+
Object.defineProperty(this, name, { value });
|
|
39
|
+
} catch {
|
|
40
|
+
// ignore any errors, since this _should_ not happen due to
|
|
41
|
+
// the "configurable" property above. But if it ever does
|
|
42
|
+
// from here-on we will be the cached value the next time
|
|
43
|
+
// around (with a very slight dip in performance)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return value;
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @name lazyMethods
|
|
54
|
+
* @description
|
|
55
|
+
* Creates lazy, on-demand getters for the specific values.
|
|
56
|
+
*/
|
|
57
|
+
export function lazyMethods <T, K, S> (result: Record<string, T>, items: readonly K[], creator: (item: K, index: number, self: S) => T, getName?: (item: K, index: number) => string): Record<string, T> {
|
|
58
|
+
for (let i = 0, count = items.length; i < count; i++) {
|
|
59
|
+
lazyMethod(result, items[i], creator, getName, i);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
|
5
|
+
|
|
6
|
+
import type { Logger } from './types.js';
|
|
7
|
+
|
|
8
|
+
import { BN } from './bn/index.js';
|
|
9
|
+
import { logger, loggerFormat } from './index.js';
|
|
10
|
+
|
|
11
|
+
describe('logger', (): void => {
|
|
12
|
+
const dateMatch = expect.stringMatching(/20[0-9]{2}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/);
|
|
13
|
+
const prefixMatch = expect.stringMatching(/TEST:/);
|
|
14
|
+
let l: Logger;
|
|
15
|
+
let ln: Logger;
|
|
16
|
+
let spy: Partial<Console>;
|
|
17
|
+
let oldEnv: typeof process.env;
|
|
18
|
+
|
|
19
|
+
beforeEach((): void => {
|
|
20
|
+
oldEnv = process.env;
|
|
21
|
+
process.env['NODE_ENV'] = 'development';
|
|
22
|
+
|
|
23
|
+
ln = logger('notDebug');
|
|
24
|
+
|
|
25
|
+
process.env['DEBUG'] = 'test';
|
|
26
|
+
|
|
27
|
+
l = logger('test');
|
|
28
|
+
|
|
29
|
+
spy = {
|
|
30
|
+
error: jest.fn(),
|
|
31
|
+
log: jest.fn(),
|
|
32
|
+
warn: jest.fn()
|
|
33
|
+
};
|
|
34
|
+
global.console = spy as Console;
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
afterEach((): void => {
|
|
38
|
+
process.env = oldEnv;
|
|
39
|
+
jest.restoreAllMocks();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
describe('loggerFormat', (): void => {
|
|
43
|
+
it('returns null as-is', (): void => {
|
|
44
|
+
expect(loggerFormat(null)).toEqual(null);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('returns undefined as-is', (): void => {
|
|
48
|
+
expect(loggerFormat(undefined)).toEqual(undefined);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('logs to console.log with .log', (): void => {
|
|
53
|
+
l.log('console.log test');
|
|
54
|
+
|
|
55
|
+
expect(spy.log).toHaveBeenCalledWith(
|
|
56
|
+
dateMatch,
|
|
57
|
+
prefixMatch,
|
|
58
|
+
expect.stringMatching('console.log test')
|
|
59
|
+
);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('logs with multiple values', (): void => {
|
|
63
|
+
l.log('test', 'a', 2, new BN('12345678900987654321'), Buffer.from([0, 1, 2, 3]));
|
|
64
|
+
|
|
65
|
+
expect(spy.log).toHaveBeenCalledWith(
|
|
66
|
+
dateMatch,
|
|
67
|
+
prefixMatch,
|
|
68
|
+
expect.stringMatching('test'),
|
|
69
|
+
expect.stringMatching('a'),
|
|
70
|
+
2,
|
|
71
|
+
expect.stringMatching('12345678900987654321'),
|
|
72
|
+
expect.stringMatching('0x00010203')
|
|
73
|
+
);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('logs when called with function', (): void => {
|
|
77
|
+
l.log((): string => 'a function test');
|
|
78
|
+
|
|
79
|
+
expect(spy.log).toHaveBeenCalledWith(
|
|
80
|
+
dateMatch,
|
|
81
|
+
prefixMatch,
|
|
82
|
+
expect.stringMatching('a function test')
|
|
83
|
+
);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('logs to console.error with .error', (): void => {
|
|
87
|
+
l.error('console.error test');
|
|
88
|
+
|
|
89
|
+
expect(spy.error).toHaveBeenCalledWith(
|
|
90
|
+
dateMatch,
|
|
91
|
+
prefixMatch,
|
|
92
|
+
expect.stringMatching('console.error test')
|
|
93
|
+
);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('logs to console.warn with .warn', (): void => {
|
|
97
|
+
l.warn('console.warn test');
|
|
98
|
+
|
|
99
|
+
expect(spy.warn).toHaveBeenCalledWith(
|
|
100
|
+
dateMatch,
|
|
101
|
+
prefixMatch,
|
|
102
|
+
expect.stringMatching('console.warn test')
|
|
103
|
+
);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('does debug log when DEBUG specified', (): void => {
|
|
107
|
+
l.debug('test');
|
|
108
|
+
|
|
109
|
+
expect(spy.log).toHaveBeenCalledWith(
|
|
110
|
+
dateMatch,
|
|
111
|
+
prefixMatch,
|
|
112
|
+
expect.stringMatching('test')
|
|
113
|
+
);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('does debug log when DEBUG partial specified', (): void => {
|
|
117
|
+
process.env['DEBUG'] = 'test*';
|
|
118
|
+
|
|
119
|
+
l = logger('testing');
|
|
120
|
+
l.debug('test');
|
|
121
|
+
|
|
122
|
+
expect(spy.log).toHaveBeenCalledWith(
|
|
123
|
+
dateMatch,
|
|
124
|
+
expect.stringMatching(/TESTING:/),
|
|
125
|
+
expect.stringMatching('test')
|
|
126
|
+
);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('does not debug log when non-matching DEBUG specified', (): void => {
|
|
130
|
+
process.env['DEBUG'] = 'blah';
|
|
131
|
+
|
|
132
|
+
l = logger('test');
|
|
133
|
+
l.debug('test');
|
|
134
|
+
|
|
135
|
+
expect(spy.log).not.toHaveBeenCalled();
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('does debug log when DEBUG=* specified', (): void => {
|
|
139
|
+
process.env['DEBUG'] = '*';
|
|
140
|
+
|
|
141
|
+
l = logger('test');
|
|
142
|
+
l.debug('test');
|
|
143
|
+
|
|
144
|
+
expect(spy.log).toHaveBeenCalled();
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('does not debug log when no process.env', (): void => {
|
|
148
|
+
process.env = undefined as unknown as typeof process.env;
|
|
149
|
+
|
|
150
|
+
l = logger('test');
|
|
151
|
+
l.debug('test');
|
|
152
|
+
|
|
153
|
+
expect(spy.log).not.toHaveBeenCalled();
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('does not debug log when no DEBUG specified', (): void => {
|
|
157
|
+
ln.debug('test');
|
|
158
|
+
|
|
159
|
+
expect(spy.log).not.toHaveBeenCalled();
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it('does not debug log when explicitly excluded', (): void => {
|
|
163
|
+
process.env['DEBUG'] = '*,-test';
|
|
164
|
+
|
|
165
|
+
l = logger('test');
|
|
166
|
+
l.debug('test');
|
|
167
|
+
|
|
168
|
+
expect(spy.log).not.toHaveBeenCalled();
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it('does not debug log when part of exclusion group', (): void => {
|
|
172
|
+
process.env['DEBUG'] = '*,-test:*';
|
|
173
|
+
|
|
174
|
+
l = logger('test:sub');
|
|
175
|
+
l.debug('test');
|
|
176
|
+
|
|
177
|
+
expect(spy.log).not.toHaveBeenCalled();
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('does debug log when not part of exclusion groups', (): void => {
|
|
181
|
+
process.env['DEBUG'] = '*,-test:*,-tes,-a:*';
|
|
182
|
+
|
|
183
|
+
l = logger('test');
|
|
184
|
+
l.debug('test');
|
|
185
|
+
|
|
186
|
+
expect(spy.log).toHaveBeenCalled();
|
|
187
|
+
});
|
|
188
|
+
});
|