complete-common 2.29.0 → 2.31.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/dist/functions/array.d.ts.map +1 -1
- package/dist/functions/assert.d.cts +4 -2
- package/dist/functions/assert.d.mts +4 -2
- package/dist/functions/assert.d.ts +4 -2
- package/dist/functions/assert.d.ts.map +1 -1
- package/dist/functions/enums.d.cts +2 -2
- package/dist/functions/enums.d.mts +2 -2
- package/dist/functions/enums.d.ts +2 -2
- package/dist/functions/set.d.cts +1 -1
- package/dist/functions/set.d.mts +1 -1
- package/dist/functions/set.d.ts +1 -1
- package/dist/functions/set.d.ts.map +1 -1
- package/dist/functions/sort.d.ts.map +1 -1
- package/dist/functions/string.d.ts.map +1 -1
- package/dist/functions/time.d.cts +1 -1
- package/dist/functions/time.d.mts +1 -1
- package/dist/functions/time.d.ts +1 -1
- package/dist/functions/time.d.ts.map +1 -1
- package/dist/functions/tuple.d.cts +2 -2
- package/dist/functions/tuple.d.mts +2 -2
- package/dist/functions/tuple.d.ts +2 -2
- package/dist/functions/types.d.cts +1 -1
- package/dist/functions/types.d.mts +1 -1
- package/dist/functions/types.d.ts +1 -1
- package/dist/functions/utils.d.cts +2 -4
- package/dist/functions/utils.d.mts +2 -4
- package/dist/functions/utils.d.ts +2 -4
- package/dist/functions/utils.d.ts.map +1 -1
- package/dist/index.cjs +44 -44
- package/dist/index.mjs +44 -45
- package/package.json +4 -4
- package/src/functions/array.ts +2 -8
- package/src/functions/assert.ts +16 -4
- package/src/functions/enums.ts +2 -2
- package/src/functions/object.ts +1 -1
- package/src/functions/set.ts +2 -7
- package/src/functions/sort.ts +1 -3
- package/src/functions/string.ts +28 -23
- package/src/functions/time.ts +5 -2
- package/src/functions/tuple.ts +2 -2
- package/src/functions/types.ts +1 -1
- package/src/functions/utils.ts +13 -11
package/dist/index.cjs
CHANGED
|
@@ -102,7 +102,7 @@ function assertEnumValue(value, transpiledEnum, msg, set) {
|
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
function assertInteger(value, msg) {
|
|
105
|
-
if (!Number.
|
|
105
|
+
if (!Number.isSafeInteger(value)) {
|
|
106
106
|
throw new TypeError(msg);
|
|
107
107
|
}
|
|
108
108
|
}
|
|
@@ -126,6 +126,11 @@ function assertObject(value, ...[msg]) {
|
|
|
126
126
|
throw new TypeError(msg);
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
|
+
function assertPositiveInteger(value, msg) {
|
|
130
|
+
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
131
|
+
throw new TypeError(msg);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
129
134
|
function assertString(value, ...[msg]) {
|
|
130
135
|
if (typeof value !== "string") {
|
|
131
136
|
throw new TypeError(msg);
|
|
@@ -156,11 +161,7 @@ function getRandomInt(min, max, exceptions = []) {
|
|
|
156
161
|
}
|
|
157
162
|
|
|
158
163
|
function arrayCopyTwoDimensional(array) {
|
|
159
|
-
|
|
160
|
-
for (const subArray of array) {
|
|
161
|
-
copiedArray.push([...subArray]);
|
|
162
|
-
}
|
|
163
|
-
return copiedArray;
|
|
164
|
+
return Array.from(array, (subArray) => [...subArray]);
|
|
164
165
|
}
|
|
165
166
|
function arrayEquals(array1, array2) {
|
|
166
167
|
if (array1.length !== array2.length) {
|
|
@@ -207,7 +208,7 @@ function arrayRemoveInPlace(array, ...elementsToRemove) {
|
|
|
207
208
|
return removedElements;
|
|
208
209
|
}
|
|
209
210
|
function emptyArray(array) {
|
|
210
|
-
array.
|
|
211
|
+
array.length = 0;
|
|
211
212
|
}
|
|
212
213
|
async function filterAsync(array, predicate) {
|
|
213
214
|
const results = await Promise.all(
|
|
@@ -394,11 +395,7 @@ function combineSets(...sets) {
|
|
|
394
395
|
return newSet;
|
|
395
396
|
}
|
|
396
397
|
function copySet(oldSet) {
|
|
397
|
-
|
|
398
|
-
for (const value of oldSet) {
|
|
399
|
-
newSet.add(value);
|
|
400
|
-
}
|
|
401
|
-
return newSet;
|
|
398
|
+
return new Set(oldSet);
|
|
402
399
|
}
|
|
403
400
|
function objectKeysToSet(object) {
|
|
404
401
|
const set = /* @__PURE__ */ new Set();
|
|
@@ -426,15 +423,13 @@ function setHas(set, ...elements) {
|
|
|
426
423
|
function sortCaseInsensitive(array) {
|
|
427
424
|
const newArray = [...array];
|
|
428
425
|
newArray.sort(
|
|
429
|
-
(a, b) => a.localeCompare(b, void 0, {
|
|
430
|
-
sensitivity: "base"
|
|
431
|
-
})
|
|
426
|
+
(a, b) => a.localeCompare(b, void 0, { sensitivity: "base" })
|
|
432
427
|
);
|
|
433
428
|
return newArray;
|
|
434
429
|
}
|
|
435
430
|
|
|
436
|
-
const FLOAT_REGEX =
|
|
437
|
-
const INTEGER_REGEX = /^-?\d
|
|
431
|
+
const FLOAT_REGEX = /^-?(?:\d+(?:\.\d+)?|\.\d+)$/v;
|
|
432
|
+
const INTEGER_REGEX = /^-?\d+$/v;
|
|
438
433
|
function* eRange(start, end, increment = 1) {
|
|
439
434
|
if (end === void 0) {
|
|
440
435
|
yield* eRange(0, start, increment);
|
|
@@ -453,7 +448,7 @@ function* iRange(start, end, increment = 1) {
|
|
|
453
448
|
yield* eRange(start, exclusiveEnd, increment);
|
|
454
449
|
}
|
|
455
450
|
function isKeyOf(key, target) {
|
|
456
|
-
return key
|
|
451
|
+
return Object.hasOwn(target, key);
|
|
457
452
|
}
|
|
458
453
|
function noop() {
|
|
459
454
|
}
|
|
@@ -462,10 +457,10 @@ function parseFloatSafe(string) {
|
|
|
462
457
|
return void 0;
|
|
463
458
|
}
|
|
464
459
|
const trimmedString = string.trim();
|
|
465
|
-
if (FLOAT_REGEX.
|
|
460
|
+
if (!FLOAT_REGEX.test(trimmedString)) {
|
|
466
461
|
return void 0;
|
|
467
462
|
}
|
|
468
|
-
const number = Number
|
|
463
|
+
const number = Number(trimmedString);
|
|
469
464
|
return Number.isNaN(number) ? void 0 : number;
|
|
470
465
|
}
|
|
471
466
|
function parseIntSafe(string) {
|
|
@@ -473,10 +468,10 @@ function parseIntSafe(string) {
|
|
|
473
468
|
return void 0;
|
|
474
469
|
}
|
|
475
470
|
const trimmedString = string.trim();
|
|
476
|
-
if (INTEGER_REGEX.
|
|
471
|
+
if (!INTEGER_REGEX.test(trimmedString)) {
|
|
477
472
|
return void 0;
|
|
478
473
|
}
|
|
479
|
-
const number =
|
|
474
|
+
const number = Math.trunc(Number(trimmedString));
|
|
480
475
|
return Number.isNaN(number) ? void 0 : number;
|
|
481
476
|
}
|
|
482
477
|
function repeat(num, func) {
|
|
@@ -487,17 +482,17 @@ function repeat(num, func) {
|
|
|
487
482
|
function todo(...args) {
|
|
488
483
|
}
|
|
489
484
|
|
|
490
|
-
const ASCII_REGEX =
|
|
491
|
-
const DIACRITIC_REGEX = /\p{Diacritic}/
|
|
492
|
-
const
|
|
493
|
-
const
|
|
494
|
-
const KEBAB_CASE_REGEX = /^[\da-z]+(?:-[\da-z]+)
|
|
495
|
-
const SEMANTIC_VERSION_REGEX = /^v*(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)
|
|
496
|
-
const WHITESPACE_REGEX = /\s
|
|
497
|
-
const WHITESPACE_GLOBAL_REGEX = /\s/
|
|
498
|
-
const TITLE_CASE_BOUNDARY_REGEX = /(?<=[\da-z])(?=[A-Z])/
|
|
499
|
-
const UPPERCASE_REGEX = /^[A-Z]
|
|
500
|
-
const LOWERCASE_REGEX = /^[a-z]
|
|
485
|
+
const ASCII_REGEX = /^\p{ASCII}*$/v;
|
|
486
|
+
const DIACRITIC_REGEX = /\p{Diacritic}/v;
|
|
487
|
+
const FIRST_LETTER_CAPITALIZED_REGEX = /^\p{Lu}/v;
|
|
488
|
+
const EMOJI_REGEX = /\p{Extended_Pictographic}|[#*0-9]\u{FE0F}?\u{20E3}/v;
|
|
489
|
+
const KEBAB_CASE_REGEX = /^[\da-z]+(?:-[\da-z]+)*$/v;
|
|
490
|
+
const SEMANTIC_VERSION_REGEX = /^v*(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)/v;
|
|
491
|
+
const WHITESPACE_REGEX = /\s/v;
|
|
492
|
+
const WHITESPACE_GLOBAL_REGEX = /\s/gv;
|
|
493
|
+
const TITLE_CASE_BOUNDARY_REGEX = /(?<=[\da-z])(?=[A-Z])/gv;
|
|
494
|
+
const UPPERCASE_REGEX = /^[A-Z]*$/v;
|
|
495
|
+
const LOWERCASE_REGEX = /^[a-z]*$/v;
|
|
501
496
|
function capitalizeFirstLetter(string) {
|
|
502
497
|
if (string === "") {
|
|
503
498
|
return string;
|
|
@@ -555,8 +550,8 @@ function isUpperCase(string) {
|
|
|
555
550
|
return UPPERCASE_REGEX.test(string);
|
|
556
551
|
}
|
|
557
552
|
function kebabCaseToCamelCase(string) {
|
|
558
|
-
return string.replaceAll(/-./
|
|
559
|
-
const firstLetterOfWord = match
|
|
553
|
+
return string.replaceAll(/-./gv, (match) => {
|
|
554
|
+
const firstLetterOfWord = match.at(1);
|
|
560
555
|
return firstLetterOfWord === void 0 ? "" : firstLetterOfWord.toUpperCase();
|
|
561
556
|
});
|
|
562
557
|
}
|
|
@@ -568,14 +563,14 @@ function normalizeString(string) {
|
|
|
568
563
|
let sanitizedString = string;
|
|
569
564
|
sanitizedString = removeNonPrintableCharacters(sanitizedString);
|
|
570
565
|
sanitizedString = sanitizedString.replaceAll("\n\r", "\n");
|
|
571
|
-
sanitizedString = sanitizedString.replaceAll(/\p{Zl}/
|
|
572
|
-
sanitizedString = sanitizedString.replaceAll(/\p{Zp}/
|
|
573
|
-
sanitizedString = sanitizedString.replaceAll(/\p{Zs}/
|
|
566
|
+
sanitizedString = sanitizedString.replaceAll(/\p{Zl}/gv, "\n");
|
|
567
|
+
sanitizedString = sanitizedString.replaceAll(/\p{Zp}/gv, "\n");
|
|
568
|
+
sanitizedString = sanitizedString.replaceAll(/\p{Zs}/gv, " ");
|
|
574
569
|
sanitizedString = sanitizedString.trim();
|
|
575
570
|
return sanitizedString;
|
|
576
571
|
}
|
|
577
572
|
function parseSemanticVersion(versionString) {
|
|
578
|
-
const match =
|
|
573
|
+
const match = SEMANTIC_VERSION_REGEX.exec(versionString);
|
|
579
574
|
if (match === null || match.groups === void 0) {
|
|
580
575
|
return void 0;
|
|
581
576
|
}
|
|
@@ -589,7 +584,11 @@ function parseSemanticVersion(versionString) {
|
|
|
589
584
|
if (majorVersion === void 0 || minorVersion === void 0 || patchVersion === void 0) {
|
|
590
585
|
return void 0;
|
|
591
586
|
}
|
|
592
|
-
return {
|
|
587
|
+
return {
|
|
588
|
+
majorVersion,
|
|
589
|
+
minorVersion,
|
|
590
|
+
patchVersion
|
|
591
|
+
};
|
|
593
592
|
}
|
|
594
593
|
function removeLinesBetweenMarkers(string, marker) {
|
|
595
594
|
const lines = string.split("\n");
|
|
@@ -616,7 +615,7 @@ function removeLinesMatching(string, match) {
|
|
|
616
615
|
return newLines.join("\n");
|
|
617
616
|
}
|
|
618
617
|
function removeNonPrintableCharacters(string) {
|
|
619
|
-
return string.replaceAll(/\p{C}/
|
|
618
|
+
return string.replaceAll(/\p{C}/gv, "");
|
|
620
619
|
}
|
|
621
620
|
function removeWhitespace(string) {
|
|
622
621
|
return string.replaceAll(WHITESPACE_GLOBAL_REGEX, "");
|
|
@@ -641,7 +640,7 @@ function satisfiesSemanticVersion(version, minimumVersion) {
|
|
|
641
640
|
return majorVersion > minimumMajorVersion || majorVersion === minimumMajorVersion && minorVersion > minimumMinorVersion || majorVersion === minimumMajorVersion && minorVersion === minimumMinorVersion && patchVersion >= minimumPatchVersion;
|
|
642
641
|
}
|
|
643
642
|
function titleCaseToKebabCase(string) {
|
|
644
|
-
return string.replaceAll(TITLE_CASE_BOUNDARY_REGEX, "-").replaceAll(/ +/
|
|
643
|
+
return string.replaceAll(TITLE_CASE_BOUNDARY_REGEX, "-").replaceAll(/ +/gv, "-").toLowerCase();
|
|
645
644
|
}
|
|
646
645
|
function trimPrefix(string, prefix, trimAll = false) {
|
|
647
646
|
if (trimAll) {
|
|
@@ -667,11 +666,11 @@ function truncateString(string, maxLength) {
|
|
|
667
666
|
return string.slice(0, maxLength);
|
|
668
667
|
}
|
|
669
668
|
|
|
670
|
-
function getElapsedSeconds(startTime) {
|
|
669
|
+
function getElapsedSeconds(startTime, roundToInteger = true) {
|
|
671
670
|
const endTime = Date.now();
|
|
672
671
|
const elapsedMilliseconds = endTime - startTime;
|
|
673
672
|
const elapsedSeconds = elapsedMilliseconds / 1e3;
|
|
674
|
-
return Math.floor(elapsedSeconds);
|
|
673
|
+
return roundToInteger ? Math.floor(elapsedSeconds) : elapsedSeconds;
|
|
675
674
|
}
|
|
676
675
|
|
|
677
676
|
function* tupleEntries(tuple) {
|
|
@@ -709,6 +708,7 @@ exports.assertIs = assertIs;
|
|
|
709
708
|
exports.assertNotNull = assertNotNull;
|
|
710
709
|
exports.assertNumber = assertNumber;
|
|
711
710
|
exports.assertObject = assertObject;
|
|
711
|
+
exports.assertPositiveInteger = assertPositiveInteger;
|
|
712
712
|
exports.assertString = assertString;
|
|
713
713
|
exports.assertStringNotEmpty = assertStringNotEmpty;
|
|
714
714
|
exports.capitalizeFirstLetter = capitalizeFirstLetter;
|
package/dist/index.mjs
CHANGED
|
@@ -100,7 +100,7 @@ function assertEnumValue(value, transpiledEnum, msg, set) {
|
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
function assertInteger(value, msg) {
|
|
103
|
-
if (!Number.
|
|
103
|
+
if (!Number.isSafeInteger(value)) {
|
|
104
104
|
throw new TypeError(msg);
|
|
105
105
|
}
|
|
106
106
|
}
|
|
@@ -124,6 +124,11 @@ function assertObject(value, ...[msg]) {
|
|
|
124
124
|
throw new TypeError(msg);
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
|
+
function assertPositiveInteger(value, msg) {
|
|
128
|
+
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
129
|
+
throw new TypeError(msg);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
127
132
|
function assertString(value, ...[msg]) {
|
|
128
133
|
if (typeof value !== "string") {
|
|
129
134
|
throw new TypeError(msg);
|
|
@@ -154,11 +159,7 @@ function getRandomInt(min, max, exceptions = []) {
|
|
|
154
159
|
}
|
|
155
160
|
|
|
156
161
|
function arrayCopyTwoDimensional(array) {
|
|
157
|
-
|
|
158
|
-
for (const subArray of array) {
|
|
159
|
-
copiedArray.push([...subArray]);
|
|
160
|
-
}
|
|
161
|
-
return copiedArray;
|
|
162
|
+
return Array.from(array, (subArray) => [...subArray]);
|
|
162
163
|
}
|
|
163
164
|
function arrayEquals(array1, array2) {
|
|
164
165
|
if (array1.length !== array2.length) {
|
|
@@ -205,7 +206,7 @@ function arrayRemoveInPlace(array, ...elementsToRemove) {
|
|
|
205
206
|
return removedElements;
|
|
206
207
|
}
|
|
207
208
|
function emptyArray(array) {
|
|
208
|
-
array.
|
|
209
|
+
array.length = 0;
|
|
209
210
|
}
|
|
210
211
|
async function filterAsync(array, predicate) {
|
|
211
212
|
const results = await Promise.all(
|
|
@@ -392,11 +393,7 @@ function combineSets(...sets) {
|
|
|
392
393
|
return newSet;
|
|
393
394
|
}
|
|
394
395
|
function copySet(oldSet) {
|
|
395
|
-
|
|
396
|
-
for (const value of oldSet) {
|
|
397
|
-
newSet.add(value);
|
|
398
|
-
}
|
|
399
|
-
return newSet;
|
|
396
|
+
return new Set(oldSet);
|
|
400
397
|
}
|
|
401
398
|
function objectKeysToSet(object) {
|
|
402
399
|
const set = /* @__PURE__ */ new Set();
|
|
@@ -424,15 +421,13 @@ function setHas(set, ...elements) {
|
|
|
424
421
|
function sortCaseInsensitive(array) {
|
|
425
422
|
const newArray = [...array];
|
|
426
423
|
newArray.sort(
|
|
427
|
-
(a, b) => a.localeCompare(b, void 0, {
|
|
428
|
-
sensitivity: "base"
|
|
429
|
-
})
|
|
424
|
+
(a, b) => a.localeCompare(b, void 0, { sensitivity: "base" })
|
|
430
425
|
);
|
|
431
426
|
return newArray;
|
|
432
427
|
}
|
|
433
428
|
|
|
434
|
-
const FLOAT_REGEX =
|
|
435
|
-
const INTEGER_REGEX = /^-?\d
|
|
429
|
+
const FLOAT_REGEX = /^-?(?:\d+(?:\.\d+)?|\.\d+)$/v;
|
|
430
|
+
const INTEGER_REGEX = /^-?\d+$/v;
|
|
436
431
|
function* eRange(start, end, increment = 1) {
|
|
437
432
|
if (end === void 0) {
|
|
438
433
|
yield* eRange(0, start, increment);
|
|
@@ -451,7 +446,7 @@ function* iRange(start, end, increment = 1) {
|
|
|
451
446
|
yield* eRange(start, exclusiveEnd, increment);
|
|
452
447
|
}
|
|
453
448
|
function isKeyOf(key, target) {
|
|
454
|
-
return key
|
|
449
|
+
return Object.hasOwn(target, key);
|
|
455
450
|
}
|
|
456
451
|
function noop() {
|
|
457
452
|
}
|
|
@@ -460,10 +455,10 @@ function parseFloatSafe(string) {
|
|
|
460
455
|
return void 0;
|
|
461
456
|
}
|
|
462
457
|
const trimmedString = string.trim();
|
|
463
|
-
if (FLOAT_REGEX.
|
|
458
|
+
if (!FLOAT_REGEX.test(trimmedString)) {
|
|
464
459
|
return void 0;
|
|
465
460
|
}
|
|
466
|
-
const number = Number
|
|
461
|
+
const number = Number(trimmedString);
|
|
467
462
|
return Number.isNaN(number) ? void 0 : number;
|
|
468
463
|
}
|
|
469
464
|
function parseIntSafe(string) {
|
|
@@ -471,10 +466,10 @@ function parseIntSafe(string) {
|
|
|
471
466
|
return void 0;
|
|
472
467
|
}
|
|
473
468
|
const trimmedString = string.trim();
|
|
474
|
-
if (INTEGER_REGEX.
|
|
469
|
+
if (!INTEGER_REGEX.test(trimmedString)) {
|
|
475
470
|
return void 0;
|
|
476
471
|
}
|
|
477
|
-
const number =
|
|
472
|
+
const number = Math.trunc(Number(trimmedString));
|
|
478
473
|
return Number.isNaN(number) ? void 0 : number;
|
|
479
474
|
}
|
|
480
475
|
function repeat(num, func) {
|
|
@@ -485,17 +480,17 @@ function repeat(num, func) {
|
|
|
485
480
|
function todo(...args) {
|
|
486
481
|
}
|
|
487
482
|
|
|
488
|
-
const ASCII_REGEX =
|
|
489
|
-
const DIACRITIC_REGEX = /\p{Diacritic}/
|
|
490
|
-
const
|
|
491
|
-
const
|
|
492
|
-
const KEBAB_CASE_REGEX = /^[\da-z]+(?:-[\da-z]+)
|
|
493
|
-
const SEMANTIC_VERSION_REGEX = /^v*(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)
|
|
494
|
-
const WHITESPACE_REGEX = /\s
|
|
495
|
-
const WHITESPACE_GLOBAL_REGEX = /\s/
|
|
496
|
-
const TITLE_CASE_BOUNDARY_REGEX = /(?<=[\da-z])(?=[A-Z])/
|
|
497
|
-
const UPPERCASE_REGEX = /^[A-Z]
|
|
498
|
-
const LOWERCASE_REGEX = /^[a-z]
|
|
483
|
+
const ASCII_REGEX = /^\p{ASCII}*$/v;
|
|
484
|
+
const DIACRITIC_REGEX = /\p{Diacritic}/v;
|
|
485
|
+
const FIRST_LETTER_CAPITALIZED_REGEX = /^\p{Lu}/v;
|
|
486
|
+
const EMOJI_REGEX = /\p{Extended_Pictographic}|[#*0-9]\u{FE0F}?\u{20E3}/v;
|
|
487
|
+
const KEBAB_CASE_REGEX = /^[\da-z]+(?:-[\da-z]+)*$/v;
|
|
488
|
+
const SEMANTIC_VERSION_REGEX = /^v*(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)/v;
|
|
489
|
+
const WHITESPACE_REGEX = /\s/v;
|
|
490
|
+
const WHITESPACE_GLOBAL_REGEX = /\s/gv;
|
|
491
|
+
const TITLE_CASE_BOUNDARY_REGEX = /(?<=[\da-z])(?=[A-Z])/gv;
|
|
492
|
+
const UPPERCASE_REGEX = /^[A-Z]*$/v;
|
|
493
|
+
const LOWERCASE_REGEX = /^[a-z]*$/v;
|
|
499
494
|
function capitalizeFirstLetter(string) {
|
|
500
495
|
if (string === "") {
|
|
501
496
|
return string;
|
|
@@ -553,8 +548,8 @@ function isUpperCase(string) {
|
|
|
553
548
|
return UPPERCASE_REGEX.test(string);
|
|
554
549
|
}
|
|
555
550
|
function kebabCaseToCamelCase(string) {
|
|
556
|
-
return string.replaceAll(/-./
|
|
557
|
-
const firstLetterOfWord = match
|
|
551
|
+
return string.replaceAll(/-./gv, (match) => {
|
|
552
|
+
const firstLetterOfWord = match.at(1);
|
|
558
553
|
return firstLetterOfWord === void 0 ? "" : firstLetterOfWord.toUpperCase();
|
|
559
554
|
});
|
|
560
555
|
}
|
|
@@ -566,14 +561,14 @@ function normalizeString(string) {
|
|
|
566
561
|
let sanitizedString = string;
|
|
567
562
|
sanitizedString = removeNonPrintableCharacters(sanitizedString);
|
|
568
563
|
sanitizedString = sanitizedString.replaceAll("\n\r", "\n");
|
|
569
|
-
sanitizedString = sanitizedString.replaceAll(/\p{Zl}/
|
|
570
|
-
sanitizedString = sanitizedString.replaceAll(/\p{Zp}/
|
|
571
|
-
sanitizedString = sanitizedString.replaceAll(/\p{Zs}/
|
|
564
|
+
sanitizedString = sanitizedString.replaceAll(/\p{Zl}/gv, "\n");
|
|
565
|
+
sanitizedString = sanitizedString.replaceAll(/\p{Zp}/gv, "\n");
|
|
566
|
+
sanitizedString = sanitizedString.replaceAll(/\p{Zs}/gv, " ");
|
|
572
567
|
sanitizedString = sanitizedString.trim();
|
|
573
568
|
return sanitizedString;
|
|
574
569
|
}
|
|
575
570
|
function parseSemanticVersion(versionString) {
|
|
576
|
-
const match =
|
|
571
|
+
const match = SEMANTIC_VERSION_REGEX.exec(versionString);
|
|
577
572
|
if (match === null || match.groups === void 0) {
|
|
578
573
|
return void 0;
|
|
579
574
|
}
|
|
@@ -587,7 +582,11 @@ function parseSemanticVersion(versionString) {
|
|
|
587
582
|
if (majorVersion === void 0 || minorVersion === void 0 || patchVersion === void 0) {
|
|
588
583
|
return void 0;
|
|
589
584
|
}
|
|
590
|
-
return {
|
|
585
|
+
return {
|
|
586
|
+
majorVersion,
|
|
587
|
+
minorVersion,
|
|
588
|
+
patchVersion
|
|
589
|
+
};
|
|
591
590
|
}
|
|
592
591
|
function removeLinesBetweenMarkers(string, marker) {
|
|
593
592
|
const lines = string.split("\n");
|
|
@@ -614,7 +613,7 @@ function removeLinesMatching(string, match) {
|
|
|
614
613
|
return newLines.join("\n");
|
|
615
614
|
}
|
|
616
615
|
function removeNonPrintableCharacters(string) {
|
|
617
|
-
return string.replaceAll(/\p{C}/
|
|
616
|
+
return string.replaceAll(/\p{C}/gv, "");
|
|
618
617
|
}
|
|
619
618
|
function removeWhitespace(string) {
|
|
620
619
|
return string.replaceAll(WHITESPACE_GLOBAL_REGEX, "");
|
|
@@ -639,7 +638,7 @@ function satisfiesSemanticVersion(version, minimumVersion) {
|
|
|
639
638
|
return majorVersion > minimumMajorVersion || majorVersion === minimumMajorVersion && minorVersion > minimumMinorVersion || majorVersion === minimumMajorVersion && minorVersion === minimumMinorVersion && patchVersion >= minimumPatchVersion;
|
|
640
639
|
}
|
|
641
640
|
function titleCaseToKebabCase(string) {
|
|
642
|
-
return string.replaceAll(TITLE_CASE_BOUNDARY_REGEX, "-").replaceAll(/ +/
|
|
641
|
+
return string.replaceAll(TITLE_CASE_BOUNDARY_REGEX, "-").replaceAll(/ +/gv, "-").toLowerCase();
|
|
643
642
|
}
|
|
644
643
|
function trimPrefix(string, prefix, trimAll = false) {
|
|
645
644
|
if (trimAll) {
|
|
@@ -665,11 +664,11 @@ function truncateString(string, maxLength) {
|
|
|
665
664
|
return string.slice(0, maxLength);
|
|
666
665
|
}
|
|
667
666
|
|
|
668
|
-
function getElapsedSeconds(startTime) {
|
|
667
|
+
function getElapsedSeconds(startTime, roundToInteger = true) {
|
|
669
668
|
const endTime = Date.now();
|
|
670
669
|
const elapsedMilliseconds = endTime - startTime;
|
|
671
670
|
const elapsedSeconds = elapsedMilliseconds / 1e3;
|
|
672
|
-
return Math.floor(elapsedSeconds);
|
|
671
|
+
return roundToInteger ? Math.floor(elapsedSeconds) : elapsedSeconds;
|
|
673
672
|
}
|
|
674
673
|
|
|
675
674
|
function* tupleEntries(tuple) {
|
|
@@ -681,4 +680,4 @@ function* tupleKeys(tuple) {
|
|
|
681
680
|
|
|
682
681
|
const ReadonlyMap = Map;
|
|
683
682
|
|
|
684
|
-
export { HOUR_IN_MILLISECONDS, MINUTE_IN_MILLISECONDS, ReadonlyMap, ReadonlySet, SECOND_IN_MILLISECONDS, addSetsToSet, arrayCopyTwoDimensional, arrayEquals, arrayRemove, arrayRemoveAllInPlace, arrayRemoveInPlace, assertArray, assertArrayBoolean, assertArrayLength, assertArrayNonEmpty, assertArrayNumber, assertArrayObject, assertArrayString, assertBoolean, assertDefined, assertEnumValue, assertInteger, assertIs, assertNotNull, assertNumber, assertObject, assertString, assertStringNotEmpty, capitalizeFirstLetter, clamp, combineSets, copySet, eRange, emptyArray, escapeHTMLCharacters, filterAsync, filterMap, filterMapAsync, getElapsedSeconds, getEnumEntries, getEnumKeys, getEnumValues, getNumConsecutiveDiacritics, getRandomArrayElement, getRandomArrayIndex, getRandomInt, getWidenedObjectValue, hasDiacritic, hasEmoji, hasWhitespace, iRange, includes, includesAny, interfaceSatisfiesEnum, isASCII, isArray, isArrayBoolean, isArrayNumber, isArrayObject, isArrayString, isEnumValue, isFirstLetterCapitalized, isKebabCase, isKeyOf, isLowerCase, isObject, isSemanticVersion, isUpperCase, kebabCaseToCamelCase, kebabCaseToPascalCase, mapAsync, mapFilter, mapFind, newArray, noop, normalizeString, objectFilter, objectKeysToSet, objectMap, objectToMap, objectToReverseMap, objectValuesToSet, parseFloatSafe, parseIntSafe, parseSemanticVersion, removeLinesBetweenMarkers, removeLinesMatching, removeNonPrintableCharacters, removeWhitespace, repeat, reverseObject, satisfiesSemanticVersion, setAdd, setHas, sortCaseInsensitive, sumArray, titleCaseToKebabCase, todo, trimPrefix, trimSuffix, truncateString, tupleEntries, tupleKeys, unique };
|
|
683
|
+
export { HOUR_IN_MILLISECONDS, MINUTE_IN_MILLISECONDS, ReadonlyMap, ReadonlySet, SECOND_IN_MILLISECONDS, addSetsToSet, arrayCopyTwoDimensional, arrayEquals, arrayRemove, arrayRemoveAllInPlace, arrayRemoveInPlace, assertArray, assertArrayBoolean, assertArrayLength, assertArrayNonEmpty, assertArrayNumber, assertArrayObject, assertArrayString, assertBoolean, assertDefined, assertEnumValue, assertInteger, assertIs, assertNotNull, assertNumber, assertObject, assertPositiveInteger, assertString, assertStringNotEmpty, capitalizeFirstLetter, clamp, combineSets, copySet, eRange, emptyArray, escapeHTMLCharacters, filterAsync, filterMap, filterMapAsync, getElapsedSeconds, getEnumEntries, getEnumKeys, getEnumValues, getNumConsecutiveDiacritics, getRandomArrayElement, getRandomArrayIndex, getRandomInt, getWidenedObjectValue, hasDiacritic, hasEmoji, hasWhitespace, iRange, includes, includesAny, interfaceSatisfiesEnum, isASCII, isArray, isArrayBoolean, isArrayNumber, isArrayObject, isArrayString, isEnumValue, isFirstLetterCapitalized, isKebabCase, isKeyOf, isLowerCase, isObject, isSemanticVersion, isUpperCase, kebabCaseToCamelCase, kebabCaseToPascalCase, mapAsync, mapFilter, mapFind, newArray, noop, normalizeString, objectFilter, objectKeysToSet, objectMap, objectToMap, objectToReverseMap, objectValuesToSet, parseFloatSafe, parseIntSafe, parseSemanticVersion, removeLinesBetweenMarkers, removeLinesMatching, removeNonPrintableCharacters, removeWhitespace, repeat, reverseObject, satisfiesSemanticVersion, setAdd, setHas, sortCaseInsensitive, sumArray, titleCaseToKebabCase, todo, trimPrefix, trimSuffix, truncateString, tupleEntries, tupleKeys, unique };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "complete-common",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.31.0",
|
|
4
4
|
"description": "Helper functions for TypeScript projects.",
|
|
5
5
|
"homepage": "https://complete-ts.github.io/",
|
|
6
6
|
"bugs": {
|
|
@@ -32,10 +32,10 @@
|
|
|
32
32
|
"test": "bun test ./tests"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@types/node": "
|
|
36
|
-
"complete-node": "
|
|
35
|
+
"@types/node": "26.0.1",
|
|
36
|
+
"complete-node": "18.0.0",
|
|
37
37
|
"typedoc": "0.28.19",
|
|
38
|
-
"typedoc-plugin-markdown": "4.
|
|
38
|
+
"typedoc-plugin-markdown": "4.12.0",
|
|
39
39
|
"typescript": "6.0.3",
|
|
40
40
|
"unbuild": "3.6.1"
|
|
41
41
|
}
|
package/src/functions/array.ts
CHANGED
|
@@ -17,13 +17,7 @@ import { isObject } from "./types.js";
|
|
|
17
17
|
export function arrayCopyTwoDimensional<T>(
|
|
18
18
|
array: ReadonlyArray<readonly T[]>,
|
|
19
19
|
): ReadonlyArray<readonly T[]> {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
for (const subArray of array) {
|
|
23
|
-
copiedArray.push([...subArray]);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return copiedArray;
|
|
20
|
+
return Array.from(array, (subArray) => [...subArray]);
|
|
27
21
|
}
|
|
28
22
|
|
|
29
23
|
/**
|
|
@@ -134,7 +128,7 @@ export function arrayRemoveInPlace<T>(
|
|
|
134
128
|
/** Helper function to remove all of the elements in an array in-place. */
|
|
135
129
|
// eslint-disable-next-line complete/prefer-readonly-parameter-types
|
|
136
130
|
export function emptyArray(array: unknown[]): void {
|
|
137
|
-
array.
|
|
131
|
+
array.length = 0; // eslint-disable-line no-param-reassign
|
|
138
132
|
}
|
|
139
133
|
|
|
140
134
|
/**
|
package/src/functions/assert.ts
CHANGED
|
@@ -114,7 +114,7 @@ export function assertArrayNumber<T>(
|
|
|
114
114
|
|
|
115
115
|
/**
|
|
116
116
|
* Helper function to throw an error if the provided value is not an array with every element being
|
|
117
|
-
* an object (i.e
|
|
117
|
+
* an object (i.e., a TypeScript record).
|
|
118
118
|
*/
|
|
119
119
|
export function assertArrayObject<T>(
|
|
120
120
|
value: T,
|
|
@@ -212,9 +212,9 @@ export function assertInteger(
|
|
|
212
212
|
value: unknown,
|
|
213
213
|
msg: string,
|
|
214
214
|
): asserts value is number {
|
|
215
|
-
// `Number.
|
|
215
|
+
// `Number.isSafeInteger` will correctly return false for non-number variables such as strings,
|
|
216
216
|
// booleans, and so on.
|
|
217
|
-
if (!Number.
|
|
217
|
+
if (!Number.isSafeInteger(value)) {
|
|
218
218
|
throw new TypeError(msg);
|
|
219
219
|
}
|
|
220
220
|
}
|
|
@@ -269,7 +269,7 @@ export function assertNumber<T>(
|
|
|
269
269
|
}
|
|
270
270
|
|
|
271
271
|
/**
|
|
272
|
-
* Helper function to throw an error if the provided value is not an object (i.e
|
|
272
|
+
* Helper function to throw an error if the provided value is not an object (i.e., a TypeScript
|
|
273
273
|
* record).
|
|
274
274
|
*
|
|
275
275
|
* This is useful to have TypeScript narrow a `Record<string, unknown> | undefined` value to
|
|
@@ -290,6 +290,18 @@ export function assertObject<T>(
|
|
|
290
290
|
}
|
|
291
291
|
}
|
|
292
292
|
|
|
293
|
+
/** Helper function to throw an error if the provided value is not a positive integer. */
|
|
294
|
+
export function assertPositiveInteger(
|
|
295
|
+
value: unknown,
|
|
296
|
+
msg: string,
|
|
297
|
+
): asserts value is number {
|
|
298
|
+
// `Number.isSafeInteger` will correctly return false for non-number variables such as strings,
|
|
299
|
+
// booleans, and so on.
|
|
300
|
+
if (!Number.isSafeInteger(value) || (value as number) <= 0) {
|
|
301
|
+
throw new TypeError(msg);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
293
305
|
/** Helper function to throw an error if the provided value is not a string. */
|
|
294
306
|
export function assertString<T>(
|
|
295
307
|
value: T,
|
package/src/functions/enums.ts
CHANGED
|
@@ -57,7 +57,7 @@ export function getEnumValues<T extends TranspiledEnum>(
|
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
59
|
* Helper function to validate that an interface contains all of the keys of an enum. You must
|
|
60
|
-
* specify both generic parameters in order for this to work properly (i.e
|
|
60
|
+
* specify both generic parameters in order for this to work properly (i.e., the interface and then
|
|
61
61
|
* the enum).
|
|
62
62
|
*
|
|
63
63
|
* For example:
|
|
@@ -78,7 +78,7 @@ export function getEnumValues<T extends TranspiledEnum>(
|
|
|
78
78
|
* interfaceSatisfiesEnum<MyEnumToType, MyEnum>();
|
|
79
79
|
* ```
|
|
80
80
|
*
|
|
81
|
-
* This function is only meant to be used with interfaces (i.e
|
|
81
|
+
* This function is only meant to be used with interfaces (i.e., types that will not exist at
|
|
82
82
|
* run-time). If you are generating an object that will contain all of the keys of an enum, use the
|
|
83
83
|
* `satisfies` operator with the `Record` type instead.
|
|
84
84
|
*/
|
package/src/functions/object.ts
CHANGED
|
@@ -35,7 +35,7 @@ export function objectFilter<K extends PropertyKey, V>(
|
|
|
35
35
|
|
|
36
36
|
// eslint-disable-next-line complete/no-for-in
|
|
37
37
|
for (const key in object) {
|
|
38
|
-
const value = object[key];
|
|
38
|
+
const value = object[key]; // eslint-disable-line unicorn/no-unsafe-property-key
|
|
39
39
|
const match = predicate(value);
|
|
40
40
|
if (match) {
|
|
41
41
|
array.push(value);
|
package/src/functions/set.ts
CHANGED
|
@@ -41,14 +41,9 @@ export function combineSets<T>(
|
|
|
41
41
|
return newSet;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
/** Helper function to copy a set. (
|
|
44
|
+
/** Helper function to copy a set. (Under the hood, this simply calls the `Set` constructor.) */
|
|
45
45
|
export function copySet<T>(oldSet: ReadonlySet<T>): ReadonlySet<T> {
|
|
46
|
-
|
|
47
|
-
for (const value of oldSet) {
|
|
48
|
-
newSet.add(value);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return newSet;
|
|
46
|
+
return new Set(oldSet);
|
|
52
47
|
}
|
|
53
48
|
|
|
54
49
|
/** Helper function to convert the keys of an object to a set. */
|
package/src/functions/sort.ts
CHANGED
|
@@ -16,9 +16,7 @@ export function sortCaseInsensitive(
|
|
|
16
16
|
): readonly string[] {
|
|
17
17
|
const newArray = [...array];
|
|
18
18
|
newArray.sort((a, b) =>
|
|
19
|
-
a.localeCompare(b, undefined, {
|
|
20
|
-
sensitivity: "base",
|
|
21
|
-
}),
|
|
19
|
+
a.localeCompare(b, undefined, { sensitivity: "base" }),
|
|
22
20
|
);
|
|
23
21
|
|
|
24
22
|
return newArray;
|