complete-common 2.28.0 → 2.30.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/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 +42 -42
- package/dist/index.d.cts +2 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +42 -43
- package/dist/types/Expect.d.cts +6 -0
- package/dist/types/Expect.d.mts +6 -0
- package/dist/types/Expect.d.ts +6 -0
- package/dist/types/Expect.d.ts.map +1 -0
- package/dist/types/KeysMatch.d.cts +25 -0
- package/dist/types/KeysMatch.d.mts +25 -0
- package/dist/types/KeysMatch.d.ts +25 -0
- package/dist/types/KeysMatch.d.ts.map +1 -0
- 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/tuple.ts +2 -2
- package/src/functions/types.ts +1 -1
- package/src/functions/utils.ts +13 -11
- package/src/index.ts +2 -0
- package/src/types/Expect.ts +5 -0
- package/src/types/KeysMatch.ts +28 -0
package/dist/index.d.ts
CHANGED
|
@@ -17,8 +17,10 @@ export type * from "./interfaces/SemanticVersion.js";
|
|
|
17
17
|
export type * from "./types/AddSubtract.js";
|
|
18
18
|
export type * from "./types/CompositionTypeSatisfiesEnum.js";
|
|
19
19
|
export type * from "./types/ERange.js";
|
|
20
|
+
export type * from "./types/Expect.js";
|
|
20
21
|
export type * from "./types/Immutable.js";
|
|
21
22
|
export type * from "./types/IRange.js";
|
|
23
|
+
export type * from "./types/KeysMatch.js";
|
|
22
24
|
export type * from "./types/NaturalNumbersLessThan.js";
|
|
23
25
|
export type * from "./types/NaturalNumbersLessThanOrEqualTo.js";
|
|
24
26
|
export type * from "./types/ObjectValues.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,mBAAmB,iCAAiC,CAAC;AACrD,mBAAmB,wBAAwB,CAAC;AAC5C,mBAAmB,yCAAyC,CAAC;AAC7D,mBAAmB,mBAAmB,CAAC;AACvC,mBAAmB,sBAAsB,CAAC;AAC1C,mBAAmB,mBAAmB,CAAC;AACvC,mBAAmB,mCAAmC,CAAC;AACvD,mBAAmB,4CAA4C,CAAC;AAChE,mBAAmB,yBAAyB,CAAC;AAC7C,cAAc,wBAAwB,CAAC;AACvC,mBAAmB,2BAA2B,CAAC;AAC/C,cAAc,wBAAwB,CAAC;AACvC,mBAAmB,2BAA2B,CAAC;AAC/C,mBAAmB,kBAAkB,CAAC;AACtC,mBAAmB,yBAAyB,CAAC;AAC7C,mBAAmB,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,mBAAmB,iCAAiC,CAAC;AACrD,mBAAmB,wBAAwB,CAAC;AAC5C,mBAAmB,yCAAyC,CAAC;AAC7D,mBAAmB,mBAAmB,CAAC;AACvC,mBAAmB,mBAAmB,CAAC;AACvC,mBAAmB,sBAAsB,CAAC;AAC1C,mBAAmB,mBAAmB,CAAC;AACvC,mBAAmB,sBAAsB,CAAC;AAC1C,mBAAmB,mCAAmC,CAAC;AACvD,mBAAmB,4CAA4C,CAAC;AAChE,mBAAmB,yBAAyB,CAAC;AAC7C,cAAc,wBAAwB,CAAC;AACvC,mBAAmB,2BAA2B,CAAC;AAC/C,cAAc,wBAAwB,CAAC;AACvC,mBAAmB,2BAA2B,CAAC;AAC/C,mBAAmB,kBAAkB,CAAC;AACtC,mBAAmB,yBAAyB,CAAC;AAC7C,mBAAmB,sBAAsB,CAAC"}
|
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) {
|
|
@@ -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 };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Expect.d.ts","sourceRoot":"","sources":["../../src/types/Expect.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,MAAM,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper type to ensure that an array of keys matches an interface.
|
|
3
|
+
*
|
|
4
|
+
* For example:
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* interface Foo {
|
|
8
|
+
* arg1: string;
|
|
9
|
+
* arg2: string;
|
|
10
|
+
* }
|
|
11
|
+
*
|
|
12
|
+
* const FOO_KEYS = ["arg1", "arg2"] as const;
|
|
13
|
+
* type _ = Expect<KeysMatch<Foo, typeof FOO_KEYS>>;
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export type KeysMatch<T, Keys extends readonly PropertyKey[]> = [
|
|
17
|
+
keyof T
|
|
18
|
+
] extends [Keys[number]] ? [Keys[number]] extends [keyof T] ? true : {
|
|
19
|
+
error: "Extra keys not in interface";
|
|
20
|
+
extra: Exclude<Keys[number], keyof T>;
|
|
21
|
+
} : {
|
|
22
|
+
error: "Missing keys from interface";
|
|
23
|
+
missing: Exclude<keyof T, Keys[number]>;
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=KeysMatch.d.ts.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper type to ensure that an array of keys matches an interface.
|
|
3
|
+
*
|
|
4
|
+
* For example:
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* interface Foo {
|
|
8
|
+
* arg1: string;
|
|
9
|
+
* arg2: string;
|
|
10
|
+
* }
|
|
11
|
+
*
|
|
12
|
+
* const FOO_KEYS = ["arg1", "arg2"] as const;
|
|
13
|
+
* type _ = Expect<KeysMatch<Foo, typeof FOO_KEYS>>;
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export type KeysMatch<T, Keys extends readonly PropertyKey[]> = [
|
|
17
|
+
keyof T
|
|
18
|
+
] extends [Keys[number]] ? [Keys[number]] extends [keyof T] ? true : {
|
|
19
|
+
error: "Extra keys not in interface";
|
|
20
|
+
extra: Exclude<Keys[number], keyof T>;
|
|
21
|
+
} : {
|
|
22
|
+
error: "Missing keys from interface";
|
|
23
|
+
missing: Exclude<keyof T, Keys[number]>;
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=KeysMatch.d.ts.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper type to ensure that an array of keys matches an interface.
|
|
3
|
+
*
|
|
4
|
+
* For example:
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* interface Foo {
|
|
8
|
+
* arg1: string;
|
|
9
|
+
* arg2: string;
|
|
10
|
+
* }
|
|
11
|
+
*
|
|
12
|
+
* const FOO_KEYS = ["arg1", "arg2"] as const;
|
|
13
|
+
* type _ = Expect<KeysMatch<Foo, typeof FOO_KEYS>>;
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export type KeysMatch<T, Keys extends readonly PropertyKey[]> = [
|
|
17
|
+
keyof T
|
|
18
|
+
] extends [Keys[number]] ? [Keys[number]] extends [keyof T] ? true : {
|
|
19
|
+
error: "Extra keys not in interface";
|
|
20
|
+
extra: Exclude<Keys[number], keyof T>;
|
|
21
|
+
} : {
|
|
22
|
+
error: "Missing keys from interface";
|
|
23
|
+
missing: Exclude<keyof T, Keys[number]>;
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=KeysMatch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KeysMatch.d.ts","sourceRoot":"","sources":["../../src/types/KeysMatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,EAAE,IAAI,SAAS,SAAS,WAAW,EAAE,IAAI;IAC9D,MAAM,CAAC;CACR,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GACpB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,GAC9B,IAAI,GACJ;IACE,KAAK,EAAE,6BAA6B,CAAC;IACrC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;CACvC,GACH;IACE,KAAK,EAAE,6BAA6B,CAAC;IACrC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;CACzC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "complete-common",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.30.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;
|
package/src/functions/string.ts
CHANGED
|
@@ -14,25 +14,25 @@ import { parseIntSafe } from "./utils.js";
|
|
|
14
14
|
// they will return inconsistent results due to the `lastIndex` property persisting between calls.
|
|
15
15
|
|
|
16
16
|
/** We use a "*" instead of a "+" so that an empty string will match. */
|
|
17
|
-
|
|
18
|
-
const ASCII_REGEX = /^[\u0000-\u007F]*$/;
|
|
17
|
+
const ASCII_REGEX = /^\p{ASCII}*$/v;
|
|
19
18
|
|
|
20
|
-
const DIACRITIC_REGEX = /\p{Diacritic}/
|
|
19
|
+
const DIACRITIC_REGEX = /\p{Diacritic}/v;
|
|
20
|
+
const FIRST_LETTER_CAPITALIZED_REGEX = /^\p{Lu}/v;
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
* - We can't use `/\p{Emoji}/
|
|
24
|
-
* - We can't use `/\p{Extended_Pictographic}/
|
|
23
|
+
* - We can't use `/\p{Emoji}/v` because it has a false positive on "#" characters.
|
|
24
|
+
* - We can't use `/\p{Extended_Pictographic}/v` because it has a false negative on keycap emojis.
|
|
25
25
|
*/
|
|
26
|
-
const EMOJI_REGEX =
|
|
26
|
+
const EMOJI_REGEX = /\p{Extended_Pictographic}|[#*0-9]\u{FE0F}?\u{20E3}/v;
|
|
27
27
|
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
const WHITESPACE_REGEX = /\s
|
|
32
|
-
const WHITESPACE_GLOBAL_REGEX = /\s/
|
|
33
|
-
const TITLE_CASE_BOUNDARY_REGEX = /(?<=[\da-z])(?=[A-Z])/
|
|
34
|
-
const UPPERCASE_REGEX = /^[A-Z]
|
|
35
|
-
const LOWERCASE_REGEX = /^[a-z]
|
|
28
|
+
const KEBAB_CASE_REGEX = /^[\da-z]+(?:-[\da-z]+)*$/v;
|
|
29
|
+
const SEMANTIC_VERSION_REGEX =
|
|
30
|
+
/^v*(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)/v;
|
|
31
|
+
const WHITESPACE_REGEX = /\s/v;
|
|
32
|
+
const WHITESPACE_GLOBAL_REGEX = /\s/gv;
|
|
33
|
+
const TITLE_CASE_BOUNDARY_REGEX = /(?<=[\da-z])(?=[A-Z])/gv;
|
|
34
|
+
const UPPERCASE_REGEX = /^[A-Z]*$/v;
|
|
35
|
+
const LOWERCASE_REGEX = /^[a-z]*$/v;
|
|
36
36
|
|
|
37
37
|
/** Helper function to capitalize the first letter of a string. */
|
|
38
38
|
export function capitalizeFirstLetter(string: string): string {
|
|
@@ -124,6 +124,7 @@ export function isASCII(str: string): boolean {
|
|
|
124
124
|
* https://stackoverflow.com/questions/8334606/check-if-first-letter-of-word-is-a-capital-letter
|
|
125
125
|
*/
|
|
126
126
|
export function isFirstLetterCapitalized(string: string): boolean {
|
|
127
|
+
// eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
|
|
127
128
|
return FIRST_LETTER_CAPITALIZED_REGEX.test(string);
|
|
128
129
|
}
|
|
129
130
|
|
|
@@ -157,8 +158,8 @@ export function isUpperCase(string: string): boolean {
|
|
|
157
158
|
|
|
158
159
|
/** Helper function to convert a string from kebab-case to camelCase. */
|
|
159
160
|
export function kebabCaseToCamelCase(string: string): string {
|
|
160
|
-
return string.replaceAll(/-./
|
|
161
|
-
const firstLetterOfWord = match
|
|
161
|
+
return string.replaceAll(/-./gv, (match) => {
|
|
162
|
+
const firstLetterOfWord = match.at(1);
|
|
162
163
|
return firstLetterOfWord === undefined
|
|
163
164
|
? ""
|
|
164
165
|
: firstLetterOfWord.toUpperCase();
|
|
@@ -189,11 +190,11 @@ export function normalizeString(string: string): string {
|
|
|
189
190
|
|
|
190
191
|
// Normalize newlines.
|
|
191
192
|
sanitizedString = sanitizedString.replaceAll("\n\r", "\n");
|
|
192
|
-
sanitizedString = sanitizedString.replaceAll(/\p{Zl}/
|
|
193
|
-
sanitizedString = sanitizedString.replaceAll(/\p{Zp}/
|
|
193
|
+
sanitizedString = sanitizedString.replaceAll(/\p{Zl}/gv, "\n");
|
|
194
|
+
sanitizedString = sanitizedString.replaceAll(/\p{Zp}/gv, "\n");
|
|
194
195
|
|
|
195
196
|
// Normalize spaces.
|
|
196
|
-
sanitizedString = sanitizedString.replaceAll(/\p{Zs}/
|
|
197
|
+
sanitizedString = sanitizedString.replaceAll(/\p{Zs}/gv, " ");
|
|
197
198
|
|
|
198
199
|
// Remove leading/trailing whitespace.
|
|
199
200
|
sanitizedString = sanitizedString.trim();
|
|
@@ -210,7 +211,7 @@ export function normalizeString(string: string): string {
|
|
|
210
211
|
export function parseSemanticVersion(
|
|
211
212
|
versionString: string,
|
|
212
213
|
): SemanticVersion | undefined {
|
|
213
|
-
const match =
|
|
214
|
+
const match = SEMANTIC_VERSION_REGEX.exec(versionString);
|
|
214
215
|
if (match === null || match.groups === undefined) {
|
|
215
216
|
return undefined;
|
|
216
217
|
}
|
|
@@ -232,7 +233,11 @@ export function parseSemanticVersion(
|
|
|
232
233
|
return undefined;
|
|
233
234
|
}
|
|
234
235
|
|
|
235
|
-
return {
|
|
236
|
+
return {
|
|
237
|
+
majorVersion,
|
|
238
|
+
minorVersion,
|
|
239
|
+
patchVersion,
|
|
240
|
+
};
|
|
236
241
|
}
|
|
237
242
|
|
|
238
243
|
/* eslint-disable jsdoc/escape-inline-tags */
|
|
@@ -301,7 +306,7 @@ export function removeLinesMatching(string: string, match: string): string {
|
|
|
301
306
|
* https://stackoverflow.com/questions/11598786/how-to-replace-non-printable-unicode-characters-javascript
|
|
302
307
|
*/
|
|
303
308
|
export function removeNonPrintableCharacters(string: string): string {
|
|
304
|
-
return string.replaceAll(/\p{C}/
|
|
309
|
+
return string.replaceAll(/\p{C}/gv, "");
|
|
305
310
|
}
|
|
306
311
|
|
|
307
312
|
/** Helper function to remove all whitespace characters from a string. */
|
|
@@ -353,7 +358,7 @@ export function satisfiesSemanticVersion(
|
|
|
353
358
|
export function titleCaseToKebabCase(string: string): string {
|
|
354
359
|
return string
|
|
355
360
|
.replaceAll(TITLE_CASE_BOUNDARY_REGEX, "-")
|
|
356
|
-
.replaceAll(/ +/
|
|
361
|
+
.replaceAll(/ +/gv, "-")
|
|
357
362
|
.toLowerCase();
|
|
358
363
|
}
|
|
359
364
|
|
package/src/functions/tuple.ts
CHANGED
|
@@ -13,7 +13,7 @@ type TupleValue<T extends readonly unknown[]> = T[0];
|
|
|
13
13
|
type TupleEntry<T extends readonly unknown[]> = [TupleKey<T>, TupleValue<T>]; // eslint-disable-line perfectionist/sort-modules
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* Helper function to get the entries (i.e
|
|
16
|
+
* Helper function to get the entries (i.e., indexes and values) of a tuple in a type-safe way.
|
|
17
17
|
*
|
|
18
18
|
* This is useful because the vanilla `Array.entries` method will always have the keys be of type
|
|
19
19
|
* `number`.
|
|
@@ -25,7 +25,7 @@ export function* tupleEntries<T extends readonly unknown[]>(
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
* Helper function to get the keys (i.e
|
|
28
|
+
* Helper function to get the keys (i.e., indexes) of a tuple in a type-safe way.
|
|
29
29
|
*
|
|
30
30
|
* This is useful because the vanilla `Array.keys` method will always have the keys be of type
|
|
31
31
|
* `number`.
|
package/src/functions/types.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* Helper function to narrow an unknown value to an object (i.e
|
|
8
|
+
* Helper function to narrow an unknown value to an object (i.e., a TypeScript record).
|
|
9
9
|
*
|
|
10
10
|
* Under the hood, this checks for `typeof variable === "object"`, `variable !== null`, and
|
|
11
11
|
* `!Array.isArray(variable)`.
|