nhb-toolbox 4.28.21 → 4.28.24
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 +5 -0
- package/dist/cjs/array/sort.js +65 -8
- package/dist/cjs/date/plugins/businessPlugin.js +33 -9
- package/dist/cjs/index.js +9 -10
- package/dist/dts/array/sort.d.ts +25 -6
- package/dist/dts/date/plugins/businessPlugin.d.ts +73 -2
- package/dist/dts/index.d.ts +1 -2
- package/dist/dts/types/index.d.ts +26 -13
- package/dist/dts/utils/index.d.ts +3 -3
- package/dist/esm/array/sort.js +61 -5
- package/dist/esm/date/plugins/businessPlugin.js +33 -9
- package/dist/esm/index.js +1 -2
- package/package.json +6 -6
- package/dist/cjs/array/utils.js +0 -60
- package/dist/dts/array/utils.d.ts +0 -13
- package/dist/esm/array/utils.js +0 -57
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,11 @@ All notable changes to the package will be documented here.
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
+
## [4.28.24] - 2025-12-11
|
|
10
|
+
|
|
11
|
+
- **Updated** *type names* `VoidFunction` to `VoidFn`. `DelayedFn<T>` is used for both *debounced* and *throttled* functions.
|
|
12
|
+
- **Added** *new* `Chronos` *business plugin methods* `weekendsBetween`, `weekendsInMonth` and `weekendsInYear`.
|
|
13
|
+
|
|
9
14
|
## [4.28.21] - 2025-12-07
|
|
10
15
|
|
|
11
16
|
- **Added** *missing exports* for `getTimeZoneIds` and `getNativeTimeZoneId` *utilities*.
|
package/dist/cjs/array/sort.js
CHANGED
|
@@ -1,14 +1,71 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.naturalSort = naturalSort;
|
|
3
4
|
exports.sortAnArray = sortAnArray;
|
|
4
5
|
const non_primitives_1 = require("../guards/non-primitives");
|
|
5
6
|
const primitives_1 = require("../guards/primitives");
|
|
6
|
-
|
|
7
|
+
function naturalSort(a, b, options) {
|
|
8
|
+
const { caseInsensitive = true, localeAware = false } = options || {};
|
|
9
|
+
const _createChunks = (str) => {
|
|
10
|
+
const chunks = [];
|
|
11
|
+
let current = '';
|
|
12
|
+
let isNumeric = false;
|
|
13
|
+
for (const char of str) {
|
|
14
|
+
const charIsNum = !Number.isNaN(Number(char));
|
|
15
|
+
if (current?.length === 0) {
|
|
16
|
+
current = char;
|
|
17
|
+
isNumeric = charIsNum;
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
if (charIsNum === isNumeric) {
|
|
21
|
+
current += char;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
chunks?.push(isNumeric ? Number(current) : current);
|
|
25
|
+
current = char;
|
|
26
|
+
isNumeric = charIsNum;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (current?.length > 0) {
|
|
30
|
+
chunks?.push(isNumeric ? Number(current) : current);
|
|
31
|
+
}
|
|
32
|
+
return chunks;
|
|
33
|
+
};
|
|
34
|
+
const aChunks = _createChunks(a);
|
|
35
|
+
const bChunks = _createChunks(b);
|
|
36
|
+
for (let i = 0; i < Math.min(aChunks?.length, bChunks?.length); i++) {
|
|
37
|
+
let aChunk = aChunks[i];
|
|
38
|
+
let bChunk = bChunks[i];
|
|
39
|
+
if (caseInsensitive && typeof aChunk === 'string' && typeof bChunk === 'string') {
|
|
40
|
+
aChunk = aChunk?.toLowerCase();
|
|
41
|
+
bChunk = bChunk?.toLowerCase();
|
|
42
|
+
}
|
|
43
|
+
if (typeof aChunk !== typeof bChunk) {
|
|
44
|
+
return typeof aChunk === 'string' ? 1 : -1;
|
|
45
|
+
}
|
|
46
|
+
if (aChunk !== bChunk) {
|
|
47
|
+
if (typeof aChunk === 'number' && typeof bChunk === 'number') {
|
|
48
|
+
return aChunk - bChunk;
|
|
49
|
+
}
|
|
50
|
+
if (typeof aChunk === 'string' && typeof bChunk === 'string') {
|
|
51
|
+
if (localeAware) {
|
|
52
|
+
const cmp = aChunk.localeCompare(bChunk, undefined, {
|
|
53
|
+
sensitivity: caseInsensitive ? 'accent' : 'variant',
|
|
54
|
+
});
|
|
55
|
+
if (cmp !== 0)
|
|
56
|
+
return cmp;
|
|
57
|
+
}
|
|
58
|
+
return aChunk < bChunk ? -1 : 1;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return aChunks?.length - bChunks?.length;
|
|
63
|
+
}
|
|
7
64
|
function sortAnArray(array, options) {
|
|
8
65
|
if (!(0, non_primitives_1.isValidArray)(array))
|
|
9
66
|
return array;
|
|
10
67
|
if ((0, non_primitives_1.isArrayOfType)(array, primitives_1.isString)) {
|
|
11
|
-
return [...array].sort((a, b) => options?.sortOrder === 'desc' ?
|
|
68
|
+
return [...array].sort((a, b) => options?.sortOrder === 'desc' ? naturalSort(b, a) : naturalSort(a, b));
|
|
12
69
|
}
|
|
13
70
|
if ((0, non_primitives_1.isArrayOfType)(array, primitives_1.isNumber)) {
|
|
14
71
|
return [...array].sort((a, b) => (options?.sortOrder === 'desc' ? b - a : a - b));
|
|
@@ -28,15 +85,15 @@ function sortAnArray(array, options) {
|
|
|
28
85
|
if (keyA == null || keyB == null) {
|
|
29
86
|
return keyA == null ? 1 : -1;
|
|
30
87
|
}
|
|
31
|
-
if (
|
|
88
|
+
if ((0, primitives_1.isString)(keyA) && (0, primitives_1.isString)(keyB)) {
|
|
32
89
|
return options?.sortOrder === 'desc' ?
|
|
33
|
-
|
|
34
|
-
:
|
|
90
|
+
naturalSort(keyB, keyA)
|
|
91
|
+
: naturalSort(keyA, keyB);
|
|
35
92
|
}
|
|
36
|
-
if (
|
|
93
|
+
if ((0, primitives_1.isNumber)(keyA) && (0, primitives_1.isNumber)(keyB)) {
|
|
37
94
|
return options?.sortOrder === 'desc' ? keyB - keyA : keyA - keyB;
|
|
38
95
|
}
|
|
39
|
-
if (
|
|
96
|
+
if ((0, primitives_1.isBoolean)(keyA) && (0, primitives_1.isBoolean)(keyB)) {
|
|
40
97
|
return options?.sortOrder === 'desc' ?
|
|
41
98
|
Number(keyB) - Number(keyA)
|
|
42
99
|
: Number(keyA) - Number(keyB);
|
|
@@ -44,5 +101,5 @@ function sortAnArray(array, options) {
|
|
|
44
101
|
return 0;
|
|
45
102
|
});
|
|
46
103
|
}
|
|
47
|
-
return array;
|
|
104
|
+
return [...array];
|
|
48
105
|
}
|
|
@@ -15,11 +15,12 @@ const businessPlugin = ($Chronos) => {
|
|
|
15
15
|
mask[d] = false;
|
|
16
16
|
return mask;
|
|
17
17
|
};
|
|
18
|
-
const
|
|
19
|
-
let total = Math.floor(
|
|
20
|
-
let dayIndex =
|
|
21
|
-
for (let i = 0; i <
|
|
22
|
-
|
|
18
|
+
const _countDays = (sWeek, days, mask, step = 1, wd = true) => {
|
|
19
|
+
let total = Math.floor(days / 7) * mask.filter((m) => (wd ? Boolean(m) : !m)).length;
|
|
20
|
+
let dayIndex = ((sWeek % 7) + 7) % 7;
|
|
21
|
+
for (let i = 0; i < days % 7; i++) {
|
|
22
|
+
const isMatch = wd ? Boolean(mask[dayIndex]) : !mask[dayIndex];
|
|
23
|
+
if (isMatch)
|
|
23
24
|
total++;
|
|
24
25
|
dayIndex = (dayIndex + step + 7) % 7;
|
|
25
26
|
}
|
|
@@ -67,26 +68,49 @@ const businessPlugin = ($Chronos) => {
|
|
|
67
68
|
};
|
|
68
69
|
$Chronos.prototype.workdaysBetween = function (to, wDef = 0, wLen = 2) {
|
|
69
70
|
const end = cast(to).startOf('day');
|
|
70
|
-
const start = this.
|
|
71
|
+
const start = this.startOf('day');
|
|
71
72
|
if (start.isSame(end, 'day'))
|
|
72
73
|
return 0;
|
|
73
74
|
const step = start.isBefore(end, 'day') ? 1 : -1;
|
|
74
75
|
const totalDays = Math.abs(end.diff(start, 'day'));
|
|
75
76
|
const weekendMask = _buildWeekendMask(wDef, wLen);
|
|
76
77
|
const startWeekday = (start.isoWeekDay + step) % 7;
|
|
77
|
-
return
|
|
78
|
+
return _countDays(startWeekday, totalDays, weekendMask, step);
|
|
79
|
+
};
|
|
80
|
+
$Chronos.prototype.weekendsBetween = function (to, wDef = 0, wLen = 2) {
|
|
81
|
+
const end = cast(to).startOf('day');
|
|
82
|
+
const start = this.startOf('day');
|
|
83
|
+
if (start.isSame(end, 'day'))
|
|
84
|
+
return 0;
|
|
85
|
+
const step = start.isBefore(end, 'day') ? 1 : -1;
|
|
86
|
+
const totalDays = Math.abs(end.diff(start, 'day'));
|
|
87
|
+
const weekendMask = _buildWeekendMask(wDef, wLen);
|
|
88
|
+
const startWeekday = (start.isoWeekDay + step) % 7;
|
|
89
|
+
return _countDays(startWeekday, totalDays, weekendMask, step, false);
|
|
78
90
|
};
|
|
79
91
|
$Chronos.prototype.workdaysInMonth = function (wDef = 0, wLen = 2) {
|
|
80
92
|
const daysInMonth = this.daysInMonth();
|
|
81
93
|
const weekendMask = _buildWeekendMask(wDef, wLen);
|
|
82
94
|
const startWeekday = this.startOf('month').isoWeekDay % 7;
|
|
83
|
-
return
|
|
95
|
+
return _countDays(startWeekday, daysInMonth, weekendMask);
|
|
96
|
+
};
|
|
97
|
+
$Chronos.prototype.weekendsInMonth = function (wDef = 0, wLen = 2) {
|
|
98
|
+
const daysInMonth = this.daysInMonth();
|
|
99
|
+
const weekendMask = _buildWeekendMask(wDef, wLen);
|
|
100
|
+
const startWeekday = this.startOf('month').isoWeekDay % 7;
|
|
101
|
+
return _countDays(startWeekday, daysInMonth, weekendMask, 1, false);
|
|
84
102
|
};
|
|
85
103
|
$Chronos.prototype.workdaysInYear = function (wDef = 0, wLen = 2) {
|
|
86
104
|
const daysInYear = this.isLeapYear() ? 366 : 365;
|
|
87
105
|
const weekendMask = _buildWeekendMask(wDef, wLen);
|
|
88
106
|
const startWeekday = this.startOf('year').isoWeekDay % 7;
|
|
89
|
-
return
|
|
107
|
+
return _countDays(startWeekday, daysInYear, weekendMask);
|
|
108
|
+
};
|
|
109
|
+
$Chronos.prototype.weekendsInYear = function (wDef = 0, wLen = 2) {
|
|
110
|
+
const daysInYear = this.isLeapYear() ? 366 : 365;
|
|
111
|
+
const weekendMask = _buildWeekendMask(wDef, wLen);
|
|
112
|
+
const startWeekday = this.startOf('year').isoWeekDay % 7;
|
|
113
|
+
return _countDays(startWeekday, daysInYear, weekendMask, 1, false);
|
|
90
114
|
};
|
|
91
115
|
$Chronos.prototype.isBusinessHour = function (options) {
|
|
92
116
|
const _isBusinessHour = () => {
|
package/dist/cjs/index.js
CHANGED
|
@@ -4,7 +4,7 @@ exports.convertToDecimal = exports.calculateLCM = exports.calculateLCD = exports
|
|
|
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.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.isTimeWithUnit = exports.isNativeTimeZoneId = exports.isLeapYear = exports.isDateLike = exports.parseMSec = exports.parseMs = 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
|
-
exports.convertIntoFormData = exports.
|
|
7
|
+
exports.convertIntoFormData = 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.naturalSortForString = exports.naturalSort = exports.compareSorter = exports.compareNaturally = 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.getTimeZoneIds = exports.getTimeZoneDetails = exports.getTimeStringFromUTC = exports.getTimeFromMinutes = exports.getNativeTimeZoneId = exports.getMinutesFromUTC = exports.getHourMinutesFromMinutes = exports.getCurrentTime = exports.getCurrentDateTime = exports.formatUTCOffset = void 0;
|
|
8
8
|
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 = exports.isCustomFile = exports.serializeForm = exports.parseFormData = exports.createFormData = exports.createControlledFormData = void 0;
|
|
9
9
|
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.stripJsonEdgeGarbage = exports.stableStringify = 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 = exports.toggleFullScreen = exports.smoothScrollTo = exports.copyToClipboard = exports.updateQueryParam = exports.queryStringToObject = void 0;
|
|
10
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 = exports.isJSON = exports.isFunction = exports.isError = exports.isEmptyObjectGuard = exports.isEmptyObject = exports.isDate = exports.isArrayWithLength = void 0;
|
|
@@ -273,6 +273,10 @@ Object.defineProperty(exports, "totalDeltaByField", { enumerable: true, get: fun
|
|
|
273
273
|
var Finder_1 = require("./array/Finder");
|
|
274
274
|
Object.defineProperty(exports, "Finder", { enumerable: true, get: function () { return Finder_1.Finder; } });
|
|
275
275
|
var sort_1 = require("./array/sort");
|
|
276
|
+
Object.defineProperty(exports, "compareNaturally", { enumerable: true, get: function () { return sort_1.naturalSort; } });
|
|
277
|
+
Object.defineProperty(exports, "compareSorter", { enumerable: true, get: function () { return sort_1.naturalSort; } });
|
|
278
|
+
Object.defineProperty(exports, "naturalSort", { enumerable: true, get: function () { return sort_1.naturalSort; } });
|
|
279
|
+
Object.defineProperty(exports, "naturalSortForString", { enumerable: true, get: function () { return sort_1.naturalSort; } });
|
|
276
280
|
Object.defineProperty(exports, "sortAnArray", { enumerable: true, get: function () { return sort_1.sortAnArray; } });
|
|
277
281
|
var transform_1 = require("./array/transform");
|
|
278
282
|
Object.defineProperty(exports, "createOptionsArray", { enumerable: true, get: function () { return transform_1.createOptionsArray; } });
|
|
@@ -290,11 +294,6 @@ Object.defineProperty(exports, "removeDuplicatesFromArray", { enumerable: true,
|
|
|
290
294
|
Object.defineProperty(exports, "rotateArray", { enumerable: true, get: function () { return transform_1.rotateArray; } });
|
|
291
295
|
Object.defineProperty(exports, "splitArray", { enumerable: true, get: function () { return transform_1.splitArray; } });
|
|
292
296
|
Object.defineProperty(exports, "splitArrayByProperty", { enumerable: true, get: function () { return transform_1.splitArrayByProperty; } });
|
|
293
|
-
var utils_3 = require("./array/utils");
|
|
294
|
-
Object.defineProperty(exports, "compareNaturally", { enumerable: true, get: function () { return utils_3.naturalSort; } });
|
|
295
|
-
Object.defineProperty(exports, "compareSorter", { enumerable: true, get: function () { return utils_3.naturalSort; } });
|
|
296
|
-
Object.defineProperty(exports, "naturalSort", { enumerable: true, get: function () { return utils_3.naturalSort; } });
|
|
297
|
-
Object.defineProperty(exports, "naturalSortForString", { enumerable: true, get: function () { return utils_3.naturalSort; } });
|
|
298
297
|
var convert_4 = require("./form/convert");
|
|
299
298
|
Object.defineProperty(exports, "convertIntoFormData", { enumerable: true, get: function () { return convert_4.createControlledFormData; } });
|
|
300
299
|
Object.defineProperty(exports, "createControlledFormData", { enumerable: true, get: function () { return convert_4.createControlledFormData; } });
|
|
@@ -356,10 +355,10 @@ Object.defineProperty(exports, "parseQueryString", { enumerable: true, get: func
|
|
|
356
355
|
Object.defineProperty(exports, "parseQueryStringLiteral", { enumerable: true, get: function () { return query_1.parseQueryStringLiteral; } });
|
|
357
356
|
Object.defineProperty(exports, "queryStringToObject", { enumerable: true, get: function () { return query_1.parseQueryString; } });
|
|
358
357
|
Object.defineProperty(exports, "updateQueryParam", { enumerable: true, get: function () { return query_1.updateQueryParam; } });
|
|
359
|
-
var
|
|
360
|
-
Object.defineProperty(exports, "copyToClipboard", { enumerable: true, get: function () { return
|
|
361
|
-
Object.defineProperty(exports, "smoothScrollTo", { enumerable: true, get: function () { return
|
|
362
|
-
Object.defineProperty(exports, "toggleFullScreen", { enumerable: true, get: function () { return
|
|
358
|
+
var utils_3 = require("./dom/utils");
|
|
359
|
+
Object.defineProperty(exports, "copyToClipboard", { enumerable: true, get: function () { return utils_3.copyToClipboard; } });
|
|
360
|
+
Object.defineProperty(exports, "smoothScrollTo", { enumerable: true, get: function () { return utils_3.smoothScrollTo; } });
|
|
361
|
+
Object.defineProperty(exports, "toggleFullScreen", { enumerable: true, get: function () { return utils_3.toggleFullScreen; } });
|
|
363
362
|
var storage_1 = require("./dom/storage");
|
|
364
363
|
Object.defineProperty(exports, "getFromLocalStorage", { enumerable: true, get: function () { return storage_1.getFromLocalStorage; } });
|
|
365
364
|
Object.defineProperty(exports, "getFromSessionStorage", { enumerable: true, get: function () { return storage_1.getFromSessionStorage; } });
|
package/dist/dts/array/sort.d.ts
CHANGED
|
@@ -1,20 +1,39 @@
|
|
|
1
1
|
import type { GenericObject } from '../object/types';
|
|
2
|
-
import type {
|
|
2
|
+
import type { BasicPrimitive } from '../types/index';
|
|
3
|
+
import type { OrderOption, SortByOption, SortNature } from './types';
|
|
3
4
|
/**
|
|
4
|
-
*
|
|
5
|
+
* Compare two strings using natural sorting (e.g., `"file2"` < `"file10"`).
|
|
6
|
+
* - Optionally supports case-insensitive and locale-aware string chunk comparisons.
|
|
5
7
|
*
|
|
6
|
-
* -
|
|
8
|
+
* @param a - The first string to compare.
|
|
9
|
+
* @param b - The second string to compare.
|
|
10
|
+
* @param options - Optional settings to configure comparison behavior.
|
|
11
|
+
* @returns A negative number if `a` comes before `b`, a positive number if `a` comes after `b`, or 0 if equal.
|
|
12
|
+
*/
|
|
13
|
+
export declare function naturalSort(a: string, b: string, options?: SortNature): number;
|
|
14
|
+
/**
|
|
15
|
+
* * Sorts an array of objects based on the provided options.
|
|
16
|
+
*
|
|
17
|
+
* @remarks
|
|
18
|
+
* - Sorts array by the specified field in the options `sortByField`.
|
|
19
|
+
* - Uses {@link naturalSort} for sorting string values.
|
|
7
20
|
*
|
|
8
21
|
* @param array - The array of objects to sort.
|
|
9
|
-
* @param options - Sorting options.
|
|
22
|
+
* @param options - Sorting options for objects.
|
|
10
23
|
* @returns The sorted array.
|
|
11
24
|
*/
|
|
12
25
|
export declare function sortAnArray<T extends GenericObject>(array: T[], options: SortByOption<T>): T[];
|
|
13
26
|
/**
|
|
14
|
-
* * Sorts an array of `strings`, `numbers` or `boolean
|
|
27
|
+
* * Sorts an array of `strings`, `numbers` or `boolean` based on the provided options.
|
|
28
|
+
*
|
|
29
|
+
* @remarks
|
|
30
|
+
* - If the array contains strings, it sorts them alphabetically.
|
|
31
|
+
* - If the array contains numbers, it sorts them numerically.
|
|
32
|
+
* - If the array contains booleans, it sorts them by their boolean value.
|
|
33
|
+
* - Uses {@link naturalSort} for sorting string values.
|
|
15
34
|
*
|
|
16
35
|
* @param array - The array of `strings`, `numbers` or `boolean` to sort.
|
|
17
36
|
* @param options - Sorting options.
|
|
18
37
|
* @returns The sorted array.
|
|
19
38
|
*/
|
|
20
|
-
export declare function sortAnArray<T extends
|
|
39
|
+
export declare function sortAnArray<T extends BasicPrimitive>(array: T[], options?: OrderOption): T[];
|
|
@@ -266,7 +266,7 @@ declare module '../Chronos' {
|
|
|
266
266
|
* @remarks This calculation is exclusive of the starting date and inclusive of the ending date.
|
|
267
267
|
*
|
|
268
268
|
* @example
|
|
269
|
-
* new Chronos('2025-12-15').workdaysBetween(
|
|
269
|
+
* new Chronos('2025-12-15').workdaysBetween('2025-12-21');
|
|
270
270
|
* // default weekend Friday & Saturday -> 4
|
|
271
271
|
*/
|
|
272
272
|
workdaysBetween(other: ChronosInput, weekStartsOn?: Enumerate<7>, weekendLength?: NumberRange<1, 4>): number;
|
|
@@ -280,10 +280,39 @@ declare module '../Chronos' {
|
|
|
280
280
|
* @remarks This calculation is exclusive of the starting date and inclusive of the ending date.
|
|
281
281
|
*
|
|
282
282
|
* @example
|
|
283
|
-
* new Chronos('2025-12-15').workdaysBetween(
|
|
283
|
+
* new Chronos('2025-12-15').workdaysBetween('2025-12-20', [0, 6]);
|
|
284
284
|
* // custom weekend Sunday & Saturday -> 4
|
|
285
285
|
*/
|
|
286
286
|
workdaysBetween(other: ChronosInput, weekendDays: RangeTuple<Enumerate<7>, 1, 4>): number;
|
|
287
|
+
/**
|
|
288
|
+
* @instance Calculates the number of weekends between the current date and another using week start day and weekend length.
|
|
289
|
+
*
|
|
290
|
+
* @param other The target date to compare against.
|
|
291
|
+
* @param weekStartsOn Optional. The day index (0–6) that the week starts on. Default is `0` (Sunday).
|
|
292
|
+
* @param weekendLength Optional. Number of consecutive days at the end of the week considered as weekend. Must be between 1 and 4. Default is `2`.
|
|
293
|
+
* @returns The total count of weekends between the two dates.
|
|
294
|
+
*
|
|
295
|
+
* @remarks This calculation is exclusive of the starting date and inclusive of the ending date.
|
|
296
|
+
*
|
|
297
|
+
* @example
|
|
298
|
+
* new Chronos('2025-12-15').weekendsBetween('2025-12-21');
|
|
299
|
+
* // default weekend Friday & Saturday -> 2
|
|
300
|
+
*/
|
|
301
|
+
weekendsBetween(other: ChronosInput, weekStartsOn?: Enumerate<7>, weekendLength?: NumberRange<1, 4>): number;
|
|
302
|
+
/**
|
|
303
|
+
* @instance Calculates the number of weekends between the current date and another using custom weekend days.
|
|
304
|
+
*
|
|
305
|
+
* @param other The target date to compare against.
|
|
306
|
+
* @param weekendDays A tuple of custom weekend day indices (0–6). Must contain 1–4 elements.
|
|
307
|
+
* @returns The total count of weekends between the two dates.
|
|
308
|
+
*
|
|
309
|
+
* @remarks This calculation is exclusive of the starting date and inclusive of the ending date.
|
|
310
|
+
*
|
|
311
|
+
* @example
|
|
312
|
+
* new Chronos('2025-12-15').weekendsBetween('2025-12-20', [0, 6]);
|
|
313
|
+
* // custom weekend Sunday & Saturday -> 1
|
|
314
|
+
*/
|
|
315
|
+
weekendsBetween(other: ChronosInput, weekendDays: RangeTuple<Enumerate<7>, 1, 4>): number;
|
|
287
316
|
/**
|
|
288
317
|
* @instance Counts the number of workdays in the current month using week start day and weekend length.
|
|
289
318
|
*
|
|
@@ -305,6 +334,27 @@ declare module '../Chronos' {
|
|
|
305
334
|
* new Chronos('2025-01-01').workdaysInMonth([0, 6]); // Sunday & Saturday are weekends
|
|
306
335
|
*/
|
|
307
336
|
workdaysInMonth(weekendDays: RangeTuple<Enumerate<7>, 1, 4>): number;
|
|
337
|
+
/**
|
|
338
|
+
* @instance Counts the number of weekends in the current month using week start day and weekend length.
|
|
339
|
+
*
|
|
340
|
+
* @param weekStartsOn Optional. The day index (0–6) that the week starts on. Default is `0` (Sunday).
|
|
341
|
+
* @param weekendLength Optional. Number of consecutive days at the end of the week considered as weekend. Must be between 1 and 4. Default is `2`.
|
|
342
|
+
* @returns Number of weekends in the current month.
|
|
343
|
+
*
|
|
344
|
+
* @example
|
|
345
|
+
* new Chronos('2025-01-01').weekendsInMonth(); // default weekend Friday & Saturday -> 8
|
|
346
|
+
*/
|
|
347
|
+
weekendsInMonth(weekStartsOn?: Enumerate<7>, weekendLength?: NumberRange<1, 4>): number;
|
|
348
|
+
/**
|
|
349
|
+
* @instance Counts the number of weekends in the current month using custom weekend days.
|
|
350
|
+
*
|
|
351
|
+
* @param weekendDays A tuple of custom weekend day indices (0–6). Must contain 1–4 elements.
|
|
352
|
+
* @returns Number of weekends in the current month.
|
|
353
|
+
*
|
|
354
|
+
* @example
|
|
355
|
+
* new Chronos('2025-01-01').weekendsInMonth([0, 6]); // Sunday & Saturday are weekends
|
|
356
|
+
*/
|
|
357
|
+
weekendsInMonth(weekendDays: RangeTuple<Enumerate<7>, 1, 4>): number;
|
|
308
358
|
/**
|
|
309
359
|
* @instance Counts the number of workdays in the current year using week start day and weekend length.
|
|
310
360
|
*
|
|
@@ -326,6 +376,27 @@ declare module '../Chronos' {
|
|
|
326
376
|
* new Chronos('2025-01-01').workdaysInYear([0, 6]); // Sunday & Saturday are weekends
|
|
327
377
|
*/
|
|
328
378
|
workdaysInYear(weekendDays: RangeTuple<Enumerate<7>, 1, 4>): number;
|
|
379
|
+
/**
|
|
380
|
+
* @instance Counts the number of weekends in the current year using week start day and weekend length.
|
|
381
|
+
*
|
|
382
|
+
* @param weekStartsOn Optional. The day index (0–6) that the week starts on. Default is `0` (Sunday).
|
|
383
|
+
* @param weekendLength Optional. Number of consecutive days at the end of the week considered as weekend. Must be between 1–4. Default is `2`.
|
|
384
|
+
* @returns Number of weekends in the current year.
|
|
385
|
+
*
|
|
386
|
+
* @example
|
|
387
|
+
* new Chronos('2025-01-01').weekendsInYear(); // default weekend Friday & Saturday -> 104
|
|
388
|
+
*/
|
|
389
|
+
weekendsInYear(weekStartsOn?: Enumerate<7>, weekendLength?: NumberRange<1, 4>): number;
|
|
390
|
+
/**
|
|
391
|
+
* @instance Counts the number of weekends in the current year using custom weekend days.
|
|
392
|
+
*
|
|
393
|
+
* @param weekendDays A tuple of custom weekend day indices (0–6). Must contain 1–4 elements.
|
|
394
|
+
* @returns Number of weekends in the current year.
|
|
395
|
+
*
|
|
396
|
+
* @example
|
|
397
|
+
* new Chronos('2025-01-01').weekendsInYear([0, 6]); // Sunday & Saturday are weekends
|
|
398
|
+
*/
|
|
399
|
+
weekendsInYear(weekendDays: RangeTuple<Enumerate<7>, 1, 4>): number;
|
|
329
400
|
/**
|
|
330
401
|
* @instance Checks if the current time fall within business hours using week start day and weekend length & other options.
|
|
331
402
|
*
|
package/dist/dts/index.d.ts
CHANGED
|
@@ -48,9 +48,8 @@ export { convertMinutesToTime as convertMinutesToHourMinutes, convertMinutesToTi
|
|
|
48
48
|
export { filterArrayOfObjects, flattenArray, getLastArrayElement, isInvalidOrEmptyArray, isInvalidOrEmptyArray as isValidEmptyArray, shuffleArray, } from './array/basics';
|
|
49
49
|
export { averageByField, averageByField as avgByField, groupAndAverageByField, groupAndAverageByField as groupAndAvgByField, groupAndSumByField, sumByField, sumFieldDifference, sumFieldDifference as totalDeltaByField, } from './array/calc';
|
|
50
50
|
export { Finder } from './array/Finder';
|
|
51
|
-
export { sortAnArray } from './array/sort';
|
|
51
|
+
export { naturalSort as compareNaturally, naturalSort as compareSorter, naturalSort, naturalSort as naturalSortForString, sortAnArray, } from './array/sort';
|
|
52
52
|
export { createOptionsArray, getDuplicates as extractDuplicates, getDuplicates as extractDuplicatesFromArray, findMissingElements as extractMissingElements, findMissingElements, getDuplicates, getDuplicates as getDuplicatesFromArray, findMissingElements as getMissingElements, splitArrayByProperty as groupArrayByProperty, moveArrayElement, removeDuplicatesFromArray as removeDuplicates, removeDuplicatesFromArray, rotateArray, splitArray, splitArrayByProperty, } from './array/transform';
|
|
53
|
-
export { naturalSort as compareNaturally, naturalSort as compareSorter, naturalSort, naturalSort as naturalSortForString, } from './array/utils';
|
|
54
53
|
export { createControlledFormData as convertIntoFormData, createControlledFormData, createControlledFormData as createFormData, } from './form/convert';
|
|
55
54
|
export { parseFormData, serializeForm } from './form/transform';
|
|
56
55
|
export { isCustomFile, isCustomFileArray, isFileArray, isFileList, isFileOrBlob, isFileUpload, isOriginFileObj, isValidFormData, } from './form/guards';
|
|
@@ -6,7 +6,18 @@ declare const __brand: unique symbol;
|
|
|
6
6
|
type $Brand<B> = {
|
|
7
7
|
[__brand]: B;
|
|
8
8
|
};
|
|
9
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* * Creates a branded version of a base type by intersecting it with a unique compile-time marker.
|
|
11
|
+
*
|
|
12
|
+
* @param T - Base type to brand.
|
|
13
|
+
* @param B - Brand identifier used to distinguish this type from structurally similar types.
|
|
14
|
+
|
|
15
|
+
* @remarks Useful for preventing accidental mixing of structurally identical types, while keeping the runtime value unchanged.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* type UserId = Branded<string, 'UserId'>;
|
|
19
|
+
* const id = 'abc123' as UserId;
|
|
20
|
+
*/
|
|
10
21
|
export type Branded<T, B> = T & $Brand<B>;
|
|
11
22
|
/** Represents a value that may or may not be present. */
|
|
12
23
|
export type Maybe<T> = T | undefined;
|
|
@@ -16,10 +27,14 @@ export type FlattenPartial<T> = Partial<{
|
|
|
16
27
|
}>;
|
|
17
28
|
/** Union of `number` and numeric string */
|
|
18
29
|
export type Numeric = number | `${number}`;
|
|
30
|
+
/** Union of Basic Primitive Types (i.e. `string | number | boolean`) */
|
|
31
|
+
export type BasicPrimitive = string | number | boolean;
|
|
32
|
+
/** `null` or `undefined` */
|
|
33
|
+
export type NullOrUndefined = null | undefined;
|
|
19
34
|
/** Union of All Primitive Types (i.e. `string | number | boolean | symbol | bigint | null | undefined`) */
|
|
20
|
-
export type Primitive =
|
|
35
|
+
export type Primitive = string | number | boolean | symbol | bigint | null | undefined;
|
|
21
36
|
/** Union of Normal Primitive Types (i.e. `string | number | boolean | null | undefined`) */
|
|
22
|
-
export type NormalPrimitive =
|
|
37
|
+
export type NormalPrimitive = string | number | boolean | null | undefined;
|
|
23
38
|
/** Extract normal primitive key(s) (i.e. `string | number | boolean | null | undefined`) from an object */
|
|
24
39
|
export type NormalPrimitiveKey<T> = {
|
|
25
40
|
[K in keyof T]: T[K] extends NormalPrimitive ? K : never;
|
|
@@ -35,24 +50,23 @@ export type OwnKeys<T> = {
|
|
|
35
50
|
}[keyof T];
|
|
36
51
|
/** Extract primitive (string, number or boolean) key(s) from an object */
|
|
37
52
|
export type NonNullishPrimitiveKey<T> = {
|
|
38
|
-
[K in keyof T]: T[K] extends
|
|
53
|
+
[K in keyof T]: T[K] extends BasicPrimitive ? K : never;
|
|
39
54
|
}[keyof T];
|
|
40
|
-
/** Falsy primitive type
|
|
41
|
-
export type FalsyPrimitive =
|
|
55
|
+
/** Falsy primitive type */
|
|
56
|
+
export type FalsyPrimitive = false | '' | 0 | null | undefined;
|
|
42
57
|
/** A generic class constructor */
|
|
43
58
|
export type Constructor = new (...args: any[]) => any;
|
|
44
59
|
/** Generic function type */
|
|
45
60
|
export type GenericFn = (...args: any[]) => any;
|
|
46
61
|
/** Generic function type that returns `void` */
|
|
47
|
-
export type
|
|
48
|
-
/**
|
|
49
|
-
export type DelayedFn<T extends
|
|
50
|
-
|
|
51
|
-
export type ThrottledFn<T extends VoidFunction> = (...args: Parameters<T>) => void;
|
|
62
|
+
export type VoidFn = (...args: any[]) => void;
|
|
63
|
+
/** Delayed (debounced or throttled) function type after certain delay */
|
|
64
|
+
export type DelayedFn<T extends VoidFn> = (...args: Parameters<T>) => void;
|
|
65
|
+
export type { DelayedFn as ThrottledFn, VoidFn as VoidFunction };
|
|
52
66
|
/** Asynchronous function type */
|
|
53
67
|
export type AsyncFunction<T> = (...args: any[]) => Promise<T>;
|
|
54
68
|
/** Advanced types to exclude from counting as object key */
|
|
55
|
-
export type AdvancedTypes = Array<unknown> | File | FileList | Chronos | DateLike | Blob | Date | RegExp | WeakMap<WeakKey, unknown> | WeakSet<WeakKey> | Map<unknown, unknown> | Set<unknown> | Function | GenericFn |
|
|
69
|
+
export type AdvancedTypes = Array<unknown> | File | FileList | Chronos | DateLike | Blob | Date | RegExp | WeakMap<WeakKey, unknown> | WeakSet<WeakKey> | Map<unknown, unknown> | Set<unknown> | Function | GenericFn | VoidFn | AsyncFunction<unknown> | Promise<unknown> | Error | EvalError | RangeError | ReferenceError | SyntaxError | TypeError | URIError | bigint | symbol;
|
|
56
70
|
/** Helper to detect if a type has methods */
|
|
57
71
|
export type HasMethods<T> = {
|
|
58
72
|
[K in keyof T]: T[K] extends Function ? true : never;
|
|
@@ -139,4 +153,3 @@ export type List<T = any> = ReadonlyArray<T>;
|
|
|
139
153
|
export type Serializer<T> = (value: T) => string;
|
|
140
154
|
/** Function type for deserializing a string to a value of type `T`. */
|
|
141
155
|
export type Deserializer<T> = (value: string) => T;
|
|
142
|
-
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { GenericObject } from '../object/types';
|
|
2
|
-
import type { ClassDetails, Constructor, DelayedFn, Maybe, Primitive,
|
|
2
|
+
import type { ClassDetails, Constructor, DelayedFn, Maybe, Primitive, VoidFn } from '../types/index';
|
|
3
3
|
import type { ArrayOfObjectsToStringOptions, ArrayOfPrimitivesToStringOptions, ProtoMethodOptions } from './types';
|
|
4
4
|
/**
|
|
5
5
|
* * Deeply compare two values (arrays, objects, or primitive values).
|
|
@@ -55,7 +55,7 @@ export declare function convertArrayToString<T extends Primitive>(array: Maybe<T
|
|
|
55
55
|
*
|
|
56
56
|
* debouncedSearch('laptop'); // Executes after 300ms of inactivity.
|
|
57
57
|
*/
|
|
58
|
-
export declare function debounceAction<T extends
|
|
58
|
+
export declare function debounceAction<T extends VoidFn>(callback: T, delay?: number): DelayedFn<T>;
|
|
59
59
|
/**
|
|
60
60
|
* * A generic throttle function that ensures a callback is executed at most once per specified interval.
|
|
61
61
|
*
|
|
@@ -70,7 +70,7 @@ export declare function debounceAction<T extends VoidFunction>(callback: T, dela
|
|
|
70
70
|
*
|
|
71
71
|
* window.addEventListener('resize', throttledResize);
|
|
72
72
|
*/
|
|
73
|
-
export declare function throttleAction<T extends
|
|
73
|
+
export declare function throttleAction<T extends VoidFn>(callback: T, delay?: number): DelayedFn<T>;
|
|
74
74
|
/**
|
|
75
75
|
* * Retrieves the names of all instance methods defined directly on a class prototype.
|
|
76
76
|
*
|
package/dist/esm/array/sort.js
CHANGED
|
@@ -1,6 +1,62 @@
|
|
|
1
1
|
import { isArrayOfType, isObject, isValidArray } from '../guards/non-primitives.js';
|
|
2
2
|
import { isBoolean, isNumber, isString } from '../guards/primitives.js';
|
|
3
|
-
|
|
3
|
+
export function naturalSort(a, b, options) {
|
|
4
|
+
const { caseInsensitive = true, localeAware = false } = options || {};
|
|
5
|
+
const _createChunks = (str) => {
|
|
6
|
+
const chunks = [];
|
|
7
|
+
let current = '';
|
|
8
|
+
let isNumeric = false;
|
|
9
|
+
for (const char of str) {
|
|
10
|
+
const charIsNum = !Number.isNaN(Number(char));
|
|
11
|
+
if (current?.length === 0) {
|
|
12
|
+
current = char;
|
|
13
|
+
isNumeric = charIsNum;
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
if (charIsNum === isNumeric) {
|
|
17
|
+
current += char;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
chunks?.push(isNumeric ? Number(current) : current);
|
|
21
|
+
current = char;
|
|
22
|
+
isNumeric = charIsNum;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (current?.length > 0) {
|
|
26
|
+
chunks?.push(isNumeric ? Number(current) : current);
|
|
27
|
+
}
|
|
28
|
+
return chunks;
|
|
29
|
+
};
|
|
30
|
+
const aChunks = _createChunks(a);
|
|
31
|
+
const bChunks = _createChunks(b);
|
|
32
|
+
for (let i = 0; i < Math.min(aChunks?.length, bChunks?.length); i++) {
|
|
33
|
+
let aChunk = aChunks[i];
|
|
34
|
+
let bChunk = bChunks[i];
|
|
35
|
+
if (caseInsensitive && typeof aChunk === 'string' && typeof bChunk === 'string') {
|
|
36
|
+
aChunk = aChunk?.toLowerCase();
|
|
37
|
+
bChunk = bChunk?.toLowerCase();
|
|
38
|
+
}
|
|
39
|
+
if (typeof aChunk !== typeof bChunk) {
|
|
40
|
+
return typeof aChunk === 'string' ? 1 : -1;
|
|
41
|
+
}
|
|
42
|
+
if (aChunk !== bChunk) {
|
|
43
|
+
if (typeof aChunk === 'number' && typeof bChunk === 'number') {
|
|
44
|
+
return aChunk - bChunk;
|
|
45
|
+
}
|
|
46
|
+
if (typeof aChunk === 'string' && typeof bChunk === 'string') {
|
|
47
|
+
if (localeAware) {
|
|
48
|
+
const cmp = aChunk.localeCompare(bChunk, undefined, {
|
|
49
|
+
sensitivity: caseInsensitive ? 'accent' : 'variant',
|
|
50
|
+
});
|
|
51
|
+
if (cmp !== 0)
|
|
52
|
+
return cmp;
|
|
53
|
+
}
|
|
54
|
+
return aChunk < bChunk ? -1 : 1;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return aChunks?.length - bChunks?.length;
|
|
59
|
+
}
|
|
4
60
|
export function sortAnArray(array, options) {
|
|
5
61
|
if (!isValidArray(array))
|
|
6
62
|
return array;
|
|
@@ -25,15 +81,15 @@ export function sortAnArray(array, options) {
|
|
|
25
81
|
if (keyA == null || keyB == null) {
|
|
26
82
|
return keyA == null ? 1 : -1;
|
|
27
83
|
}
|
|
28
|
-
if (
|
|
84
|
+
if (isString(keyA) && isString(keyB)) {
|
|
29
85
|
return options?.sortOrder === 'desc' ?
|
|
30
86
|
naturalSort(keyB, keyA)
|
|
31
87
|
: naturalSort(keyA, keyB);
|
|
32
88
|
}
|
|
33
|
-
if (
|
|
89
|
+
if (isNumber(keyA) && isNumber(keyB)) {
|
|
34
90
|
return options?.sortOrder === 'desc' ? keyB - keyA : keyA - keyB;
|
|
35
91
|
}
|
|
36
|
-
if (
|
|
92
|
+
if (isBoolean(keyA) && isBoolean(keyB)) {
|
|
37
93
|
return options?.sortOrder === 'desc' ?
|
|
38
94
|
Number(keyB) - Number(keyA)
|
|
39
95
|
: Number(keyA) - Number(keyB);
|
|
@@ -41,5 +97,5 @@ export function sortAnArray(array, options) {
|
|
|
41
97
|
return 0;
|
|
42
98
|
});
|
|
43
99
|
}
|
|
44
|
-
return array;
|
|
100
|
+
return [...array];
|
|
45
101
|
}
|
|
@@ -12,11 +12,12 @@ export const businessPlugin = ($Chronos) => {
|
|
|
12
12
|
mask[d] = false;
|
|
13
13
|
return mask;
|
|
14
14
|
};
|
|
15
|
-
const
|
|
16
|
-
let total = Math.floor(
|
|
17
|
-
let dayIndex =
|
|
18
|
-
for (let i = 0; i <
|
|
19
|
-
|
|
15
|
+
const _countDays = (sWeek, days, mask, step = 1, wd = true) => {
|
|
16
|
+
let total = Math.floor(days / 7) * mask.filter((m) => (wd ? Boolean(m) : !m)).length;
|
|
17
|
+
let dayIndex = ((sWeek % 7) + 7) % 7;
|
|
18
|
+
for (let i = 0; i < days % 7; i++) {
|
|
19
|
+
const isMatch = wd ? Boolean(mask[dayIndex]) : !mask[dayIndex];
|
|
20
|
+
if (isMatch)
|
|
20
21
|
total++;
|
|
21
22
|
dayIndex = (dayIndex + step + 7) % 7;
|
|
22
23
|
}
|
|
@@ -64,26 +65,49 @@ export const businessPlugin = ($Chronos) => {
|
|
|
64
65
|
};
|
|
65
66
|
$Chronos.prototype.workdaysBetween = function (to, wDef = 0, wLen = 2) {
|
|
66
67
|
const end = cast(to).startOf('day');
|
|
67
|
-
const start = this.
|
|
68
|
+
const start = this.startOf('day');
|
|
68
69
|
if (start.isSame(end, 'day'))
|
|
69
70
|
return 0;
|
|
70
71
|
const step = start.isBefore(end, 'day') ? 1 : -1;
|
|
71
72
|
const totalDays = Math.abs(end.diff(start, 'day'));
|
|
72
73
|
const weekendMask = _buildWeekendMask(wDef, wLen);
|
|
73
74
|
const startWeekday = (start.isoWeekDay + step) % 7;
|
|
74
|
-
return
|
|
75
|
+
return _countDays(startWeekday, totalDays, weekendMask, step);
|
|
76
|
+
};
|
|
77
|
+
$Chronos.prototype.weekendsBetween = function (to, wDef = 0, wLen = 2) {
|
|
78
|
+
const end = cast(to).startOf('day');
|
|
79
|
+
const start = this.startOf('day');
|
|
80
|
+
if (start.isSame(end, 'day'))
|
|
81
|
+
return 0;
|
|
82
|
+
const step = start.isBefore(end, 'day') ? 1 : -1;
|
|
83
|
+
const totalDays = Math.abs(end.diff(start, 'day'));
|
|
84
|
+
const weekendMask = _buildWeekendMask(wDef, wLen);
|
|
85
|
+
const startWeekday = (start.isoWeekDay + step) % 7;
|
|
86
|
+
return _countDays(startWeekday, totalDays, weekendMask, step, false);
|
|
75
87
|
};
|
|
76
88
|
$Chronos.prototype.workdaysInMonth = function (wDef = 0, wLen = 2) {
|
|
77
89
|
const daysInMonth = this.daysInMonth();
|
|
78
90
|
const weekendMask = _buildWeekendMask(wDef, wLen);
|
|
79
91
|
const startWeekday = this.startOf('month').isoWeekDay % 7;
|
|
80
|
-
return
|
|
92
|
+
return _countDays(startWeekday, daysInMonth, weekendMask);
|
|
93
|
+
};
|
|
94
|
+
$Chronos.prototype.weekendsInMonth = function (wDef = 0, wLen = 2) {
|
|
95
|
+
const daysInMonth = this.daysInMonth();
|
|
96
|
+
const weekendMask = _buildWeekendMask(wDef, wLen);
|
|
97
|
+
const startWeekday = this.startOf('month').isoWeekDay % 7;
|
|
98
|
+
return _countDays(startWeekday, daysInMonth, weekendMask, 1, false);
|
|
81
99
|
};
|
|
82
100
|
$Chronos.prototype.workdaysInYear = function (wDef = 0, wLen = 2) {
|
|
83
101
|
const daysInYear = this.isLeapYear() ? 366 : 365;
|
|
84
102
|
const weekendMask = _buildWeekendMask(wDef, wLen);
|
|
85
103
|
const startWeekday = this.startOf('year').isoWeekDay % 7;
|
|
86
|
-
return
|
|
104
|
+
return _countDays(startWeekday, daysInYear, weekendMask);
|
|
105
|
+
};
|
|
106
|
+
$Chronos.prototype.weekendsInYear = function (wDef = 0, wLen = 2) {
|
|
107
|
+
const daysInYear = this.isLeapYear() ? 366 : 365;
|
|
108
|
+
const weekendMask = _buildWeekendMask(wDef, wLen);
|
|
109
|
+
const startWeekday = this.startOf('year').isoWeekDay % 7;
|
|
110
|
+
return _countDays(startWeekday, daysInYear, weekendMask, 1, false);
|
|
87
111
|
};
|
|
88
112
|
$Chronos.prototype.isBusinessHour = function (options) {
|
|
89
113
|
const _isBusinessHour = () => {
|
package/dist/esm/index.js
CHANGED
|
@@ -33,9 +33,8 @@ export { convertMinutesToTime as convertMinutesToHourMinutes, convertMinutesToTi
|
|
|
33
33
|
export { filterArrayOfObjects, flattenArray, getLastArrayElement, isInvalidOrEmptyArray, isInvalidOrEmptyArray as isValidEmptyArray, shuffleArray, } from './array/basics.js';
|
|
34
34
|
export { averageByField, averageByField as avgByField, groupAndAverageByField, groupAndAverageByField as groupAndAvgByField, groupAndSumByField, sumByField, sumFieldDifference, sumFieldDifference as totalDeltaByField, } from './array/calc.js';
|
|
35
35
|
export { Finder } from './array/Finder.js';
|
|
36
|
-
export { sortAnArray } from './array/sort.js';
|
|
36
|
+
export { naturalSort as compareNaturally, naturalSort as compareSorter, naturalSort, naturalSort as naturalSortForString, sortAnArray, } from './array/sort.js';
|
|
37
37
|
export { createOptionsArray, getDuplicates as extractDuplicates, getDuplicates as extractDuplicatesFromArray, findMissingElements as extractMissingElements, findMissingElements, getDuplicates, getDuplicates as getDuplicatesFromArray, findMissingElements as getMissingElements, splitArrayByProperty as groupArrayByProperty, moveArrayElement, removeDuplicatesFromArray as removeDuplicates, removeDuplicatesFromArray, rotateArray, splitArray, splitArrayByProperty, } from './array/transform.js';
|
|
38
|
-
export { naturalSort as compareNaturally, naturalSort as compareSorter, naturalSort, naturalSort as naturalSortForString, } from './array/utils.js';
|
|
39
38
|
export { createControlledFormData as convertIntoFormData, createControlledFormData, createControlledFormData as createFormData, } from './form/convert.js';
|
|
40
39
|
export { parseFormData, serializeForm } from './form/transform.js';
|
|
41
40
|
export { isCustomFile, isCustomFileArray, isFileArray, isFileList, isFileOrBlob, isFileUpload, isOriginFileObj, isValidFormData, } from './form/guards.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nhb-toolbox",
|
|
3
|
-
"version": "4.28.
|
|
3
|
+
"version": "4.28.24",
|
|
4
4
|
"description": "A versatile collection of smart, efficient, and reusable utility functions, classes and types for everyday development needs.",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -41,9 +41,9 @@
|
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@eslint/js": "^9.39.1",
|
|
43
43
|
"@types/jest": "^30.0.0",
|
|
44
|
-
"@types/node": "^
|
|
45
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
46
|
-
"@typescript-eslint/parser": "^8.
|
|
44
|
+
"@types/node": "^25.0.0",
|
|
45
|
+
"@typescript-eslint/eslint-plugin": "^8.49.0",
|
|
46
|
+
"@typescript-eslint/parser": "^8.49.0",
|
|
47
47
|
"eslint": "^9.39.1",
|
|
48
48
|
"eslint-config-prettier": "^10.1.8",
|
|
49
49
|
"eslint-plugin-prettier": "^5.5.4",
|
|
@@ -51,11 +51,11 @@
|
|
|
51
51
|
"husky": "^9.1.7",
|
|
52
52
|
"jest": "^30.2.0",
|
|
53
53
|
"lint-staged": "^16.2.7",
|
|
54
|
-
"nhb-scripts": "^1.
|
|
54
|
+
"nhb-scripts": "^1.9.0",
|
|
55
55
|
"prettier": "^3.7.4",
|
|
56
56
|
"ts-jest": "^29.4.6",
|
|
57
57
|
"typescript": "^5.9.3",
|
|
58
|
-
"typescript-eslint": "^8.
|
|
58
|
+
"typescript-eslint": "^8.49.0"
|
|
59
59
|
},
|
|
60
60
|
"keywords": [
|
|
61
61
|
"toolbox",
|
package/dist/cjs/array/utils.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.naturalSort = naturalSort;
|
|
4
|
-
function naturalSort(a, b, options) {
|
|
5
|
-
const { caseInsensitive = true, localeAware = false } = options || {};
|
|
6
|
-
const _createChunks = (str) => {
|
|
7
|
-
const chunks = [];
|
|
8
|
-
let current = '';
|
|
9
|
-
let isNumeric = false;
|
|
10
|
-
for (const char of str) {
|
|
11
|
-
const charIsNum = !Number.isNaN(Number(char));
|
|
12
|
-
if (current?.length === 0) {
|
|
13
|
-
current = char;
|
|
14
|
-
isNumeric = charIsNum;
|
|
15
|
-
continue;
|
|
16
|
-
}
|
|
17
|
-
if (charIsNum === isNumeric) {
|
|
18
|
-
current += char;
|
|
19
|
-
}
|
|
20
|
-
else {
|
|
21
|
-
chunks?.push(isNumeric ? Number(current) : current);
|
|
22
|
-
current = char;
|
|
23
|
-
isNumeric = charIsNum;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
if (current?.length > 0) {
|
|
27
|
-
chunks?.push(isNumeric ? Number(current) : current);
|
|
28
|
-
}
|
|
29
|
-
return chunks;
|
|
30
|
-
};
|
|
31
|
-
const aChunks = _createChunks(a);
|
|
32
|
-
const bChunks = _createChunks(b);
|
|
33
|
-
for (let i = 0; i < Math.min(aChunks?.length, bChunks?.length); i++) {
|
|
34
|
-
let aChunk = aChunks[i];
|
|
35
|
-
let bChunk = bChunks[i];
|
|
36
|
-
if (caseInsensitive && typeof aChunk === 'string' && typeof bChunk === 'string') {
|
|
37
|
-
aChunk = aChunk?.toLowerCase();
|
|
38
|
-
bChunk = bChunk?.toLowerCase();
|
|
39
|
-
}
|
|
40
|
-
if (typeof aChunk !== typeof bChunk) {
|
|
41
|
-
return typeof aChunk === 'string' ? 1 : -1;
|
|
42
|
-
}
|
|
43
|
-
if (aChunk !== bChunk) {
|
|
44
|
-
if (typeof aChunk === 'number' && typeof bChunk === 'number') {
|
|
45
|
-
return aChunk - bChunk;
|
|
46
|
-
}
|
|
47
|
-
if (typeof aChunk === 'string' && typeof bChunk === 'string') {
|
|
48
|
-
if (localeAware) {
|
|
49
|
-
const cmp = aChunk.localeCompare(bChunk, undefined, {
|
|
50
|
-
sensitivity: caseInsensitive ? 'accent' : 'variant',
|
|
51
|
-
});
|
|
52
|
-
if (cmp !== 0)
|
|
53
|
-
return cmp;
|
|
54
|
-
}
|
|
55
|
-
return aChunk < bChunk ? -1 : 1;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return aChunks?.length - bChunks?.length;
|
|
60
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { SortNature } from './types';
|
|
2
|
-
/**
|
|
3
|
-
* * Compare two strings using natural sorting (e.g., "file2" < "file10").
|
|
4
|
-
* Optionally supports case-insensitive and locale-aware string chunk comparisons.
|
|
5
|
-
*
|
|
6
|
-
* @param a - The first string to compare.
|
|
7
|
-
* @param b - The second string to compare.
|
|
8
|
-
* @param options - Optional settings to configure comparison behavior.
|
|
9
|
-
* @param options.caseInsensitive - If true, compares string chunks without case sensitivity. Defaults to `true`.
|
|
10
|
-
* @param options.localeAware - If true, uses localeCompare for string chunk comparisons. Defaults to `false`.
|
|
11
|
-
* @returns A negative number if `a` comes before `b`, a positive number if `a` comes after `b`, or 0 if equal.
|
|
12
|
-
*/
|
|
13
|
-
export declare function naturalSort(a: string, b: string, options?: SortNature): number;
|
package/dist/esm/array/utils.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
export function naturalSort(a, b, options) {
|
|
2
|
-
const { caseInsensitive = true, localeAware = false } = options || {};
|
|
3
|
-
const _createChunks = (str) => {
|
|
4
|
-
const chunks = [];
|
|
5
|
-
let current = '';
|
|
6
|
-
let isNumeric = false;
|
|
7
|
-
for (const char of str) {
|
|
8
|
-
const charIsNum = !Number.isNaN(Number(char));
|
|
9
|
-
if (current?.length === 0) {
|
|
10
|
-
current = char;
|
|
11
|
-
isNumeric = charIsNum;
|
|
12
|
-
continue;
|
|
13
|
-
}
|
|
14
|
-
if (charIsNum === isNumeric) {
|
|
15
|
-
current += char;
|
|
16
|
-
}
|
|
17
|
-
else {
|
|
18
|
-
chunks?.push(isNumeric ? Number(current) : current);
|
|
19
|
-
current = char;
|
|
20
|
-
isNumeric = charIsNum;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
if (current?.length > 0) {
|
|
24
|
-
chunks?.push(isNumeric ? Number(current) : current);
|
|
25
|
-
}
|
|
26
|
-
return chunks;
|
|
27
|
-
};
|
|
28
|
-
const aChunks = _createChunks(a);
|
|
29
|
-
const bChunks = _createChunks(b);
|
|
30
|
-
for (let i = 0; i < Math.min(aChunks?.length, bChunks?.length); i++) {
|
|
31
|
-
let aChunk = aChunks[i];
|
|
32
|
-
let bChunk = bChunks[i];
|
|
33
|
-
if (caseInsensitive && typeof aChunk === 'string' && typeof bChunk === 'string') {
|
|
34
|
-
aChunk = aChunk?.toLowerCase();
|
|
35
|
-
bChunk = bChunk?.toLowerCase();
|
|
36
|
-
}
|
|
37
|
-
if (typeof aChunk !== typeof bChunk) {
|
|
38
|
-
return typeof aChunk === 'string' ? 1 : -1;
|
|
39
|
-
}
|
|
40
|
-
if (aChunk !== bChunk) {
|
|
41
|
-
if (typeof aChunk === 'number' && typeof bChunk === 'number') {
|
|
42
|
-
return aChunk - bChunk;
|
|
43
|
-
}
|
|
44
|
-
if (typeof aChunk === 'string' && typeof bChunk === 'string') {
|
|
45
|
-
if (localeAware) {
|
|
46
|
-
const cmp = aChunk.localeCompare(bChunk, undefined, {
|
|
47
|
-
sensitivity: caseInsensitive ? 'accent' : 'variant',
|
|
48
|
-
});
|
|
49
|
-
if (cmp !== 0)
|
|
50
|
-
return cmp;
|
|
51
|
-
}
|
|
52
|
-
return aChunk < bChunk ? -1 : 1;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return aChunks?.length - bChunks?.length;
|
|
57
|
-
}
|