@andrew_l/toolkit 0.0.2 → 0.2.5
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/dist/index.cjs +224 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +103 -24
- package/dist/index.d.mts +103 -24
- package/dist/index.d.ts +103 -24
- package/dist/index.mjs +222 -39
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const _get = require('lodash/get');
|
|
4
|
-
const _cloneDeep = require('lodash/cloneDeep');
|
|
5
|
-
const _cloneDeepWith = require('lodash/cloneDeepWith');
|
|
6
|
-
const _defaultsDeep = require('lodash/defaultsDeep');
|
|
7
|
-
const _set = require('lodash/set');
|
|
8
|
-
const _unset = require('lodash/unset');
|
|
3
|
+
const _get = require('lodash/get.js');
|
|
4
|
+
const _cloneDeep = require('lodash/cloneDeep.js');
|
|
5
|
+
const _cloneDeepWith = require('lodash/cloneDeepWith.js');
|
|
6
|
+
const _defaultsDeep = require('lodash/defaultsDeep.js');
|
|
7
|
+
const _set = require('lodash/set.js');
|
|
8
|
+
const _unset = require('lodash/unset.js');
|
|
9
9
|
|
|
10
10
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
11
11
|
|
|
@@ -248,6 +248,30 @@ function difference(...arrays) {
|
|
|
248
248
|
return Array.from(set);
|
|
249
249
|
}
|
|
250
250
|
|
|
251
|
+
function groupBy(array, keyBy, objectMode) {
|
|
252
|
+
const getItemKey = isFunction(keyBy) ? keyBy : (item) => item?.[keyBy];
|
|
253
|
+
let key;
|
|
254
|
+
if (objectMode === true) {
|
|
255
|
+
const result2 = {};
|
|
256
|
+
for (const item of array) {
|
|
257
|
+
key = getItemKey(item);
|
|
258
|
+
result2[key] = result2[key] || [];
|
|
259
|
+
result2[key].push(item);
|
|
260
|
+
}
|
|
261
|
+
return result2;
|
|
262
|
+
}
|
|
263
|
+
const result = /* @__PURE__ */ new Map();
|
|
264
|
+
for (const item of array) {
|
|
265
|
+
key = getItemKey(item);
|
|
266
|
+
if (!result.has(key)) {
|
|
267
|
+
result.set(key, [item]);
|
|
268
|
+
} else {
|
|
269
|
+
result.get(key).push(item);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return result;
|
|
273
|
+
}
|
|
274
|
+
|
|
251
275
|
function intersection(...arrays) {
|
|
252
276
|
if (arrays.length === 0) return [];
|
|
253
277
|
if (arrays.length === 1) return arrays[0];
|
|
@@ -358,6 +382,7 @@ let AssertionError;
|
|
|
358
382
|
(r) => r.BrowserAssertionError
|
|
359
383
|
) : await import('node:assert').then((r) => r.AssertionError);
|
|
360
384
|
})();
|
|
385
|
+
|
|
361
386
|
function ok(value, message) {
|
|
362
387
|
if (!value) {
|
|
363
388
|
throw toError$1(
|
|
@@ -379,6 +404,11 @@ function equal(actual, expected, message) {
|
|
|
379
404
|
});
|
|
380
405
|
}
|
|
381
406
|
}
|
|
407
|
+
function empty$1(value, message) {
|
|
408
|
+
if (isEmpty(value)) {
|
|
409
|
+
throw toError$1(empty$1, value, message, "Expected not empty value.");
|
|
410
|
+
}
|
|
411
|
+
}
|
|
382
412
|
function object(value, message) {
|
|
383
413
|
if (!isObject(value)) {
|
|
384
414
|
throw toError$1(object, value, message, "Expected object value.");
|
|
@@ -409,6 +439,36 @@ function number$1(value, message) {
|
|
|
409
439
|
throw toError$1(number$1, value, message, "Expected number value.");
|
|
410
440
|
}
|
|
411
441
|
}
|
|
442
|
+
function date(value, message) {
|
|
443
|
+
if (!isDate(value)) {
|
|
444
|
+
throw toError$1(date, value, message, "Expected date value.");
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
function fn(value, message) {
|
|
448
|
+
if (!isNumber(value)) {
|
|
449
|
+
throw toError$1(fn, value, message, "Expected function value.");
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
function greaterThan(value, target, message) {
|
|
453
|
+
if (!isNumber(value) || value < target) {
|
|
454
|
+
throw toError$1(
|
|
455
|
+
greaterThan,
|
|
456
|
+
value,
|
|
457
|
+
message,
|
|
458
|
+
"Expected number value greater then " + target + "."
|
|
459
|
+
);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
function lessThan(value, target, message) {
|
|
463
|
+
if (!isNumber(value) || value > target) {
|
|
464
|
+
throw toError$1(
|
|
465
|
+
lessThan,
|
|
466
|
+
value,
|
|
467
|
+
message,
|
|
468
|
+
"Expected number value less then " + target + "."
|
|
469
|
+
);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
412
472
|
function array(value, message) {
|
|
413
473
|
if (!Array.isArray(value)) {
|
|
414
474
|
throw toError$1(array, value, message, "Expected array value.");
|
|
@@ -442,7 +502,12 @@ const assert = {
|
|
|
442
502
|
arrayNumbers: arrayNumbers,
|
|
443
503
|
arrayStrings: arrayStrings,
|
|
444
504
|
boolean: boolean,
|
|
505
|
+
date: date,
|
|
506
|
+
empty: empty$1,
|
|
445
507
|
equal: equal,
|
|
508
|
+
fn: fn,
|
|
509
|
+
greaterThan: greaterThan,
|
|
510
|
+
lessThan: lessThan,
|
|
446
511
|
notEmptyString: notEmptyString,
|
|
447
512
|
number: number$1,
|
|
448
513
|
object: object,
|
|
@@ -450,6 +515,53 @@ const assert = {
|
|
|
450
515
|
string: string
|
|
451
516
|
};
|
|
452
517
|
|
|
518
|
+
function weightedRoundRobin(arr) {
|
|
519
|
+
ok(arr.length > 0, "Array must contain at least one item.");
|
|
520
|
+
const instance = new WeightedRoundRobin(
|
|
521
|
+
arr.map((v) => ({
|
|
522
|
+
item: v.item,
|
|
523
|
+
weight: Math.min(v.weight ?? 1, 1)
|
|
524
|
+
}))
|
|
525
|
+
);
|
|
526
|
+
return () => instance.nextItem();
|
|
527
|
+
}
|
|
528
|
+
const gcd = (a, b) => !b ? a : gcd(b, a % b);
|
|
529
|
+
class WeightedRoundRobin {
|
|
530
|
+
constructor(items) {
|
|
531
|
+
this.items = items;
|
|
532
|
+
this.maxWeight = this._calculateMaxWeight();
|
|
533
|
+
this.gcdWeight = this._calculateGCD();
|
|
534
|
+
}
|
|
535
|
+
currentIndex = -1;
|
|
536
|
+
currentWeight = 0;
|
|
537
|
+
maxWeight;
|
|
538
|
+
gcdWeight;
|
|
539
|
+
_calculateGCD() {
|
|
540
|
+
return this.items.reduce(
|
|
541
|
+
(acc, curr) => gcd(acc, curr.weight),
|
|
542
|
+
this.items[0].weight
|
|
543
|
+
);
|
|
544
|
+
}
|
|
545
|
+
_calculateMaxWeight() {
|
|
546
|
+
return Math.max(...this.items.map((s) => s.weight));
|
|
547
|
+
}
|
|
548
|
+
nextItem() {
|
|
549
|
+
const n = this.items.length;
|
|
550
|
+
while (true) {
|
|
551
|
+
this.currentIndex = (this.currentIndex + 1) % n;
|
|
552
|
+
if (this.currentIndex === 0) {
|
|
553
|
+
this.currentWeight -= this.gcdWeight;
|
|
554
|
+
if (this.currentWeight <= 0) {
|
|
555
|
+
this.currentWeight = this.maxWeight;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
if (this.items[this.currentIndex].weight >= this.currentWeight) {
|
|
559
|
+
return this.items[this.currentIndex].item;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
453
565
|
class Base64Encoding {
|
|
454
566
|
alphabet;
|
|
455
567
|
padding;
|
|
@@ -658,13 +770,12 @@ const def = (obj, key, value, writable = false) => {
|
|
|
658
770
|
const rndCharacters = "abcdefghijklmnopqrstuvwxyz0123456789";
|
|
659
771
|
const charactersLength = rndCharacters.length;
|
|
660
772
|
function randomString(length) {
|
|
661
|
-
let
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
);
|
|
773
|
+
let str = "";
|
|
774
|
+
let num = isNumber(length) ? Math.max(0, length) : 0;
|
|
775
|
+
while (num--) {
|
|
776
|
+
str += rndCharacters[charactersLength * Math.random() | 0];
|
|
666
777
|
}
|
|
667
|
-
return
|
|
778
|
+
return str;
|
|
668
779
|
}
|
|
669
780
|
|
|
670
781
|
const objectKeys = /* @__PURE__ */ new WeakMap();
|
|
@@ -1457,27 +1568,57 @@ function flatten(obj, {
|
|
|
1457
1568
|
isObjectCompare = isObject
|
|
1458
1569
|
} = {}) {
|
|
1459
1570
|
const result = {};
|
|
1460
|
-
const
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1571
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
1572
|
+
if (isObjectCompare(obj)) {
|
|
1573
|
+
iter(
|
|
1574
|
+
result,
|
|
1575
|
+
seen,
|
|
1576
|
+
isObjectCompare,
|
|
1577
|
+
separator,
|
|
1578
|
+
withArrays,
|
|
1579
|
+
obj,
|
|
1580
|
+
initialPrefix,
|
|
1581
|
+
true
|
|
1582
|
+
);
|
|
1583
|
+
}
|
|
1584
|
+
return result;
|
|
1585
|
+
}
|
|
1586
|
+
function iter(output, seen, isObjectCompare, separator, withArrays, val, key, initial) {
|
|
1587
|
+
if (seen.has(val)) return;
|
|
1588
|
+
let k, pfx = key && !initial ? key + separator : key;
|
|
1589
|
+
if (Array.isArray(val)) {
|
|
1590
|
+
seen.add(val);
|
|
1591
|
+
if (!withArrays) {
|
|
1592
|
+
output[key] = val;
|
|
1469
1593
|
return;
|
|
1470
1594
|
}
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1595
|
+
for (k = 0; k < val.length; k++) {
|
|
1596
|
+
iter(
|
|
1597
|
+
output,
|
|
1598
|
+
seen,
|
|
1599
|
+
isObjectCompare,
|
|
1600
|
+
separator,
|
|
1601
|
+
withArrays,
|
|
1602
|
+
val[k],
|
|
1603
|
+
pfx + k
|
|
1604
|
+
);
|
|
1476
1605
|
}
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1606
|
+
} else if (isObjectCompare(val)) {
|
|
1607
|
+
seen.add(val);
|
|
1608
|
+
for (k in val) {
|
|
1609
|
+
iter(
|
|
1610
|
+
output,
|
|
1611
|
+
seen,
|
|
1612
|
+
isObjectCompare,
|
|
1613
|
+
separator,
|
|
1614
|
+
withArrays,
|
|
1615
|
+
val[k],
|
|
1616
|
+
pfx + k
|
|
1617
|
+
);
|
|
1618
|
+
}
|
|
1619
|
+
} else {
|
|
1620
|
+
output[key] = val;
|
|
1621
|
+
}
|
|
1481
1622
|
}
|
|
1482
1623
|
|
|
1483
1624
|
function has(value, keys) {
|
|
@@ -1558,12 +1699,40 @@ const toMap = (obj) => {
|
|
|
1558
1699
|
return map;
|
|
1559
1700
|
};
|
|
1560
1701
|
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1702
|
+
const badKeys = Object.freeze(
|
|
1703
|
+
/* @__PURE__ */ new Set(["constructor", "__proto__", "prototype"])
|
|
1704
|
+
);
|
|
1705
|
+
function unflatten(input, separator = "_") {
|
|
1706
|
+
if (!isObject(input)) {
|
|
1707
|
+
return {};
|
|
1708
|
+
}
|
|
1709
|
+
let arr, tmp, output;
|
|
1710
|
+
let i = 0, k, key;
|
|
1711
|
+
for (k in input) {
|
|
1712
|
+
tmp = output;
|
|
1713
|
+
arr = k.split(separator);
|
|
1714
|
+
for (i = 0; i < arr.length; ) {
|
|
1715
|
+
key = arr[i++];
|
|
1716
|
+
if (tmp == null) {
|
|
1717
|
+
tmp = empty(+key);
|
|
1718
|
+
output = output || tmp;
|
|
1719
|
+
}
|
|
1720
|
+
if (badKeys.has(key)) break;
|
|
1721
|
+
if (i < arr.length) {
|
|
1722
|
+
if (key in tmp) {
|
|
1723
|
+
tmp = tmp[key];
|
|
1724
|
+
} else {
|
|
1725
|
+
tmp = tmp[key] = empty(+arr[i]);
|
|
1726
|
+
}
|
|
1727
|
+
} else {
|
|
1728
|
+
tmp[key] = input[k];
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
return output;
|
|
1733
|
+
}
|
|
1734
|
+
function empty(key) {
|
|
1735
|
+
return key === key ? [] : {};
|
|
1567
1736
|
}
|
|
1568
1737
|
|
|
1569
1738
|
const unset = _unset__default;
|
|
@@ -3188,7 +3357,7 @@ function getFileExtension(name, withDot = true) {
|
|
|
3188
3357
|
return null;
|
|
3189
3358
|
}
|
|
3190
3359
|
const ext = name.split(".").at(-1)?.split("?")?.at(0);
|
|
3191
|
-
return ext ? withDot ?
|
|
3360
|
+
return ext ? withDot ? `.${ext}` : ext : null;
|
|
3192
3361
|
}
|
|
3193
3362
|
|
|
3194
3363
|
const DEF_PROTOCOLS = ["http://", "https://"];
|
|
@@ -3206,7 +3375,21 @@ function getFileName(value) {
|
|
|
3206
3375
|
if (!ext) {
|
|
3207
3376
|
return value;
|
|
3208
3377
|
}
|
|
3209
|
-
return value.slice(0, -ext.length
|
|
3378
|
+
return value.slice(0, -ext.length);
|
|
3379
|
+
}
|
|
3380
|
+
|
|
3381
|
+
function getMostSpecificPaths(keys) {
|
|
3382
|
+
keys = [...keys].sort();
|
|
3383
|
+
const result = [];
|
|
3384
|
+
for (let i = 0; i < keys.length; i++) {
|
|
3385
|
+
const currentPath = keys[i];
|
|
3386
|
+
const nextPath = keys[i + 1];
|
|
3387
|
+
if (currentPath === nextPath) continue;
|
|
3388
|
+
if (!nextPath || !nextPath.startsWith(currentPath + ".")) {
|
|
3389
|
+
result.push(currentPath);
|
|
3390
|
+
}
|
|
3391
|
+
}
|
|
3392
|
+
return result;
|
|
3210
3393
|
}
|
|
3211
3394
|
|
|
3212
3395
|
function humanFileSize(bytes, digits = 1, withSpace = true) {
|
|
@@ -4325,9 +4508,11 @@ exports.get = get;
|
|
|
4325
4508
|
exports.getFileExtension = getFileExtension;
|
|
4326
4509
|
exports.getFileName = getFileName;
|
|
4327
4510
|
exports.getInitials = getInitials;
|
|
4511
|
+
exports.getMostSpecificPaths = getMostSpecificPaths;
|
|
4328
4512
|
exports.getRandomInt = getRandomInt;
|
|
4329
4513
|
exports.getRandomTime = getRandomTime;
|
|
4330
4514
|
exports.getWords = getWords;
|
|
4515
|
+
exports.groupBy = groupBy;
|
|
4331
4516
|
exports.has = has;
|
|
4332
4517
|
exports.hasOwn = hasOwn;
|
|
4333
4518
|
exports.hasProtocol = hasProtocol;
|
|
@@ -4431,6 +4616,7 @@ exports.uniq = uniq;
|
|
|
4431
4616
|
exports.uniqBy = uniqBy;
|
|
4432
4617
|
exports.unset = unset;
|
|
4433
4618
|
exports.weeksInYear = weeksInYear;
|
|
4619
|
+
exports.weightedRoundRobin = weightedRoundRobin;
|
|
4434
4620
|
exports.withCache = withCache;
|
|
4435
4621
|
exports.withCacheBucket = withCacheBucket;
|
|
4436
4622
|
exports.withCacheBucketBatch = withCacheBucketBatch;
|