danholibraryjs 2.0.1 → 2.0.2
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/README.md +1 -0
- package/dist/Extensions/Array/random.extension.d.ts +1 -2
- package/dist/Extensions/Array/random.extension.js +1 -22
- package/dist/Extensions/Array/string.extension.d.ts +3 -4
- package/dist/Extensions/Number.d.ts +2 -2
- package/dist/Extensions/Number.js +1 -1
- package/dist/Extensions/Object/arrays.extension.d.ts +14 -0
- package/dist/Extensions/Object/arrays.extension.js +7 -2
- package/dist/Extensions/Object/extracts.extension.d.ts +6 -6
- package/dist/Extensions/Object/extracts.extension.js +10 -7
- package/dist/Extensions/String/index.d.ts +1 -0
- package/dist/Extensions/String/index.js +1 -0
- package/dist/Extensions/String/string.extension.d.ts +6 -0
- package/dist/Extensions/String/string.extension.js +10 -0
- package/dist/Types/Able.d.ts +1 -1
- package/dist/Utils/NumberUtils.d.ts +5 -0
- package/dist/Utils/NumberUtils.js +25 -1
- package/dist/Utils/StringUtils.d.ts +5 -0
- package/dist/Utils/StringUtils.js +6 -1
- package/dist/Utils/TimeUtils/index.d.ts +3 -0
- package/dist/Utils/TimeUtils/index.js +2 -0
- package/dist/Utils/TimeUtils/string.util.d.ts +3 -0
- package/dist/Utils/TimeUtils/string.util.js +19 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/docs/Extensions.md +48 -15
- package/docs/Types.md +1 -1
- package/docs/Utils.md +335 -0
- package/docs/index.md +1 -0
- package/package.json +1 -1
- package/src/Extensions/Array/random.extension.ts +2 -25
- package/src/Extensions/Array/string.extension.ts +3 -4
- package/src/Extensions/Number.ts +3 -3
- package/src/Extensions/Object/arrays.extension.ts +23 -2
- package/src/Extensions/Object/extracts.extension.ts +18 -13
- package/src/Extensions/String/index.ts +2 -1
- package/src/Extensions/String/string.extension.ts +11 -0
- package/src/Types/Able.ts +1 -1
- package/src/Utils/NumberUtils.ts +27 -0
- package/src/Utils/StringUtils.ts +7 -1
- package/src/Utils/TimeUtils/index.ts +2 -0
- package/src/Utils/TimeUtils/string.util.ts +13 -0
- package/src/index.ts +2 -1
- package/src/Extensions/Object/properties.ts +0 -51
package/README.md
CHANGED
|
@@ -15,9 +15,8 @@ declare global {
|
|
|
15
15
|
* @param items An array of tuples where each tuple contains an item and its corresponding weight.
|
|
16
16
|
* @returns A randomly selected item based on the provided weights.
|
|
17
17
|
*/
|
|
18
|
-
randomWithPercentages(items: [item: T, weight: number]
|
|
18
|
+
randomWithPercentages(items: Array<[item: T, weight: number]>): T;
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
export declare function random<T>(this: Array<T>): T;
|
|
22
22
|
export declare function shuffle<T>(this: Array<T>): Array<T>;
|
|
23
|
-
export declare function randomWithPercentages<T>(items: [item: T, weight: number][]): T;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.shuffle = exports.random = void 0;
|
|
4
4
|
function random() {
|
|
5
5
|
const randomIndex = Math.floor(Math.random() * this.length);
|
|
6
6
|
return this[randomIndex];
|
|
@@ -12,24 +12,3 @@ function shuffle() {
|
|
|
12
12
|
}
|
|
13
13
|
exports.shuffle = shuffle;
|
|
14
14
|
Array.prototype.shuffle = shuffle;
|
|
15
|
-
function randomWithPercentages(items) {
|
|
16
|
-
if (items.length === 0)
|
|
17
|
-
throw new Error('Items array cannot be empty');
|
|
18
|
-
// Calculate total weight in case weights don't sum to 100
|
|
19
|
-
const totalWeight = items.reduce((sum, [, weight]) => sum + weight, 0);
|
|
20
|
-
if (totalWeight === 0)
|
|
21
|
-
throw new Error('Total weight must be greater than zero');
|
|
22
|
-
// Generate random number between 0 and totalWeight
|
|
23
|
-
const random = Math.random() * totalWeight;
|
|
24
|
-
// Find the item that corresponds to this random value
|
|
25
|
-
let currentWeight = 0;
|
|
26
|
-
for (const [item, weight] of items) {
|
|
27
|
-
currentWeight += weight;
|
|
28
|
-
if (random <= currentWeight) {
|
|
29
|
-
return item;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
throw new Error('Unable to select an item based on weights');
|
|
33
|
-
}
|
|
34
|
-
exports.randomWithPercentages = randomWithPercentages;
|
|
35
|
-
Array.prototype.randomWithPercentages = randomWithPercentages;
|
|
@@ -2,12 +2,11 @@ declare global {
|
|
|
2
2
|
interface Array<T> {
|
|
3
3
|
/**
|
|
4
4
|
* Joins the elements of the array into a string, with optional custom separators.
|
|
5
|
-
* @param
|
|
6
|
-
* @param
|
|
7
|
-
* @param endSeparator The separator to use before the last element.
|
|
5
|
+
* @param separator The default separator to use between elements. Defaults to ','.
|
|
6
|
+
* @param endSeparator The separator to use before the last element. Default is '&'.
|
|
8
7
|
* @returns A string with the joined elements.
|
|
9
8
|
*/
|
|
10
|
-
join(
|
|
9
|
+
join(separator?: string, endSeparator?: string): string;
|
|
11
10
|
}
|
|
12
11
|
}
|
|
13
12
|
export declare function join<T>(this: Array<T>, separator?: string, endSeparator?: string): string;
|
|
@@ -4,10 +4,10 @@ type Separators = {
|
|
|
4
4
|
};
|
|
5
5
|
declare global {
|
|
6
6
|
interface Number {
|
|
7
|
-
toSeparationString(separators
|
|
7
|
+
toSeparationString(separators?: Partial<Separators>): string;
|
|
8
8
|
toRomanNumeral(): string;
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
|
-
export declare function toSeparationString(this: number, separators
|
|
11
|
+
export declare function toSeparationString(this: number, separators?: Partial<Separators>): string;
|
|
12
12
|
export declare function toRomanNumeral(this: number): string;
|
|
13
13
|
export {};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.toRomanNumeral = exports.toSeparationString = void 0;
|
|
4
4
|
function toSeparationString(separators) {
|
|
5
|
-
const { thousand = '.', decimal = '.' } = separators;
|
|
5
|
+
const { thousand = '.', decimal = '.' } = separators || {};
|
|
6
6
|
const [integerPart, decimalPart] = this.toString().split('.');
|
|
7
7
|
const formattedInteger = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, thousand);
|
|
8
8
|
return decimalPart ? `${formattedInteger}${decimal}${decimalPart}` : formattedInteger;
|
|
@@ -6,6 +6,18 @@ declare global {
|
|
|
6
6
|
* @param from Object to destruct
|
|
7
7
|
*/
|
|
8
8
|
array<From extends {} = {}>(from: From): Array<[keyof From, ValueOf<From>]>;
|
|
9
|
+
/**
|
|
10
|
+
* Destructures object into array of property keys or values depending on selector
|
|
11
|
+
* @param from Object to destruct
|
|
12
|
+
* @param selector Selects whether to return keys or values
|
|
13
|
+
*/
|
|
14
|
+
array<From extends {} = {}>(from: From, selector: 'keys'): Array<keyof From>;
|
|
15
|
+
/**
|
|
16
|
+
* Destructures object into array of property keys or values depending on selector
|
|
17
|
+
* @param from Object to destruct
|
|
18
|
+
* @param selector Selects whether to return keys or values
|
|
19
|
+
*/
|
|
20
|
+
array<From extends {} = {}>(from: From, selector: 'values'): Array<ValueOf<From>>;
|
|
9
21
|
/**
|
|
10
22
|
* Destructures object into array of property keys
|
|
11
23
|
* @param from Object to destruct
|
|
@@ -14,4 +26,6 @@ declare global {
|
|
|
14
26
|
}
|
|
15
27
|
}
|
|
16
28
|
export declare function array<From extends {} = {}>(this: object, from: From): Array<[keyof From, ValueOf<From>]>;
|
|
29
|
+
export declare function array<From extends {} = {}>(this: object, from: From, selector: 'keys'): Array<keyof From>;
|
|
30
|
+
export declare function array<From extends {} = {}>(this: object, from: From, selector: 'values'): Array<ValueOf<From>>;
|
|
17
31
|
export declare function keysOf<From extends {} = {}>(this: object, from: From): Array<keyof From>;
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.keysOf = exports.array = void 0;
|
|
4
|
-
function array(from) {
|
|
5
|
-
|
|
4
|
+
function array(from, selector) {
|
|
5
|
+
const entries = Object.entries(from);
|
|
6
|
+
switch (selector) {
|
|
7
|
+
case 'keys': return entries.map(([key]) => key);
|
|
8
|
+
case 'values': return entries.map(([, value]) => value);
|
|
9
|
+
default: return entries;
|
|
10
|
+
}
|
|
6
11
|
}
|
|
7
12
|
exports.array = array;
|
|
8
13
|
Object.array = array;
|
|
@@ -13,24 +13,24 @@ declare global {
|
|
|
13
13
|
*/
|
|
14
14
|
pick<From extends {}, Props extends keyof From>(from: From, ...props: Array<Props | Partial<From>>): Pick<From, Props>;
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
16
|
+
* Returns the difference between two objects (properties where values differ)
|
|
17
17
|
* @param source Source object
|
|
18
18
|
* @param target Target object
|
|
19
|
-
* @param exclude Properties to exclude from
|
|
20
|
-
* @returns Object with properties
|
|
19
|
+
* @param exclude Properties to exclude from comparison
|
|
20
|
+
* @returns Object with properties where values differ between source and target, excluding specified properties
|
|
21
21
|
*/
|
|
22
|
-
difference<T extends object>(source: T, target: T, ...exclude: Array<keyof T>):
|
|
22
|
+
difference<T extends object>(source: T, target: T, ...exclude: Array<keyof T>): Partial<T>;
|
|
23
23
|
/**
|
|
24
24
|
* Deeply combines objects, with later objects in parameters taking precedence over earlier ones. Does not combine arrays.
|
|
25
25
|
* @param objects Objects to combine
|
|
26
26
|
* @returns Combined object
|
|
27
27
|
*/
|
|
28
|
-
combine<T extends Record<string, any | undefined>>(...objects: Array<
|
|
28
|
+
combine<T extends Record<string, any | undefined>>(...objects: Array<Combinable<T> | undefined>): T;
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
export declare function omit<From extends {}, Props extends keyof From>(from: From, ...props: Array<Props | Partial<From>>): Omit<From, Props>;
|
|
32
32
|
export declare function pick<From extends {}, Props extends keyof From>(from: From, ...props: Array<Props | Partial<From>>): Pick<From, Props>;
|
|
33
|
-
export declare function difference<T extends object>(source: T, target: T, ...exclude: Array<keyof T>):
|
|
33
|
+
export declare function difference<T extends object>(source: T, target: T, ...exclude: Array<keyof T>): Partial<T>;
|
|
34
34
|
type Combinable<T extends Record<string, any>> = {
|
|
35
35
|
[key in keyof T]?: T[key] extends Record<string, any> ? Combinable<T[key]> : T[key];
|
|
36
36
|
};
|
|
@@ -30,13 +30,16 @@ function pick(from, ...props) {
|
|
|
30
30
|
exports.pick = pick;
|
|
31
31
|
Object.pick = pick;
|
|
32
32
|
function difference(source, target, ...exclude) {
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
return [...
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
const excludeSet = new Set(exclude);
|
|
34
|
+
const allKeys = new Set([...Object.keysOf(source), ...Object.keysOf(target)]);
|
|
35
|
+
return [...allKeys].reduce((acc, key) => {
|
|
36
|
+
if (excludeSet.has(key))
|
|
37
|
+
return acc;
|
|
38
|
+
const sourceValue = source[key];
|
|
39
|
+
const targetValue = target[key];
|
|
40
|
+
if (JSON.stringify(sourceValue) !== JSON.stringify(targetValue)) {
|
|
41
|
+
acc[key] = targetValue;
|
|
42
|
+
}
|
|
40
43
|
return acc;
|
|
41
44
|
}, {});
|
|
42
45
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.truncate = void 0;
|
|
4
|
+
function truncate(length, ellipsis = "...") {
|
|
5
|
+
if (this.length <= length)
|
|
6
|
+
return this;
|
|
7
|
+
return this.slice(0, length - ellipsis.length) + ellipsis;
|
|
8
|
+
}
|
|
9
|
+
exports.truncate = truncate;
|
|
10
|
+
String.prototype.truncate = truncate;
|
package/dist/Types/Able.d.ts
CHANGED
|
@@ -1 +1,6 @@
|
|
|
1
1
|
export declare function between(min: number, max: number): number;
|
|
2
|
+
export declare function randomWithPercentages<T>(items: [item: T, weight: number][]): T;
|
|
3
|
+
export declare const NumberUtils: {
|
|
4
|
+
between: typeof between;
|
|
5
|
+
randomWithPercentages: typeof randomWithPercentages;
|
|
6
|
+
};
|
|
@@ -1,7 +1,31 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.between = void 0;
|
|
3
|
+
exports.NumberUtils = exports.randomWithPercentages = exports.between = void 0;
|
|
4
4
|
function between(min, max) {
|
|
5
5
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
6
6
|
}
|
|
7
7
|
exports.between = between;
|
|
8
|
+
function randomWithPercentages(items) {
|
|
9
|
+
if (items.length === 0)
|
|
10
|
+
throw new Error('Items array cannot be empty');
|
|
11
|
+
// Calculate total weight in case weights don't sum to 100
|
|
12
|
+
const totalWeight = items.reduce((sum, [, weight]) => sum + weight, 0);
|
|
13
|
+
if (totalWeight === 0)
|
|
14
|
+
throw new Error('Total weight must be greater than zero');
|
|
15
|
+
// Generate random number between 0 and totalWeight
|
|
16
|
+
const random = Math.random() * totalWeight;
|
|
17
|
+
// Find the item that corresponds to this random value
|
|
18
|
+
let currentWeight = 0;
|
|
19
|
+
for (const [item, weight] of items) {
|
|
20
|
+
currentWeight += weight;
|
|
21
|
+
if (random <= currentWeight) {
|
|
22
|
+
return item;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
throw new Error('Unable to select an item based on weights');
|
|
26
|
+
}
|
|
27
|
+
exports.randomWithPercentages = randomWithPercentages;
|
|
28
|
+
exports.NumberUtils = {
|
|
29
|
+
between,
|
|
30
|
+
randomWithPercentages,
|
|
31
|
+
};
|
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
export declare function classNames(...args: Array<any>): string;
|
|
2
2
|
export declare function randomId(length?: number): string;
|
|
3
3
|
export declare function pluralize(countable: number | ArrayLike<any> | Map<any, any>, singular: string, plural?: string): string;
|
|
4
|
+
export declare const StringUtils: {
|
|
5
|
+
classNames: typeof classNames;
|
|
6
|
+
randomId: typeof randomId;
|
|
7
|
+
pluralize: typeof pluralize;
|
|
8
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.pluralize = exports.randomId = exports.classNames = void 0;
|
|
3
|
+
exports.StringUtils = exports.pluralize = exports.randomId = exports.classNames = void 0;
|
|
4
4
|
function classNames(...args) {
|
|
5
5
|
return args.reduce((acc, arg) => {
|
|
6
6
|
if (!arg)
|
|
@@ -45,3 +45,8 @@ function pluralize(countable, singular, plural) {
|
|
|
45
45
|
return `${singular}s`;
|
|
46
46
|
}
|
|
47
47
|
exports.pluralize = pluralize;
|
|
48
|
+
exports.StringUtils = {
|
|
49
|
+
classNames,
|
|
50
|
+
randomId,
|
|
51
|
+
pluralize
|
|
52
|
+
};
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export declare const TimeUtils: {
|
|
2
|
+
ensureStartZero(num: number): string;
|
|
3
|
+
get12HourFormat(hour: number): string;
|
|
4
|
+
get24HourFormat(hour: number): string;
|
|
2
5
|
throttle<T>(throttleId: string, callback: () => T, cooldown: number): T;
|
|
3
6
|
wrapInThrottle<T_1>(callback: (...args: T_1[]) => void, cooldown: number): (...args: T_1[]) => void;
|
|
4
7
|
isThrottleOnCooldown(throttleId: string): boolean;
|
|
@@ -27,8 +27,10 @@ exports.TimeUtils = void 0;
|
|
|
27
27
|
const Debounce = __importStar(require("./debounce.util"));
|
|
28
28
|
const Functions = __importStar(require("./functions.util"));
|
|
29
29
|
const Throttle = __importStar(require("./throttle.util"));
|
|
30
|
+
const StringUtils = __importStar(require("./string.util"));
|
|
30
31
|
exports.TimeUtils = {
|
|
31
32
|
...Functions,
|
|
32
33
|
...Debounce,
|
|
33
34
|
...Throttle,
|
|
35
|
+
...StringUtils,
|
|
34
36
|
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.get24HourFormat = exports.get12HourFormat = exports.ensureStartZero = void 0;
|
|
4
|
+
function ensureStartZero(num) {
|
|
5
|
+
return num < 10 ? `0${num}` : num.toString();
|
|
6
|
+
}
|
|
7
|
+
exports.ensureStartZero = ensureStartZero;
|
|
8
|
+
function get12HourFormat(hour) {
|
|
9
|
+
if (hour === 0)
|
|
10
|
+
return '12am';
|
|
11
|
+
if (hour > 12)
|
|
12
|
+
return `${hour - 12}pm`;
|
|
13
|
+
return `${hour}am`;
|
|
14
|
+
}
|
|
15
|
+
exports.get12HourFormat = get12HourFormat;
|
|
16
|
+
function get24HourFormat(hour) {
|
|
17
|
+
return ensureStartZero(hour);
|
|
18
|
+
}
|
|
19
|
+
exports.get24HourFormat = get24HourFormat;
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/docs/Extensions.md
CHANGED
|
@@ -108,16 +108,6 @@ interface ArrayConstructor {
|
|
|
108
108
|
}
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
-
#### Standalone Functions
|
|
112
|
-
|
|
113
|
-
```ts
|
|
114
|
-
/**
|
|
115
|
-
* Selects random item from weighted items
|
|
116
|
-
* @param items Array of [item, weight] tuples where weight is probability
|
|
117
|
-
*/
|
|
118
|
-
function randomWithPercentages<T>(items: [item: T, weight: number][]): T;
|
|
119
|
-
```
|
|
120
|
-
|
|
121
111
|
### Function
|
|
122
112
|
|
|
123
113
|
```ts
|
|
@@ -192,9 +182,9 @@ interface Map<K, V> {
|
|
|
192
182
|
interface Number {
|
|
193
183
|
/**
|
|
194
184
|
* Formats number with thousand and decimal separators
|
|
195
|
-
* @param separators Custom separators for thousand and decimal
|
|
185
|
+
* @param separators Custom separators for thousand and decimal (optional)
|
|
196
186
|
*/
|
|
197
|
-
toSeparationString(separators
|
|
187
|
+
toSeparationString(separators?: Partial<{ thousand: string; decimal: string }>): string;
|
|
198
188
|
|
|
199
189
|
/**
|
|
200
190
|
* Converts number to Roman numeral (1-3999)
|
|
@@ -210,16 +200,52 @@ interface Number {
|
|
|
210
200
|
```ts
|
|
211
201
|
interface ObjectConstructor {
|
|
212
202
|
/**
|
|
213
|
-
*
|
|
214
|
-
* @param from Object to
|
|
203
|
+
* Destructures object into array of [property, value]
|
|
204
|
+
* @param from Object to destruct
|
|
205
|
+
*/
|
|
206
|
+
array<From extends {} = {}>(from: From): Array<[keyof From, ValueOf<From>]>;
|
|
207
|
+
/**
|
|
208
|
+
* Destructures object into array of property keys or values depending on selector
|
|
209
|
+
* @param from Object to destruct
|
|
210
|
+
* @param selector Selects whether to return keys or values
|
|
215
211
|
*/
|
|
216
|
-
array<From = {}>(from: From): Array<
|
|
212
|
+
array<From extends {} = {}>(from: From, selector: 'keys'): Array<keyof From>;
|
|
213
|
+
/**
|
|
214
|
+
* Destructures object into array of property keys or values depending on selector
|
|
215
|
+
* @param from Object to destruct
|
|
216
|
+
* @param selector Selects whether to return keys or values
|
|
217
|
+
*/
|
|
218
|
+
array<From extends {} = {}>(from: From, selector: 'values'): Array<ValueOf<From>>;
|
|
217
219
|
|
|
218
220
|
/**
|
|
219
221
|
* Returns array of object keys with proper typing
|
|
220
222
|
* @param from Object to get keys from
|
|
221
223
|
*/
|
|
222
224
|
keysOf<From = {}>(from: From): Array<keyof From>;
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Object with property filter methods by type
|
|
228
|
+
* Methods: getStrings, getNumbers, getBooleans, getUndefineds, getNulls,
|
|
229
|
+
* getObjects, getFunctions, getAnys, getDates, getRegExps,
|
|
230
|
+
* getPromises, getArrays, getMaps, getSets
|
|
231
|
+
* @example Object.properties.getStrings(obj) // Returns object with only string properties
|
|
232
|
+
*/
|
|
233
|
+
properties: {
|
|
234
|
+
getStrings<Source extends {}, AllowFunctions extends boolean = false>(source: Source, withFunctions?: AllowFunctions): Partial<Source>;
|
|
235
|
+
getNumbers<Source extends {}, AllowFunctions extends boolean = false>(source: Source, withFunctions?: AllowFunctions): Partial<Source>;
|
|
236
|
+
getBooleans<Source extends {}, AllowFunctions extends boolean = false>(source: Source, withFunctions?: AllowFunctions): Partial<Source>;
|
|
237
|
+
getUndefineds<Source extends {}, AllowFunctions extends boolean = false>(source: Source, withFunctions?: AllowFunctions): Partial<Source>;
|
|
238
|
+
getNulls<Source extends {}, AllowFunctions extends boolean = false>(source: Source, withFunctions?: AllowFunctions): Partial<Source>;
|
|
239
|
+
getObjects<Source extends {}, AllowFunctions extends boolean = false>(source: Source, withFunctions?: AllowFunctions): Partial<Source>;
|
|
240
|
+
getFunctions<Source extends {}, AllowFunctions extends boolean = false>(source: Source, withFunctions?: AllowFunctions): Partial<Source>;
|
|
241
|
+
getAnys<Source extends {}, AllowFunctions extends boolean = false>(source: Source, withFunctions?: AllowFunctions): Partial<Source>;
|
|
242
|
+
getDates<Source extends {}, AllowFunctions extends boolean = false>(source: Source, withFunctions?: AllowFunctions): Partial<Source>;
|
|
243
|
+
getRegExps<Source extends {}, AllowFunctions extends boolean = false>(source: Source, withFunctions?: AllowFunctions): Partial<Source>;
|
|
244
|
+
getPromises<Source extends {}, AllowFunctions extends boolean = false>(source: Source, withFunctions?: AllowFunctions): Partial<Source>;
|
|
245
|
+
getArrays<Source extends {}, AllowFunctions extends boolean = false>(source: Source, withFunctions?: AllowFunctions): Partial<Source>;
|
|
246
|
+
getMaps<Source extends {}, AllowFunctions extends boolean = false>(source: Source, withFunctions?: AllowFunctions): Partial<Source>;
|
|
247
|
+
getSets<Source extends {}, AllowFunctions extends boolean = false>(source: Source, withFunctions?: AllowFunctions): Partial<Source>;
|
|
248
|
+
};
|
|
223
249
|
}
|
|
224
250
|
```
|
|
225
251
|
|
|
@@ -278,6 +304,13 @@ interface String {
|
|
|
278
304
|
* @param to Cases to convert to, can chain multiple conversions
|
|
279
305
|
*/
|
|
280
306
|
convertCase(from: Case, ...to: Array<Case>): string;
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Truncates string to specified length with optional ellipsis
|
|
310
|
+
* @param length Maximum length of string
|
|
311
|
+
* @param ellipsis String to append if truncated (default: '...')
|
|
312
|
+
*/
|
|
313
|
+
truncate(length: number, ellipsis?: string): string;
|
|
281
314
|
}
|
|
282
315
|
```
|
|
283
316
|
|
package/docs/Types.md
CHANGED
|
@@ -38,7 +38,7 @@ type Functionable<T, Args extends any[] = []> = T | ((...args: Args) => T);
|
|
|
38
38
|
/**
|
|
39
39
|
* Value can be either T or a Promise that resolves to T
|
|
40
40
|
*/
|
|
41
|
-
type
|
|
41
|
+
type Promiseable<T> = T | Promise<T>;
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
44
|
* Value can be T or null
|
package/docs/Utils.md
ADDED
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
# [DanhoLibraryJS](../README.md)
|
|
2
|
+
|
|
3
|
+
## Utils
|
|
4
|
+
|
|
5
|
+
Utility functions and classes for common tasks.
|
|
6
|
+
|
|
7
|
+
### ApiUtils
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
/**
|
|
11
|
+
* API utility class for making HTTP requests
|
|
12
|
+
*/
|
|
13
|
+
class ApiUtils<ApiEndpoints extends string> {
|
|
14
|
+
/**
|
|
15
|
+
* @param options Configuration options
|
|
16
|
+
* @param options.baseEndpointDev Base URL for development environment
|
|
17
|
+
* @param options.baseEndpoint Base URL for production environment (optional)
|
|
18
|
+
* @param options.log Enable request logging (default: false)
|
|
19
|
+
*/
|
|
20
|
+
constructor(options: {
|
|
21
|
+
baseEndpointDev: string;
|
|
22
|
+
baseEndpoint?: string;
|
|
23
|
+
log?: boolean;
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Make a request to the API
|
|
28
|
+
* @param path The path to the endpoint
|
|
29
|
+
* @param options Request options (method, body, headers, etc.)
|
|
30
|
+
* @returns The response from the API
|
|
31
|
+
*/
|
|
32
|
+
public async request<TData>(
|
|
33
|
+
path: ApiEndpoints,
|
|
34
|
+
options?: RequestOptions
|
|
35
|
+
): Promise<TData>;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Get the base endpoint URL based on environment
|
|
39
|
+
*/
|
|
40
|
+
public get baseEndpoint(): string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Request options type
|
|
45
|
+
*/
|
|
46
|
+
type RequestOptions<TBody = any> = Omit<RequestInit, 'method' | 'body'> & {
|
|
47
|
+
method?: HttpMethods;
|
|
48
|
+
body?: TBody;
|
|
49
|
+
params?: Record<string, string | number | boolean>;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* HTTP methods
|
|
54
|
+
*/
|
|
55
|
+
type HttpMethods =
|
|
56
|
+
| 'GET'
|
|
57
|
+
| 'POST'
|
|
58
|
+
| 'PUT'
|
|
59
|
+
| 'PATCH'
|
|
60
|
+
| 'DELETE'
|
|
61
|
+
| 'HEAD'
|
|
62
|
+
| 'OPTIONS';
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### ColorUtils
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
/**
|
|
69
|
+
* RGB color as tuple
|
|
70
|
+
*/
|
|
71
|
+
type RGB = [number, number, number];
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Hex color string
|
|
75
|
+
*/
|
|
76
|
+
type Hex = `#${string}`;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Color type identifier
|
|
80
|
+
*/
|
|
81
|
+
type ColorType = 'hex' | 'rgb' | 'hsl';
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Convert colors between different formats
|
|
85
|
+
* @param value Color value to convert
|
|
86
|
+
* @param fromOrTo Source format (for strings) or target format (for RGB)
|
|
87
|
+
* @param to Target format (when converting from string)
|
|
88
|
+
*/
|
|
89
|
+
function convert(value: RGB, to: Exclude<ColorType, 'rgb'>): string;
|
|
90
|
+
function convert(value: string, from: Exclude<ColorType, 'rgb'>, to: 'rgb'): RGB;
|
|
91
|
+
function convert(value: string | RGB, fromOrTo: ColorType, to?: ColorType): string | RGB;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Generate a random hex color
|
|
95
|
+
* @returns Random hex color string
|
|
96
|
+
*/
|
|
97
|
+
function generateRandomColor(): Hex;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Color utilities object
|
|
101
|
+
*/
|
|
102
|
+
const ColorUtils = {
|
|
103
|
+
convert,
|
|
104
|
+
generateRandomColor
|
|
105
|
+
};
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### FormUtils
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
/**
|
|
112
|
+
* Serialize a form into an object
|
|
113
|
+
* @param form The form element to serialize
|
|
114
|
+
* @param log Whether to log the serialization process (default: false)
|
|
115
|
+
* @returns An object containing the form data
|
|
116
|
+
*/
|
|
117
|
+
function serializeForm<T extends object>(form: HTMLFormElement, log?: boolean): T;
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### NumberUtils
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
/**
|
|
124
|
+
* Generate a random number between min and max (inclusive)
|
|
125
|
+
* @param min Minimum value
|
|
126
|
+
* @param max Maximum value
|
|
127
|
+
* @returns Random number between min and max
|
|
128
|
+
*/
|
|
129
|
+
function between(min: number, max: number): number;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Select a random item from weighted items
|
|
133
|
+
* @param items Array of [item, weight] tuples where weight determines probability
|
|
134
|
+
* @returns Randomly selected item based on weights
|
|
135
|
+
* @throws Error if items array is empty or total weight is zero
|
|
136
|
+
*/
|
|
137
|
+
function randomWithPercentages<T>(items: [item: T, weight: number][]): T;
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Number utilities object
|
|
141
|
+
*/
|
|
142
|
+
const NumberUtils = {
|
|
143
|
+
between,
|
|
144
|
+
randomWithPercentages,
|
|
145
|
+
};
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### PatcherUtils
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
/**
|
|
152
|
+
* Patch event type
|
|
153
|
+
*/
|
|
154
|
+
type PatchEvent = 'before' | 'instead' | 'after';
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Monkey patch a property or method on an object
|
|
158
|
+
* @param target Object to patch
|
|
159
|
+
* @param property Property or method name to patch
|
|
160
|
+
* @param event When to run the patch ('before', 'instead', or 'after')
|
|
161
|
+
* @param replacement Replacement function or value handler
|
|
162
|
+
* @returns Function to unpatch
|
|
163
|
+
*/
|
|
164
|
+
function patch<
|
|
165
|
+
TTarget extends object,
|
|
166
|
+
TProperty extends keyof TTarget,
|
|
167
|
+
TPatchEvent extends PatchEvent,
|
|
168
|
+
TPatchReplacement extends PatcherReplacement<TTarget, TProperty, TPatchEvent>
|
|
169
|
+
>(
|
|
170
|
+
target: TTarget,
|
|
171
|
+
property: TProperty,
|
|
172
|
+
event: TPatchEvent,
|
|
173
|
+
replacement: TPatchReplacement
|
|
174
|
+
): (() => void) | undefined;
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Remove all patches from a specific property
|
|
178
|
+
* @param target Object with patches
|
|
179
|
+
* @param property Property to unpatch
|
|
180
|
+
*/
|
|
181
|
+
function unpatch<TTarget extends object, TProperty extends keyof TTarget>(
|
|
182
|
+
target: TTarget,
|
|
183
|
+
property: TProperty
|
|
184
|
+
): void;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Remove all patches from all objects
|
|
188
|
+
*/
|
|
189
|
+
function unpatchAll(): void;
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### StringUtils
|
|
193
|
+
|
|
194
|
+
```ts
|
|
195
|
+
/**
|
|
196
|
+
* Combines class names from various input types
|
|
197
|
+
* Supports strings, objects (key-value where truthy values include the key),
|
|
198
|
+
* arrays, and nested structures
|
|
199
|
+
* @param args Class name arguments
|
|
200
|
+
* @returns Combined class name string
|
|
201
|
+
*/
|
|
202
|
+
function classNames(...args: Array<any>): string;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Generate a random ID string
|
|
206
|
+
* @param length Length of the ID (default: 16)
|
|
207
|
+
* @returns Random alphanumeric string
|
|
208
|
+
*/
|
|
209
|
+
function randomId(length?: number): string;
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Pluralize a word based on count
|
|
213
|
+
* @param countable Number, array-like object, or Map to count
|
|
214
|
+
* @param singular Singular form of the word
|
|
215
|
+
* @param plural Optional custom plural form (default: adds 's' to singular)
|
|
216
|
+
* @returns Singular or plural form based on count
|
|
217
|
+
*/
|
|
218
|
+
function pluralize(
|
|
219
|
+
countable: number | ArrayLike<any> | Map<any, any>,
|
|
220
|
+
singular: string,
|
|
221
|
+
plural?: string
|
|
222
|
+
): string;
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### TimeUtils
|
|
226
|
+
|
|
227
|
+
```ts
|
|
228
|
+
/**
|
|
229
|
+
* Wait for a specified amount of time or execute a callback after a delay
|
|
230
|
+
* @param time Milliseconds to wait
|
|
231
|
+
*/
|
|
232
|
+
function wait<T>(time: number): Promise<void>;
|
|
233
|
+
function wait<T>(callback: (...args: any[]) => T, time: number): Promise<T>;
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Get Unix timestamp from various date formats
|
|
237
|
+
* @param date Date object or date string
|
|
238
|
+
*/
|
|
239
|
+
function getUnixTime(date: Date | string): number;
|
|
240
|
+
function getUnixTime(timestamp: number): number;
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Debounce a function call
|
|
244
|
+
* @param debounceId Unique identifier for this debounce
|
|
245
|
+
* @param callback Function to debounce
|
|
246
|
+
* @param delay Delay in milliseconds
|
|
247
|
+
* @param signal Optional AbortSignal to cancel the debounce
|
|
248
|
+
* @returns Promise that resolves with callback result or rejects if cancelled
|
|
249
|
+
*/
|
|
250
|
+
function debounce<T>(
|
|
251
|
+
debounceId: string,
|
|
252
|
+
callback: () => T,
|
|
253
|
+
delay: number,
|
|
254
|
+
signal?: AbortSignal
|
|
255
|
+
): Promise<T>;
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Wrap a function in a debounce
|
|
259
|
+
* @param callback Function to wrap
|
|
260
|
+
* @param delay Delay in milliseconds
|
|
261
|
+
* @returns Debounced function
|
|
262
|
+
*/
|
|
263
|
+
function wrapInDebounce<T>(
|
|
264
|
+
callback: (...args: T[]) => void,
|
|
265
|
+
delay: number
|
|
266
|
+
): (...args: T[]) => void;
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Throttle a function call
|
|
270
|
+
* @param throttleId Unique identifier for this throttle
|
|
271
|
+
* @param callback Function to throttle
|
|
272
|
+
* @param cooldown Cooldown period in milliseconds
|
|
273
|
+
* @returns Callback result or undefined if on cooldown
|
|
274
|
+
*/
|
|
275
|
+
function throttle<T>(
|
|
276
|
+
throttleId: string,
|
|
277
|
+
callback: () => T,
|
|
278
|
+
cooldown: number
|
|
279
|
+
): T | undefined;
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Wrap a function in a throttle
|
|
283
|
+
* @param callback Function to wrap
|
|
284
|
+
* @param cooldown Cooldown period in milliseconds
|
|
285
|
+
* @returns Throttled function
|
|
286
|
+
*/
|
|
287
|
+
function wrapInThrottle<T>(
|
|
288
|
+
callback: (...args: T[]) => void,
|
|
289
|
+
cooldown: number
|
|
290
|
+
): (...args: T[]) => void;
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Check if a throttle is currently on cooldown
|
|
294
|
+
* @param throttleId Throttle identifier to check
|
|
295
|
+
* @returns True if on cooldown, false otherwise
|
|
296
|
+
*/
|
|
297
|
+
function isThrottleOnCooldown(throttleId: string): boolean;
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Ensure a number is formatted with a leading zero if less than 10
|
|
301
|
+
* @param num Number to format
|
|
302
|
+
* @returns String with leading zero if needed
|
|
303
|
+
*/
|
|
304
|
+
function ensureStartZero(num: number): string;
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Convert 24-hour format to 12-hour format with am/pm
|
|
308
|
+
* @param hour Hour in 24-hour format (0-23)
|
|
309
|
+
* @returns Hour in 12-hour format with am/pm suffix
|
|
310
|
+
*/
|
|
311
|
+
function get12HourFormat(hour: number): string;
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Format hour in 24-hour format with leading zero
|
|
315
|
+
* @param hour Hour to format
|
|
316
|
+
* @returns Hour as two-digit string
|
|
317
|
+
*/
|
|
318
|
+
function get24HourFormat(hour: number): string;
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Time utilities object containing all time-related functions
|
|
322
|
+
*/
|
|
323
|
+
const TimeUtils = {
|
|
324
|
+
wait,
|
|
325
|
+
getUnixTime,
|
|
326
|
+
debounce,
|
|
327
|
+
wrapInDebounce,
|
|
328
|
+
throttle,
|
|
329
|
+
wrapInThrottle,
|
|
330
|
+
isThrottleOnCooldown,
|
|
331
|
+
ensureStartZero,
|
|
332
|
+
get12HourFormat,
|
|
333
|
+
get24HourFormat
|
|
334
|
+
};
|
|
335
|
+
```
|
package/docs/index.md
CHANGED
package/package.json
CHANGED
|
@@ -17,7 +17,7 @@ declare global {
|
|
|
17
17
|
* @param items An array of tuples where each tuple contains an item and its corresponding weight.
|
|
18
18
|
* @returns A randomly selected item based on the provided weights.
|
|
19
19
|
*/
|
|
20
|
-
randomWithPercentages(items: [item: T, weight: number]
|
|
20
|
+
randomWithPercentages(items: Array<[item: T, weight: number]>): T;
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
|
|
@@ -30,27 +30,4 @@ Array.prototype.random = random;
|
|
|
30
30
|
export function shuffle<T>(this: Array<T>): Array<T> {
|
|
31
31
|
return this.sort(() => Math.random() - 0.5);
|
|
32
32
|
}
|
|
33
|
-
Array.prototype.shuffle = shuffle;
|
|
34
|
-
|
|
35
|
-
export function randomWithPercentages<T>(items: [item: T, weight: number][]): T {
|
|
36
|
-
if (items.length === 0) throw new Error('Items array cannot be empty');
|
|
37
|
-
|
|
38
|
-
// Calculate total weight in case weights don't sum to 100
|
|
39
|
-
const totalWeight = items.reduce((sum, [, weight]) => sum + weight, 0);
|
|
40
|
-
if (totalWeight === 0) throw new Error('Total weight must be greater than zero');
|
|
41
|
-
|
|
42
|
-
// Generate random number between 0 and totalWeight
|
|
43
|
-
const random = Math.random() * totalWeight;
|
|
44
|
-
|
|
45
|
-
// Find the item that corresponds to this random value
|
|
46
|
-
let currentWeight = 0;
|
|
47
|
-
for (const [item, weight] of items) {
|
|
48
|
-
currentWeight += weight;
|
|
49
|
-
if (random <= currentWeight) {
|
|
50
|
-
return item;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
throw new Error('Unable to select an item based on weights');
|
|
55
|
-
}
|
|
56
|
-
Array.prototype.randomWithPercentages = randomWithPercentages;
|
|
33
|
+
Array.prototype.shuffle = shuffle;
|
|
@@ -2,12 +2,11 @@ declare global {
|
|
|
2
2
|
interface Array<T> {
|
|
3
3
|
/**
|
|
4
4
|
* Joins the elements of the array into a string, with optional custom separators.
|
|
5
|
-
* @param
|
|
6
|
-
* @param
|
|
7
|
-
* @param endSeparator The separator to use before the last element.
|
|
5
|
+
* @param separator The default separator to use between elements. Defaults to ','.
|
|
6
|
+
* @param endSeparator The separator to use before the last element. Default is '&'.
|
|
8
7
|
* @returns A string with the joined elements.
|
|
9
8
|
*/
|
|
10
|
-
join(
|
|
9
|
+
join(separator?: string, endSeparator?: string): string;
|
|
11
10
|
}
|
|
12
11
|
}
|
|
13
12
|
|
package/src/Extensions/Number.ts
CHANGED
|
@@ -5,13 +5,13 @@ type Separators = {
|
|
|
5
5
|
|
|
6
6
|
declare global {
|
|
7
7
|
interface Number {
|
|
8
|
-
toSeparationString(separators
|
|
8
|
+
toSeparationString(separators?: Partial<Separators>): string;
|
|
9
9
|
toRomanNumeral(): string;
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export function toSeparationString(this: number, separators
|
|
14
|
-
const { thousand = '.', decimal = '.' } = separators;
|
|
13
|
+
export function toSeparationString(this: number, separators?: Partial<Separators>): string {
|
|
14
|
+
const { thousand = '.', decimal = '.' } = separators || {};
|
|
15
15
|
const [integerPart, decimalPart] = this.toString().split('.');
|
|
16
16
|
const formattedInteger = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, thousand);
|
|
17
17
|
return decimalPart ? `${formattedInteger}${decimal}${decimalPart}` : formattedInteger;
|
|
@@ -7,6 +7,18 @@ declare global {
|
|
|
7
7
|
* @param from Object to destruct
|
|
8
8
|
*/
|
|
9
9
|
array<From extends {} = {}>(from: From): Array<[keyof From, ValueOf<From>]>;
|
|
10
|
+
/**
|
|
11
|
+
* Destructures object into array of property keys or values depending on selector
|
|
12
|
+
* @param from Object to destruct
|
|
13
|
+
* @param selector Selects whether to return keys or values
|
|
14
|
+
*/
|
|
15
|
+
array<From extends {} = {}>(from: From, selector: 'keys'): Array<keyof From>;
|
|
16
|
+
/**
|
|
17
|
+
* Destructures object into array of property keys or values depending on selector
|
|
18
|
+
* @param from Object to destruct
|
|
19
|
+
* @param selector Selects whether to return keys or values
|
|
20
|
+
*/
|
|
21
|
+
array<From extends {} = {}>(from: From, selector: 'values'): Array<ValueOf<From>>;
|
|
10
22
|
|
|
11
23
|
/**
|
|
12
24
|
* Destructures object into array of property keys
|
|
@@ -16,8 +28,17 @@ declare global {
|
|
|
16
28
|
}
|
|
17
29
|
}
|
|
18
30
|
|
|
19
|
-
export function array<From extends {} = {}>(this: object, from: From): Array<[keyof From, ValueOf<From>]
|
|
20
|
-
|
|
31
|
+
export function array<From extends {} = {}>(this: object, from: From): Array<[keyof From, ValueOf<From>]>;
|
|
32
|
+
export function array<From extends {} = {}>(this: object, from: From, selector: 'keys'): Array<keyof From>;
|
|
33
|
+
export function array<From extends {} = {}>(this: object, from: From, selector: 'values'): Array<ValueOf<From>>;
|
|
34
|
+
export function array<From extends {} = {}>(this: object, from: From, selector?: 'keys' | 'values') {
|
|
35
|
+
const entries = Object.entries(from) as Array<[keyof From, ValueOf<From>]>;
|
|
36
|
+
|
|
37
|
+
switch (selector) {
|
|
38
|
+
case 'keys': return entries.map(([key]) => key);
|
|
39
|
+
case 'values': return entries.map(([, value]) => value);
|
|
40
|
+
default: return entries;
|
|
41
|
+
}
|
|
21
42
|
}
|
|
22
43
|
Object.array = array;
|
|
23
44
|
|
|
@@ -15,20 +15,20 @@ declare global {
|
|
|
15
15
|
pick<From extends {}, Props extends keyof From>(from: From, ...props: Array<Props | Partial<From>>): Pick<From, Props>;
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
18
|
+
* Returns the difference between two objects (properties where values differ)
|
|
19
19
|
* @param source Source object
|
|
20
20
|
* @param target Target object
|
|
21
|
-
* @param exclude Properties to exclude from
|
|
22
|
-
* @returns Object with properties
|
|
21
|
+
* @param exclude Properties to exclude from comparison
|
|
22
|
+
* @returns Object with properties where values differ between source and target, excluding specified properties
|
|
23
23
|
*/
|
|
24
|
-
difference<T extends object>(source: T, target: T, ...exclude: Array<keyof T>):
|
|
24
|
+
difference<T extends object>(source: T, target: T, ...exclude: Array<keyof T>): Partial<T>;
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Deeply combines objects, with later objects in parameters taking precedence over earlier ones. Does not combine arrays.
|
|
28
28
|
* @param objects Objects to combine
|
|
29
29
|
* @returns Combined object
|
|
30
30
|
*/
|
|
31
|
-
combine<T extends Record<string, any | undefined>>(...objects: Array<
|
|
31
|
+
combine<T extends Record<string, any | undefined>>(...objects: Array<Combinable<T> | undefined>): T;
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -60,16 +60,21 @@ export function pick<From extends {}, Props extends keyof From>(from: From, ...p
|
|
|
60
60
|
}
|
|
61
61
|
Object.pick = pick;
|
|
62
62
|
|
|
63
|
-
export function difference<T extends object>(source: T, target: T, ...exclude: Array<keyof T>):
|
|
64
|
-
const
|
|
65
|
-
|
|
63
|
+
export function difference<T extends object>(source: T, target: T, ...exclude: Array<keyof T>): Partial<T> {
|
|
64
|
+
const excludeSet = new Set(exclude);
|
|
65
|
+
const allKeys = new Set([...Object.keysOf(source), ...Object.keysOf(target)]);
|
|
66
66
|
|
|
67
|
-
return [...
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
return [...allKeys].reduce((acc, key) => {
|
|
68
|
+
if (excludeSet.has(key)) return acc;
|
|
69
|
+
|
|
70
|
+
const sourceValue = (source as any)[key];
|
|
71
|
+
const targetValue = (target as any)[key];
|
|
72
|
+
|
|
73
|
+
if (JSON.stringify(sourceValue) !== JSON.stringify(targetValue)) {
|
|
74
|
+
acc[key] = targetValue;
|
|
75
|
+
}
|
|
71
76
|
return acc;
|
|
72
|
-
}, {} as T
|
|
77
|
+
}, {} as any) as Partial<T>;
|
|
73
78
|
}
|
|
74
79
|
Object.difference = difference;
|
|
75
80
|
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export * from './case.extension';
|
|
1
|
+
export * from './case.extension';
|
|
2
|
+
export * from './string.extension';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
interface String {
|
|
3
|
+
truncate(length: number, ellipsis?: string): string;
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function truncate(this: string, length: number, ellipsis: string = "..."): string {
|
|
8
|
+
if (this.length <= length) return this;
|
|
9
|
+
return this.slice(0, length - ellipsis.length) + ellipsis;
|
|
10
|
+
}
|
|
11
|
+
String.prototype.truncate = truncate;
|
package/src/Types/Able.ts
CHANGED
package/src/Utils/NumberUtils.ts
CHANGED
|
@@ -1,3 +1,30 @@
|
|
|
1
1
|
export function between(min: number, max: number): number {
|
|
2
2
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function randomWithPercentages<T>(items: [item: T, weight: number][]): T {
|
|
6
|
+
if (items.length === 0) throw new Error('Items array cannot be empty');
|
|
7
|
+
|
|
8
|
+
// Calculate total weight in case weights don't sum to 100
|
|
9
|
+
const totalWeight = items.reduce((sum, [, weight]) => sum + weight, 0);
|
|
10
|
+
if (totalWeight === 0) throw new Error('Total weight must be greater than zero');
|
|
11
|
+
|
|
12
|
+
// Generate random number between 0 and totalWeight
|
|
13
|
+
const random = Math.random() * totalWeight;
|
|
14
|
+
|
|
15
|
+
// Find the item that corresponds to this random value
|
|
16
|
+
let currentWeight = 0;
|
|
17
|
+
for (const [item, weight] of items) {
|
|
18
|
+
currentWeight += weight;
|
|
19
|
+
if (random <= currentWeight) {
|
|
20
|
+
return item;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
throw new Error('Unable to select an item based on weights');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const NumberUtils = {
|
|
28
|
+
between,
|
|
29
|
+
randomWithPercentages,
|
|
3
30
|
}
|
package/src/Utils/StringUtils.ts
CHANGED
|
@@ -41,4 +41,10 @@ export function pluralize(countable: number | ArrayLike<any> | Map<any, any>, si
|
|
|
41
41
|
if (count === 1) return singular;
|
|
42
42
|
if (plural) return plural;
|
|
43
43
|
return `${singular}s`;
|
|
44
|
-
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const StringUtils = {
|
|
47
|
+
classNames,
|
|
48
|
+
randomId,
|
|
49
|
+
pluralize
|
|
50
|
+
};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import * as Debounce from './debounce.util';
|
|
2
2
|
import * as Functions from './functions.util';
|
|
3
3
|
import * as Throttle from './throttle.util';
|
|
4
|
+
import * as StringUtils from './string.util';
|
|
4
5
|
|
|
5
6
|
export const TimeUtils = {
|
|
6
7
|
...Functions,
|
|
7
8
|
...Debounce,
|
|
8
9
|
...Throttle,
|
|
10
|
+
...StringUtils,
|
|
9
11
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function ensureStartZero(num: number): string {
|
|
2
|
+
return num < 10 ? `0${num}` : num.toString();
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function get12HourFormat(hour: number): string {
|
|
6
|
+
if (hour === 0) return '12am';
|
|
7
|
+
if (hour > 12) return `${hour - 12}pm`;
|
|
8
|
+
return `${hour}am`;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function get24HourFormat(hour: number): string {
|
|
12
|
+
return ensureStartZero(hour);
|
|
13
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { PropertiesWith, If } from '../../Types';
|
|
2
|
-
import { convertCase } from '../String/case.extension';
|
|
3
|
-
|
|
4
|
-
type PrimitiveMap = {
|
|
5
|
-
string: string;
|
|
6
|
-
number: number;
|
|
7
|
-
boolean: boolean;
|
|
8
|
-
undefined: undefined;
|
|
9
|
-
null: null;
|
|
10
|
-
object: object;
|
|
11
|
-
function: Function;
|
|
12
|
-
any: any;
|
|
13
|
-
Date: Date;
|
|
14
|
-
RegExp: RegExp;
|
|
15
|
-
Promise: Promise<any>;
|
|
16
|
-
Array: Array<any>;
|
|
17
|
-
Map: Map<any, any>;
|
|
18
|
-
Set: Set<any>;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Object with getPrimitiveTypes<Source, AllowFunctions extends boolean>(
|
|
23
|
-
* source: Source,
|
|
24
|
-
* allowFunctions: AllowFunctions = false
|
|
25
|
-
* ): Object with properties from source that matches primitive type
|
|
26
|
-
*/
|
|
27
|
-
export type Properties = {
|
|
28
|
-
[Key in keyof PrimitiveMap as `get${Capitalize<Key>}s`]:
|
|
29
|
-
<Source extends {}, AllowFunctions extends boolean = false>(source: Source, withFunctions?: AllowFunctions) =>
|
|
30
|
-
If<AllowFunctions,
|
|
31
|
-
PropertiesWith<PrimitiveMap[Key] | ((...args: any[]) => PrimitiveMap[Key]), Source>,
|
|
32
|
-
PropertiesWith<PrimitiveMap[Key], Source>
|
|
33
|
-
>
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export const properties: Properties = [
|
|
37
|
-
'string', 'number', 'boolean', 'undefined', 'null',
|
|
38
|
-
'object', 'function', 'any',
|
|
39
|
-
'Date', 'RegExp', 'Promise', 'Array', 'Map', 'Set'
|
|
40
|
-
].reduce((result, primitive) => {
|
|
41
|
-
result[`get${convertCase('camel', 'pascal')}s` as keyof Properties] = function <Source extends {}, AllowFunctions extends boolean = false>(source: Source, withFunctions: AllowFunctions = false as AllowFunctions) {
|
|
42
|
-
return Object.keysOf<Source>(source).reduce((result, key) => {
|
|
43
|
-
if ((source[key] as any).constructor.name === primitive ||
|
|
44
|
-
(withFunctions && typeof source[key] === 'function' && source[key] as any).constructor.name === primitive) {
|
|
45
|
-
result[key] = source[key];
|
|
46
|
-
}
|
|
47
|
-
return result;
|
|
48
|
-
}, {} as any);
|
|
49
|
-
};
|
|
50
|
-
return result;
|
|
51
|
-
}, {} as Properties);
|