@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.
Files changed (260) hide show
  1. package/README.md +17 -0
  2. package/package.json +49 -0
  3. package/src/array/chunk.spec.ts +29 -0
  4. package/src/array/chunk.ts +35 -0
  5. package/src/array/filter.spec.ts +20 -0
  6. package/src/array/filter.ts +24 -0
  7. package/src/array/flatten.spec.ts +33 -0
  8. package/src/array/flatten.ts +51 -0
  9. package/src/array/index.ts +14 -0
  10. package/src/array/range.spec.ts +29 -0
  11. package/src/array/range.ts +31 -0
  12. package/src/array/shuffle.spec.ts +39 -0
  13. package/src/array/shuffle.ts +27 -0
  14. package/src/array/unzip.spec.ts +14 -0
  15. package/src/array/unzip.ts +18 -0
  16. package/src/array/zip.spec.ts +26 -0
  17. package/src/array/zip.ts +17 -0
  18. package/src/assert.spec.ts +40 -0
  19. package/src/assert.ts +50 -0
  20. package/src/bi/consts.ts +112 -0
  21. package/src/bi/helpers.ts +23 -0
  22. package/src/bi/index.ts +16 -0
  23. package/src/bi/max.spec.ts +32 -0
  24. package/src/bi/min.spec.ts +26 -0
  25. package/src/bi/min.ts +16 -0
  26. package/src/bi/sqrt.spec.ts +59 -0
  27. package/src/bi/sqrt.ts +43 -0
  28. package/src/bi/toBigInt.spec.ts +69 -0
  29. package/src/bi/toBigInt.ts +33 -0
  30. package/src/bi/toHex.spec.ts +56 -0
  31. package/src/bi/toHex.ts +16 -0
  32. package/src/bi/toU8a.spec.ts +99 -0
  33. package/src/bi/toU8a.ts +72 -0
  34. package/src/bn/bn.ts +6 -0
  35. package/src/bn/consts.spec.ts +38 -0
  36. package/src/bn/consts.ts +112 -0
  37. package/src/bn/fromHex.spec.ts +15 -0
  38. package/src/bn/fromHex.ts +4 -0
  39. package/src/bn/index.ts +18 -0
  40. package/src/bn/max.spec.ts +32 -0
  41. package/src/bn/min.spec.ts +26 -0
  42. package/src/bn/min.ts +36 -0
  43. package/src/bn/sqrt.spec.ts +37 -0
  44. package/src/bn/sqrt.ts +50 -0
  45. package/src/bn/toBn.spec.ts +53 -0
  46. package/src/bn/toBn.ts +43 -0
  47. package/src/bn/toHex.spec.ts +50 -0
  48. package/src/bn/toHex.ts +27 -0
  49. package/src/bn/toU8a.spec.ts +60 -0
  50. package/src/bn/toU8a.ts +45 -0
  51. package/src/buffer/index.ts +8 -0
  52. package/src/buffer/toU8a.spec.ts +20 -0
  53. package/src/buffer/toU8a.ts +20 -0
  54. package/src/bundle.ts +35 -0
  55. package/src/compact/addLength.spec.ts +14 -0
  56. package/src/compact/addLength.ts +24 -0
  57. package/src/compact/defaults.ts +7 -0
  58. package/src/compact/fromU8a.spec.ts +84 -0
  59. package/src/compact/fromU8a.ts +109 -0
  60. package/src/compact/index.ts +28 -0
  61. package/src/compact/stripLength.spec.ts +17 -0
  62. package/src/compact/stripLength.ts +26 -0
  63. package/src/compact/toU8a.spec.ts +59 -0
  64. package/src/compact/toU8a.ts +53 -0
  65. package/src/compact/types.ts +4 -0
  66. package/src/detectPackage.spec.ts +110 -0
  67. package/src/detectPackage.ts +138 -0
  68. package/src/extractTime.spec.ts +21 -0
  69. package/src/extractTime.ts +71 -0
  70. package/src/float/index.ts +4 -0
  71. package/src/float/toU8a.spec.ts +52 -0
  72. package/src/float/toU8a.ts +30 -0
  73. package/src/format/formatBalance.spec.ts +296 -0
  74. package/src/format/formatBalance.ts +177 -0
  75. package/src/format/formatDate.spec.ts +17 -0
  76. package/src/format/formatDate.ts +22 -0
  77. package/src/format/formatDecimal.spec.ts +28 -0
  78. package/src/format/formatDecimal.ts +22 -0
  79. package/src/format/formatElapsed.spec.ts +44 -0
  80. package/src/format/formatElapsed.ts +35 -0
  81. package/src/format/formatNumber.spec.ts +60 -0
  82. package/src/format/formatNumber.ts +29 -0
  83. package/src/format/getSeparator.spec.ts +53 -0
  84. package/src/format/getSeparator.ts +15 -0
  85. package/src/format/index.ts +9 -0
  86. package/src/format/si.ts +52 -0
  87. package/src/has.spec.ts +12 -0
  88. package/src/has.ts +38 -0
  89. package/src/hex/addPrefix.spec.ts +32 -0
  90. package/src/hex/addPrefix.ts +26 -0
  91. package/src/hex/fixLength.spec.ts +38 -0
  92. package/src/hex/fixLength.ts +36 -0
  93. package/src/hex/hasPrefix.spec.ts +32 -0
  94. package/src/hex/hasPrefix.ts +24 -0
  95. package/src/hex/index.ts +16 -0
  96. package/src/hex/stripPrefix.spec.ts +44 -0
  97. package/src/hex/stripPrefix.ts +30 -0
  98. package/src/hex/toBigInt.spec.ts +74 -0
  99. package/src/hex/toBigInt.ts +19 -0
  100. package/src/hex/toBn.spec.ts +74 -0
  101. package/src/hex/toBn.ts +40 -0
  102. package/src/hex/toNumber.spec.ts +20 -0
  103. package/src/hex/toNumber.ts +24 -0
  104. package/src/hex/toString.spec.ts +20 -0
  105. package/src/hex/toString.ts +25 -0
  106. package/src/hex/toU8a.spec.ts +76 -0
  107. package/src/hex/toU8a.ts +68 -0
  108. package/src/hex/toU8aBuffer.spec.ts +38 -0
  109. package/src/hex/toU8aBuffer.ts +52 -0
  110. package/src/index.spec.ts +12 -0
  111. package/src/index.ts +6 -0
  112. package/src/is/array.spec.ts +20 -0
  113. package/src/is/array.ts +10 -0
  114. package/src/is/ascii.spec.ts +49 -0
  115. package/src/is/ascii.ts +52 -0
  116. package/src/is/bigInt.spec.ts +26 -0
  117. package/src/is/bigInt.ts +20 -0
  118. package/src/is/bn.spec.ts +21 -0
  119. package/src/is/bn.ts +23 -0
  120. package/src/is/boolean.spec.ts +26 -0
  121. package/src/is/boolean.ts +20 -0
  122. package/src/is/buffer.spec.ts +26 -0
  123. package/src/is/buffer.ts +28 -0
  124. package/src/is/childClass.spec.ts +36 -0
  125. package/src/is/childClass.ts +29 -0
  126. package/src/is/class.spec.ts +37 -0
  127. package/src/is/class.ts +12 -0
  128. package/src/is/codec.spec.ts +52 -0
  129. package/src/is/codec.ts +26 -0
  130. package/src/is/compact.spec.ts +27 -0
  131. package/src/is/compact.ts +19 -0
  132. package/src/is/error.spec.ts +20 -0
  133. package/src/is/error.ts +23 -0
  134. package/src/is/function.spec.ts +20 -0
  135. package/src/is/function.ts +23 -0
  136. package/src/is/helpers.ts +23 -0
  137. package/src/is/hex.spec.ts +77 -0
  138. package/src/is/hex.ts +36 -0
  139. package/src/is/index.ts +36 -0
  140. package/src/is/instanceOf.spec.ts +48 -0
  141. package/src/is/instanceOf.ts +24 -0
  142. package/src/is/ip.spec.ts +50 -0
  143. package/src/is/ip.ts +56 -0
  144. package/src/is/jsonObject.spec.ts +51 -0
  145. package/src/is/jsonObject.ts +45 -0
  146. package/src/is/null.spec.ts +20 -0
  147. package/src/is/null.ts +20 -0
  148. package/src/is/number.spec.ts +20 -0
  149. package/src/is/number.ts +20 -0
  150. package/src/is/object.spec.ts +32 -0
  151. package/src/is/object.ts +24 -0
  152. package/src/is/observable.spec.ts +26 -0
  153. package/src/is/observable.ts +22 -0
  154. package/src/is/promise.spec.ts +32 -0
  155. package/src/is/promise.ts +6 -0
  156. package/src/is/riscv.spec.ts +36 -0
  157. package/src/is/riscv.ts +27 -0
  158. package/src/is/string.spec.ts +32 -0
  159. package/src/is/string.ts +22 -0
  160. package/src/is/testChain.spec.ts +25 -0
  161. package/src/is/testChain.ts +12 -0
  162. package/src/is/toBigInt.spec.ts +22 -0
  163. package/src/is/toBigInt.ts +8 -0
  164. package/src/is/toBn.spec.ts +25 -0
  165. package/src/is/toBn.ts +8 -0
  166. package/src/is/u8a.spec.ts +42 -0
  167. package/src/is/u8a.ts +25 -0
  168. package/src/is/undefined.spec.ts +23 -0
  169. package/src/is/undefined.ts +21 -0
  170. package/src/is/utf8.spec.ts +42 -0
  171. package/src/is/utf8.ts +207 -0
  172. package/src/is/wasm.spec.ts +20 -0
  173. package/src/is/wasm.ts +17 -0
  174. package/src/lazy.spec.ts +71 -0
  175. package/src/lazy.ts +63 -0
  176. package/src/logger.spec.ts +188 -0
  177. package/src/logger.ts +160 -0
  178. package/src/memoize.spec.ts +79 -0
  179. package/src/memoize.ts +49 -0
  180. package/src/mod.ts +4 -0
  181. package/src/nextTick.ts +26 -0
  182. package/src/noop.ts +16 -0
  183. package/src/number/index.ts +9 -0
  184. package/src/number/toHex.spec.ts +44 -0
  185. package/src/number/toHex.ts +27 -0
  186. package/src/number/toU8a.spec.ts +50 -0
  187. package/src/number/toU8a.ts +25 -0
  188. package/src/object/clear.spec.ts +14 -0
  189. package/src/object/clear.ts +16 -0
  190. package/src/object/copy.spec.ts +17 -0
  191. package/src/object/copy.ts +12 -0
  192. package/src/object/entries.spec.ts +20 -0
  193. package/src/object/entries.ts +12 -0
  194. package/src/object/index.ts +10 -0
  195. package/src/object/keys.spec.ts +19 -0
  196. package/src/object/keys.ts +10 -0
  197. package/src/object/property.spec.ts +149 -0
  198. package/src/object/property.ts +39 -0
  199. package/src/object/spread.spec.ts +36 -0
  200. package/src/object/spread.ts +38 -0
  201. package/src/object/values.spec.ts +19 -0
  202. package/src/object/values.ts +10 -0
  203. package/src/packageDetect.ts +13 -0
  204. package/src/packageInfo.ts +6 -0
  205. package/src/promisify.spec.ts +50 -0
  206. package/src/promisify.ts +30 -0
  207. package/src/string/camelCase.spec.ts +119 -0
  208. package/src/string/camelCase.ts +79 -0
  209. package/src/string/index.ts +12 -0
  210. package/src/string/lowerFirst.spec.ts +41 -0
  211. package/src/string/lowerFirst.ts +46 -0
  212. package/src/string/pascalCase.spec.ts +26 -0
  213. package/src/string/shorten.spec.ts +38 -0
  214. package/src/string/shorten.ts +24 -0
  215. package/src/string/toHex.spec.ts +26 -0
  216. package/src/string/toHex.ts +27 -0
  217. package/src/string/toU8a.spec.ts +31 -0
  218. package/src/string/toU8a.ts +28 -0
  219. package/src/string/upperFirst.spec.ts +41 -0
  220. package/src/stringify.spec.ts +33 -0
  221. package/src/stringify.ts +20 -0
  222. package/src/test/index.ts +4 -0
  223. package/src/test/performance.ts +92 -0
  224. package/src/types.ts +100 -0
  225. package/src/u8a/cmp.spec.ts +62 -0
  226. package/src/u8a/cmp.ts +50 -0
  227. package/src/u8a/concat.spec.ts +42 -0
  228. package/src/u8a/concat.ts +60 -0
  229. package/src/u8a/concatBuffer.ts +34 -0
  230. package/src/u8a/empty.spec.ts +46 -0
  231. package/src/u8a/empty.ts +22 -0
  232. package/src/u8a/eq.spec.ts +113 -0
  233. package/src/u8a/eq.ts +46 -0
  234. package/src/u8a/fixLength.spec.ts +34 -0
  235. package/src/u8a/fixLength.ts +34 -0
  236. package/src/u8a/index.ts +22 -0
  237. package/src/u8a/sorted.spec.ts +20 -0
  238. package/src/u8a/sorted.ts +22 -0
  239. package/src/u8a/toBigInt.spec.ts +106 -0
  240. package/src/u8a/toBigInt.ts +100 -0
  241. package/src/u8a/toBn.spec.ts +106 -0
  242. package/src/u8a/toBn.ts +101 -0
  243. package/src/u8a/toBuffer.spec.ts +20 -0
  244. package/src/u8a/toBuffer.ts +28 -0
  245. package/src/u8a/toFloat.spec.ts +86 -0
  246. package/src/u8a/toFloat.ts +26 -0
  247. package/src/u8a/toHex.spec.ts +94 -0
  248. package/src/u8a/toHex.ts +68 -0
  249. package/src/u8a/toHexBuffer.spec.ts +63 -0
  250. package/src/u8a/toHexBuffer.ts +30 -0
  251. package/src/u8a/toNumber.spec.ts +47 -0
  252. package/src/u8a/toNumber.ts +80 -0
  253. package/src/u8a/toString.spec.ts +36 -0
  254. package/src/u8a/toString.ts +26 -0
  255. package/src/u8a/toU8a.spec.ts +63 -0
  256. package/src/u8a/toU8a.ts +46 -0
  257. package/src/u8a/wrap.spec.ts +139 -0
  258. package/src/u8a/wrap.ts +65 -0
  259. package/tsconfig.build.json +19 -0
  260. package/tsconfig.spec.json +17 -0
@@ -0,0 +1,149 @@
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 { perf } from '../test/index.js';
7
+ import { objectProperties, objectProperty } from './index.js';
8
+
9
+ describe('objectProperty/objectProperties', (): void => {
10
+ it('sets a property', (): void => {
11
+ const test: { a?: unknown } = {};
12
+
13
+ expect(test.a).toEqual(undefined);
14
+
15
+ objectProperty(test, 'a', () => 2);
16
+
17
+ expect(Object.prototype.hasOwnProperty.call(test, 'a')).toBe(true);
18
+ expect('a' in test).toEqual(true);
19
+ expect(test.a).toEqual(2);
20
+ });
21
+
22
+ it('does not override an existing property (record)', (): void => {
23
+ const test = { a: 1 };
24
+
25
+ expect(test.a).toEqual(1);
26
+
27
+ objectProperty(test, 'a', () => 2);
28
+
29
+ expect(test.a).toEqual(1);
30
+ });
31
+
32
+ it('does not override an existing property (class)', (): void => {
33
+ class Test {
34
+ b = 1;
35
+
36
+ get a () {
37
+ return 1 + 0;
38
+ }
39
+ }
40
+
41
+ const test = new Test();
42
+
43
+ expect(test.a).toEqual(1);
44
+ expect(test.b).toEqual(1);
45
+
46
+ objectProperty(test, 'a', () => 2);
47
+ objectProperty(test, 'b', () => 2);
48
+
49
+ expect(test.a).toEqual(1);
50
+ expect(test.b).toEqual(1);
51
+ });
52
+
53
+ it('does not override an existing property (inherited)', (): void => {
54
+ class Parent extends Map<string, unknown> {
55
+ constructor () {
56
+ super();
57
+
58
+ this.set('a', 1);
59
+ }
60
+
61
+ get a (): unknown {
62
+ return this.get('a');
63
+ }
64
+ }
65
+
66
+ class Child extends Parent {
67
+ constructor () {
68
+ super();
69
+
70
+ this.set('b', 1);
71
+ }
72
+
73
+ get b (): unknown {
74
+ return this.get('b');
75
+ }
76
+ }
77
+
78
+ const test = new Child() as unknown as { a: number; b: number; c?: number };
79
+
80
+ expect(test.a).toEqual(1);
81
+ expect(test.b).toEqual(1);
82
+ expect(test.c).toEqual(undefined);
83
+
84
+ objectProperties(test, ['a', 'b', 'c'], () => 2);
85
+
86
+ expect(test.a).toEqual(1);
87
+ expect(test.b).toEqual(1);
88
+ expect(test.c).toEqual(2);
89
+ });
90
+
91
+ it('works with this used in classes', (): void => {
92
+ class Test extends Map<string, unknown> {
93
+ constructor () {
94
+ super();
95
+
96
+ this.set('a', 1);
97
+
98
+ objectProperty(this, 'a', (k) => this.get(k));
99
+ }
100
+ }
101
+
102
+ const test = new Test() as unknown as { a: number };
103
+
104
+ expect(test.a).toEqual(1);
105
+ });
106
+
107
+ it('works with this used in classes (multiples)', (): void => {
108
+ class Test extends Map<string, unknown> {
109
+ constructor () {
110
+ super();
111
+
112
+ this.set('a', 1);
113
+ this.set('b', 2);
114
+
115
+ objectProperties(this, ['a', 'b'], (k) => this.get(k));
116
+ }
117
+ }
118
+
119
+ const test = new Test() as unknown as { a: number; b: number };
120
+
121
+ expect(test.a).toEqual(1);
122
+ expect(test.b).toEqual(2);
123
+ });
124
+
125
+ it('calls back with the key name (single)', (): void => {
126
+ const test: { a?: number } = {};
127
+ const getter = jest.fn(() => 123);
128
+
129
+ objectProperty(test, 'a', getter);
130
+
131
+ expect(getter).not.toHaveBeenCalled();
132
+ expect(test.a).toEqual(123);
133
+ expect(getter).toHaveBeenCalledWith('a', 0, expect.objectContaining({}));
134
+ });
135
+
136
+ it('calls back with the key name & index (numtiple)', (): void => {
137
+ const test: { a?: number; b?: number; c?: number } = {};
138
+ const getter = jest.fn(() => 123);
139
+
140
+ objectProperties(test, ['a', 'b', 'c'], getter);
141
+
142
+ expect(getter).not.toHaveBeenCalled();
143
+ expect(test.b).toEqual(123);
144
+ expect(getter).toHaveBeenCalledWith('b', 1, expect.objectContaining({}));
145
+ });
146
+
147
+ perf('objectProperties (obj)', 50_000, [[]], () => objectProperties({}, ['foo', 'bar', 'baz'], (k) => k));
148
+ perf('objectProperties (map)', 50_000, [[]], () => objectProperties(new Map(), ['foo', 'bar', 'baz'], (k) => k));
149
+ });
@@ -0,0 +1,39 @@
1
+ // Copyright 2017-2025 @polkadot/util authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /**
5
+ * @name objectProperty
6
+ * @summary Assign a get property on the input object
7
+ */
8
+ export function objectProperty <S> (that: object, key: string, getter: (key: string, index: number, self: S) => unknown, getName?: (key: string, index: number) => string, index = 0): void {
9
+ const name = getName
10
+ ? getName(key, index)
11
+ : key;
12
+
13
+ // There are 3 approaches here -
14
+ // - Object.prototype.hasOwnProperty.call(that, key) - this only checks the current class, i.e
15
+ // will retuirn false if the property is set in the parent class
16
+ // - isUndefined(...) - this may yield a false positive when the property is there, but not set.
17
+ // Additionally, on pre-defined getters it may make a call
18
+ // - key in that - Does not need to be combined with either of the above and checks the full chain
19
+ if (!(name in that)) {
20
+ Object.defineProperty(that, name, {
21
+ enumerable: true,
22
+ // Unlike in lazy, we always call into the upper function, i.e. this method
23
+ // does not cache old values (it is expected to be used for dynamic values)
24
+ get: function (): unknown {
25
+ return getter(key, index, this as S);
26
+ }
27
+ });
28
+ }
29
+ }
30
+
31
+ /**
32
+ * @name objectProperties
33
+ * @summary Assign get properties on the input object
34
+ */
35
+ export function objectProperties <S> (that: object, keys: string[], getter: (key: string, index: number, self: S) => unknown, getName?: (key: string, index: number) => string): void {
36
+ for (let i = 0, count = keys.length; i < count; i++) {
37
+ objectProperty(that, keys[i], getter, getName, i);
38
+ }
39
+ }
@@ -0,0 +1,36 @@
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 { perf } from '../test/index.js';
7
+ import { objectSpread } from './index.js';
8
+
9
+ describe('objectSpread', (): void => {
10
+ it('spreads obj sources', (): void => {
11
+ expect(
12
+ objectSpread({}, { a: 1, b: 2, c: 3 }, { d: 4, e: 5, f: 6 })
13
+ ).toEqual({ a: 1, b: 2, c: 3, d: 4, e: 5, f: 6 });
14
+ });
15
+
16
+ it('spreads map sources', (): void => {
17
+ expect(
18
+ objectSpread({}, new Map<string, number>([['a', 1], ['b', 2], ['c', 3]]), new Map<string, number>([['d', 4], ['e', 5], ['f', 6]]))
19
+ ).toEqual({ a: 1, b: 2, c: 3, d: 4, e: 5, f: 6 });
20
+ });
21
+
22
+ it('spreads an object from multiple sources', (): void => {
23
+ expect(
24
+ objectSpread({ a: 1 }, { b: 2 }, { a: 2, c: { d: 3, e: 4 } }, new Map<string, unknown>([['f', 5], ['g', 6], ['h', { i: 7, k: 8 }]]))
25
+ ).toEqual({ a: 2, b: 2, c: { d: 3, e: 4 }, f: 5, g: 6, h: { i: 7, k: 8 } });
26
+ });
27
+
28
+ it('spreads an object from multiple sources (with null & undefined)', (): void => {
29
+ expect(
30
+ objectSpread({ a: 1 }, null, { b: 2 }, undefined, { a: 2, c: { d: 3, e: 4 } })
31
+ ).toEqual({ a: 2, b: 2, c: { d: 3, e: 4 } });
32
+ });
33
+
34
+ perf('objectSpread (obj)', 350_000, [[{}, { a: 1, b: 2, c: 3 }, { d: 4, e: 5, f: 6 }]], objectSpread);
35
+ perf('objectSpread (map)', 350_000, [[{}, new Map<string, number>([['a', 1], ['b', 2], ['c', 3]]), new Map<string, number>([['d', 4], ['e', 5], ['f', 6]])]], objectSpread);
36
+ });
@@ -0,0 +1,38 @@
1
+ // Copyright 2017-2025 @polkadot/util authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /**
5
+ * @name objectSpread
6
+ * @summary Concats all sources into the destination
7
+ * @description Spreads object properties while maintaining object integrity
8
+ */
9
+ export function objectSpread <T extends object> (dest: object, ...sources: (object | undefined | null)[]): T {
10
+ const filterProps = new Set(['__proto__', 'constructor', 'prototype']);
11
+
12
+ for (let i = 0, count = sources.length; i < count; i++) {
13
+ const src = sources[i];
14
+
15
+ if (src) {
16
+ if (typeof (src as Map<string, unknown>).entries === 'function') {
17
+ for (const [key, value] of (src as Map<string, unknown>).entries()) {
18
+ if (!filterProps.has(key)) {
19
+ (dest as Record<string, unknown>)[key] = value;
20
+ }
21
+ }
22
+ } else {
23
+ // Create a clean copy of the source object
24
+ const sanitizedSrc = Object.create(null) as Record<string, unknown>;
25
+
26
+ for (const [key, value] of Object.entries(src)) {
27
+ if (!filterProps.has(key)) {
28
+ sanitizedSrc[key] = value;
29
+ }
30
+ }
31
+
32
+ Object.assign(dest, sanitizedSrc);
33
+ }
34
+ }
35
+ }
36
+
37
+ return dest as T;
38
+ }
@@ -0,0 +1,19 @@
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 { objectValues } from './index.js';
7
+
8
+ describe('objectValues', (): void => {
9
+ it('extracts all values', (): void => {
10
+ const o = { a: 1, b: 2, c: 3 };
11
+ const values = objectValues(o);
12
+
13
+ expect(values).toEqual([1, 2, 3]);
14
+
15
+ for (const v of values) {
16
+ expect(v).toBeDefined();
17
+ }
18
+ });
19
+ });
@@ -0,0 +1,10 @@
1
+ // Copyright 2017-2025 @polkadot/util authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /**
5
+ * @name objectValues
6
+ * @summary A version of Object.values that is typed for TS
7
+ */
8
+ export function objectValues<T extends object> (obj: T): T[keyof T][] {
9
+ return Object.values(obj) as T[keyof T][];
10
+ }
@@ -0,0 +1,13 @@
1
+ // Copyright 2017-2025 @polkadot/util authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ // Do not edit, auto-generated by @polkadot/dev
5
+ // (packageInfo imports will be kept as-is, user-editable)
6
+
7
+ import { packageInfo as decoderInfo } from '@pezkuwi/x-textdecoder';
8
+ import { packageInfo as encoderInfo } from '@pezkuwi/x-textencoder';
9
+
10
+ import { detectPackage } from './detectPackage.js';
11
+ import { packageInfo } from './packageInfo.js';
12
+
13
+ detectPackage(packageInfo, null, [decoderInfo, encoderInfo]);
@@ -0,0 +1,6 @@
1
+ // Copyright 2017-2025 @polkadot/util authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ // Do not edit, auto-generated by @polkadot/dev
5
+
6
+ export const packageInfo = { name: '@polkadot/util', path: 'auto', type: 'auto', version: '14.0.1' };
@@ -0,0 +1,50 @@
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 { promisify } from './index.js';
7
+
8
+ describe('promisify', (): void => {
9
+ it('handles functions with no parameters (resolve)', (): Promise<void> => {
10
+ const fn = (cb: (error: null, value: [boolean, string, number]) => void): void =>
11
+ cb(null, [true, 'test', 1]);
12
+
13
+ return promisify(null, fn).then((result): void => {
14
+ expect(result).toEqual([true, 'test', 1]);
15
+ });
16
+ });
17
+
18
+ it('handles functions with no parameters (reject)', (): Promise<void> => {
19
+ const fn = (cb: (error: Error, result?: boolean) => void): void =>
20
+ cb(new Error('test reject'));
21
+
22
+ return promisify(null, fn)
23
+ .then((): void => {
24
+ throw new Error('Received unexpected result');
25
+ })
26
+ .catch((error: Error): void => {
27
+ // eslint-disable-next-line jest/no-conditional-expect
28
+ expect(error.message).toEqual('test reject');
29
+ });
30
+ });
31
+
32
+ it('handles functions with parameters (resolve)', (): Promise<void> => {
33
+ const fn = (a: number, b: boolean, cb: (error: Error | null, result?: [number, boolean]) => void): void =>
34
+ cb(null, [a, b]);
35
+
36
+ return promisify(null, fn, 2, false).then((result: [number, boolean]): void => {
37
+ expect(result).toEqual([2, false]);
38
+ });
39
+ });
40
+
41
+ it('handles functions with parameters (reject)', (): Promise<void> => {
42
+ const fn = (a: number, b: boolean, c: string, cb: (error: Error | null, result?: [number, boolean, string]) => void): void =>
43
+ cb(new Error(`test reject: ${a},${b.toString()},${c}`));
44
+
45
+ return promisify(null, fn, 3, 'string', true).catch((error: Error): void => {
46
+ // eslint-disable-next-line jest/no-conditional-expect
47
+ expect(error.message).toEqual('test reject: 3,string,true');
48
+ });
49
+ });
50
+ });
@@ -0,0 +1,30 @@
1
+ // Copyright 2017-2025 @polkadot/util authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /**
5
+ * @name promisify
6
+ * @summary Wraps an async callback into a `Promise`
7
+ * @description
8
+ * Wraps the supplied async function `fn` that has a standard JS callback `(error: Error, result: any)` into a `Promise`, passing the supplied parameters. When `error` is set, the Promise is rejected, else the Promise resolves with the `result` value.
9
+ * @example
10
+ * <BR>
11
+ *
12
+ * ```javascript
13
+ * const { promisify } from '@pezkuwi/util';
14
+ *
15
+ * await promisify(null, ((a, cb) => cb(null, a), true); // resolves with `true`
16
+ * await promisify(null, (cb) => cb(new Error('error!'))); // rejects with `error!`
17
+ * ```
18
+ */
19
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
+ export function promisify <R = any> (self: unknown, fn: (...params: any[]) => any, ...params: any[]): Promise<R> {
21
+ return new Promise((resolve, reject): void => {
22
+ fn.apply(self, params.concat((error: Error | null, result?: R): void => {
23
+ if (error) {
24
+ reject(error);
25
+ } else {
26
+ resolve(result as R);
27
+ }
28
+ }));
29
+ });
30
+ }
@@ -0,0 +1,119 @@
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 { getRandomValues } from '@pezkuwi/x-randomvalues';
7
+
8
+ import { arrayRange } from '../array/index.js';
9
+ import { perf } from '../test/index.js';
10
+ import { stringCamelCase, stringUpperFirst } from './index.js';
11
+
12
+ const SEPS = [' ', '_', '-', '.', ','];
13
+ const words = 'bring|brisk|broccoli|broken|bronze|broom|brother|brown|brush|bubble|buddy|budget|buffalo|build|bulb|bulk|bullet|bundle|bunker|burden'.split('|');
14
+
15
+ function randomAsNumber (): number {
16
+ const rand = getRandomValues(new Uint8Array(4));
17
+
18
+ return rand.reduce((v, t) => (v * t) + v, 0);
19
+ }
20
+
21
+ const randomWords = arrayRange(256).map((): [string] => {
22
+ let result = '';
23
+
24
+ for (let i = 0; i < 6; i++) {
25
+ let word = words[randomAsNumber() % words.length];
26
+
27
+ if (randomAsNumber() % 2) {
28
+ word = stringUpperFirst(word);
29
+ }
30
+
31
+ if (i === 0) {
32
+ result = word;
33
+ } else {
34
+ result += `${SEPS[randomAsNumber() % SEPS.length]}${word}`;
35
+ }
36
+ }
37
+
38
+ return [result];
39
+ });
40
+
41
+ describe('stringCamelCase', (): void => {
42
+ it('works correctly', (): void => {
43
+ expect(
44
+ stringCamelCase('Snake_case-...SomethingSomething spaced')
45
+ ).toBe('snakeCaseSomethingSomethingSpaced');
46
+ });
47
+
48
+ it('works correctly for String (class', (): void => {
49
+ expect(
50
+ stringCamelCase(String('Foo_bar-baz---test-_ spaced....Extra'))
51
+ ).toBe('fooBarBazTestSpacedExtra');
52
+ });
53
+
54
+ it('adjusts all-uppercase', (): void => {
55
+ expect(
56
+ stringCamelCase('DEDUP_KEY_PREFIX')
57
+ ).toEqual('dedupKeyPrefix');
58
+ expect(
59
+ stringCamelCase(String('DEDUP_KEY_PREFIX'))
60
+ ).toEqual('dedupKeyPrefix');
61
+ expect(
62
+ stringCamelCase('SOMETHING')
63
+ ).toEqual('something');
64
+ expect(
65
+ stringCamelCase('NMap')
66
+ ).toEqual('nMap');
67
+ });
68
+
69
+ it('adjusts all-uppercase + digits', (): void => {
70
+ expect(
71
+ stringCamelCase('SS58 PreFIX')
72
+ ).toEqual('ss58PreFIX');
73
+ expect(
74
+ stringCamelCase('SS58Prefix')
75
+ ).toEqual('ss58Prefix');
76
+ expect(
77
+ stringCamelCase('UUID64')
78
+ ).toEqual('uuid64');
79
+ expect(
80
+ stringCamelCase('BLAKE2B')
81
+ ).toEqual('blake2b');
82
+ expect(
83
+ stringCamelCase('NFTOrder')
84
+ ).toEqual('nftOrder');
85
+ expect(
86
+ stringCamelCase('EVM')
87
+ ).toEqual('evm');
88
+ expect(
89
+ stringCamelCase('A')
90
+ ).toEqual('a');
91
+ expect(
92
+ stringCamelCase('A1')
93
+ ).toEqual('a1');
94
+ expect(
95
+ stringCamelCase('A1b')
96
+ ).toEqual('a1b');
97
+ expect(
98
+ stringCamelCase('A1B')
99
+ ).toEqual('a1b');
100
+ expect(
101
+ stringCamelCase('RawVRFOutput')
102
+ ).toEqual('rawVRFOutput');
103
+ });
104
+
105
+ it('adjusts with leading _', (): void => {
106
+ expect(
107
+ stringCamelCase('_reserved')
108
+ ).toEqual('reserved');
109
+ });
110
+
111
+ it('adjusts with minimal chars per part', (): void => {
112
+ expect(
113
+ stringCamelCase('_a_b_c_def')
114
+ ).toEqual('aBCDef');
115
+ });
116
+
117
+ perf('stringCamelCase (random)', 100_000, randomWords, stringCamelCase);
118
+ perf('stringCamelCase (NFTOrder)', 100_000, [['NFTOrder']], stringCamelCase);
119
+ });
@@ -0,0 +1,79 @@
1
+ // Copyright 2017-2025 @polkadot/util authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import type { AnyString } from '../types.js';
5
+
6
+ export const CC_TO_UP = new Array<string>(256);
7
+ export const CC_TO_LO = new Array<string>(256);
8
+
9
+ for (let i = 0, count = CC_TO_UP.length; i < count; i++) {
10
+ CC_TO_LO[i] = String.fromCharCode(i).toLowerCase();
11
+ CC_TO_UP[i] = String.fromCharCode(i).toUpperCase();
12
+ }
13
+
14
+ /** @internal */
15
+ function formatAllCaps (w: string): string {
16
+ return w.slice(0, w.length - 1).toLowerCase() + CC_TO_UP[w.charCodeAt(w.length - 1)];
17
+ }
18
+
19
+ /**
20
+ * @internal
21
+ *
22
+ * Inspired by https://stackoverflow.com/a/2970667
23
+ *
24
+ * This is not as optimal as the original SO answer (we split into per-word),
25
+ * however it does pass the tests (which the SO version doesn't) and is still
26
+ * a major improvement over the original camelcase npm package -
27
+ *
28
+ * camelcase: 20.88 μs/op
29
+ * this: 1.00 μs/op
30
+ *
31
+ * Caveat of this: only Ascii, but acceptable for the intended usecase
32
+ */
33
+ function converter (format: (w: string, i: number) => string): (value: AnyString) => string {
34
+ return (value: AnyString): string => {
35
+ const parts = value
36
+ // replace all separators (including consequtive) with spaces
37
+ .replace(/[-_., ]+/g, ' ')
38
+ // we don't want leading or trailing spaces
39
+ .trim()
40
+ // split into words
41
+ .split(' ');
42
+ let result = '';
43
+
44
+ for (let i = 0, count = parts.length; i < count; i++) {
45
+ const w = parts[i];
46
+
47
+ // apply the formatting
48
+ result += format(
49
+ /^[\dA-Z]+$/.test(w)
50
+ // all full uppercase + letters are changed to lowercase
51
+ ? w.toLowerCase()
52
+ // all consecutive capitals + letters are changed to lowercase
53
+ // e.g. UUID64 -> uuid64, while preserving splits, eg. NFTOrder -> nftOrder
54
+ : w.replace(/^[\dA-Z]{2,}[^a-z]/, formatAllCaps),
55
+ i
56
+ );
57
+ }
58
+
59
+ return result;
60
+ };
61
+ }
62
+
63
+ /**
64
+ * @name stringCamelCase
65
+ * @summary Convert a dash/dot/underscore/space separated Ascii string/String to camelCase
66
+ */
67
+ export const stringCamelCase = /*#__PURE__*/ converter((w, i) =>
68
+ // lowercase for first letter/first word, else uppercase first, rest unchanged
69
+ (i ? CC_TO_UP[w.charCodeAt(0)] : CC_TO_LO[w.charCodeAt(0)]) + w.slice(1)
70
+ );
71
+
72
+ /**
73
+ * @name stringPascalCase
74
+ * @summary Convert a dash/dot/underscore/space separated Ascii string/String to PascalCase
75
+ */
76
+ export const stringPascalCase = /*#__PURE__*/ converter((w) =>
77
+ // uppercase the first character, leave the rest unchanged
78
+ CC_TO_UP[w.charCodeAt(0)] + w.slice(1)
79
+ );
@@ -0,0 +1,12 @@
1
+ // Copyright 2017-2025 @polkadot/util authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /**
5
+ * @summary Utility methods to convert to work with `string` values
6
+ */
7
+
8
+ export { stringCamelCase, stringPascalCase } from './camelCase.js';
9
+ export { stringLowerFirst, stringUpperFirst } from './lowerFirst.js';
10
+ export { stringShorten } from './shorten.js';
11
+ export { stringToHex } from './toHex.js';
12
+ export { stringToU8a } from './toU8a.js';
@@ -0,0 +1,41 @@
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 { perf } from '../test/index.js';
7
+ import { stringLowerFirst } from './index.js';
8
+
9
+ describe('stringLowerFirst', (): void => {
10
+ it("lowers the first letter if it's a capital letter", (): void => {
11
+ expect(
12
+ stringLowerFirst('ABC')
13
+ ).toBe('aBC');
14
+ });
15
+
16
+ it("lowers the first letter if it's a capital letter (String)", (): void => {
17
+ expect(
18
+ stringLowerFirst(String('ABC'))
19
+ ).toBe('aBC');
20
+ });
21
+
22
+ it("lowers the first letter if it's a lowercase letter", (): void => {
23
+ expect(
24
+ stringLowerFirst('abc')
25
+ ).toBe('abc');
26
+ });
27
+
28
+ it('returns undefined as empty', (): void => {
29
+ expect(
30
+ stringLowerFirst()
31
+ ).toBe('');
32
+ });
33
+
34
+ it('returns null as empty', (): void => {
35
+ expect(
36
+ stringLowerFirst(null)
37
+ ).toBe('');
38
+ });
39
+
40
+ perf('stringLowerFirst', 1_000_000, [['HelloWorldSomething']], stringLowerFirst);
41
+ });