nhb-toolbox 4.26.74 → 4.27.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 +15 -0
- package/README.md +3 -4
- package/dist/cjs/guards/specials.js +3 -2
- package/dist/cjs/hash/helpers.js +108 -0
- package/dist/cjs/hash/index.js +248 -0
- package/dist/cjs/hash/types.js +2 -0
- package/dist/cjs/index.js +7 -4
- package/dist/cjs/number/convert.js +1 -1
- package/dist/cjs/string/anagram.js +31 -11
- package/dist/cjs/string/basics.js +0 -29
- package/dist/cjs/string/case.js +152 -3
- package/dist/cjs/utils/index.js +14 -0
- package/dist/dts/guards/specials.d.ts +4 -3
- package/dist/dts/hash/helpers.d.ts +23 -0
- package/dist/dts/hash/index.d.ts +147 -0
- package/dist/dts/hash/types.d.ts +44 -0
- package/dist/dts/index.d.ts +3 -3
- package/dist/dts/string/anagram.d.ts +23 -5
- package/dist/dts/string/basics.d.ts +1 -10
- package/dist/dts/string/case.d.ts +233 -1
- package/dist/dts/string/types.d.ts +137 -9
- package/dist/dts/types/index.d.ts +4 -4
- package/dist/dts/utils/index.d.ts +41 -1
- package/dist/dts/utils/types.d.ts +26 -2
- package/dist/esm/guards/specials.js +3 -2
- package/dist/esm/hash/helpers.js +99 -0
- package/dist/esm/hash/index.js +231 -0
- package/dist/esm/hash/types.js +1 -0
- package/dist/esm/index.js +3 -3
- package/dist/esm/number/convert.js +1 -1
- package/dist/esm/string/anagram.js +31 -11
- package/dist/esm/string/basics.js +0 -28
- package/dist/esm/string/case.js +140 -3
- package/dist/esm/utils/index.js +13 -0
- package/package.json +24 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,21 @@ All notable changes to the package will be documented here.
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
+
## [4.27.0] - 2025-11-28
|
|
10
|
+
|
|
11
|
+
### New
|
|
12
|
+
|
|
13
|
+
- **Added** *typed* **string case converters** which can only be imported via the *subpath* `'nhb-toolbox/change-case'`.
|
|
14
|
+
- **Also added** *new* utility types for formatting case(s) in type level.
|
|
15
|
+
- **Added** *new* hash utilities: `randomHex`, `md5`, `sha1`, `uuid`. `decodeUUID` and *uuid version checkers* derived from `isUUID`.
|
|
16
|
+
- **Hash utilities** can only be imported via the *subpath* `'nhb-toolbox/hash'`
|
|
17
|
+
- **Added** *new* `definePrototypeMethod` utility to inject *prototype* methods in a safe (also *type-safe*) manner.
|
|
18
|
+
|
|
19
|
+
### Updates
|
|
20
|
+
|
|
21
|
+
- **Updated** `convertStringCase` utility to accept new format: `'Sentence case'`.
|
|
22
|
+
- **Updated** `isUUID` to verify versions 1-8 (not just `v4`). It now *narrows down* the value to **branded type** `UUID<UUIDVersion>`.
|
|
23
|
+
|
|
9
24
|
## [4.26.74] - 2025-11-23
|
|
10
25
|
|
|
11
26
|
- **Added** optional `serializer` and `deserializer` for *local and session storage* utilities with *improved error handling*.
|
package/README.md
CHANGED
|
@@ -359,12 +359,11 @@ const user = {
|
|
|
359
359
|
};
|
|
360
360
|
|
|
361
361
|
sanitizeData(user, { ignoreNullish: true, ignoreEmpty: true });
|
|
362
|
-
// Returns { name: "John Doe", address: { city: "NYC" } } with exact input type
|
|
362
|
+
// Returns { name: "John Doe", address: { city: "NYC" } } with exact input type which may cause issue when accessing missing properties
|
|
363
363
|
|
|
364
|
-
sanitizeData(user, { ignoreNullish: true }, 'partial');
|
|
365
|
-
// Return type:
|
|
364
|
+
sanitizeData(user, { ignoreNullish: true, ignoreEmpty: true }, 'partial');
|
|
365
|
+
// Return type: $DeepPartial<typeof user> safe property access by making all the properties (nested objects/arrays) optional
|
|
366
366
|
// Returns { name: "John Doe", address: { city: "NYC" } }
|
|
367
|
-
// { name: 'John' }
|
|
368
367
|
```
|
|
369
368
|
|
|
370
369
|
[Documentation →](https://toolbox.nazmul-nhb.dev/docs/utilities/object/sanitizeData)
|
|
@@ -24,8 +24,9 @@ function isDateString(value) {
|
|
|
24
24
|
return (0, primitives_1.isString)(value) && !isNaN(Date.parse(value));
|
|
25
25
|
}
|
|
26
26
|
function isUUID(value) {
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
const h = '[0-9a-f]';
|
|
28
|
+
const expr = new RegExp(`^${h}{8}-${h}{4}-[1-8]${h}{3}-[89ab]${h}{3}-${h}{12}$`, 'i');
|
|
29
|
+
return (0, primitives_1.isString)(value) && expr.test(value);
|
|
29
30
|
}
|
|
30
31
|
function isBrowser() {
|
|
31
32
|
return typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports._runMd5Rounds = _runMd5Rounds;
|
|
4
|
+
exports._uuidTimestamp = _uuidTimestamp;
|
|
5
|
+
exports._randomNode48 = _randomNode48;
|
|
6
|
+
exports._clockSeq14 = _clockSeq14;
|
|
7
|
+
exports._formatUUID = _formatUUID;
|
|
8
|
+
exports._isOptionV3V5 = _isOptionV3V5;
|
|
9
|
+
exports._checkUUIDVersion = _checkUUIDVersion;
|
|
10
|
+
const non_primitives_1 = require("../guards/non-primitives");
|
|
11
|
+
const primitives_1 = require("../guards/primitives");
|
|
12
|
+
const specials_1 = require("../guards/specials");
|
|
13
|
+
const index_1 = require("./index");
|
|
14
|
+
function _runMd5Rounds(words, h) {
|
|
15
|
+
let [a, b, c, d] = h;
|
|
16
|
+
const funcs = [
|
|
17
|
+
(x, y, z) => (x & y) | (~x & z),
|
|
18
|
+
(x, y, z) => (x & z) | (y & ~z),
|
|
19
|
+
(x, y, z) => x ^ y ^ z,
|
|
20
|
+
(x, y, z) => y ^ (x | ~z),
|
|
21
|
+
];
|
|
22
|
+
const r1 = [7, 12, 17, 22];
|
|
23
|
+
const r2 = [5, 9, 14, 20];
|
|
24
|
+
const r3 = [4, 11, 16, 23];
|
|
25
|
+
const r4 = [6, 10, 15, 21];
|
|
26
|
+
const shifts = [
|
|
27
|
+
...r1,
|
|
28
|
+
...r1,
|
|
29
|
+
...r1,
|
|
30
|
+
...r1,
|
|
31
|
+
...r2,
|
|
32
|
+
...r2,
|
|
33
|
+
...r2,
|
|
34
|
+
...r2,
|
|
35
|
+
...r3,
|
|
36
|
+
...r3,
|
|
37
|
+
...r3,
|
|
38
|
+
...r3,
|
|
39
|
+
...r4,
|
|
40
|
+
...r4,
|
|
41
|
+
...r4,
|
|
42
|
+
...r4,
|
|
43
|
+
];
|
|
44
|
+
const K = Array.from({ length: 64 }, (_, i) => Math.floor(Math.abs(Math.sin(i + 1)) * 2 ** 32));
|
|
45
|
+
function _rotl(x, c) {
|
|
46
|
+
return (x << c) | (x >>> (32 - c));
|
|
47
|
+
}
|
|
48
|
+
function _add(x, y) {
|
|
49
|
+
return (x + y) | 0;
|
|
50
|
+
}
|
|
51
|
+
for (let i = 0; i < 64; i++) {
|
|
52
|
+
const round = i >> 4;
|
|
53
|
+
const f = funcs[round](b, c, d);
|
|
54
|
+
let g;
|
|
55
|
+
if (round === 0)
|
|
56
|
+
g = i;
|
|
57
|
+
else if (round === 1)
|
|
58
|
+
g = (5 * i + 1) % 16;
|
|
59
|
+
else if (round === 2)
|
|
60
|
+
g = (3 * i + 5) % 16;
|
|
61
|
+
else
|
|
62
|
+
g = (7 * i) % 16;
|
|
63
|
+
const temp = d;
|
|
64
|
+
d = c;
|
|
65
|
+
c = b;
|
|
66
|
+
b = _add(b, _rotl(_add(_add(a, f), _add(words[g], K[i])), shifts[i]));
|
|
67
|
+
a = temp;
|
|
68
|
+
}
|
|
69
|
+
h[0] = _add(h[0], a);
|
|
70
|
+
h[1] = _add(h[1], b);
|
|
71
|
+
h[2] = _add(h[2], c);
|
|
72
|
+
h[3] = _add(h[3], d);
|
|
73
|
+
}
|
|
74
|
+
function _uuidTimestamp() {
|
|
75
|
+
const UUID_EPOCH_DIFF = 12219292800000n;
|
|
76
|
+
const unixMs = BigInt(Date.now());
|
|
77
|
+
const uuidMs = unixMs + UUID_EPOCH_DIFF;
|
|
78
|
+
return uuidMs * 10000n;
|
|
79
|
+
}
|
|
80
|
+
function _randomNode48() {
|
|
81
|
+
const node = (0, index_1.randomHex)(12).split('');
|
|
82
|
+
const firstByte = parseInt(node.slice(0, 2).join(''), 16);
|
|
83
|
+
const modified = (firstByte | 0b00000001).toString(16).padStart(2, '0');
|
|
84
|
+
return modified + node.slice(2).join('');
|
|
85
|
+
}
|
|
86
|
+
function _clockSeq14() {
|
|
87
|
+
const seq = parseInt((0, index_1.randomHex)(4), 16) & 0x3fff;
|
|
88
|
+
return seq.toString(16).padStart(4, '0');
|
|
89
|
+
}
|
|
90
|
+
function _formatUUID(h, v, up) {
|
|
91
|
+
const part3 = String(v) + h.slice(13, 16);
|
|
92
|
+
const part4 = _hexVariant(h.slice(16, 18)) + h.slice(18, 20);
|
|
93
|
+
const formatted = [h.slice(0, 8), h.slice(8, 12), part3, part4, h.slice(20, 32)].join('-');
|
|
94
|
+
return (up ? formatted.toUpperCase() : formatted);
|
|
95
|
+
}
|
|
96
|
+
function _hexVariant(hex) {
|
|
97
|
+
const v = parseInt(hex, 16);
|
|
98
|
+
return ((v & 0x3f) | 0x80).toString(16).padStart(2, '0');
|
|
99
|
+
}
|
|
100
|
+
function _isOptionV3V5(opt) {
|
|
101
|
+
if ((0, non_primitives_1.isObjectWithKeys)(opt, ['name', 'namespace'])) {
|
|
102
|
+
return (0, specials_1.isUUID)(opt?.namespace) && (0, primitives_1.isNonEmptyString)(opt?.name);
|
|
103
|
+
}
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
function _checkUUIDVersion(value, v) {
|
|
107
|
+
return (0, specials_1.isUUID)(value) && value[14] === v;
|
|
108
|
+
}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isUUID = exports.generateRandomID = void 0;
|
|
4
|
+
exports.randomHex = randomHex;
|
|
5
|
+
exports.md5 = md5;
|
|
6
|
+
exports.sha1 = sha1;
|
|
7
|
+
exports.uuid = uuid;
|
|
8
|
+
exports.decodeUUID = decodeUUID;
|
|
9
|
+
exports.isUUIDv1 = isUUIDv1;
|
|
10
|
+
exports.isUUIDv2 = isUUIDv2;
|
|
11
|
+
exports.isUUIDv3 = isUUIDv3;
|
|
12
|
+
exports.isUUIDv4 = isUUIDv4;
|
|
13
|
+
exports.isUUIDv5 = isUUIDv5;
|
|
14
|
+
exports.isUUIDv6 = isUUIDv6;
|
|
15
|
+
exports.isUUIDv7 = isUUIDv7;
|
|
16
|
+
exports.isUUIDv8 = isUUIDv8;
|
|
17
|
+
const specials_1 = require("../guards/specials");
|
|
18
|
+
Object.defineProperty(exports, "isUUID", { enumerable: true, get: function () { return specials_1.isUUID; } });
|
|
19
|
+
const helpers_1 = require("./helpers");
|
|
20
|
+
function randomHex(length, uppercase = false) {
|
|
21
|
+
const genHex = () => Math.floor(Math.random() * 16).toString(16);
|
|
22
|
+
const hex = Array.from({ length }, genHex).join('');
|
|
23
|
+
return uppercase ? hex.toUpperCase() : hex;
|
|
24
|
+
}
|
|
25
|
+
function md5(str) {
|
|
26
|
+
const h = [1732584193, -271733879, -1732584194, 271733878];
|
|
27
|
+
const bytes = Array.from(new TextEncoder().encode(str));
|
|
28
|
+
const n = ((bytes.length + 8) >> 6) + 1;
|
|
29
|
+
const words = new Array(n * 16).fill(0);
|
|
30
|
+
bytes.forEach((b, i) => {
|
|
31
|
+
words[i >> 2] |= b << ((i % 4) * 8);
|
|
32
|
+
});
|
|
33
|
+
words[bytes.length >> 2] |= 0x80 << ((bytes.length % 4) * 8);
|
|
34
|
+
words[n * 16 - 2] = bytes.length * 8;
|
|
35
|
+
for (let i = 0; i < words.length; i += 16) {
|
|
36
|
+
(0, helpers_1._runMd5Rounds)(words.slice(i, i + 16), h);
|
|
37
|
+
}
|
|
38
|
+
return h.map((n) => (n >>> 0).toString(16).padStart(8, '0')).join('');
|
|
39
|
+
}
|
|
40
|
+
function sha1(msg) {
|
|
41
|
+
const utf8 = new TextEncoder().encode(msg);
|
|
42
|
+
const K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6];
|
|
43
|
+
const rotl = (n, bits) => (n << bits) | (n >>> (32 - bits));
|
|
44
|
+
const toHex = (n) => (n >>> 0).toString(16).padStart(8, '0');
|
|
45
|
+
const words = new Uint32Array(((utf8.length + 8) >> 2) + 2);
|
|
46
|
+
for (let i = 0; i < utf8.length; i++) {
|
|
47
|
+
words[i >> 2] |= utf8[i] << (24 - (i % 4) * 8);
|
|
48
|
+
}
|
|
49
|
+
words[utf8.length >> 2] |= 0x80 << (24 - (utf8.length % 4) * 8);
|
|
50
|
+
words[words.length - 1] = utf8.length * 8;
|
|
51
|
+
const h = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0];
|
|
52
|
+
const W = new Uint32Array(80);
|
|
53
|
+
for (let i = 0; i < words.length; i += 16) {
|
|
54
|
+
for (let j = 0; j < 16; j++)
|
|
55
|
+
W[j] = words[i + j] | 0;
|
|
56
|
+
for (let j = 16; j < 80; j++) {
|
|
57
|
+
W[j] = rotl(W[j - 3] ^ W[j - 8] ^ W[j - 14] ^ W[j - 16], 1);
|
|
58
|
+
}
|
|
59
|
+
let a = h[0], b = h[1], c = h[2], d = h[3], e = h[4];
|
|
60
|
+
for (let j = 0; j < 80; j++) {
|
|
61
|
+
let f, k;
|
|
62
|
+
if (j < 20) {
|
|
63
|
+
f = (b & c) | (~b & d);
|
|
64
|
+
k = K[0];
|
|
65
|
+
}
|
|
66
|
+
else if (j < 40) {
|
|
67
|
+
f = b ^ c ^ d;
|
|
68
|
+
k = K[1];
|
|
69
|
+
}
|
|
70
|
+
else if (j < 60) {
|
|
71
|
+
f = (b & c) | (b & d) | (c & d);
|
|
72
|
+
k = K[2];
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
f = b ^ c ^ d;
|
|
76
|
+
k = K[3];
|
|
77
|
+
}
|
|
78
|
+
const temp = (rotl(a, 5) + f + e + k + W[j]) | 0;
|
|
79
|
+
e = d;
|
|
80
|
+
d = c;
|
|
81
|
+
c = rotl(b, 30);
|
|
82
|
+
b = a;
|
|
83
|
+
a = temp;
|
|
84
|
+
}
|
|
85
|
+
h[0] = (h[0] + a) | 0;
|
|
86
|
+
h[1] = (h[1] + b) | 0;
|
|
87
|
+
h[2] = (h[2] + c) | 0;
|
|
88
|
+
h[3] = (h[3] + d) | 0;
|
|
89
|
+
h[4] = (h[4] + e) | 0;
|
|
90
|
+
}
|
|
91
|
+
return h.map(toHex).join('');
|
|
92
|
+
}
|
|
93
|
+
function uuid(options) {
|
|
94
|
+
const { version = 'v4', uppercase = false } = options || {};
|
|
95
|
+
switch (version) {
|
|
96
|
+
case 'v1': {
|
|
97
|
+
const timestamp = (0, helpers_1._uuidTimestamp)().toString(16).padStart(15, '0');
|
|
98
|
+
const vTimeHigh = (parseInt(timestamp.slice(0, -12).padStart(3, '0'), 16) | 0x1000)
|
|
99
|
+
.toString(16)
|
|
100
|
+
.padStart(4, '0');
|
|
101
|
+
const clockSeq = (0, helpers_1._clockSeq14)();
|
|
102
|
+
const clockSeqHi = ((parseInt(clockSeq.slice(0, 2), 16) & 0x3f) | 0x80)
|
|
103
|
+
.toString(16)
|
|
104
|
+
.padStart(2, '0');
|
|
105
|
+
const clockSeqLow = clockSeq.slice(2);
|
|
106
|
+
const raw = timestamp.slice(-8) +
|
|
107
|
+
timestamp.slice(-12, -8) +
|
|
108
|
+
vTimeHigh +
|
|
109
|
+
clockSeqHi +
|
|
110
|
+
clockSeqLow +
|
|
111
|
+
(0, helpers_1._randomNode48)();
|
|
112
|
+
return (0, helpers_1._formatUUID)(raw, 1, uppercase);
|
|
113
|
+
}
|
|
114
|
+
case 'v3': {
|
|
115
|
+
if ((0, helpers_1._isOptionV3V5)(options)) {
|
|
116
|
+
const hash = md5(options.namespace + options.name);
|
|
117
|
+
return (0, helpers_1._formatUUID)(hash, 3, uppercase);
|
|
118
|
+
}
|
|
119
|
+
throw new Error('v3 requires valid namespace (uuid) and name!');
|
|
120
|
+
}
|
|
121
|
+
case 'v4': {
|
|
122
|
+
const bytes = new Uint8Array(16);
|
|
123
|
+
for (let i = 0; i < 16; i++) {
|
|
124
|
+
bytes[i] = Math.floor(Math.random() * 256);
|
|
125
|
+
}
|
|
126
|
+
let hex = '';
|
|
127
|
+
for (let i = 0; i < 16; i++) {
|
|
128
|
+
hex += bytes[i].toString(16).padStart(2, '0');
|
|
129
|
+
}
|
|
130
|
+
return (0, helpers_1._formatUUID)(hex, 4, uppercase);
|
|
131
|
+
}
|
|
132
|
+
case 'v5': {
|
|
133
|
+
if ((0, helpers_1._isOptionV3V5)(options)) {
|
|
134
|
+
const hash = sha1(options.namespace + options.name).slice(0, 32);
|
|
135
|
+
return (0, helpers_1._formatUUID)(hash, 5, uppercase);
|
|
136
|
+
}
|
|
137
|
+
throw new Error('v5 requires valid namespace (uuid) and name!');
|
|
138
|
+
}
|
|
139
|
+
case 'v6': {
|
|
140
|
+
const timestamp = (0, helpers_1._uuidTimestamp)().toString(16).padStart(15, '0');
|
|
141
|
+
const vTimeLow = (parseInt(timestamp.slice(12).padStart(3, '0'), 16) | 0x6000)
|
|
142
|
+
.toString(16)
|
|
143
|
+
.padStart(4, '0');
|
|
144
|
+
const clockSeq = (0, helpers_1._clockSeq14)();
|
|
145
|
+
const clockSeqHi = ((parseInt(clockSeq.slice(0, 2), 16) & 0x3f) | 0x80)
|
|
146
|
+
.toString(16)
|
|
147
|
+
.padStart(2, '0');
|
|
148
|
+
const clockSeqLow = clockSeq.slice(2);
|
|
149
|
+
const raw = timestamp.slice(0, 8) +
|
|
150
|
+
timestamp.slice(8, 12) +
|
|
151
|
+
vTimeLow +
|
|
152
|
+
clockSeqHi +
|
|
153
|
+
clockSeqLow +
|
|
154
|
+
(0, helpers_1._randomNode48)();
|
|
155
|
+
return (0, helpers_1._formatUUID)(raw, 6, uppercase);
|
|
156
|
+
}
|
|
157
|
+
case 'v7': {
|
|
158
|
+
const tsHex = Date.now().toString(16).padStart(12, '0');
|
|
159
|
+
return (0, helpers_1._formatUUID)(tsHex + randomHex(20), 7, uppercase);
|
|
160
|
+
}
|
|
161
|
+
case 'v8': {
|
|
162
|
+
const ts = BigInt(Date.now());
|
|
163
|
+
const bytes = new Uint8Array(16);
|
|
164
|
+
let temp = ts;
|
|
165
|
+
for (let i = 5; i >= 0; i--) {
|
|
166
|
+
bytes[i] = Number(temp & 0xffn);
|
|
167
|
+
temp >>= 8n;
|
|
168
|
+
}
|
|
169
|
+
for (let i = 6; i < 16; i++) {
|
|
170
|
+
bytes[i] = Math.floor(Math.random() * 256);
|
|
171
|
+
}
|
|
172
|
+
let hex = '';
|
|
173
|
+
for (let i = 0; i < 16; i++) {
|
|
174
|
+
hex += bytes[i].toString(16).padStart(2, '0');
|
|
175
|
+
}
|
|
176
|
+
return (0, helpers_1._formatUUID)(hex, 8, uppercase);
|
|
177
|
+
}
|
|
178
|
+
default:
|
|
179
|
+
throw new RangeError('Unsupported UUID version!');
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function decodeUUID(uuid) {
|
|
183
|
+
if (!(0, specials_1.isUUID)(uuid))
|
|
184
|
+
return null;
|
|
185
|
+
const plain = uuid.replace(/-/g, '');
|
|
186
|
+
const parts = uuid.toLowerCase().split('-');
|
|
187
|
+
const version = parseInt(parts[2][0], 16);
|
|
188
|
+
const variantNibble = parseInt(parts[3][0], 16);
|
|
189
|
+
let variant = 'RFC4122';
|
|
190
|
+
if ((variantNibble & 0b1000) === 0)
|
|
191
|
+
variant = 'NCS';
|
|
192
|
+
else if ((variantNibble & 0b1100) === 0b1000)
|
|
193
|
+
variant = 'RFC4122';
|
|
194
|
+
else if ((variantNibble & 0b1110) === 0b1100)
|
|
195
|
+
variant = 'Microsoft';
|
|
196
|
+
else
|
|
197
|
+
variant = 'Future';
|
|
198
|
+
const decoded = {
|
|
199
|
+
version,
|
|
200
|
+
variant,
|
|
201
|
+
raw: uuid,
|
|
202
|
+
plain,
|
|
203
|
+
singleInt: BigInt('0x' + plain),
|
|
204
|
+
};
|
|
205
|
+
const UUID_EPOCH_DIFF = 122192928000000000n;
|
|
206
|
+
if (version === 1 || version === 6) {
|
|
207
|
+
let tsHex = parts[2].slice(1) + parts[1] + parts[0];
|
|
208
|
+
if (version === 6)
|
|
209
|
+
tsHex = parts[0] + parts[1] + parts[2].slice(1);
|
|
210
|
+
const unixMs = Number((BigInt('0x' + tsHex) - UUID_EPOCH_DIFF) / 10000n);
|
|
211
|
+
decoded.timestamp = unixMs;
|
|
212
|
+
decoded.node = parts[4];
|
|
213
|
+
return decoded;
|
|
214
|
+
}
|
|
215
|
+
if (version === 7 || version === 8) {
|
|
216
|
+
const tsHex = parts.join('').slice(0, 12);
|
|
217
|
+
decoded.variant = version === 7 ? 'RFC4122' : 'Future';
|
|
218
|
+
decoded.timestamp = parseInt(tsHex, 16);
|
|
219
|
+
return decoded;
|
|
220
|
+
}
|
|
221
|
+
return decoded;
|
|
222
|
+
}
|
|
223
|
+
function isUUIDv1(value) {
|
|
224
|
+
return (0, helpers_1._checkUUIDVersion)(value, '1');
|
|
225
|
+
}
|
|
226
|
+
function isUUIDv2(value) {
|
|
227
|
+
return (0, helpers_1._checkUUIDVersion)(value, '2');
|
|
228
|
+
}
|
|
229
|
+
function isUUIDv3(value) {
|
|
230
|
+
return (0, helpers_1._checkUUIDVersion)(value, '3');
|
|
231
|
+
}
|
|
232
|
+
function isUUIDv4(value) {
|
|
233
|
+
return (0, helpers_1._checkUUIDVersion)(value, '4');
|
|
234
|
+
}
|
|
235
|
+
function isUUIDv5(value) {
|
|
236
|
+
return (0, helpers_1._checkUUIDVersion)(value, '5');
|
|
237
|
+
}
|
|
238
|
+
function isUUIDv6(value) {
|
|
239
|
+
return (0, helpers_1._checkUUIDVersion)(value, '6');
|
|
240
|
+
}
|
|
241
|
+
function isUUIDv7(value) {
|
|
242
|
+
return (0, helpers_1._checkUUIDVersion)(value, '7');
|
|
243
|
+
}
|
|
244
|
+
function isUUIDv8(value) {
|
|
245
|
+
return (0, helpers_1._checkUUIDVersion)(value, '8');
|
|
246
|
+
}
|
|
247
|
+
var basics_1 = require("../string/basics");
|
|
248
|
+
Object.defineProperty(exports, "generateRandomID", { enumerable: true, get: function () { return basics_1.generateRandomID; } });
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.convertToDecimal = exports.calculateLCM = exports.calculateLCD = exports.calculateHCF = exports.calculateGCD = exports.calculateFactorial = exports.calculateAverage = exports.verbalizer = exports.Verbalizer = exports.pluralizer = exports.Pluralizer = exports.VolumeConverter = exports.TimeConverter = exports.TemperatureConverter = exports.MassConverter = exports.LengthConverter = exports.DataConverter = exports.converter = exports.Converter = exports.AreaConverter = exports.wordCount = exports.parseNumbersFromText = exports.levenshteinDistance = exports.getLevenshteinDistance = exports.extractNumbersFromString = exports.extractNumbers = exports.countWordsInString = exports.countWords = exports.slugifyString = exports.reverseString = exports.replaceAllInString = exports.normalizeString = exports.maskString = exports.formatWithPlural = exports.formatUnitWithPlural = exports.formatNumberWithPluralUnit = exports.extractURLs = exports.extractEmails = exports.convertStringCase = exports.isSnakeCase = exports.isPascalCase = exports.isPalindrome = exports.isKebabCase = exports.isEmojiOnly = exports.isCamelCase = exports.generateAnagrams = exports.truncateString = exports.trimString = exports.generateRandomID =
|
|
3
|
+
exports.convertToDecimal = exports.calculateLCM = exports.calculateLCD = exports.calculateHCF = exports.calculateGCD = exports.calculateFactorial = exports.calculateAverage = exports.verbalizer = exports.Verbalizer = exports.pluralizer = exports.Pluralizer = exports.VolumeConverter = exports.TimeConverter = exports.TemperatureConverter = exports.MassConverter = exports.LengthConverter = exports.DataConverter = exports.converter = exports.Converter = exports.AreaConverter = exports.wordCount = exports.parseNumbersFromText = exports.levenshteinDistance = exports.getLevenshteinDistance = exports.extractNumbersFromString = exports.extractNumbers = exports.countWordsInString = exports.countWords = exports.slugifyString = exports.reverseString = exports.replaceAllInString = exports.normalizeString = exports.maskString = exports.formatWithPlural = exports.formatUnitWithPlural = exports.formatNumberWithPluralUnit = exports.extractURLs = exports.extractEmails = exports.convertStringCase = exports.capitalizeString = exports.isSnakeCase = exports.isPascalCase = exports.isPalindrome = exports.isKebabCase = exports.isEmojiOnly = exports.isCamelCase = exports.generateAnagrams = exports.truncateString = exports.trimString = exports.generateRandomID = void 0;
|
|
4
4
|
exports.convertRomanToNumeric = exports.convertRomanToInteger = exports.convertRomanToArabic = exports.convertNumberToWordsOrdinal = exports.convertNumberToWords = exports.cardinalWordsToOrdinal = exports.arabicToRoman = exports.isPerfectSquare = exports.isPartOfFibonacciSeries = exports.isPartOfFibonacci = exports.isOddNumber = exports.isOdd = exports.isNumberInvalid = exports.isMultiple = exports.isInvalidNumber = exports.isFibonacci = exports.isEvenNumber = exports.isEven = exports.areNumbersInvalid = exports.areInvalidNumbers = exports.getNthFibonacci = exports.getMemoizedFibonacciSeries = exports.getMemoizedFibonacci = exports.getFibonacciSeriesMemo = exports.getFibonacciSeries = exports.getFibonacciNumbers = exports.getFibonacci = exports.generateFibonacci = exports.fibonacciGenerator = exports.calculatePercentage = exports.UnitConverter = exports.Unit = exports.Currency = exports.sumOfNumbers = exports.sumNumbers = exports.sumDigits = exports.roundToDecimal = exports.roundNumber = exports.reverseNumber = exports.getSumOfNumbers = exports.getRandomNumber = exports.getRandomInt = exports.getFactors = exports.getFactorial = exports.getDivisors = exports.getAverageOfNumbers = exports.getAverage = exports.factorsOf = exports.factorial = exports.convertToFixed = void 0;
|
|
5
5
|
exports.convertHslToHex = exports.convertHslaToRgba = exports.convertHslaToHex8 = exports.convertHexToRgb = exports.convertHexToHsl = exports.convertHex8ToRgba = exports.convertHex8ToHsla = exports.convertColorCode = exports.getRandomHSL = exports.getRandomColor = exports.generateRandomHSLColor = exports.generateRandomHSL = exports.generateRandomColorInHexRGB = exports.generateRandomColor = exports.getColorForInitial = exports.getNumbersInRange = exports.roundToNearestInterval = exports.roundToNearest = exports.roundNumberToNearestInterval = exports.numberToOrdinal = exports.normalizeNumber = exports.getRandomFloat = exports.getRandomDecimal = exports.getOrdinalNumber = exports.getOrdinal = exports.formatCurrency = exports.convertToOrdinal = exports.convertNumberToOrdinal = exports.convertNumberToCurrency = exports.clampNumber = exports.cardinalToOrdinal = exports.isPrimeNumber = exports.isPrime = exports.getPrimeNumbers = exports.findPrimeNumbers = exports.wordToNumber = exports.wordsToNumber = exports.toRomanNumeral = exports.toRoman = exports.romanToNumeric = exports.romanToInteger = exports.romanToArabic = exports.numericToRoman = exports.numberToWordsOrdinal = exports.numberToWords = exports.numberToRoman = exports.integerToRoman = exports.convertWordToNumber = exports.convertWordsToNumber = exports.convertToRomanNumerals = void 0;
|
|
6
6
|
exports.getCurrentTime = exports.getCurrentDateTime = exports.formatUTCOffset = exports.formatDateTime = exports.formatDate = exports.extractTotalMinutesFromTime = exports.extractTimeStringFromUTC = exports.extractTimeFromUTC = exports.extractMinutesFromUTC = exports.extractHourMinute = exports.convertMinutesToUTCOffset = exports.convertMinutesToTime = exports.convertMinutesToHourMinutes = exports.chronusts = exports.chronusjs = exports.chronus = exports.chronosts = exports.chronosjs = exports.chronos = exports.INTERNALS = exports.Chronus = exports.Chronos = exports.isValidUTCOffSet = exports.isValidUTCOffset = exports.isValidUTC = exports.isValidTimeZoneId = exports.isValidTimeString = exports.isValidTime = exports.isNativeTimeZoneId = exports.isLeapYear = exports.isDateLike = exports.greet = exports.getGreeting = exports.generateGreeting = exports.extractSolidColorValues = exports.extractAlphaColorValues = exports.Colour = exports.Color = exports.isRGBA = exports.isRGB = exports.isHSLA = exports.isHSL = exports.isHex8 = exports.isHex6 = exports.convertRgbToRgba = exports.convertRgbToHsl = exports.convertRgbToHex = exports.convertRgbaToHsla = exports.convertRgbaToHex8 = exports.convertHslToRgb = void 0;
|
|
7
7
|
exports.isCustomFile = exports.serializeForm = exports.parseFormData = exports.createFormData = exports.createControlledFormData = exports.convertIntoFormData = exports.naturalSortForString = exports.naturalSort = exports.compareSorter = exports.compareNaturally = exports.splitArrayByProperty = exports.splitArray = exports.rotateArray = exports.removeDuplicatesFromArray = exports.removeDuplicates = exports.moveArrayElement = exports.groupArrayByProperty = exports.getMissingElements = exports.getDuplicatesFromArray = exports.getDuplicates = exports.findMissingElements = exports.extractMissingElements = exports.extractDuplicatesFromArray = exports.extractDuplicates = exports.createOptionsArray = exports.sortAnArray = exports.Finder = exports.totalDeltaByField = exports.sumFieldDifference = exports.sumByField = exports.groupAndSumByField = exports.groupAndAvgByField = exports.groupAndAverageByField = exports.avgByField = exports.averageByField = exports.shuffleArray = exports.isValidEmptyArray = exports.isInvalidOrEmptyArray = exports.getLastArrayElement = exports.flattenArray = exports.filterArrayOfObjects = exports.minutesToUTCOffset = exports.getTotalMinutesFromUTC = exports.getTotalMinutesFromTime = exports.getTotalMinutes = exports.getTimeZoneDetails = exports.getTimeStringFromUTC = exports.getTimeFromMinutes = exports.getMinutesFromUTC = exports.getHourMinutesFromMinutes = void 0;
|
|
8
8
|
exports.toggleFullScreen = exports.smoothScrollTo = exports.copyToClipboard = exports.updateQueryParam = exports.queryStringToObject = exports.parseQueryStringLiteral = exports.parseQueryString = exports.literalQueryStringToObject = exports.getQueryStringAsObject = exports.getQueryParams = exports.generateQueryParams = exports.formatQueryParams = exports.createQueryParams = exports.removeObjectFields = exports.removeFields = exports.remapObjectFields = exports.remapFields = exports.pickObjectFieldsByCondition = exports.pickObjectFields = exports.pickFieldsByCondition = exports.pickFields = exports.omitObjectFields = exports.omitFields = exports.deleteObjectFields = exports.deleteFields = exports.convertObjectValues = exports.sanitizeData = exports.parseStringifiedObjectValues = exports.parseObjectValues = exports.parseJsonToObject = exports.mergeObjects = exports.mergeAndFlattenObjects = exports.flattenObjectKeyValue = exports.flattenObjectDotNotation = exports.extractUpdatedFields = exports.extractUpdatedAndNewFields = exports.extractNewFields = exports.extractObjectKeysDeep = exports.extractObjectKeys = exports.extractKeysDeep = exports.extractKeys = exports.countObjectFields = exports.cloneObject = exports.isValidFormData = exports.isOriginFileObj = exports.isFileUpload = exports.isFileOrBlob = exports.isFileList = exports.isFileArray = exports.isCustomFileArray = void 0;
|
|
9
|
-
exports.
|
|
10
|
-
exports.isValidURL = exports.isValidEmail = exports.isUUID = exports.isURL = exports.isPhoneNumber = exports.isNumericString = exports.isNodeEnvironment = exports.isNodeENV = exports.isNode = exports.isIPAddress = exports.isExpectedNodeENV = exports.isEnvironment = exports.isEmailArray = exports.isEmail = exports.isDateString = exports.isBrowser = exports.isBase64 = exports.httpStatus = exports.HttpStatus = exports.isValidSet = exports.isValidObject = exports.isValidMap = exports.isValidJSON = exports.isValidArray = exports.isSet = exports.isReturningPromise = exports.isRegularExpression = exports.isRegExp = exports.isPromise = exports.isObjectWithKeys = exports.isObjectEmpty = exports.isObject = exports.isNotEmptyObject = exports.isMethodDescriptor = void 0;
|
|
9
|
+
exports.isJSON = exports.isFunction = exports.isError = exports.isEmptyObjectGuard = exports.isEmptyObject = exports.isDate = exports.isArrayWithLength = exports.isArrayOfType = exports.isArray = exports.doesReturnPromise = exports.isUndefined = exports.isTruthy = exports.isSymbol = exports.isString = exports.isPrimitive = exports.isPositiveInteger = exports.isNumber = exports.isNull = exports.isNormalPrimitive = exports.isNonEmptyString = exports.isInteger = exports.isFalsy = exports.isBoolean = exports.isBigInt = exports.Paginator = exports.throttleAction = exports.parsePrimitivesDeep = exports.parseJsonDeep = exports.parseJSON = exports.joinArrayElements = exports.isDeepEqual = exports.getStaticMethodsCount = exports.getStaticMethodNames = exports.getStaticGetterNames = exports.getInstanceMethodsCount = exports.getInstanceMethodNames = exports.getInstanceGetterNames = exports.getClassDetails = exports.definePrototypeMethod = exports.deepParsePrimitives = exports.debounceAction = exports.countStaticMethods = exports.countInstanceMethods = exports.convertArrayToString = exports.saveToSessionStorage = exports.saveToLocalStorage = exports.removeFromSessionStorage = exports.removeFromLocalStorage = exports.getFromSessionStorage = exports.getFromLocalStorage = void 0;
|
|
10
|
+
exports.isValidURL = exports.isValidEmail = exports.isUUID = exports.isURL = exports.isPhoneNumber = exports.isNumericString = exports.isNodeEnvironment = exports.isNodeENV = exports.isNode = exports.isIPAddress = exports.isExpectedNodeENV = exports.isEnvironment = exports.isEmailArray = exports.isEmail = exports.isDateString = exports.isBrowser = exports.isBase64 = exports.httpStatus = exports.HttpStatus = exports.isValidSet = exports.isValidObject = exports.isValidMap = exports.isValidJSON = exports.isValidArray = exports.isSet = exports.isReturningPromise = exports.isRegularExpression = exports.isRegExp = exports.isPromise = exports.isObjectWithKeys = exports.isObjectEmpty = exports.isObject = exports.isNotEmptyObject = exports.isMethodDescriptor = exports.isMethod = exports.isMap = exports.isJSONObject = void 0;
|
|
11
11
|
var basics_1 = require("./string/basics");
|
|
12
|
-
Object.defineProperty(exports, "capitalizeString", { enumerable: true, get: function () { return basics_1.capitalizeString; } });
|
|
13
12
|
Object.defineProperty(exports, "generateRandomID", { enumerable: true, get: function () { return basics_1.generateRandomID; } });
|
|
14
13
|
Object.defineProperty(exports, "trimString", { enumerable: true, get: function () { return basics_1.trimString; } });
|
|
15
14
|
Object.defineProperty(exports, "truncateString", { enumerable: true, get: function () { return basics_1.truncateString; } });
|
|
@@ -23,6 +22,7 @@ Object.defineProperty(exports, "isPalindrome", { enumerable: true, get: function
|
|
|
23
22
|
Object.defineProperty(exports, "isPascalCase", { enumerable: true, get: function () { return guards_1.isPascalCase; } });
|
|
24
23
|
Object.defineProperty(exports, "isSnakeCase", { enumerable: true, get: function () { return guards_1.isSnakeCase; } });
|
|
25
24
|
var case_1 = require("./string/case");
|
|
25
|
+
Object.defineProperty(exports, "capitalizeString", { enumerable: true, get: function () { return case_1.capitalizeString; } });
|
|
26
26
|
Object.defineProperty(exports, "convertStringCase", { enumerable: true, get: function () { return case_1.convertStringCase; } });
|
|
27
27
|
var convert_1 = require("./string/convert");
|
|
28
28
|
Object.defineProperty(exports, "extractEmails", { enumerable: true, get: function () { return convert_1.extractEmails; } });
|
|
@@ -367,9 +367,12 @@ Object.defineProperty(exports, "countInstanceMethods", { enumerable: true, get:
|
|
|
367
367
|
Object.defineProperty(exports, "countStaticMethods", { enumerable: true, get: function () { return index_1.countStaticMethods; } });
|
|
368
368
|
Object.defineProperty(exports, "debounceAction", { enumerable: true, get: function () { return index_1.debounceAction; } });
|
|
369
369
|
Object.defineProperty(exports, "deepParsePrimitives", { enumerable: true, get: function () { return index_1.deepParsePrimitives; } });
|
|
370
|
+
Object.defineProperty(exports, "definePrototypeMethod", { enumerable: true, get: function () { return index_1.definePrototypeMethod; } });
|
|
370
371
|
Object.defineProperty(exports, "getClassDetails", { enumerable: true, get: function () { return index_1.getClassDetails; } });
|
|
372
|
+
Object.defineProperty(exports, "getInstanceGetterNames", { enumerable: true, get: function () { return index_1.getInstanceGetterNames; } });
|
|
371
373
|
Object.defineProperty(exports, "getInstanceMethodNames", { enumerable: true, get: function () { return index_1.getInstanceMethodNames; } });
|
|
372
374
|
Object.defineProperty(exports, "getInstanceMethodsCount", { enumerable: true, get: function () { return index_1.countInstanceMethods; } });
|
|
375
|
+
Object.defineProperty(exports, "getStaticGetterNames", { enumerable: true, get: function () { return index_1.getStaticGetterNames; } });
|
|
373
376
|
Object.defineProperty(exports, "getStaticMethodNames", { enumerable: true, get: function () { return index_1.getStaticMethodNames; } });
|
|
374
377
|
Object.defineProperty(exports, "getStaticMethodsCount", { enumerable: true, get: function () { return index_1.countStaticMethods; } });
|
|
375
378
|
Object.defineProperty(exports, "isDeepEqual", { enumerable: true, get: function () { return index_1.isDeepEqual; } });
|
|
@@ -127,7 +127,7 @@ function numberToWordsOrdinal(number) {
|
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
129
|
function wordsToNumber(word) {
|
|
130
|
-
if (!
|
|
130
|
+
if (!(0, primitives_1.isNonEmptyString)(word))
|
|
131
131
|
return NaN;
|
|
132
132
|
const trimmed = word.trim();
|
|
133
133
|
if (/^[+-]?\d{1,3}(,\d{3})*(\.\d+)?$/.test(trimmed)) {
|
|
@@ -1,22 +1,42 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateAnagrams = generateAnagrams;
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
const non_primitives_1 = require("../guards/non-primitives");
|
|
5
|
+
const primitives_1 = require("../guards/primitives");
|
|
6
|
+
const DICT_CACHE = new WeakMap();
|
|
7
|
+
function _getDictSet(dict) {
|
|
8
|
+
if (DICT_CACHE.has(dict))
|
|
9
|
+
return DICT_CACHE.get(dict);
|
|
10
|
+
const dictSet = new Set(dict.map((w) => w.toLowerCase()));
|
|
11
|
+
DICT_CACHE.set(dict, dictSet);
|
|
12
|
+
return dictSet;
|
|
13
|
+
}
|
|
14
|
+
function generateAnagrams(word, options) {
|
|
15
|
+
if (!(0, primitives_1.isNonEmptyString)(word))
|
|
16
|
+
return [];
|
|
17
|
+
if (word?.length === 1)
|
|
6
18
|
return [word?.toLowerCase()];
|
|
7
|
-
}
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
19
|
+
const { limit = 100, dictionary = false } = options || {};
|
|
20
|
+
const outSet = new Set();
|
|
21
|
+
const dictSet = (0, non_primitives_1.isValidArray)(dictionary) ? _getDictSet(dictionary) : undefined;
|
|
22
|
+
const _permute = (current, remaining) => {
|
|
23
|
+
if (!remaining.length) {
|
|
24
|
+
if (!dictSet || dictSet.has(current)) {
|
|
25
|
+
outSet.add(current);
|
|
26
|
+
}
|
|
12
27
|
return;
|
|
13
28
|
}
|
|
14
|
-
|
|
15
|
-
|
|
29
|
+
const usedSet = new Set();
|
|
30
|
+
for (let i = 0; i < remaining.length; i++) {
|
|
31
|
+
const char = remaining[i];
|
|
32
|
+
if (usedSet.has(char))
|
|
33
|
+
continue;
|
|
34
|
+
usedSet.add(char);
|
|
35
|
+
if (limit !== 'all' && outSet.size >= limit)
|
|
16
36
|
return;
|
|
17
|
-
_permute(
|
|
37
|
+
_permute(current + char, remaining.slice(0, i) + remaining.slice(i + 1));
|
|
18
38
|
}
|
|
19
39
|
};
|
|
20
40
|
_permute('', word.toLowerCase());
|
|
21
|
-
return
|
|
41
|
+
return [...outSet];
|
|
22
42
|
}
|
|
@@ -1,36 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateRandomID = exports.truncateString = void 0;
|
|
4
|
-
exports.capitalizeString = capitalizeString;
|
|
5
4
|
exports.trimString = trimString;
|
|
6
|
-
function capitalizeString(string, options) {
|
|
7
|
-
if (typeof string !== 'string' || !string)
|
|
8
|
-
return '';
|
|
9
|
-
const trimmedString = string.trim();
|
|
10
|
-
if (!trimmedString)
|
|
11
|
-
return '';
|
|
12
|
-
const { capitalizeAll = false, capitalizeEachFirst = false, lowerCaseRest = true, } = options || {};
|
|
13
|
-
if (capitalizeAll) {
|
|
14
|
-
return trimmedString.toUpperCase();
|
|
15
|
-
}
|
|
16
|
-
if (capitalizeEachFirst) {
|
|
17
|
-
return trimmedString
|
|
18
|
-
?.split(/\s+/)
|
|
19
|
-
?.map((word) => capitalizeString(word, { lowerCaseRest }))
|
|
20
|
-
?.join(' ');
|
|
21
|
-
}
|
|
22
|
-
const matchArray = trimmedString.match(/^(\W*)(\w)(.*)$/);
|
|
23
|
-
if (matchArray && matchArray?.length === 4) {
|
|
24
|
-
const [_, leadingSymbols, firstLetter, rest] = matchArray;
|
|
25
|
-
return leadingSymbols
|
|
26
|
-
.concat(firstLetter.toUpperCase())
|
|
27
|
-
.concat(lowerCaseRest ? rest.toLowerCase() : rest);
|
|
28
|
-
}
|
|
29
|
-
return trimmedString
|
|
30
|
-
.charAt(0)
|
|
31
|
-
.toUpperCase()
|
|
32
|
-
.concat(lowerCaseRest ? trimmedString.slice(1).toLowerCase() : trimmedString.slice(1));
|
|
33
|
-
}
|
|
34
5
|
const truncateString = (string, maxLength) => {
|
|
35
6
|
if (typeof string !== 'string' || !string)
|
|
36
7
|
return '';
|