@zelgadis87/utils-core 4.3.5 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Optional.d.ts +1 -1
- package/dist/async/RateThrottler.d.ts +2 -1
- package/dist/index.d.ts +5 -8
- package/dist/lazy/index.d.ts +2 -0
- package/dist/sorting/ComparisonChain.d.ts +1 -1
- package/dist/sorting/Sorter.d.ts +1 -1
- package/dist/sorting/types.d.ts +1 -1
- package/dist/time/TimeDuration.d.ts +1 -1
- package/dist/time/TimeFrequency.d.ts +1 -1
- package/dist/time/TimeRange.d.ts +2 -2
- package/dist/time/types.d.ts +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/upgrade/DataUpgrader.d.ts +1 -1
- package/dist/upgrade/getTransitionsPath.d.ts +1 -1
- package/dist/upgrade/types.d.ts +1 -1
- package/dist/utils/{groupBy.d.ts → arrays/groupBy.d.ts} +1 -1
- package/dist/utils/{indexBy.d.ts → arrays/indexBy.d.ts} +1 -1
- package/dist/utils/{math.d.ts → arrays/statistics.d.ts} +1 -2
- package/dist/utils/arrays/uniqBy.d.ts +4 -0
- package/dist/{types → utils}/arrays.d.ts +10 -4
- package/dist/utils/errors/withTryCatch.d.ts +3 -0
- package/dist/{types → utils}/errors.d.ts +1 -0
- package/dist/utils/functions/bindThis.d.ts +1 -0
- package/dist/utils/{iff.d.ts → functions/iff.d.ts} +3 -3
- package/dist/{types → utils}/functions.d.ts +4 -0
- package/dist/utils/index.d.ts +13 -19
- package/dist/utils/json.d.ts +11 -0
- package/dist/{types → utils}/numbers.d.ts +3 -1
- package/dist/utils/primitives.d.ts +3 -0
- package/dist/utils/random.d.ts +2 -0
- package/dist/utils/{entries.d.ts → records/entries.d.ts} +1 -1
- package/dist/{types → utils}/records.d.ts +1 -0
- package/dist/{types/strings.d.ts → utils/strings/StringParts.d.ts} +2 -15
- package/dist/utils/strings.d.ts +17 -0
- package/esbuild/index.cjs +542 -701
- package/esbuild/index.mjs +536 -697
- package/package.json +1 -1
- package/src/Logger.ts +1 -1
- package/src/Optional.ts +2 -2
- package/src/async/Deferred.ts +1 -1
- package/src/async/RateThrottler.ts +8 -1
- package/src/async/index.ts +1 -0
- package/src/index.ts +5 -8
- package/src/{Lazy.ts → lazy/Lazy.ts} +1 -1
- package/src/{LazyAsync.ts → lazy/LazyAsync.ts} +1 -1
- package/src/lazy/index.ts +3 -0
- package/src/sorting/ComparisonChain.ts +2 -2
- package/src/sorting/Sorter.ts +2 -2
- package/src/sorting/types.ts +1 -1
- package/src/time/RandomTimeDuration.ts +1 -1
- package/src/time/TimeDuration.ts +1 -2
- package/src/time/TimeFrequency.ts +1 -1
- package/src/time/TimeInstantBuilder.ts +2 -2
- package/src/time/TimeRange.ts +2 -2
- package/src/time/types.ts +1 -1
- package/src/upgrade/DataUpgrader.ts +1 -1
- package/src/upgrade/getTransitionsPath.ts +1 -1
- package/src/upgrade/types.ts +1 -1
- package/src/utils/{groupBy.ts → arrays/groupBy.ts} +1 -1
- package/src/utils/{indexBy.ts → arrays/indexBy.ts} +1 -1
- package/src/utils/{math.ts → arrays/statistics.ts} +1 -13
- package/src/utils/arrays/uniqBy.ts +24 -0
- package/src/{types → utils}/arrays.ts +15 -6
- package/src/utils/errors/withTryCatch.ts +15 -0
- package/src/{types → utils}/errors.ts +2 -0
- package/src/utils/functions/bindThis.ts +4 -0
- package/src/utils/{iff.ts → functions/iff.ts} +4 -2
- package/src/{types → utils}/functions.ts +6 -0
- package/src/utils/index.ts +13 -19
- package/src/utils/json.ts +49 -0
- package/src/utils/{round.ts → numbers/round.ts} +1 -0
- package/src/{types → utils}/numbers.ts +15 -1
- package/src/utils/primitives.ts +5 -0
- package/src/utils/random.ts +9 -0
- package/src/utils/{entries.ts → records/entries.ts} +1 -1
- package/src/{types → utils}/records.ts +2 -0
- package/src/utils/strings/StringParts.ts +114 -0
- package/src/utils/strings.ts +91 -0
- package/dist/random/index.d.ts +0 -2
- package/dist/random/randomInterval.d.ts +0 -1
- package/dist/random/randomPercentage.d.ts +0 -1
- package/dist/types/index.d.ts +0 -14
- package/dist/types/json.d.ts +0 -7
- package/dist/utils/bindThis.d.ts +0 -1
- package/dist/utils/jsonCloneDeep.d.ts +0 -2
- package/dist/utils/noop.d.ts +0 -1
- package/dist/utils/omit.d.ts +0 -2
- package/dist/utils/sortBy.d.ts +0 -7
- package/dist/utils/throttle.d.ts +0 -3
- package/dist/utils/uniq.d.ts +0 -1
- package/dist/utils/uniqBy.d.ts +0 -2
- package/dist/utils/uniqByKey.d.ts +0 -1
- package/dist/utils/upsert.d.ts +0 -0
- package/dist/utils/withTryCatch.d.ts +0 -2
- package/dist/utils/withTryCatchAsync.d.ts +0 -2
- package/dist/utils/wrap.d.ts +0 -1
- package/src/random/index.ts +0 -3
- package/src/random/randomInterval.ts +0 -4
- package/src/random/randomPercentage.ts +0 -6
- package/src/types/index.ts +0 -20
- package/src/types/json.ts +0 -15
- package/src/types/strings.ts +0 -191
- package/src/utils/bindThis.ts +0 -4
- package/src/utils/jsonCloneDeep.ts +0 -31
- package/src/utils/noop.ts +0 -2
- package/src/utils/omit.ts +0 -8
- package/src/utils/sortBy.ts +0 -27
- package/src/utils/throttle.ts +0 -10
- package/src/utils/uniq.ts +0 -6
- package/src/utils/uniqBy.ts +0 -15
- package/src/utils/uniqByKey.ts +0 -5
- package/src/utils/upsert.ts +0 -2
- package/src/utils/withTryCatch.ts +0 -9
- package/src/utils/withTryCatchAsync.ts +0 -5
- package/src/utils/wrap.ts +0 -4
- /package/dist/{Lazy.d.ts → lazy/Lazy.d.ts} +0 -0
- /package/dist/{LazyAsync.d.ts → lazy/LazyAsync.d.ts} +0 -0
- /package/dist/{types → utils}/booleans.d.ts +0 -0
- /package/dist/{types → utils}/empties.d.ts +0 -0
- /package/dist/utils/{constant.d.ts → functions/constant.d.ts} +0 -0
- /package/dist/{types → utils}/nulls.d.ts +0 -0
- /package/dist/utils/{round.d.ts → numbers/round.d.ts} +0 -0
- /package/dist/{types → utils}/promises.d.ts +0 -0
- /package/src/{types → utils}/booleans.ts +0 -0
- /package/src/{types → utils}/empties.ts +0 -0
- /package/src/utils/{constant.ts → functions/constant.ts} +0 -0
- /package/src/{types → utils}/nulls.ts +0 -0
- /package/src/{types → utils}/promises.ts +0 -0
package/package.json
CHANGED
package/src/Logger.ts
CHANGED
package/src/Optional.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { TConsumer, TFunction, TPredicate, TProducer, TVoidFunction } from "./
|
|
2
|
-
import { isDefined, isNullOrUndefined } from "./
|
|
1
|
+
import { TConsumer, TFunction, TPredicate, TProducer, TVoidFunction } from "./utils/functions.js";
|
|
2
|
+
import { isDefined, isNullOrUndefined } from "./utils/nulls.js";
|
|
3
3
|
|
|
4
4
|
export class Optional<T> implements TOptional<T> {
|
|
5
5
|
|
package/src/async/Deferred.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TFunction, TimeInstant } from "..";
|
|
1
|
+
import { TFunction, TimeInstant, TPromisable } from "..";
|
|
2
2
|
import TimeFrequency from "../time/TimeFrequency";
|
|
3
3
|
import Deferred from "./Deferred";
|
|
4
4
|
|
|
@@ -44,3 +44,10 @@ export class RateThrottler {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
export default RateThrottler;
|
|
47
|
+
|
|
48
|
+
export function throttle<TParams extends unknown[], R>( fn: (...params: TParams) => TPromisable<R>, frequence: TimeFrequency ): (...params: TParams) => Promise<R> {
|
|
49
|
+
const semaphore = new RateThrottler( frequence );
|
|
50
|
+
return (...t: TParams): Promise<R> => {
|
|
51
|
+
return semaphore.execute<R>( async () => fn( ...t ) );
|
|
52
|
+
};
|
|
53
|
+
}
|
package/src/async/index.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
|
|
2
|
-
export
|
|
3
|
-
export
|
|
2
|
+
export * from './async/index.js';
|
|
3
|
+
export * from './lazy/index.js';
|
|
4
4
|
export { default as Logger } from './Logger';
|
|
5
5
|
export * from './Optional.js';
|
|
6
|
-
export * from './async';
|
|
7
|
-
export * from './random';
|
|
8
6
|
export * from './sorting/index.js';
|
|
9
|
-
export * from './time';
|
|
10
|
-
export * from './
|
|
11
|
-
export * from './
|
|
12
|
-
export * from './utils';
|
|
7
|
+
export * from './time/index.js';
|
|
8
|
+
export * from './upgrade/index.js';
|
|
9
|
+
export * from './utils/index.js';
|
|
13
10
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { identity } from "../utils/functions/constant.js";
|
|
2
|
+
import { TFunction, TKeysOfType, TReadableArray, isDefined, isNullOrUndefined } from "../utils/index.js";
|
|
3
3
|
import { TComparisonDirection, TComparisonFunction, TComparisonResult } from "./types.js";
|
|
4
4
|
|
|
5
5
|
type TCompareValueOptions = {
|
package/src/sorting/Sorter.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { identity } from "../utils/functions/constant.js";
|
|
2
|
+
import { TBiFunction, TConditionalParameterOptions, TFunction, TKeysOfType, TPositiveNumber, TReadableArray, isDefined, isNullOrUndefined } from "../utils/index.js";
|
|
3
3
|
import { TComparisonDirection, TComparisonFunction, TComparisonResult, TStrictComparisonResult } from "./types.js";
|
|
4
4
|
|
|
5
5
|
type TCompareValuesOptions = {
|
package/src/sorting/types.ts
CHANGED
package/src/time/TimeDuration.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import Deferred, { DeferredCanceledError, ICancelable, ICancelablePromise } from "../async/Deferred.js";
|
|
2
|
-
import { randomInterval } from "../random";
|
|
3
2
|
import { TComparisonResult } from "../sorting/index.js";
|
|
4
|
-
import { TIntervalHandle, TMaybe, TTimeoutHandle, ensureNonNegativeNumber, ensurePositiveNumber, pad } from "../
|
|
3
|
+
import { TIntervalHandle, TMaybe, TTimeoutHandle, ensureNonNegativeNumber, ensurePositiveNumber, pad, randomInterval } from "../utils/index.js";
|
|
5
4
|
import TimeBase from "./TimeBase";
|
|
6
5
|
import TimeInstant from "./TimeInstant";
|
|
7
6
|
import TimeUnit from "./TimeUnit";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
|
-
import { TFunction } from "../
|
|
3
|
-
import { ensureDefined } from "../
|
|
2
|
+
import { TFunction } from "../utils/functions.js";
|
|
3
|
+
import { ensureDefined } from "../utils/nulls.js";
|
|
4
4
|
import { TimeInstant, isTimeInstant } from "./TimeInstant.js";
|
|
5
5
|
import { TDayOfMonth, THourOfDay, TMillisecondOfSecond, TMinuteOfHour, TMonth, TSecondOfMinute, TUpToTwoDigits } from "./types.js";
|
|
6
6
|
|
package/src/time/TimeRange.ts
CHANGED
package/src/time/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
|
-
import { isDefined, isNumber, isPositiveNumber, TJsonSerializable } from "../types/index.ts";
|
|
3
2
|
import { jsonCloneDeep } from "../utils";
|
|
3
|
+
import { isDefined, isNumber, isPositiveNumber, TJsonSerializable } from "../utils/index.js";
|
|
4
4
|
import { EmptyUpgradeError, UnavailableUpgradeError } from "./errors";
|
|
5
5
|
import getTransitionsPath from "./getTransitionsPath";
|
|
6
6
|
import { TPossibleFromVersion, TPossibleVersion, TTransitionMatrix, TUpgradable, TUpgradeFunction, TVersionMap } from "./types";
|
package/src/upgrade/types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import { TFunction, TKeysOfType } from "
|
|
2
|
+
import { TFunction, TKeysOfType } from "..";
|
|
3
3
|
|
|
4
4
|
export function groupByString<V, K extends TKeysOfType<V, string>>( arr: V[], field: K ): Record<V[K] & string, V[]> {
|
|
5
5
|
return groupByStringWith( arr, t => t[ field ] as string );
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import { TFunction, TKeysOfType } from "
|
|
2
|
+
import { TFunction, TKeysOfType } from "..";
|
|
3
3
|
|
|
4
4
|
export function indexByString<V, K extends TKeysOfType<V, string>>( arr: V[], field: K ): Record<V[K] & string, V> {
|
|
5
5
|
return indexByStringWith( arr, t => t[ field ] as string );
|
|
@@ -1,16 +1,4 @@
|
|
|
1
|
-
import { TReadableArray } from "../
|
|
2
|
-
|
|
3
|
-
export function clamp( n: number, min: number, max: number ): number {
|
|
4
|
-
if ( min === null || max === null || n === null || isNaN( min ) || isNaN( max ) || isNaN( n ) || min > max )
|
|
5
|
-
throw new Error();
|
|
6
|
-
if ( n > max ) {
|
|
7
|
-
return max;
|
|
8
|
-
} else if ( n < min ) {
|
|
9
|
-
return min;
|
|
10
|
-
} else {
|
|
11
|
-
return n;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
1
|
+
import type { TReadableArray } from "../arrays.js";
|
|
14
2
|
|
|
15
3
|
export function average( arr: TReadableArray<number> ): number {
|
|
16
4
|
const f = 1 / arr.length;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
import { TFunction, identity } from "../functions.js";
|
|
3
|
+
|
|
4
|
+
export function uniq<T>( arr: T[] ): T[] {
|
|
5
|
+
return uniqBy( arr, identity );
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function uniqBy<T, K>( arr: T[], getter: TFunction<T, K> ): T[] {
|
|
9
|
+
return arr.reduce( ( dict, cur ) => {
|
|
10
|
+
const key = getter( cur );
|
|
11
|
+
if ( dict.keys.includes( key ) ) {
|
|
12
|
+
return dict;
|
|
13
|
+
} else {
|
|
14
|
+
return {
|
|
15
|
+
keys: [ ...dict.keys, key ],
|
|
16
|
+
values: [ ...dict.values, cur ]
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
}, { keys: [], values: [] } as { keys: K[], values: T[] } ).values;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function uniqByKey<T, K extends keyof T>( arr: T[], key: K ): T[] {
|
|
23
|
+
return uniqBy( arr, item => item[ key ] );
|
|
24
|
+
}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import { TComparisonFunction } from "../sorting/index.js";
|
|
2
|
-
import { TBiPredicate } from "./functions.js";
|
|
3
|
-
import { TMaybe } from "./nulls.js";
|
|
1
|
+
import type { TComparisonFunction } from "../sorting/index.js";
|
|
2
|
+
import type { TBiPredicate } from "./functions.js";
|
|
3
|
+
import type { TMaybe } from "./nulls.js";
|
|
4
|
+
|
|
5
|
+
export * from './arrays/groupBy.js';
|
|
6
|
+
export * from './arrays/indexBy.js';
|
|
7
|
+
export * from './arrays/statistics.js';
|
|
8
|
+
export * from './arrays/uniqBy.js';
|
|
4
9
|
|
|
5
10
|
export type TReadableArray<T> = Array<T> | ReadonlyArray<T>;
|
|
6
11
|
export type TArrayable<T> = T | T[];
|
|
@@ -67,12 +72,16 @@ export function reverse<T>( arr: TReadableArray<T> ): Array<T> {
|
|
|
67
72
|
return [ ...arr ].reverse();
|
|
68
73
|
}
|
|
69
74
|
|
|
70
|
-
export function
|
|
75
|
+
export function first<T>( arr: TReadableArray<T>, defaultValue: TMaybe<T> = null ): TMaybe<T> {
|
|
71
76
|
return ( arr.length ? arr[ 0 ] : defaultValue );
|
|
72
77
|
}
|
|
73
|
-
|
|
74
78
|
export function last<T>( arr: TReadableArray<T>, defaultValue: TMaybe<T> = null ): TMaybe<T> {
|
|
75
|
-
return
|
|
79
|
+
return( arr.length ? arr[ arr.length - 1 ] : defaultValue );
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export const head = first;
|
|
83
|
+
export function tail<T>( arr: TReadableArray<T> ): T[] {
|
|
84
|
+
return( arr.length ? arr.slice( 1 ) : [] );
|
|
76
85
|
}
|
|
77
86
|
|
|
78
87
|
export function sortedArray<T>( arr: Array<T>, sortFn?: TComparisonFunction<T> | undefined ): Array<T>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
|
|
2
|
+
import { asError } from "../errors.js";
|
|
3
|
+
import type { TFunction } from "../functions.js";
|
|
4
|
+
|
|
5
|
+
export function withTryCatch<R>( fn: TFunction<void, R> ): [ R, undefined ] | [ undefined, Error ] {
|
|
6
|
+
try {
|
|
7
|
+
return [ fn(), void 0 ] as const;
|
|
8
|
+
} catch ( e: unknown ) {
|
|
9
|
+
return [ void 0, asError( e ) ] as const;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export async function withTryCatchAsync<R>( fn: TFunction<void, Promise<R>> ): Promise<[ R, undefined ] | [ undefined, Error ]> {
|
|
14
|
+
return fn().then( ( value: R ) => [ value, void 0 ] as const, ( e: unknown ) => [ void 0, asError( e ) ] as const );
|
|
15
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TPredicate } from "
|
|
1
|
+
import { TPredicate } from "..";
|
|
2
2
|
|
|
3
3
|
type TBooleanOrPredicate = boolean | TPredicate<void>;
|
|
4
4
|
type TIff<T> = {
|
|
@@ -6,7 +6,7 @@ type TIff<T> = {
|
|
|
6
6
|
otherwise<R>( valueIfElse: R ): T | R;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export
|
|
9
|
+
export function iff<T>( firstPredicate: TBooleanOrPredicate, valueIfTrue: T ): TIff<T> {
|
|
10
10
|
|
|
11
11
|
if ( firstPredicate === true || ( firstPredicate instanceof Function && firstPredicate() === true ) ) {
|
|
12
12
|
const ret: TIff<T> = {
|
|
@@ -24,3 +24,5 @@ export default function iff<T>( firstPredicate: TBooleanOrPredicate, valueIfTrue
|
|
|
24
24
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
export default iff;
|
|
28
|
+
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
|
|
2
|
+
export * from './functions/bindThis.js';
|
|
3
|
+
export * from './functions/constant.js';
|
|
4
|
+
export * from './functions/iff.js';
|
|
5
|
+
|
|
2
6
|
export type TFunction<A, R> = ( a: A ) => R;
|
|
3
7
|
export type TVoidFunction = TFunction<void, void>
|
|
4
8
|
export type TProducer<R> = TFunction<void, R>;
|
|
@@ -25,3 +29,5 @@ export type TAsyncAnyFunction<R> = ( ...args: unknown[] ) => Promise<R>;
|
|
|
25
29
|
export function isFunction( t: unknown ): t is Function { // eslint-disable-line @typescript-eslint/no-unsafe-function-type
|
|
26
30
|
return typeof t === 'function';
|
|
27
31
|
}
|
|
32
|
+
|
|
33
|
+
export function noop(): void { } // eslint-disable-line @typescript-eslint/no-empty-function
|
package/src/utils/index.ts
CHANGED
|
@@ -1,21 +1,15 @@
|
|
|
1
1
|
|
|
2
|
-
export
|
|
3
|
-
export * from './
|
|
4
|
-
export * from './
|
|
5
|
-
export * from './
|
|
6
|
-
export
|
|
7
|
-
export * from './
|
|
8
|
-
export
|
|
9
|
-
export * from './
|
|
10
|
-
export
|
|
11
|
-
export
|
|
12
|
-
export * from './
|
|
13
|
-
export
|
|
14
|
-
export
|
|
15
|
-
export { default as uniq } from './uniq';
|
|
16
|
-
export { default as uniqBy } from './uniqBy';
|
|
17
|
-
export { default as uniqByKey } from './uniqByKey';
|
|
18
|
-
export { default as withTryCatch } from './withTryCatch';
|
|
19
|
-
export { default as withTryCatchAsync } from './withTryCatchAsync';
|
|
20
|
-
export { default as wrap } from './wrap';
|
|
2
|
+
export * from './arrays.js';
|
|
3
|
+
export * from './booleans.js';
|
|
4
|
+
export * from './empties.js';
|
|
5
|
+
export * from './errors.js';
|
|
6
|
+
export * from './functions.js';
|
|
7
|
+
export * from './json.js';
|
|
8
|
+
export * from './nulls.js';
|
|
9
|
+
export * from './numbers.js';
|
|
10
|
+
export * from './primitives.js';
|
|
11
|
+
export * from './promises.js';
|
|
12
|
+
export * from './random.js';
|
|
13
|
+
export * from './records.js';
|
|
14
|
+
export * from './strings.js';
|
|
21
15
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { withTryCatch } from "./errors.js";
|
|
2
|
+
|
|
3
|
+
export type TJsonPrimitive = string | number | boolean | null | undefined;
|
|
4
|
+
export type TJsonArray = Array<TJsonSerializable> | ReadonlyArray<TJsonSerializable>;
|
|
5
|
+
export type TJsonObject = { [ key: string ]: TJsonSerializable }
|
|
6
|
+
export type TJsonSerializable = TJsonPrimitive | TJsonArray | TJsonObject;
|
|
7
|
+
|
|
8
|
+
export function tryToParseJson<T extends TJsonSerializable>( jsonContent: string ): [ T, undefined ] | [ undefined, Error ] {
|
|
9
|
+
return withTryCatch( () => JSON.parse( jsonContent ) as T );
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function jsonCloneDeep<A extends TJsonSerializable>( a: A ): A {
|
|
13
|
+
|
|
14
|
+
// Handle the 3 simple types, and null or undefined
|
|
15
|
+
if ( null === a || "object" !== typeof a ) return a;
|
|
16
|
+
|
|
17
|
+
if ( a instanceof Date ) {
|
|
18
|
+
// Handle Date
|
|
19
|
+
return new Date( a.getTime() ) as unknown as A;
|
|
20
|
+
} else if ( a instanceof Array ) {
|
|
21
|
+
// Handle Array
|
|
22
|
+
const copy = [] as unknown[];
|
|
23
|
+
for ( let i = 0, len = a.length; i < len; i++ ) {
|
|
24
|
+
copy[ i ] = jsonCloneDeep( a[ i ] );
|
|
25
|
+
}
|
|
26
|
+
return copy as A;
|
|
27
|
+
} else if ( a instanceof Object ) {
|
|
28
|
+
// Handle Object
|
|
29
|
+
const copy = {} as Record<string | number | symbol, unknown>;
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
31
|
+
for ( let attr in ( a as TJsonObject ) ) {
|
|
32
|
+
if ( a.hasOwnProperty( attr ) )
|
|
33
|
+
copy[ attr ] = jsonCloneDeep( a[ attr ] );
|
|
34
|
+
}
|
|
35
|
+
return copy as A;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
throw new Error( "Unable to copy obj! Its type isn't supported." );
|
|
39
|
+
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function omitFromJsonObject<T extends TJsonObject, K extends keyof T>( o: T, ...keys: K[] ): Omit<T, K> {
|
|
43
|
+
return keys.reduce( ( obj, key ) => {
|
|
44
|
+
delete obj[ key ];
|
|
45
|
+
return obj;
|
|
46
|
+
}, { ...o } );
|
|
47
|
+
}
|
|
48
|
+
/** @deprecated[2024-12-23]: Use {@link omitFromJsonObject} instead. */
|
|
49
|
+
export const omit = omitFromJsonObject;
|
|
@@ -15,6 +15,7 @@ export function round( n: number, precision: number = 0, mode: TRoundMode = 'toN
|
|
|
15
15
|
const power = Math.pow( base, precision );
|
|
16
16
|
return roundModes[ mode ]( n * power ) / power;
|
|
17
17
|
}
|
|
18
|
+
|
|
18
19
|
export default round;
|
|
19
20
|
export const roundToNearest = ( n: number, precision: number = 0 ) => round( n, precision, 'toNearest' );
|
|
20
21
|
export const roundToLower = ( n: number, precision: number = 0 ) => round( n, precision, 'toLower' );
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { TFunction } from "./functions.js";
|
|
2
1
|
|
|
2
|
+
import type { TFunction } from "./functions.js";
|
|
3
|
+
|
|
4
|
+
export * from './numbers/round.js';
|
|
3
5
|
|
|
4
6
|
export type TNumericString = `${number}`;
|
|
5
7
|
export type TNumericFloatingPointString = `${number}.${number}`;
|
|
@@ -78,3 +80,15 @@ export function isNegativeNumber( v: number ): v is TNegativeNumber {
|
|
|
78
80
|
export function isZero( v: number ): v is TZero {
|
|
79
81
|
return v === 0;
|
|
80
82
|
}
|
|
83
|
+
|
|
84
|
+
export function clamp( n: number, min: number, max: number ): number {
|
|
85
|
+
if ( min === null || max === null || n === null || isNaN( min ) || isNaN( max ) || isNaN( n ) || min > max )
|
|
86
|
+
throw new Error();
|
|
87
|
+
if ( n > max ) {
|
|
88
|
+
return max;
|
|
89
|
+
} else if ( n < min ) {
|
|
90
|
+
return min;
|
|
91
|
+
} else {
|
|
92
|
+
return n;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { TReadableArray } from "../arrays.js";
|
|
2
|
+
import { TMaybe } from "../nulls.js";
|
|
3
|
+
import { capitalizeWord } from "../strings.js";
|
|
4
|
+
|
|
5
|
+
export class StringParts {
|
|
6
|
+
|
|
7
|
+
private readonly _parts: string[];
|
|
8
|
+
|
|
9
|
+
private constructor( ...parts: string[] ) {
|
|
10
|
+
this._parts = parts;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
public toUpperCase() {
|
|
14
|
+
return new StringParts( ...this.parts.map( part => part.toUpperCase() ) );
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
public toLowerCase() {
|
|
18
|
+
return new StringParts( ...this.parts.map( part => part.toLowerCase() ) );
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public capitalizeFirst() {
|
|
22
|
+
if ( !this.length ) return this;
|
|
23
|
+
return new StringParts( capitalizeWord( this.first! ), ...this.tail.map( part => part.toLowerCase() ) );
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public capitalizeEach() {
|
|
27
|
+
return new StringParts( ...this.parts.map( part => capitalizeWord( part ) ) );
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public get parts() {
|
|
31
|
+
return this._parts;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public get tail() {
|
|
35
|
+
const [ _first, ...tail ] = this.parts;
|
|
36
|
+
return tail;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public get first(): TMaybe<string> {
|
|
40
|
+
return this._parts[ 0 ] ?? null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public get last(): TMaybe<string> {
|
|
44
|
+
return this._parts[ this.length - 1 ] ?? null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public get length() {
|
|
48
|
+
return this._parts.length;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
public trim() {
|
|
52
|
+
return new StringParts( ...this.parts.map( part => part.trim() ) );
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public toSnakeCase() {
|
|
56
|
+
return this.toLowerCase().join( '_' );
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
public toCamelCase() {
|
|
60
|
+
if ( !this.length ) return '';
|
|
61
|
+
return [ this.first!.toLowerCase(), ...this.tail.map( capitalizeWord ) ].join( '' );
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public toKebabCase() {
|
|
65
|
+
return this.toLowerCase().join( '-' );
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public toPascalCase() {
|
|
69
|
+
return this.capitalizeEach().join( '' );
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public toHumanCase() {
|
|
73
|
+
return this.capitalizeFirst().join( ' ' );
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
public join( separator: string ) {
|
|
77
|
+
return this.parts.join( separator );
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
public mergeWith( { parts: otherParts }: { parts: TReadableArray<string>; } ) {
|
|
81
|
+
return new StringParts( ...this.parts, ...otherParts );
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public slice( start: number, end?: number ) {
|
|
85
|
+
return new StringParts( ...this.parts.slice( start, end ) );
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
public splice( start: number, deleteCount: number, ...items: string[] ) {
|
|
89
|
+
return new StringParts( ...this.parts.splice( start, deleteCount, ...items ) );
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
public push( part: string ) {
|
|
93
|
+
return new StringParts( ...this.parts, part );
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
public shift( part: string ) {
|
|
97
|
+
return new StringParts( part, ...this.parts );
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
public reverse() {
|
|
101
|
+
return new StringParts( ...this.parts.reverse() );
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
public static fromString = ( s: string, separator: string | RegExp = /\s+/g ) => {
|
|
105
|
+
if ( s === null || separator === null )
|
|
106
|
+
throw new Error( 'Invalid arguments' );
|
|
107
|
+
return new StringParts( ...s.split( separator ) );
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
public static fromParts = ( ...parts: string[] ) => {
|
|
111
|
+
return new StringParts( ...parts );
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
}
|