nhb-toolbox 4.29.10 → 4.29.21
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 +9 -0
- package/dist/cjs/array/Finder.js +16 -20
- package/dist/cjs/array/sort.js +4 -4
- package/dist/cjs/colors/initials.js +3 -2
- package/dist/cjs/colors/utils.js +3 -1
- package/dist/cjs/date/chronos-fn.js +4 -2
- package/dist/cjs/date/guards.js +13 -15
- package/dist/cjs/date/utils.js +17 -4
- package/dist/cjs/dom/query.js +5 -8
- package/dist/cjs/form/convert.js +2 -2
- package/dist/cjs/form/guards.js +2 -1
- package/dist/cjs/form/transform.js +4 -3
- package/dist/cjs/number/basics.js +8 -5
- package/dist/cjs/number/guards.js +10 -2
- package/dist/cjs/number/range.js +3 -4
- package/dist/cjs/pluralizer/Pluralizer.js +3 -3
- package/dist/cjs/string/convert.js +2 -1
- package/dist/cjs/utils/index.js +1 -1
- package/dist/dts/converter/Converter.d.ts +1 -1
- package/dist/dts/number/guards.d.ts +5 -4
- package/dist/dts/number/range.d.ts +4 -3
- package/dist/esm/array/Finder.js +16 -20
- package/dist/esm/array/sort.js +4 -4
- package/dist/esm/colors/initials.js +3 -2
- package/dist/esm/colors/utils.js +3 -1
- package/dist/esm/converter/Converter.js +1 -1
- package/dist/esm/date/chronos-fn.js +4 -2
- package/dist/esm/date/guards.js +14 -16
- package/dist/esm/date/plugins/timeZonePlugin.js +1 -1
- package/dist/esm/date/utils.js +17 -4
- package/dist/esm/dom/query.js +5 -8
- package/dist/esm/form/convert.js +3 -3
- package/dist/esm/form/guards.js +2 -1
- package/dist/esm/form/transform.js +4 -3
- package/dist/esm/number/basics.js +9 -6
- package/dist/esm/number/guards.js +10 -2
- package/dist/esm/number/range.js +3 -4
- package/dist/esm/pluralizer/Pluralizer.js +4 -4
- package/dist/esm/string/convert.js +2 -1
- package/dist/esm/utils/index.js +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,15 @@
|
|
|
4
4
|
|
|
5
5
|
All notable changes to the package will be documented here.
|
|
6
6
|
|
|
7
|
+
## [4.29.21] - 2026-04-05
|
|
8
|
+
|
|
9
|
+
- **Updated** tsdoc for `getNumbersInRange` utility to clarify the return type based on the `getAsString` flag.
|
|
10
|
+
|
|
11
|
+
## [4.29.20] - 2026-04-03
|
|
12
|
+
|
|
13
|
+
- **Updated** `isEven` and `isOdd` utilities to accept *numeric string* and return `false` for `NaN` and *non-integer* values.
|
|
14
|
+
- **Replaced** manual type checks with *type guards* internally for better *type safety* and *code readability*.
|
|
15
|
+
|
|
7
16
|
## [4.29.10] - 2026-03-27
|
|
8
17
|
|
|
9
18
|
- **Added** new *color utlities* `applyOpacityToHex` and `percentToHex` for working with *hex colors* and *opacity*.
|
package/dist/cjs/array/Finder.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Finder = void 0;
|
|
4
|
+
const non_primitives_1 = require("../guards/non-primitives");
|
|
5
|
+
const primitives_1 = require("../guards/primitives");
|
|
4
6
|
class Finder {
|
|
5
7
|
static #DEFAULT_TTL = 1000 * 60 * 5;
|
|
6
8
|
#cachedResult = new Map();
|
|
@@ -9,7 +11,7 @@ class Finder {
|
|
|
9
11
|
#items;
|
|
10
12
|
constructor(data, ttl = Finder.#DEFAULT_TTL) {
|
|
11
13
|
this.#ttl = ttl;
|
|
12
|
-
this.#items =
|
|
14
|
+
this.#items = (0, non_primitives_1.isFunction)(data) ? data() : data;
|
|
13
15
|
}
|
|
14
16
|
clearCache(key) {
|
|
15
17
|
if (key) {
|
|
@@ -21,14 +23,14 @@ class Finder {
|
|
|
21
23
|
}
|
|
22
24
|
findAll(matcher, keySelector, options) {
|
|
23
25
|
const { fuzzy = false, needSorting = true, cacheKey = 'finder-cache', forceBinary = false, caseInsensitive = true, data, } = options ?? {};
|
|
24
|
-
const source =
|
|
26
|
+
const source = (0, non_primitives_1.isFunction)(data) ? data() : (data ?? this.#items);
|
|
25
27
|
if (!source?.length)
|
|
26
28
|
return [];
|
|
27
29
|
const rawGetKey = typeof keySelector === 'function'
|
|
28
30
|
? keySelector
|
|
29
31
|
: (item) => item[keySelector];
|
|
30
32
|
const getKey = Finder.#createMemoizedKeyGetter(rawGetKey);
|
|
31
|
-
const normalizedMatcher = caseInsensitive &&
|
|
33
|
+
const normalizedMatcher = caseInsensitive && (0, primitives_1.isString)(matcher) ? matcher.toLowerCase() : matcher;
|
|
32
34
|
if (cacheKey) {
|
|
33
35
|
const entry = this.#cachedResult.get(cacheKey);
|
|
34
36
|
if (entry && Date.now() - entry.timestamp < this.#ttl) {
|
|
@@ -42,7 +44,7 @@ class Finder {
|
|
|
42
44
|
if (source.length < 100 && !forceBinary) {
|
|
43
45
|
results = source.filter((item) => {
|
|
44
46
|
const key = getKey(item);
|
|
45
|
-
const value = caseInsensitive &&
|
|
47
|
+
const value = caseInsensitive && (0, primitives_1.isString)(key) ? key.toLowerCase() : key;
|
|
46
48
|
return value === normalizedMatcher;
|
|
47
49
|
});
|
|
48
50
|
}
|
|
@@ -51,22 +53,18 @@ class Finder {
|
|
|
51
53
|
const firstMatch = this.binarySearch(sorted, normalizedMatcher, getKey, caseInsensitive);
|
|
52
54
|
if (firstMatch) {
|
|
53
55
|
const baseKey = getKey(firstMatch);
|
|
54
|
-
const base = caseInsensitive &&
|
|
55
|
-
? baseKey.toLowerCase()
|
|
56
|
-
: baseKey;
|
|
56
|
+
const base = caseInsensitive && (0, primitives_1.isString)(baseKey) ? baseKey.toLowerCase() : baseKey;
|
|
57
57
|
results = sorted.filter((item) => {
|
|
58
58
|
const key = getKey(item);
|
|
59
|
-
const value = caseInsensitive &&
|
|
59
|
+
const value = caseInsensitive && (0, primitives_1.isString)(key) ? key.toLowerCase() : key;
|
|
60
60
|
return value === base;
|
|
61
61
|
});
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
|
-
if (!results.length && fuzzy &&
|
|
64
|
+
if (!results.length && fuzzy && (0, primitives_1.isString)(normalizedMatcher)) {
|
|
65
65
|
results = source.filter((item) => {
|
|
66
66
|
const rawKey = getKey(item);
|
|
67
|
-
const key = caseInsensitive &&
|
|
68
|
-
? rawKey.toLowerCase()
|
|
69
|
-
: String(rawKey);
|
|
67
|
+
const key = caseInsensitive && (0, primitives_1.isString)(rawKey) ? rawKey.toLowerCase() : String(rawKey);
|
|
70
68
|
return this.#match(key, normalizedMatcher);
|
|
71
69
|
});
|
|
72
70
|
}
|
|
@@ -80,14 +78,14 @@ class Finder {
|
|
|
80
78
|
}
|
|
81
79
|
findOne(matcher, keySelector, options) {
|
|
82
80
|
const { fuzzy = false, needSorting = true, cacheKey = 'finder-cache', forceBinary = false, caseInsensitive = true, data, } = options ?? {};
|
|
83
|
-
const source =
|
|
81
|
+
const source = (0, non_primitives_1.isFunction)(data) ? data() : (data ?? this.#items);
|
|
84
82
|
if (!source?.length)
|
|
85
83
|
return undefined;
|
|
86
84
|
const rawGetKey = typeof keySelector === 'function'
|
|
87
85
|
? keySelector
|
|
88
86
|
: (item) => item[keySelector];
|
|
89
87
|
const getKey = Finder.#createMemoizedKeyGetter(rawGetKey);
|
|
90
|
-
const normalizedMatcher = caseInsensitive &&
|
|
88
|
+
const normalizedMatcher = caseInsensitive && (0, primitives_1.isString)(matcher) ? matcher.toLowerCase() : matcher;
|
|
91
89
|
if (cacheKey) {
|
|
92
90
|
const entry = this.#cachedResult.get(cacheKey);
|
|
93
91
|
if (entry && Date.now() - entry.timestamp < this.#ttl) {
|
|
@@ -101,14 +99,14 @@ class Finder {
|
|
|
101
99
|
if (source?.length < 100 && !forceBinary) {
|
|
102
100
|
result = source?.find((item) => {
|
|
103
101
|
const key = getKey(item);
|
|
104
|
-
const value = caseInsensitive &&
|
|
102
|
+
const value = caseInsensitive && (0, primitives_1.isString)(key) ? key.toLowerCase() : key;
|
|
105
103
|
return value === normalizedMatcher;
|
|
106
104
|
});
|
|
107
105
|
}
|
|
108
106
|
else {
|
|
109
107
|
result = this.binarySearch(needSorting ? this.#sortAndCache(source, getKey, cacheKey) : source, normalizedMatcher, getKey, caseInsensitive);
|
|
110
108
|
}
|
|
111
|
-
if (!result && fuzzy &&
|
|
109
|
+
if (!result && fuzzy && (0, primitives_1.isString)(normalizedMatcher)) {
|
|
112
110
|
return this.fuzzySearch(source, normalizedMatcher, getKey, caseInsensitive);
|
|
113
111
|
}
|
|
114
112
|
if (cacheKey && result) {
|
|
@@ -132,7 +130,7 @@ class Finder {
|
|
|
132
130
|
while (min <= max) {
|
|
133
131
|
const mid = Math.floor((min + max) / 2);
|
|
134
132
|
const midKey = keySelector(sorted[mid]);
|
|
135
|
-
const key = caseInsensitive &&
|
|
133
|
+
const key = caseInsensitive && (0, primitives_1.isString)(midKey) ? midKey.toLowerCase() : midKey;
|
|
136
134
|
if (key === matcher)
|
|
137
135
|
return sorted[mid];
|
|
138
136
|
if (key < matcher)
|
|
@@ -145,9 +143,7 @@ class Finder {
|
|
|
145
143
|
fuzzySearch(array, matcher, keySelector, caseInsensitive) {
|
|
146
144
|
for (const item of array) {
|
|
147
145
|
const rawKey = keySelector(item);
|
|
148
|
-
const key = caseInsensitive &&
|
|
149
|
-
? rawKey.toLowerCase()
|
|
150
|
-
: String(rawKey);
|
|
146
|
+
const key = caseInsensitive && (0, primitives_1.isString)(rawKey) ? rawKey.toLowerCase() : String(rawKey);
|
|
151
147
|
if (this.#match(key, matcher))
|
|
152
148
|
return item;
|
|
153
149
|
}
|
package/dist/cjs/array/sort.js
CHANGED
|
@@ -36,18 +36,18 @@ function naturalSort(a, b, options) {
|
|
|
36
36
|
for (let i = 0; i < Math.min(aChunks?.length, bChunks?.length); i++) {
|
|
37
37
|
let aChunk = aChunks[i];
|
|
38
38
|
let bChunk = bChunks[i];
|
|
39
|
-
if (caseInsensitive &&
|
|
39
|
+
if (caseInsensitive && (0, primitives_1.isString)(aChunk) && (0, primitives_1.isString)(bChunk)) {
|
|
40
40
|
aChunk = aChunk?.toLowerCase();
|
|
41
41
|
bChunk = bChunk?.toLowerCase();
|
|
42
42
|
}
|
|
43
43
|
if (typeof aChunk !== typeof bChunk) {
|
|
44
|
-
return
|
|
44
|
+
return (0, primitives_1.isString)(aChunk) ? 1 : -1;
|
|
45
45
|
}
|
|
46
46
|
if (aChunk !== bChunk) {
|
|
47
|
-
if (
|
|
47
|
+
if ((0, primitives_1.isNumber)(aChunk) && (0, primitives_1.isNumber)(bChunk)) {
|
|
48
48
|
return aChunk - bChunk;
|
|
49
49
|
}
|
|
50
|
-
if (
|
|
50
|
+
if ((0, primitives_1.isString)(aChunk) && (0, primitives_1.isString)(bChunk)) {
|
|
51
51
|
if (localeAware) {
|
|
52
52
|
const cmp = aChunk.localeCompare(bChunk, undefined, {
|
|
53
53
|
sensitivity: caseInsensitive ? 'accent' : 'variant',
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getColorForInitial = getColorForInitial;
|
|
4
|
+
const primitives_1 = require("../guards/primitives");
|
|
4
5
|
const constants_1 = require("./constants");
|
|
5
6
|
const helpers_1 = require("./helpers");
|
|
6
7
|
const utils_1 = require("./utils");
|
|
@@ -11,7 +12,7 @@ function getColorForInitial(input = '', opacity = 100) {
|
|
|
11
12
|
const DEFAULT = '#010514';
|
|
12
13
|
if (!input)
|
|
13
14
|
return (0, helpers_1._applyOpacity)(DEFAULT, hexOpacity);
|
|
14
|
-
if (
|
|
15
|
+
if ((0, primitives_1.isString)(input)) {
|
|
15
16
|
initial = input[0];
|
|
16
17
|
if (NUMBERS.includes(initial)) {
|
|
17
18
|
return (0, helpers_1._applyOpacity)(constants_1.NUMBER_COLOR_PALETTE[parseInt(initial, 10)], hexOpacity);
|
|
@@ -23,7 +24,7 @@ function getColorForInitial(input = '', opacity = 100) {
|
|
|
23
24
|
}
|
|
24
25
|
return (0, helpers_1._applyOpacity)(DEFAULT, hexOpacity);
|
|
25
26
|
}
|
|
26
|
-
else if (
|
|
27
|
+
else if ((0, primitives_1.isNumber)(input)) {
|
|
27
28
|
initial = input.toString()[0];
|
|
28
29
|
if (NUMBERS.includes(initial)) {
|
|
29
30
|
return (0, helpers_1._applyOpacity)(constants_1.NUMBER_COLOR_PALETTE[parseInt(initial, 10)], hexOpacity);
|
package/dist/cjs/colors/utils.js
CHANGED
|
@@ -38,6 +38,8 @@ function applyOpacityToHex(color, opacity) {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
else {
|
|
41
|
-
throw new TypeError('Invalid color value
|
|
41
|
+
throw new TypeError('Invalid color value!', {
|
|
42
|
+
cause: 'Value must be a hex color string in the format #RRGGBB or #RRGGBBAA.',
|
|
43
|
+
});
|
|
42
44
|
}
|
|
43
45
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.chronusts = exports.chronusjs = exports.chronus = exports.chronosts = exports.chronosjs = exports.chronos = void 0;
|
|
4
|
+
const non_primitives_1 = require("../guards/non-primitives");
|
|
5
|
+
const primitives_1 = require("../guards/primitives");
|
|
4
6
|
const Chronos_1 = require("./Chronos");
|
|
5
7
|
const $chronos = (valueOrYear, month, date, hours, minutes, seconds, ms) => {
|
|
6
|
-
if (
|
|
8
|
+
if ((0, primitives_1.isNumber)(valueOrYear) && (0, primitives_1.isNumber)(month)) {
|
|
7
9
|
return new Chronos_1.Chronos(valueOrYear, month, date ?? 1, hours ?? 0, minutes ?? 0, seconds ?? 0, ms ?? 0);
|
|
8
10
|
}
|
|
9
11
|
else {
|
|
@@ -15,7 +17,7 @@ function _isChronosStaticKey(prop) {
|
|
|
15
17
|
prop !== 'prototype' &&
|
|
16
18
|
prop !== 'name' &&
|
|
17
19
|
prop !== 'length' &&
|
|
18
|
-
|
|
20
|
+
(0, non_primitives_1.isFunction)(Chronos_1.Chronos[prop]));
|
|
19
21
|
}
|
|
20
22
|
exports.chronos = new Proxy($chronos, {
|
|
21
23
|
get(target, prop, receiver) {
|
package/dist/cjs/date/guards.js
CHANGED
|
@@ -7,6 +7,7 @@ exports.isNativeTimeZoneId = isNativeTimeZoneId;
|
|
|
7
7
|
exports.isLeapYear = isLeapYear;
|
|
8
8
|
exports.isDateLike = isDateLike;
|
|
9
9
|
exports.isTimeWithUnit = isTimeWithUnit;
|
|
10
|
+
const non_primitives_1 = require("../guards/non-primitives");
|
|
10
11
|
const primitives_1 = require("../guards/primitives");
|
|
11
12
|
const specials_1 = require("../guards/specials");
|
|
12
13
|
const utilities_1 = require("../number/utilities");
|
|
@@ -37,27 +38,24 @@ function isLeapYear(year) {
|
|
|
37
38
|
function isDateLike(value) {
|
|
38
39
|
if (value instanceof Date)
|
|
39
40
|
return true;
|
|
40
|
-
if (
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
typeof v.toISOString === 'function') {
|
|
41
|
+
if ((0, non_primitives_1.isObject)(value)) {
|
|
42
|
+
if ((0, non_primitives_1.isFunction)(value.format) &&
|
|
43
|
+
(0, non_primitives_1.isFunction)(value.toJSON) &&
|
|
44
|
+
(0, non_primitives_1.isFunction)(value.toISOString)) {
|
|
45
45
|
return true;
|
|
46
46
|
}
|
|
47
|
-
if (
|
|
48
|
-
typeof v.toFormat === 'function' &&
|
|
49
|
-
typeof v.isValid === 'boolean') {
|
|
47
|
+
if ((0, non_primitives_1.isFunction)(value.toISO) && (0, non_primitives_1.isFunction)(value.toFormat) && (0, primitives_1.isBoolean)(value.isValid)) {
|
|
50
48
|
return true;
|
|
51
49
|
}
|
|
52
|
-
if (
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
50
|
+
if ((0, non_primitives_1.isFunction)(value.plus) &&
|
|
51
|
+
(0, non_primitives_1.isFunction)(value.minus) &&
|
|
52
|
+
(0, non_primitives_1.isFunction)(value.equals) &&
|
|
53
|
+
(0, non_primitives_1.isFunction)(value.getClass)) {
|
|
56
54
|
return true;
|
|
57
55
|
}
|
|
58
|
-
if (
|
|
59
|
-
|
|
60
|
-
['PlainDate', 'ZonedDateTime', 'Instant'].includes(
|
|
56
|
+
if ((0, non_primitives_1.isFunction)(value.toJSON) &&
|
|
57
|
+
(0, non_primitives_1.isFunction)(value.toString) &&
|
|
58
|
+
['PlainDate', 'ZonedDateTime', 'Instant'].includes(value.constructor?.name ?? '')) {
|
|
61
59
|
return true;
|
|
62
60
|
}
|
|
63
61
|
}
|
package/dist/cjs/date/utils.js
CHANGED
|
@@ -15,6 +15,8 @@ exports.formatTimePart = formatTimePart;
|
|
|
15
15
|
exports.formatDateRelative = formatDateRelative;
|
|
16
16
|
exports.getTimestamp = getTimestamp;
|
|
17
17
|
const non_primitives_1 = require("../guards/non-primitives");
|
|
18
|
+
const primitives_1 = require("../guards/primitives");
|
|
19
|
+
const utilities_1 = require("../number/utilities");
|
|
18
20
|
const guards_1 = require("./guards");
|
|
19
21
|
const helpers_1 = require("./helpers");
|
|
20
22
|
const timezone_1 = require("./timezone");
|
|
@@ -38,13 +40,24 @@ function extractMinutesFromUTC(utc) {
|
|
|
38
40
|
return getTotalMinutes(extractTimeFromUTC(utc));
|
|
39
41
|
}
|
|
40
42
|
function convertMinutesToTime(minutes) {
|
|
41
|
-
const
|
|
43
|
+
const parsed = (0, utilities_1.normalizeNumber)(minutes);
|
|
44
|
+
if ((0, primitives_1.isUndefined)(parsed)) {
|
|
45
|
+
throw new TypeError(`Invalid numeric input!`, {
|
|
46
|
+
cause: `${minutes} cannot be converted to a number.`,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
const numMIn = Math.abs(parsed);
|
|
42
50
|
return `${String(Math.floor(numMIn / 60))}:${String(numMIn % 60).padStart(2, '0')}`;
|
|
43
51
|
}
|
|
44
52
|
function formatUTCOffset(minutes) {
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
53
|
+
const parsed = (0, utilities_1.normalizeNumber)(minutes);
|
|
54
|
+
if ((0, primitives_1.isUndefined)(parsed)) {
|
|
55
|
+
throw new TypeError(`Invalid numeric input!`, {
|
|
56
|
+
cause: `${minutes} cannot be converted to a number.`,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
const sign = parsed < 0 ? '-' : '+';
|
|
60
|
+
const abs = Math.abs(parsed);
|
|
48
61
|
const hours = String(Math.floor(abs / 60)).padStart(2, '0');
|
|
49
62
|
const mins = String(abs % 60).padStart(2, '0');
|
|
50
63
|
return `UTC${sign}${hours}:${mins}`;
|
package/dist/cjs/dom/query.js
CHANGED
|
@@ -5,22 +5,19 @@ exports.getQueryParams = getQueryParams;
|
|
|
5
5
|
exports.updateQueryParam = updateQueryParam;
|
|
6
6
|
exports.parseQueryString = parseQueryString;
|
|
7
7
|
exports.parseQueryStringLiteral = parseQueryStringLiteral;
|
|
8
|
+
const primitives_1 = require("../guards/primitives");
|
|
8
9
|
const objectify_1 = require("../object/objectify");
|
|
9
10
|
const sanitize_1 = require("../object/sanitize");
|
|
10
11
|
const index_1 = require("../utils/index");
|
|
11
12
|
function generateQueryParams(params = {}) {
|
|
12
13
|
const flattenedParams = (0, objectify_1.flattenObjectKeyValue)(params);
|
|
13
14
|
const queryParams = Object.entries(flattenedParams)
|
|
14
|
-
?.filter(([_, value]) => value
|
|
15
|
-
value !== null &&
|
|
16
|
-
!(typeof value === 'string' && value?.trim() === ''))
|
|
15
|
+
?.filter(([_, value]) => value != null && !((0, primitives_1.isString)(value) && value?.trim() === ''))
|
|
17
16
|
?.flatMap(([key, value]) => Array.isArray(value)
|
|
18
17
|
? value
|
|
19
|
-
?.filter((v) => v
|
|
20
|
-
v
|
|
21
|
-
|
|
22
|
-
?.map((v) => `${encodeURIComponent(key)}=${encodeURIComponent(typeof v === 'boolean' ? String(v) : String(v))}`)
|
|
23
|
-
: `${encodeURIComponent(key)}=${encodeURIComponent(typeof value === 'boolean' ? String(value) : String(value))}`)
|
|
18
|
+
?.filter((v) => v != null && !((0, primitives_1.isString)(v) && v.trim() === ''))
|
|
19
|
+
?.map((v) => `${encodeURIComponent(key)}=${encodeURIComponent(String(v))}`)
|
|
20
|
+
: `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)
|
|
24
21
|
.join('&');
|
|
25
22
|
return queryParams ? `?${queryParams}` : '';
|
|
26
23
|
}
|
package/dist/cjs/form/convert.js
CHANGED
|
@@ -70,7 +70,7 @@ const createControlledFormData = (data, configs) => {
|
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
else {
|
|
73
|
-
if (
|
|
73
|
+
if ((0, primitives_1.isString)(value)) {
|
|
74
74
|
if ((0, primitives_1.isNonEmptyString)(value)) {
|
|
75
75
|
let cleanString = value;
|
|
76
76
|
if (configs?.trimStrings) {
|
|
@@ -175,7 +175,7 @@ const createControlledFormData = (data, configs) => {
|
|
|
175
175
|
else {
|
|
176
176
|
const isNotNullish = value != null && value !== '';
|
|
177
177
|
if (isNotNullish || _isRequiredKey(key)) {
|
|
178
|
-
if (
|
|
178
|
+
if ((0, primitives_1.isString)(value) && _shouldLowercaseValue(key)) {
|
|
179
179
|
formData.append(transformedKey, value?.toLowerCase());
|
|
180
180
|
}
|
|
181
181
|
else {
|
package/dist/cjs/form/guards.js
CHANGED
|
@@ -8,6 +8,7 @@ exports.isFileArray = isFileArray;
|
|
|
8
8
|
exports.isFileList = isFileList;
|
|
9
9
|
exports.isFileOrBlob = isFileOrBlob;
|
|
10
10
|
exports.isFileUpload = isFileUpload;
|
|
11
|
+
const primitives_1 = require("../guards/primitives");
|
|
11
12
|
function isValidFormData(value) {
|
|
12
13
|
if (!(value instanceof FormData))
|
|
13
14
|
return false;
|
|
@@ -25,7 +26,7 @@ function isOriginFileObj(value) {
|
|
|
25
26
|
return false;
|
|
26
27
|
}
|
|
27
28
|
const obj = value;
|
|
28
|
-
return
|
|
29
|
+
return (0, primitives_1.isString)(obj.uid);
|
|
29
30
|
}
|
|
30
31
|
function isCustomFile(value) {
|
|
31
32
|
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.serializeForm = serializeForm;
|
|
4
4
|
exports.parseFormData = parseFormData;
|
|
5
5
|
const query_1 = require("../dom/query");
|
|
6
|
+
const primitives_1 = require("../guards/primitives");
|
|
6
7
|
const sanitize_1 = require("../object/sanitize");
|
|
7
8
|
function serializeForm(form, toQueryString = false) {
|
|
8
9
|
const formData = new FormData(form);
|
|
@@ -25,11 +26,11 @@ function serializeForm(form, toQueryString = false) {
|
|
|
25
26
|
}
|
|
26
27
|
function parseFormData(data, parsePrimitives = true) {
|
|
27
28
|
const parsed = {};
|
|
28
|
-
if (
|
|
29
|
+
if ((0, primitives_1.isString)(data)) {
|
|
29
30
|
const params = new URLSearchParams(data);
|
|
30
31
|
params?.forEach((value, key) => {
|
|
31
32
|
const existing = parsed[key];
|
|
32
|
-
if (
|
|
33
|
+
if ((0, primitives_1.isString)(existing)) {
|
|
33
34
|
parsed[key] = [existing, value];
|
|
34
35
|
}
|
|
35
36
|
else if (Array.isArray(existing)) {
|
|
@@ -55,7 +56,7 @@ function parseFormData(data, parsePrimitives = true) {
|
|
|
55
56
|
}
|
|
56
57
|
}
|
|
57
58
|
else {
|
|
58
|
-
if (
|
|
59
|
+
if ((0, primitives_1.isString)(existing)) {
|
|
59
60
|
parsed[key] = [existing, value];
|
|
60
61
|
}
|
|
61
62
|
else if (Array.isArray(existing)) {
|
|
@@ -43,10 +43,13 @@ const getRandomNumber = (options) => {
|
|
|
43
43
|
exports.getRandomNumber = getRandomNumber;
|
|
44
44
|
const convertToDecimal = (input, options) => {
|
|
45
45
|
const { decimalPlaces = 2, isString = false } = options || {};
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
const parsed = (0, utilities_1.normalizeNumber)(input);
|
|
47
|
+
if ((0, primitives_1.isUndefined)(parsed)) {
|
|
48
|
+
throw new TypeError(`Invalid numeric input!`, {
|
|
49
|
+
cause: `${input} cannot be converted to a number.`,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return (isString ? parsed.toFixed(decimalPlaces) : Number(parsed.toFixed(decimalPlaces)));
|
|
50
53
|
};
|
|
51
54
|
exports.convertToDecimal = convertToDecimal;
|
|
52
55
|
const calculateHCF = (...numbers) => {
|
|
@@ -117,7 +120,7 @@ function getAverage(...numbers) {
|
|
|
117
120
|
let count = 0;
|
|
118
121
|
for (const n of numbers) {
|
|
119
122
|
const num = Number(n);
|
|
120
|
-
if (
|
|
123
|
+
if ((0, primitives_1.isNumber)(num)) {
|
|
121
124
|
sum += num;
|
|
122
125
|
count++;
|
|
123
126
|
}
|
|
@@ -4,12 +4,20 @@ exports.isMultiple = exports.isOdd = exports.isEven = void 0;
|
|
|
4
4
|
exports.isPerfectSquare = isPerfectSquare;
|
|
5
5
|
exports.isFibonacci = isFibonacci;
|
|
6
6
|
exports.areInvalidNumbers = areInvalidNumbers;
|
|
7
|
+
const primitives_1 = require("../guards/primitives");
|
|
8
|
+
const utilities_1 = require("./utilities");
|
|
7
9
|
const isEven = (input) => {
|
|
8
|
-
|
|
10
|
+
const parsed = (0, utilities_1.normalizeNumber)(input);
|
|
11
|
+
if ((0, primitives_1.isUndefined)(parsed))
|
|
12
|
+
return false;
|
|
13
|
+
return parsed % 2 === 0;
|
|
9
14
|
};
|
|
10
15
|
exports.isEven = isEven;
|
|
11
16
|
const isOdd = (input) => {
|
|
12
|
-
|
|
17
|
+
const parsed = (0, utilities_1.normalizeNumber)(input);
|
|
18
|
+
if ((0, primitives_1.isUndefined)(parsed))
|
|
19
|
+
return false;
|
|
20
|
+
return parsed % 2 !== 0;
|
|
13
21
|
};
|
|
14
22
|
exports.isOdd = isOdd;
|
|
15
23
|
const isMultiple = (input, multipleOf) => {
|
package/dist/cjs/number/range.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getNumbersInRange = getNumbersInRange;
|
|
4
4
|
const basics_1 = require("../array/basics");
|
|
5
|
+
const primitives_1 = require("../guards/primitives");
|
|
5
6
|
const index_1 = require("../utils/index");
|
|
6
7
|
const basics_2 = require("./basics");
|
|
7
8
|
const guards_1 = require("./guards");
|
|
@@ -27,7 +28,7 @@ function getNumbersInRange(type = 'any', options) {
|
|
|
27
28
|
}
|
|
28
29
|
return numbers;
|
|
29
30
|
};
|
|
30
|
-
if (type === 'prime' &&
|
|
31
|
+
if (type === 'prime' && !(0, primitives_1.isUndefined)(multiplesOf)) {
|
|
31
32
|
console.warn('Warning: The "multiplesOf" option is ignored when the type is "prime"!');
|
|
32
33
|
}
|
|
33
34
|
switch (type) {
|
|
@@ -58,7 +59,5 @@ function getNumbersInRange(type = 'any', options) {
|
|
|
58
59
|
if (type !== 'prime') {
|
|
59
60
|
output = (0, helpers_1._applyMultiples)(output, multiplesOf);
|
|
60
61
|
}
|
|
61
|
-
return getAsString
|
|
62
|
-
? (0, index_1.convertArrayToString)(output, { separator })
|
|
63
|
-
: output;
|
|
62
|
+
return (getAsString ? (0, index_1.convertArrayToString)(output, { separator }) : output);
|
|
64
63
|
}
|
|
@@ -71,7 +71,7 @@ class Pluralizer {
|
|
|
71
71
|
}
|
|
72
72
|
#isUncountable(word) {
|
|
73
73
|
for (const entry of this.#uncountables) {
|
|
74
|
-
if (
|
|
74
|
+
if ((0, primitives_1.isString)(entry)) {
|
|
75
75
|
if (entry.toLowerCase() === word)
|
|
76
76
|
return true;
|
|
77
77
|
}
|
|
@@ -89,7 +89,7 @@ class Pluralizer {
|
|
|
89
89
|
this.#singularRules.push([rule, replacement]);
|
|
90
90
|
}
|
|
91
91
|
addUncountable(word) {
|
|
92
|
-
this.#uncountables.add(
|
|
92
|
+
this.#uncountables.add((0, primitives_1.isString)(word) ? word?.toLowerCase() : word);
|
|
93
93
|
}
|
|
94
94
|
addIrregular(single, plural) {
|
|
95
95
|
const singleLower = single?.toLowerCase();
|
|
@@ -99,7 +99,7 @@ class Pluralizer {
|
|
|
99
99
|
}
|
|
100
100
|
pluralize(word, options = {}) {
|
|
101
101
|
const count = (0, utilities_1.normalizeNumber)(options?.count);
|
|
102
|
-
if (
|
|
102
|
+
if (!(0, primitives_1.isUndefined)(count)) {
|
|
103
103
|
const pluralized = count === 1 ? this.toSingular(word) : this.toPlural(word);
|
|
104
104
|
return options?.inclusive ? `${count} ${pluralized}` : pluralized;
|
|
105
105
|
}
|
|
@@ -5,10 +5,11 @@ exports.normalizeString = normalizeString;
|
|
|
5
5
|
exports.extractEmails = extractEmails;
|
|
6
6
|
exports.extractURLs = extractURLs;
|
|
7
7
|
exports.formatUnitWithPlural = formatUnitWithPlural;
|
|
8
|
+
const primitives_1 = require("../guards/primitives");
|
|
8
9
|
const basics_1 = require("./basics");
|
|
9
10
|
const replaceAllInString = (input, find, replace) => {
|
|
10
11
|
const trimmedString = (0, basics_1.trimString)(input);
|
|
11
|
-
const regex =
|
|
12
|
+
const regex = (0, primitives_1.isString)(find)
|
|
12
13
|
? new RegExp(find, 'g')
|
|
13
14
|
: new RegExp(find, find?.flags.includes('g') ? find?.flags : find?.flags + 'g');
|
|
14
15
|
return trimmedString?.replace(regex, replace);
|
package/dist/cjs/utils/index.js
CHANGED
|
@@ -198,7 +198,7 @@ function deepParsePrimitives(input) {
|
|
|
198
198
|
return input;
|
|
199
199
|
}
|
|
200
200
|
function definePrototypeMethod(proto, name, impl, options) {
|
|
201
|
-
const alreadyExists = Object.
|
|
201
|
+
const alreadyExists = Object.hasOwn(proto, name);
|
|
202
202
|
if (alreadyExists && !options?.overwrite)
|
|
203
203
|
return;
|
|
204
204
|
Object.defineProperty(proto, name, {
|
|
@@ -14,4 +14,4 @@ import { $Volume } from './volume';
|
|
|
14
14
|
* The returned instance exposes only methods relevant to the provided unit type.
|
|
15
15
|
*/
|
|
16
16
|
export declare function Converter<U extends $Unit>(value: Numeric, unit?: U): Converted<U>;
|
|
17
|
-
export { $Area as AreaConverter,
|
|
17
|
+
export { $Area as AreaConverter, $Data as DataConverter, $Length as LengthConverter, $Mass as MassConverter, $Temperature as TemperatureConverter, $Time as TimeConverter, $Volume as VolumeConverter, Converter as converter, };
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
+
import type { Numeric } from '../types/index';
|
|
1
2
|
/**
|
|
2
3
|
* * Check if a number is even or not.
|
|
3
4
|
*
|
|
4
|
-
* @param input The number to check.
|
|
5
|
+
* @param input The number or numeric string to check.
|
|
5
6
|
* @returns Boolean: `true` if even and `false` if not even.
|
|
6
7
|
*/
|
|
7
|
-
export declare const isEven: (input:
|
|
8
|
+
export declare const isEven: (input: Numeric) => boolean;
|
|
8
9
|
/**
|
|
9
10
|
* * Checks if a number is odd or not.
|
|
10
11
|
*
|
|
11
|
-
* @param input The number to check.
|
|
12
|
+
* @param input The number or numeric string to check.
|
|
12
13
|
* @returns Boolean: `true` if odd and `false` if not odd.
|
|
13
14
|
*/
|
|
14
|
-
export declare const isOdd: (input:
|
|
15
|
+
export declare const isOdd: (input: Numeric) => boolean;
|
|
15
16
|
/**
|
|
16
17
|
* * Checks if a number is a multiple of another number.
|
|
17
18
|
*
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { NumberType, RangedNumbers, RangeOptions } from './types';
|
|
2
2
|
/**
|
|
3
|
-
* * Function to get numbers within a range based on the provided
|
|
4
|
-
*
|
|
3
|
+
* * Function to get numbers within a range based on the provided {@link NumberType} and options.
|
|
4
|
+
*
|
|
5
|
+
* @remarks Returns either string or array of numbers based on the {@link RangeOptions.getAsString getAsString} option.
|
|
5
6
|
*
|
|
6
7
|
* @param type - The type of numbers to generate ('random', 'prime', etc.).
|
|
7
8
|
* @param options - Options to configure number generation, including range and formatting.
|
|
8
|
-
* @returns
|
|
9
|
+
* @returns The numbers in the range based on {@link type} and {@link options} either as string or array of numbers.
|
|
9
10
|
*/
|
|
10
11
|
export declare function getNumbersInRange<T extends boolean = false>(type?: NumberType, options?: RangeOptions<T>): RangedNumbers<T>;
|
package/dist/esm/array/Finder.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { isFunction } from '../guards/non-primitives.js';
|
|
2
|
+
import { isString } from '../guards/primitives.js';
|
|
1
3
|
export class Finder {
|
|
2
4
|
static #DEFAULT_TTL = 1000 * 60 * 5;
|
|
3
5
|
#cachedResult = new Map();
|
|
@@ -6,7 +8,7 @@ export class Finder {
|
|
|
6
8
|
#items;
|
|
7
9
|
constructor(data, ttl = Finder.#DEFAULT_TTL) {
|
|
8
10
|
this.#ttl = ttl;
|
|
9
|
-
this.#items =
|
|
11
|
+
this.#items = isFunction(data) ? data() : data;
|
|
10
12
|
}
|
|
11
13
|
clearCache(key) {
|
|
12
14
|
if (key) {
|
|
@@ -18,14 +20,14 @@ export class Finder {
|
|
|
18
20
|
}
|
|
19
21
|
findAll(matcher, keySelector, options) {
|
|
20
22
|
const { fuzzy = false, needSorting = true, cacheKey = 'finder-cache', forceBinary = false, caseInsensitive = true, data, } = options ?? {};
|
|
21
|
-
const source =
|
|
23
|
+
const source = isFunction(data) ? data() : (data ?? this.#items);
|
|
22
24
|
if (!source?.length)
|
|
23
25
|
return [];
|
|
24
26
|
const rawGetKey = typeof keySelector === 'function'
|
|
25
27
|
? keySelector
|
|
26
28
|
: (item) => item[keySelector];
|
|
27
29
|
const getKey = Finder.#createMemoizedKeyGetter(rawGetKey);
|
|
28
|
-
const normalizedMatcher = caseInsensitive &&
|
|
30
|
+
const normalizedMatcher = caseInsensitive && isString(matcher) ? matcher.toLowerCase() : matcher;
|
|
29
31
|
if (cacheKey) {
|
|
30
32
|
const entry = this.#cachedResult.get(cacheKey);
|
|
31
33
|
if (entry && Date.now() - entry.timestamp < this.#ttl) {
|
|
@@ -39,7 +41,7 @@ export class Finder {
|
|
|
39
41
|
if (source.length < 100 && !forceBinary) {
|
|
40
42
|
results = source.filter((item) => {
|
|
41
43
|
const key = getKey(item);
|
|
42
|
-
const value = caseInsensitive &&
|
|
44
|
+
const value = caseInsensitive && isString(key) ? key.toLowerCase() : key;
|
|
43
45
|
return value === normalizedMatcher;
|
|
44
46
|
});
|
|
45
47
|
}
|
|
@@ -48,22 +50,18 @@ export class Finder {
|
|
|
48
50
|
const firstMatch = this.binarySearch(sorted, normalizedMatcher, getKey, caseInsensitive);
|
|
49
51
|
if (firstMatch) {
|
|
50
52
|
const baseKey = getKey(firstMatch);
|
|
51
|
-
const base = caseInsensitive &&
|
|
52
|
-
? baseKey.toLowerCase()
|
|
53
|
-
: baseKey;
|
|
53
|
+
const base = caseInsensitive && isString(baseKey) ? baseKey.toLowerCase() : baseKey;
|
|
54
54
|
results = sorted.filter((item) => {
|
|
55
55
|
const key = getKey(item);
|
|
56
|
-
const value = caseInsensitive &&
|
|
56
|
+
const value = caseInsensitive && isString(key) ? key.toLowerCase() : key;
|
|
57
57
|
return value === base;
|
|
58
58
|
});
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
-
if (!results.length && fuzzy &&
|
|
61
|
+
if (!results.length && fuzzy && isString(normalizedMatcher)) {
|
|
62
62
|
results = source.filter((item) => {
|
|
63
63
|
const rawKey = getKey(item);
|
|
64
|
-
const key = caseInsensitive &&
|
|
65
|
-
? rawKey.toLowerCase()
|
|
66
|
-
: String(rawKey);
|
|
64
|
+
const key = caseInsensitive && isString(rawKey) ? rawKey.toLowerCase() : String(rawKey);
|
|
67
65
|
return this.#match(key, normalizedMatcher);
|
|
68
66
|
});
|
|
69
67
|
}
|
|
@@ -77,14 +75,14 @@ export class Finder {
|
|
|
77
75
|
}
|
|
78
76
|
findOne(matcher, keySelector, options) {
|
|
79
77
|
const { fuzzy = false, needSorting = true, cacheKey = 'finder-cache', forceBinary = false, caseInsensitive = true, data, } = options ?? {};
|
|
80
|
-
const source =
|
|
78
|
+
const source = isFunction(data) ? data() : (data ?? this.#items);
|
|
81
79
|
if (!source?.length)
|
|
82
80
|
return undefined;
|
|
83
81
|
const rawGetKey = typeof keySelector === 'function'
|
|
84
82
|
? keySelector
|
|
85
83
|
: (item) => item[keySelector];
|
|
86
84
|
const getKey = Finder.#createMemoizedKeyGetter(rawGetKey);
|
|
87
|
-
const normalizedMatcher = caseInsensitive &&
|
|
85
|
+
const normalizedMatcher = caseInsensitive && isString(matcher) ? matcher.toLowerCase() : matcher;
|
|
88
86
|
if (cacheKey) {
|
|
89
87
|
const entry = this.#cachedResult.get(cacheKey);
|
|
90
88
|
if (entry && Date.now() - entry.timestamp < this.#ttl) {
|
|
@@ -98,14 +96,14 @@ export class Finder {
|
|
|
98
96
|
if (source?.length < 100 && !forceBinary) {
|
|
99
97
|
result = source?.find((item) => {
|
|
100
98
|
const key = getKey(item);
|
|
101
|
-
const value = caseInsensitive &&
|
|
99
|
+
const value = caseInsensitive && isString(key) ? key.toLowerCase() : key;
|
|
102
100
|
return value === normalizedMatcher;
|
|
103
101
|
});
|
|
104
102
|
}
|
|
105
103
|
else {
|
|
106
104
|
result = this.binarySearch(needSorting ? this.#sortAndCache(source, getKey, cacheKey) : source, normalizedMatcher, getKey, caseInsensitive);
|
|
107
105
|
}
|
|
108
|
-
if (!result && fuzzy &&
|
|
106
|
+
if (!result && fuzzy && isString(normalizedMatcher)) {
|
|
109
107
|
return this.fuzzySearch(source, normalizedMatcher, getKey, caseInsensitive);
|
|
110
108
|
}
|
|
111
109
|
if (cacheKey && result) {
|
|
@@ -129,7 +127,7 @@ export class Finder {
|
|
|
129
127
|
while (min <= max) {
|
|
130
128
|
const mid = Math.floor((min + max) / 2);
|
|
131
129
|
const midKey = keySelector(sorted[mid]);
|
|
132
|
-
const key = caseInsensitive &&
|
|
130
|
+
const key = caseInsensitive && isString(midKey) ? midKey.toLowerCase() : midKey;
|
|
133
131
|
if (key === matcher)
|
|
134
132
|
return sorted[mid];
|
|
135
133
|
if (key < matcher)
|
|
@@ -142,9 +140,7 @@ export class Finder {
|
|
|
142
140
|
fuzzySearch(array, matcher, keySelector, caseInsensitive) {
|
|
143
141
|
for (const item of array) {
|
|
144
142
|
const rawKey = keySelector(item);
|
|
145
|
-
const key = caseInsensitive &&
|
|
146
|
-
? rawKey.toLowerCase()
|
|
147
|
-
: String(rawKey);
|
|
143
|
+
const key = caseInsensitive && isString(rawKey) ? rawKey.toLowerCase() : String(rawKey);
|
|
148
144
|
if (this.#match(key, matcher))
|
|
149
145
|
return item;
|
|
150
146
|
}
|
package/dist/esm/array/sort.js
CHANGED
|
@@ -32,18 +32,18 @@ export function naturalSort(a, b, options) {
|
|
|
32
32
|
for (let i = 0; i < Math.min(aChunks?.length, bChunks?.length); i++) {
|
|
33
33
|
let aChunk = aChunks[i];
|
|
34
34
|
let bChunk = bChunks[i];
|
|
35
|
-
if (caseInsensitive &&
|
|
35
|
+
if (caseInsensitive && isString(aChunk) && isString(bChunk)) {
|
|
36
36
|
aChunk = aChunk?.toLowerCase();
|
|
37
37
|
bChunk = bChunk?.toLowerCase();
|
|
38
38
|
}
|
|
39
39
|
if (typeof aChunk !== typeof bChunk) {
|
|
40
|
-
return
|
|
40
|
+
return isString(aChunk) ? 1 : -1;
|
|
41
41
|
}
|
|
42
42
|
if (aChunk !== bChunk) {
|
|
43
|
-
if (
|
|
43
|
+
if (isNumber(aChunk) && isNumber(bChunk)) {
|
|
44
44
|
return aChunk - bChunk;
|
|
45
45
|
}
|
|
46
|
-
if (
|
|
46
|
+
if (isString(aChunk) && isString(bChunk)) {
|
|
47
47
|
if (localeAware) {
|
|
48
48
|
const cmp = aChunk.localeCompare(bChunk, undefined, {
|
|
49
49
|
sensitivity: caseInsensitive ? 'accent' : 'variant',
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isNumber, isString } from '../guards/primitives.js';
|
|
1
2
|
import { ALPHABET_COLOR_PALETTE, NUMBER_COLOR_PALETTE } from './constants.js';
|
|
2
3
|
import { _applyOpacity } from './helpers.js';
|
|
3
4
|
import { percentToHex } from './utils.js';
|
|
@@ -8,7 +9,7 @@ export function getColorForInitial(input = '', opacity = 100) {
|
|
|
8
9
|
const DEFAULT = '#010514';
|
|
9
10
|
if (!input)
|
|
10
11
|
return _applyOpacity(DEFAULT, hexOpacity);
|
|
11
|
-
if (
|
|
12
|
+
if (isString(input)) {
|
|
12
13
|
initial = input[0];
|
|
13
14
|
if (NUMBERS.includes(initial)) {
|
|
14
15
|
return _applyOpacity(NUMBER_COLOR_PALETTE[parseInt(initial, 10)], hexOpacity);
|
|
@@ -20,7 +21,7 @@ export function getColorForInitial(input = '', opacity = 100) {
|
|
|
20
21
|
}
|
|
21
22
|
return _applyOpacity(DEFAULT, hexOpacity);
|
|
22
23
|
}
|
|
23
|
-
else if (
|
|
24
|
+
else if (isNumber(input)) {
|
|
24
25
|
initial = input.toString()[0];
|
|
25
26
|
if (NUMBERS.includes(initial)) {
|
|
26
27
|
return _applyOpacity(NUMBER_COLOR_PALETTE[parseInt(initial, 10)], hexOpacity);
|
package/dist/esm/colors/utils.js
CHANGED
|
@@ -32,6 +32,8 @@ export function applyOpacityToHex(color, opacity) {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
else {
|
|
35
|
-
throw new TypeError('Invalid color value
|
|
35
|
+
throw new TypeError('Invalid color value!', {
|
|
36
|
+
cause: 'Value must be a hex color string in the format #RRGGBB or #RRGGBBAA.',
|
|
37
|
+
});
|
|
36
38
|
}
|
|
37
39
|
}
|
|
@@ -36,4 +36,4 @@ export function Converter(value, unit) {
|
|
|
36
36
|
return new $BaseConverter(value, unit);
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
-
export { $Area as AreaConverter,
|
|
39
|
+
export { $Area as AreaConverter, $Data as DataConverter, $Length as LengthConverter, $Mass as MassConverter, $Temperature as TemperatureConverter, $Time as TimeConverter, $Volume as VolumeConverter, Converter as converter, };
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { isFunction } from '../guards/non-primitives.js';
|
|
2
|
+
import { isNumber } from '../guards/primitives.js';
|
|
1
3
|
import { Chronos } from './Chronos.js';
|
|
2
4
|
const $chronos = (valueOrYear, month, date, hours, minutes, seconds, ms) => {
|
|
3
|
-
if (
|
|
5
|
+
if (isNumber(valueOrYear) && isNumber(month)) {
|
|
4
6
|
return new Chronos(valueOrYear, month, date ?? 1, hours ?? 0, minutes ?? 0, seconds ?? 0, ms ?? 0);
|
|
5
7
|
}
|
|
6
8
|
else {
|
|
@@ -12,7 +14,7 @@ function _isChronosStaticKey(prop) {
|
|
|
12
14
|
prop !== 'prototype' &&
|
|
13
15
|
prop !== 'name' &&
|
|
14
16
|
prop !== 'length' &&
|
|
15
|
-
|
|
17
|
+
isFunction(Chronos[prop]));
|
|
16
18
|
}
|
|
17
19
|
export const chronos = new Proxy($chronos, {
|
|
18
20
|
get(target, prop, receiver) {
|
package/dist/esm/date/guards.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isFunction, isObject } from '../guards/non-primitives.js';
|
|
2
|
+
import { isBoolean, isNonEmptyString, isString } from '../guards/primitives.js';
|
|
2
3
|
import { isNumericString } from '../guards/specials.js';
|
|
3
4
|
import { normalizeNumber } from '../number/utilities.js';
|
|
4
5
|
import { IANA_TZ_IDS, NATIVE_TZ_IDS } from './timezone.js';
|
|
@@ -28,27 +29,24 @@ export function isLeapYear(year) {
|
|
|
28
29
|
export function isDateLike(value) {
|
|
29
30
|
if (value instanceof Date)
|
|
30
31
|
return true;
|
|
31
|
-
if (value
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
typeof v.toISOString === 'function') {
|
|
32
|
+
if (isObject(value)) {
|
|
33
|
+
if (isFunction(value.format) &&
|
|
34
|
+
isFunction(value.toJSON) &&
|
|
35
|
+
isFunction(value.toISOString)) {
|
|
36
36
|
return true;
|
|
37
37
|
}
|
|
38
|
-
if (
|
|
39
|
-
typeof v.toFormat === 'function' &&
|
|
40
|
-
typeof v.isValid === 'boolean') {
|
|
38
|
+
if (isFunction(value.toISO) && isFunction(value.toFormat) && isBoolean(value.isValid)) {
|
|
41
39
|
return true;
|
|
42
40
|
}
|
|
43
|
-
if (
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
if (isFunction(value.plus) &&
|
|
42
|
+
isFunction(value.minus) &&
|
|
43
|
+
isFunction(value.equals) &&
|
|
44
|
+
isFunction(value.getClass)) {
|
|
47
45
|
return true;
|
|
48
46
|
}
|
|
49
|
-
if (
|
|
50
|
-
|
|
51
|
-
['PlainDate', 'ZonedDateTime', 'Instant'].includes(
|
|
47
|
+
if (isFunction(value.toJSON) &&
|
|
48
|
+
isFunction(value.toString) &&
|
|
49
|
+
['PlainDate', 'ZonedDateTime', 'Instant'].includes(value.constructor?.name ?? '')) {
|
|
52
50
|
return true;
|
|
53
51
|
}
|
|
54
52
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { INTERNALS } from '../constants.js';
|
|
2
2
|
import { isValidUTCOffset } from '../guards.js';
|
|
3
3
|
import { _gmtToUtcOffset, _resolveNativeTzName } from '../helpers.js';
|
|
4
|
-
import { NATIVE_TZ_IDS,
|
|
4
|
+
import { NATIVE_TZ_IDS, TIME_ZONE_LABELS, TIME_ZONES } from '../timezone.js';
|
|
5
5
|
import { extractMinutesFromUTC } from '../utils.js';
|
|
6
6
|
export const timeZonePlugin = ($Chronos) => {
|
|
7
7
|
const { internalDate: $Date, withOrigin, offset } = $Chronos[INTERNALS];
|
package/dist/esm/date/utils.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { isObject } from '../guards/non-primitives.js';
|
|
2
|
+
import { isUndefined } from '../guards/primitives.js';
|
|
3
|
+
import { normalizeNumber } from '../number/utilities.js';
|
|
2
4
|
import { isValidUTCOffset } from './guards.js';
|
|
3
5
|
import { _dateArgsToDate, _formatDate, _gmtToUtcOffset, _normalizeOffset, _resolveNativeTzName, } from './helpers.js';
|
|
4
6
|
import { NATIVE_TZ_IDS } from './timezone.js';
|
|
@@ -22,13 +24,24 @@ export function extractMinutesFromUTC(utc) {
|
|
|
22
24
|
return getTotalMinutes(extractTimeFromUTC(utc));
|
|
23
25
|
}
|
|
24
26
|
export function convertMinutesToTime(minutes) {
|
|
25
|
-
const
|
|
27
|
+
const parsed = normalizeNumber(minutes);
|
|
28
|
+
if (isUndefined(parsed)) {
|
|
29
|
+
throw new TypeError(`Invalid numeric input!`, {
|
|
30
|
+
cause: `${minutes} cannot be converted to a number.`,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
const numMIn = Math.abs(parsed);
|
|
26
34
|
return `${String(Math.floor(numMIn / 60))}:${String(numMIn % 60).padStart(2, '0')}`;
|
|
27
35
|
}
|
|
28
36
|
export function formatUTCOffset(minutes) {
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
37
|
+
const parsed = normalizeNumber(minutes);
|
|
38
|
+
if (isUndefined(parsed)) {
|
|
39
|
+
throw new TypeError(`Invalid numeric input!`, {
|
|
40
|
+
cause: `${minutes} cannot be converted to a number.`,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
const sign = parsed < 0 ? '-' : '+';
|
|
44
|
+
const abs = Math.abs(parsed);
|
|
32
45
|
const hours = String(Math.floor(abs / 60)).padStart(2, '0');
|
|
33
46
|
const mins = String(abs % 60).padStart(2, '0');
|
|
34
47
|
return `UTC${sign}${hours}:${mins}`;
|
package/dist/esm/dom/query.js
CHANGED
|
@@ -1,19 +1,16 @@
|
|
|
1
|
+
import { isString } from '../guards/primitives.js';
|
|
1
2
|
import { flattenObjectKeyValue } from '../object/objectify.js';
|
|
2
3
|
import { parseObjectValues } from '../object/sanitize.js';
|
|
3
4
|
import { deepParsePrimitives } from '../utils/index.js';
|
|
4
5
|
export function generateQueryParams(params = {}) {
|
|
5
6
|
const flattenedParams = flattenObjectKeyValue(params);
|
|
6
7
|
const queryParams = Object.entries(flattenedParams)
|
|
7
|
-
?.filter(([_, value]) => value
|
|
8
|
-
value !== null &&
|
|
9
|
-
!(typeof value === 'string' && value?.trim() === ''))
|
|
8
|
+
?.filter(([_, value]) => value != null && !(isString(value) && value?.trim() === ''))
|
|
10
9
|
?.flatMap(([key, value]) => Array.isArray(value)
|
|
11
10
|
? value
|
|
12
|
-
?.filter((v) => v
|
|
13
|
-
v
|
|
14
|
-
|
|
15
|
-
?.map((v) => `${encodeURIComponent(key)}=${encodeURIComponent(typeof v === 'boolean' ? String(v) : String(v))}`)
|
|
16
|
-
: `${encodeURIComponent(key)}=${encodeURIComponent(typeof value === 'boolean' ? String(value) : String(value))}`)
|
|
11
|
+
?.filter((v) => v != null && !(isString(v) && v.trim() === ''))
|
|
12
|
+
?.map((v) => `${encodeURIComponent(key)}=${encodeURIComponent(String(v))}`)
|
|
13
|
+
: `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)
|
|
17
14
|
.join('&');
|
|
18
15
|
return queryParams ? `?${queryParams}` : '';
|
|
19
16
|
}
|
package/dist/esm/form/convert.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isDateLike } from '../date/guards.js';
|
|
2
2
|
import { isEmptyObject, isNotEmptyObject, isValidArray } from '../guards/non-primitives.js';
|
|
3
|
-
import { isNonEmptyString } from '../guards/primitives.js';
|
|
3
|
+
import { isNonEmptyString, isString } from '../guards/primitives.js';
|
|
4
4
|
import { isCustomFile, isCustomFileArray, isFileArray, isFileList, isFileOrBlob, isFileUpload, } from './guards.js';
|
|
5
5
|
export const createControlledFormData = (data, configs) => {
|
|
6
6
|
const formData = new FormData();
|
|
@@ -67,7 +67,7 @@ export const createControlledFormData = (data, configs) => {
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
else {
|
|
70
|
-
if (
|
|
70
|
+
if (isString(value)) {
|
|
71
71
|
if (isNonEmptyString(value)) {
|
|
72
72
|
let cleanString = value;
|
|
73
73
|
if (configs?.trimStrings) {
|
|
@@ -172,7 +172,7 @@ export const createControlledFormData = (data, configs) => {
|
|
|
172
172
|
else {
|
|
173
173
|
const isNotNullish = value != null && value !== '';
|
|
174
174
|
if (isNotNullish || _isRequiredKey(key)) {
|
|
175
|
-
if (
|
|
175
|
+
if (isString(value) && _shouldLowercaseValue(key)) {
|
|
176
176
|
formData.append(transformedKey, value?.toLowerCase());
|
|
177
177
|
}
|
|
178
178
|
else {
|
package/dist/esm/form/guards.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isString } from '../guards/primitives.js';
|
|
1
2
|
export function isValidFormData(value) {
|
|
2
3
|
if (!(value instanceof FormData))
|
|
3
4
|
return false;
|
|
@@ -15,7 +16,7 @@ export function isOriginFileObj(value) {
|
|
|
15
16
|
return false;
|
|
16
17
|
}
|
|
17
18
|
const obj = value;
|
|
18
|
-
return
|
|
19
|
+
return isString(obj.uid);
|
|
19
20
|
}
|
|
20
21
|
export function isCustomFile(value) {
|
|
21
22
|
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { generateQueryParams } from '../dom/query.js';
|
|
2
|
+
import { isString } from '../guards/primitives.js';
|
|
2
3
|
import { parseObjectValues } from '../object/sanitize.js';
|
|
3
4
|
export function serializeForm(form, toQueryString = false) {
|
|
4
5
|
const formData = new FormData(form);
|
|
@@ -21,11 +22,11 @@ export function serializeForm(form, toQueryString = false) {
|
|
|
21
22
|
}
|
|
22
23
|
export function parseFormData(data, parsePrimitives = true) {
|
|
23
24
|
const parsed = {};
|
|
24
|
-
if (
|
|
25
|
+
if (isString(data)) {
|
|
25
26
|
const params = new URLSearchParams(data);
|
|
26
27
|
params?.forEach((value, key) => {
|
|
27
28
|
const existing = parsed[key];
|
|
28
|
-
if (
|
|
29
|
+
if (isString(existing)) {
|
|
29
30
|
parsed[key] = [existing, value];
|
|
30
31
|
}
|
|
31
32
|
else if (Array.isArray(existing)) {
|
|
@@ -51,7 +52,7 @@ export function parseFormData(data, parsePrimitives = true) {
|
|
|
51
52
|
}
|
|
52
53
|
}
|
|
53
54
|
else {
|
|
54
|
-
if (
|
|
55
|
+
if (isString(existing)) {
|
|
55
56
|
parsed[key] = [existing, value];
|
|
56
57
|
}
|
|
57
58
|
else if (Array.isArray(existing)) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isNumber } from '../guards/primitives.js';
|
|
1
|
+
import { isNumber, isUndefined } from '../guards/primitives.js';
|
|
2
2
|
import { _find2NumbersHCF, _find2NumbersLCM } from './helpers.js';
|
|
3
3
|
import { normalizeNumber } from './utilities.js';
|
|
4
4
|
export const getRandomNumber = (options) => {
|
|
@@ -32,10 +32,13 @@ export const getRandomNumber = (options) => {
|
|
|
32
32
|
};
|
|
33
33
|
export const convertToDecimal = (input, options) => {
|
|
34
34
|
const { decimalPlaces = 2, isString = false } = options || {};
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
const parsed = normalizeNumber(input);
|
|
36
|
+
if (isUndefined(parsed)) {
|
|
37
|
+
throw new TypeError(`Invalid numeric input!`, {
|
|
38
|
+
cause: `${input} cannot be converted to a number.`,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return (isString ? parsed.toFixed(decimalPlaces) : Number(parsed.toFixed(decimalPlaces)));
|
|
39
42
|
};
|
|
40
43
|
export const calculateHCF = (...numbers) => {
|
|
41
44
|
const converted = numbers?.map(Number);
|
|
@@ -103,7 +106,7 @@ export function getAverage(...numbers) {
|
|
|
103
106
|
let count = 0;
|
|
104
107
|
for (const n of numbers) {
|
|
105
108
|
const num = Number(n);
|
|
106
|
-
if (
|
|
109
|
+
if (isNumber(num)) {
|
|
107
110
|
sum += num;
|
|
108
111
|
count++;
|
|
109
112
|
}
|
|
@@ -1,8 +1,16 @@
|
|
|
1
|
+
import { isUndefined } from '../guards/primitives.js';
|
|
2
|
+
import { normalizeNumber } from './utilities.js';
|
|
1
3
|
export const isEven = (input) => {
|
|
2
|
-
|
|
4
|
+
const parsed = normalizeNumber(input);
|
|
5
|
+
if (isUndefined(parsed))
|
|
6
|
+
return false;
|
|
7
|
+
return parsed % 2 === 0;
|
|
3
8
|
};
|
|
4
9
|
export const isOdd = (input) => {
|
|
5
|
-
|
|
10
|
+
const parsed = normalizeNumber(input);
|
|
11
|
+
if (isUndefined(parsed))
|
|
12
|
+
return false;
|
|
13
|
+
return parsed % 2 !== 0;
|
|
6
14
|
};
|
|
7
15
|
export const isMultiple = (input, multipleOf) => {
|
|
8
16
|
return input % multipleOf === 0;
|
package/dist/esm/number/range.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { shuffleArray } from '../array/basics.js';
|
|
2
|
+
import { isUndefined } from '../guards/primitives.js';
|
|
2
3
|
import { convertArrayToString } from '../utils/index.js';
|
|
3
4
|
import { getRandomNumber } from './basics.js';
|
|
4
5
|
import { isEven, isOdd } from './guards.js';
|
|
@@ -24,7 +25,7 @@ export function getNumbersInRange(type = 'any', options) {
|
|
|
24
25
|
}
|
|
25
26
|
return numbers;
|
|
26
27
|
};
|
|
27
|
-
if (type === 'prime' && multiplesOf
|
|
28
|
+
if (type === 'prime' && !isUndefined(multiplesOf)) {
|
|
28
29
|
console.warn('Warning: The "multiplesOf" option is ignored when the type is "prime"!');
|
|
29
30
|
}
|
|
30
31
|
switch (type) {
|
|
@@ -55,7 +56,5 @@ export function getNumbersInRange(type = 'any', options) {
|
|
|
55
56
|
if (type !== 'prime') {
|
|
56
57
|
output = _applyMultiples(output, multiplesOf);
|
|
57
58
|
}
|
|
58
|
-
return getAsString
|
|
59
|
-
? convertArrayToString(output, { separator })
|
|
60
|
-
: output;
|
|
59
|
+
return (getAsString ? convertArrayToString(output, { separator }) : output);
|
|
61
60
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isNonEmptyString } from '../guards/primitives.js';
|
|
1
|
+
import { isNonEmptyString, isString, isUndefined } from '../guards/primitives.js';
|
|
2
2
|
import { normalizeNumber } from '../number/utilities.js';
|
|
3
3
|
import { irregularRules, pluralRules, singularRules, uncountables } from './rules.js';
|
|
4
4
|
export class Pluralizer {
|
|
@@ -68,7 +68,7 @@ export class Pluralizer {
|
|
|
68
68
|
}
|
|
69
69
|
#isUncountable(word) {
|
|
70
70
|
for (const entry of this.#uncountables) {
|
|
71
|
-
if (
|
|
71
|
+
if (isString(entry)) {
|
|
72
72
|
if (entry.toLowerCase() === word)
|
|
73
73
|
return true;
|
|
74
74
|
}
|
|
@@ -86,7 +86,7 @@ export class Pluralizer {
|
|
|
86
86
|
this.#singularRules.push([rule, replacement]);
|
|
87
87
|
}
|
|
88
88
|
addUncountable(word) {
|
|
89
|
-
this.#uncountables.add(
|
|
89
|
+
this.#uncountables.add(isString(word) ? word?.toLowerCase() : word);
|
|
90
90
|
}
|
|
91
91
|
addIrregular(single, plural) {
|
|
92
92
|
const singleLower = single?.toLowerCase();
|
|
@@ -96,7 +96,7 @@ export class Pluralizer {
|
|
|
96
96
|
}
|
|
97
97
|
pluralize(word, options = {}) {
|
|
98
98
|
const count = normalizeNumber(options?.count);
|
|
99
|
-
if (
|
|
99
|
+
if (!isUndefined(count)) {
|
|
100
100
|
const pluralized = count === 1 ? this.toSingular(word) : this.toPlural(word);
|
|
101
101
|
return options?.inclusive ? `${count} ${pluralized}` : pluralized;
|
|
102
102
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { isString } from '../guards/primitives.js';
|
|
1
2
|
import { trimString } from './basics.js';
|
|
2
3
|
export const replaceAllInString = (input, find, replace) => {
|
|
3
4
|
const trimmedString = trimString(input);
|
|
4
|
-
const regex =
|
|
5
|
+
const regex = isString(find)
|
|
5
6
|
? new RegExp(find, 'g')
|
|
6
7
|
: new RegExp(find, find?.flags.includes('g') ? find?.flags : find?.flags + 'g');
|
|
7
8
|
return trimmedString?.replace(regex, replace);
|
package/dist/esm/utils/index.js
CHANGED
|
@@ -179,7 +179,7 @@ export function deepParsePrimitives(input) {
|
|
|
179
179
|
return input;
|
|
180
180
|
}
|
|
181
181
|
export function definePrototypeMethod(proto, name, impl, options) {
|
|
182
|
-
const alreadyExists = Object.
|
|
182
|
+
const alreadyExists = Object.hasOwn(proto, name);
|
|
183
183
|
if (alreadyExists && !options?.overwrite)
|
|
184
184
|
return;
|
|
185
185
|
Object.defineProperty(proto, name, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nhb-toolbox",
|
|
3
|
-
"version": "4.29.
|
|
3
|
+
"version": "4.29.21",
|
|
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",
|
|
@@ -44,14 +44,14 @@
|
|
|
44
44
|
},
|
|
45
45
|
"license": "Apache-2.0",
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@biomejs/biome": "^2.4.
|
|
47
|
+
"@biomejs/biome": "^2.4.10",
|
|
48
48
|
"@types/jest": "^30.0.0",
|
|
49
49
|
"@types/node": "^25.5.0",
|
|
50
50
|
"husky": "^9.1.7",
|
|
51
51
|
"jest": "^30.3.0",
|
|
52
52
|
"lint-staged": "^16.4.0",
|
|
53
53
|
"nhb-scripts": "^1.9.2",
|
|
54
|
-
"ts-jest": "^29.4.
|
|
54
|
+
"ts-jest": "^29.4.9",
|
|
55
55
|
"typescript": "^6.0.2"
|
|
56
56
|
},
|
|
57
57
|
"keywords": [
|