@zelgadis87/utils-core 4.3.4 → 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} +3 -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 +548 -697
- package/esbuild/index.mjs +540 -693
- package/package.json +3 -40
- 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
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { range } from "./arrays.js";
|
|
2
|
+
import { ensureDefined, isNullOrUndefined } from "./nulls.js";
|
|
3
|
+
|
|
4
|
+
export * from './strings/StringParts.js';
|
|
5
|
+
|
|
6
|
+
// Semantic-only
|
|
7
|
+
export type THtmlString = string;
|
|
8
|
+
export type TUrl = string;
|
|
9
|
+
export type TRelativeUrl = string;
|
|
10
|
+
|
|
11
|
+
export function hashCode( str: string ): number {
|
|
12
|
+
let hash = 0
|
|
13
|
+
for ( let i = 0; i < str.length; ++i )
|
|
14
|
+
hash = Math.imul( 31, hash ) + str.charCodeAt( i )
|
|
15
|
+
return hash | 0
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function repeat( char: string, times: number ): string {
|
|
19
|
+
return times > 0 ? range( 0, times - 1 ).map( _ => char ).join( '' ) : '';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function capitalizeWord( word: string ): string {
|
|
23
|
+
return word[ 0 ].toUpperCase() + word.substring( 1 ).toLowerCase();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function splitWords( text: string, regEx: RegExp = /\s+/ ): string[] {
|
|
27
|
+
return text.split( regEx ).filter( t => t.length > 0 );
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function stringToNumber( s: string | null | undefined ): number | null {
|
|
31
|
+
if ( isNullOrUndefined( s ) )
|
|
32
|
+
return null;
|
|
33
|
+
return Number( s );
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function pad( str: string, n: number, char: string, where: 'left' | 'right' = 'left' ): string {
|
|
37
|
+
const length = ensureDefined( str ).length;
|
|
38
|
+
if ( length >= ensureDefined( n ) ) return str;
|
|
39
|
+
|
|
40
|
+
if ( ensureDefined( char ).length !== 1 )
|
|
41
|
+
throw new Error( 'Illegal pad character' );
|
|
42
|
+
const padding = repeat( char, n - length );
|
|
43
|
+
return ( where === 'left' ? padding : '' ) + str + ( where === 'right' ? padding : '' );
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function padLeft( str: string, n: number, char: string ): string {
|
|
47
|
+
return pad( str, n, char, 'left' );
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function padRight( str: string, n: number, char: string ): string {
|
|
51
|
+
return pad( str, n, char, 'right' );
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function ellipsis( str: string, maxLength: number, padChar: string, padWhere: 'left' | 'right' = 'left' ): string {
|
|
55
|
+
if ( maxLength < 4 )
|
|
56
|
+
throw new Error( 'Invalid argument maxLength' );
|
|
57
|
+
if ( str.length <= maxLength ) {
|
|
58
|
+
return pad( str, maxLength, padChar, padWhere );
|
|
59
|
+
} else {
|
|
60
|
+
return str.substring( 0, maxLength - 3 ) + '...';
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function pluralize( n: number, singular: string, plural?: string ): string {
|
|
65
|
+
|
|
66
|
+
if ( !singular || !singular.length )
|
|
67
|
+
throw new Error();
|
|
68
|
+
if ( n === 1 )
|
|
69
|
+
return singular;
|
|
70
|
+
|
|
71
|
+
plural = plural ?? singular + 's';
|
|
72
|
+
|
|
73
|
+
const firstUppercase = singular.charAt( 0 ) === singular.charAt( 0 ).toUpperCase();
|
|
74
|
+
if ( firstUppercase ) {
|
|
75
|
+
const PLURAL = plural.toUpperCase();
|
|
76
|
+
const isAllUppercase = plural === PLURAL;
|
|
77
|
+
plural = isAllUppercase ? PLURAL : plural.charAt( 0 ).toUpperCase() + plural.slice( 1 ).toLowerCase();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return plural;
|
|
81
|
+
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function wrapWithString( str: string, delimiter: string ): string {
|
|
85
|
+
return delimiter + str + delimiter;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** @deprecated[2024-12-23]: Use {@link wrapWithString} instead. */
|
|
89
|
+
export const wrap = wrapWithString;
|
|
90
|
+
|
|
91
|
+
|
package/dist/random/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function randomInterval(min: number, max: number): number;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function randomPercentage(min: number, max: number): number;
|
package/dist/types/index.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export type TTimeoutHandle = ReturnType<typeof setTimeout>;
|
|
2
|
-
export type TIntervalHandle = ReturnType<typeof setInterval>;
|
|
3
|
-
export type TPrimitive = string | number | boolean | null;
|
|
4
|
-
export * from './arrays';
|
|
5
|
-
export * from './booleans.ts';
|
|
6
|
-
export * from './empties.ts';
|
|
7
|
-
export * from './errors.ts';
|
|
8
|
-
export * from './functions';
|
|
9
|
-
export * from './json';
|
|
10
|
-
export * from './nulls';
|
|
11
|
-
export * from './numbers';
|
|
12
|
-
export * from './promises';
|
|
13
|
-
export * from './records';
|
|
14
|
-
export * from './strings';
|
package/dist/types/json.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export type TJsonPrimitive = string | number | boolean | null | undefined;
|
|
2
|
-
export type TJsonArray = Array<TJsonSerializable> | ReadonlyArray<TJsonSerializable>;
|
|
3
|
-
export type TJsonObject = {
|
|
4
|
-
[key: string]: TJsonSerializable;
|
|
5
|
-
};
|
|
6
|
-
export type TJsonSerializable = TJsonPrimitive | TJsonArray | TJsonObject;
|
|
7
|
-
export declare function tryToParseJson<T extends TJsonSerializable>(jsonContent: string): [T, null] | [null, Error];
|
package/dist/utils/bindThis.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function bindThis<F extends Function>(this: void, fn: F, _this: object): F;
|
package/dist/utils/noop.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function noop(): void;
|
package/dist/utils/omit.d.ts
DELETED
package/dist/utils/sortBy.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { TFunction, TKeysOfType } from "../types";
|
|
2
|
-
type TKeyOrGetter<T> = T extends Record<string, unknown> ? TKeysOfType<T, number> & keyof T | TFunction<T, number | null> : TFunction<T, number | null>;
|
|
3
|
-
/**
|
|
4
|
-
* @deprecated[2023-11-01]: Use {@link Sorter} instead.
|
|
5
|
-
*/
|
|
6
|
-
export default function sortBy<T>(keyOrGetter: TKeyOrGetter<T>, direction?: 'ASC' | 'DESC', nulls?: 'FIRST' | 'LAST'): (a: T, b: T) => number;
|
|
7
|
-
export {};
|
package/dist/utils/throttle.d.ts
DELETED
package/dist/utils/uniq.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function uniq<T>(arr: T[]): T[];
|
package/dist/utils/uniqBy.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function uniqByKey<T, K extends keyof T>(arr: T[], key: K): T[];
|
package/dist/utils/upsert.d.ts
DELETED
|
File without changes
|
package/dist/utils/wrap.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function wrap(str: string, delimiter: string): string;
|
package/src/random/index.ts
DELETED
package/src/types/index.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
// Semantic only
|
|
3
|
-
|
|
4
|
-
export type TTimeoutHandle = ReturnType<typeof setTimeout>;
|
|
5
|
-
export type TIntervalHandle = ReturnType<typeof setInterval>;
|
|
6
|
-
|
|
7
|
-
export type TPrimitive = string | number | boolean | null;
|
|
8
|
-
|
|
9
|
-
export * from './arrays';
|
|
10
|
-
export * from './booleans.ts';
|
|
11
|
-
export * from './empties.ts';
|
|
12
|
-
export * from './errors.ts';
|
|
13
|
-
export * from './functions';
|
|
14
|
-
export * from './json';
|
|
15
|
-
export * from './nulls';
|
|
16
|
-
export * from './numbers';
|
|
17
|
-
export * from './promises';
|
|
18
|
-
export * from './records';
|
|
19
|
-
export * from './strings';
|
|
20
|
-
|
package/src/types/json.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { asError } from "./errors.ts";
|
|
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, null ] | [ null, Error ] {
|
|
9
|
-
try {
|
|
10
|
-
const data = JSON.parse( jsonContent );
|
|
11
|
-
return [ data as T, null ];
|
|
12
|
-
} catch ( err ) {
|
|
13
|
-
return [ null, asError( err ) ];
|
|
14
|
-
}
|
|
15
|
-
}
|
package/src/types/strings.ts
DELETED
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
import { range, TReadableArray } from "./arrays.js";
|
|
2
|
-
import { ensureDefined, isNullOrUndefined, TMaybe } from "./nulls.js";
|
|
3
|
-
|
|
4
|
-
// Semantic-only
|
|
5
|
-
export type THtmlString = string;
|
|
6
|
-
export type TUrl = string;
|
|
7
|
-
export type TRelativeUrl = string;
|
|
8
|
-
|
|
9
|
-
export function hashCode( str: string ): number {
|
|
10
|
-
let hash = 0
|
|
11
|
-
for ( let i = 0; i < str.length; ++i )
|
|
12
|
-
hash = Math.imul( 31, hash ) + str.charCodeAt( i )
|
|
13
|
-
return hash | 0
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function repeat( char: string, times: number ): string {
|
|
17
|
-
return times > 0 ? range( 0, times - 1 ).map( _ => char ).join( '' ) : '';
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function capitalizeWord( word: string ): string {
|
|
21
|
-
return word[ 0 ].toUpperCase() + word.substring( 1 ).toLowerCase();
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function splitWords( text: string, regEx: RegExp = /\s+/ ): string[] {
|
|
25
|
-
return text.split( regEx ).filter( t => t.length > 0 );
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function stringToNumber( s: string | null | undefined ): number | null {
|
|
29
|
-
if ( isNullOrUndefined( s ) )
|
|
30
|
-
return null;
|
|
31
|
-
return Number( s );
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function pad( str: string, n: number, char: string, where: 'left' | 'right' = 'left' ): string {
|
|
35
|
-
const length = ensureDefined( str ).length;
|
|
36
|
-
if ( length >= ensureDefined( n ) ) return str;
|
|
37
|
-
|
|
38
|
-
if ( ensureDefined( char ).length !== 1 )
|
|
39
|
-
throw new Error( 'Illegal pad character' );
|
|
40
|
-
const padding = repeat( char, n - length );
|
|
41
|
-
return ( where === 'left' ? padding : '' ) + str + ( where === 'right' ? padding : '' );
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export function padLeft( str: string, n: number, char: string ): string {
|
|
45
|
-
return pad( str, n, char, 'left' );
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function padRight( str: string, n: number, char: string ): string {
|
|
49
|
-
return pad( str, n, char, 'right' );
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export function ellipsis( str: string, maxLength: number, padChar: string, padWhere: 'left' | 'right' = 'left' ): string {
|
|
53
|
-
if ( maxLength < 4 )
|
|
54
|
-
throw new Error( 'Invalid argument maxLength' );
|
|
55
|
-
if ( str.length <= maxLength ) {
|
|
56
|
-
return pad( str, maxLength, padChar, padWhere );
|
|
57
|
-
} else {
|
|
58
|
-
return str.substring( 0, maxLength - 3 ) + '...';
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export default function pluralize( n: number, singular: string, plural?: string ): string {
|
|
63
|
-
|
|
64
|
-
if ( !singular || !singular.length )
|
|
65
|
-
throw new Error();
|
|
66
|
-
if ( n === 1 )
|
|
67
|
-
return singular;
|
|
68
|
-
|
|
69
|
-
plural = plural ?? singular + 's';
|
|
70
|
-
|
|
71
|
-
const firstUppercase = singular.charAt( 0 ) === singular.charAt( 0 ).toUpperCase();
|
|
72
|
-
if ( firstUppercase ) {
|
|
73
|
-
const PLURAL = plural.toUpperCase();
|
|
74
|
-
const isAllUppercase = plural === PLURAL;
|
|
75
|
-
plural = isAllUppercase ? PLURAL : plural.charAt( 0 ).toUpperCase() + plural.slice( 1 ).toLowerCase();
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return plural;
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export class StringParts {
|
|
83
|
-
|
|
84
|
-
private readonly _parts: string[]
|
|
85
|
-
|
|
86
|
-
private constructor( ...parts: string[] ) {
|
|
87
|
-
this._parts = parts;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
public toUpperCase() {
|
|
91
|
-
return new StringParts( ...this.parts.map( part => part.toUpperCase() ) );
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
public toLowerCase() {
|
|
95
|
-
return new StringParts( ...this.parts.map( part => part.toLowerCase() ) );
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
public capitalizeFirst() {
|
|
99
|
-
if ( !this.length ) return this;
|
|
100
|
-
return new StringParts( capitalizeWord( this.first! ), ...this.tail.map( part => part.toLowerCase() ) );
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
public capitalizeEach() {
|
|
104
|
-
return new StringParts( ...this.parts.map( part => capitalizeWord( part ) ) );
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
public get parts() {
|
|
108
|
-
return this._parts;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
public get tail() {
|
|
112
|
-
const [ _first, ...tail ] = this.parts;
|
|
113
|
-
return tail;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
public get first(): TMaybe<string> {
|
|
117
|
-
return this._parts[ 0 ] ?? null;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
public get last(): TMaybe<string> {
|
|
121
|
-
return this._parts[ this.length - 1 ] ?? null;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
public get length() {
|
|
125
|
-
return this._parts.length;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
public trim() {
|
|
129
|
-
return new StringParts( ...this.parts.map( part => part.trim() ) )
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
public toSnakeCase() {
|
|
133
|
-
return this.toLowerCase().join( '_' );
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
public toCamelCase() {
|
|
137
|
-
if ( !this.length ) return '';
|
|
138
|
-
return [ this.first!.toLowerCase(), ...this.tail.map( capitalizeWord ) ].join( '' );
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
public toKebabCase() {
|
|
142
|
-
return this.toLowerCase().join( '-' );
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
public toPascalCase() {
|
|
146
|
-
return this.capitalizeEach().join( '' );
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
public toHumanCase() {
|
|
150
|
-
return this.capitalizeFirst().join( ' ' );
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
public join( separator: string ) {
|
|
154
|
-
return this.parts.join( separator );
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
public mergeWith( { parts: otherParts }: { parts: TReadableArray<string> } ) {
|
|
158
|
-
return new StringParts( ...this.parts, ...otherParts )
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
public slice( start: number, end?: number ) {
|
|
162
|
-
return new StringParts( ...this.parts.slice( start, end ) )
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
public splice( start: number, deleteCount: number, ...items: string[] ) {
|
|
166
|
-
return new StringParts( ...this.parts.splice( start, deleteCount, ...items ) )
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
public push( part: string ) {
|
|
170
|
-
return new StringParts( ...this.parts, part )
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
public shift( part: string ) {
|
|
174
|
-
return new StringParts( part, ...this.parts )
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
public reverse() {
|
|
178
|
-
return new StringParts( ...this.parts.reverse() )
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
public static fromString = ( s: string, separator: string | RegExp = /\s+/g ) => {
|
|
182
|
-
if ( s === null || separator === null )
|
|
183
|
-
throw new Error( 'Invalid arguments' );
|
|
184
|
-
return new StringParts( ...s.split( separator ) );
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
public static fromParts = ( ...parts: string[] ) => {
|
|
188
|
-
return new StringParts( ...parts );
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
}
|
package/src/utils/bindThis.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { TJsonObject, TJsonSerializable } from "../types";
|
|
2
|
-
|
|
3
|
-
export default function jsonCloneDeep<A extends TJsonSerializable>( a: A ): A {
|
|
4
|
-
|
|
5
|
-
// Handle the 3 simple types, and null or undefined
|
|
6
|
-
if ( null === a || "object" !== typeof a ) return a;
|
|
7
|
-
|
|
8
|
-
if ( a instanceof Date ) {
|
|
9
|
-
// Handle Date
|
|
10
|
-
return new Date( a.getTime() ) as unknown as A;
|
|
11
|
-
} else if ( a instanceof Array ) {
|
|
12
|
-
// Handle Array
|
|
13
|
-
const copy = [] as unknown[];
|
|
14
|
-
for ( let i = 0, len = a.length; i < len; i++ ) {
|
|
15
|
-
copy[ i ] = jsonCloneDeep( a[ i ] );
|
|
16
|
-
}
|
|
17
|
-
return copy as A;
|
|
18
|
-
} else if ( a instanceof Object ) {
|
|
19
|
-
// Handle Object
|
|
20
|
-
const copy = {} as Record<string | number | symbol, unknown>;
|
|
21
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
22
|
-
for ( let attr in ( a as TJsonObject ) ) {
|
|
23
|
-
if ( a.hasOwnProperty( attr ) )
|
|
24
|
-
copy[ attr ] = jsonCloneDeep( a[ attr ] );
|
|
25
|
-
}
|
|
26
|
-
return copy as A;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
throw new Error( "Unable to copy obj! Its type isn't supported." );
|
|
30
|
-
|
|
31
|
-
}
|
package/src/utils/noop.ts
DELETED
package/src/utils/omit.ts
DELETED
package/src/utils/sortBy.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { TFunction, TKeysOfType } from "../types";
|
|
2
|
-
|
|
3
|
-
type TKeyOrGetter<T> = T extends Record<string, unknown> ? TKeysOfType<T, number> & keyof T | TFunction<T, number | null> : TFunction<T, number | null>;
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @deprecated[2023-11-01]: Use {@link Sorter} instead.
|
|
7
|
-
*/
|
|
8
|
-
export default function sortBy<T>( keyOrGetter: TKeyOrGetter<T>, direction: 'ASC' | 'DESC' = 'ASC', nulls: 'FIRST' | 'LAST' = 'LAST' ) {
|
|
9
|
-
const directionNum = direction === 'ASC' ? -1 : 1;
|
|
10
|
-
const nullsNum = nulls === 'LAST' ? -1 : 1;
|
|
11
|
-
const sortByNum = ( a: number | null | undefined, b: number | null | undefined ) => {
|
|
12
|
-
if ( a === b )
|
|
13
|
-
return -1;
|
|
14
|
-
const aDefined = !( a === null || a === undefined || isNaN( a ) );
|
|
15
|
-
const bDefined = !( b === null || b === undefined || isNaN( b ) );
|
|
16
|
-
if ( !aDefined && !bDefined )
|
|
17
|
-
return -1;
|
|
18
|
-
if ( aDefined !== bDefined )
|
|
19
|
-
return nullsNum * ( aDefined ? 1 : -1 );
|
|
20
|
-
return ( a! > b! ? -1 : 1 ) * directionNum;
|
|
21
|
-
}
|
|
22
|
-
if ( typeof keyOrGetter === "function" ) {
|
|
23
|
-
return ( a: T, b: T ) => sortByNum( keyOrGetter( a ), keyOrGetter( b ) );
|
|
24
|
-
} else {
|
|
25
|
-
return ( a: T, b: T ) => sortByNum( a[ keyOrGetter as keyof T ] as number, b[ keyOrGetter as keyof T ] as number );
|
|
26
|
-
}
|
|
27
|
-
}
|
package/src/utils/throttle.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { RateThrottler } from "../async";
|
|
2
|
-
import TimeFrequency from "../time/TimeFrequency";
|
|
3
|
-
import { TPromisable } from "../types";
|
|
4
|
-
|
|
5
|
-
export default function throttle<TParams extends unknown[], R>( fn: (...params: TParams) => TPromisable<R>, frequence: TimeFrequency ): (...params: TParams) => Promise<R> {
|
|
6
|
-
const semaphore = new RateThrottler( frequence );
|
|
7
|
-
return (...t: TParams): Promise<R> => {
|
|
8
|
-
return semaphore.execute<R>( async () => fn( ...t ) );
|
|
9
|
-
};
|
|
10
|
-
}
|
package/src/utils/uniq.ts
DELETED
package/src/utils/uniqBy.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { TFunction } from "../types";
|
|
2
|
-
|
|
3
|
-
export default function uniqBy<T, K>( arr: T[], getter: TFunction<T, K> ): T[] {
|
|
4
|
-
return arr.reduce( ( dict, cur ) => {
|
|
5
|
-
const key = getter( cur );
|
|
6
|
-
if ( dict.keys.includes( key ) ) {
|
|
7
|
-
return dict;
|
|
8
|
-
} else {
|
|
9
|
-
return {
|
|
10
|
-
keys: [ ...dict.keys, key ],
|
|
11
|
-
values: [ ...dict.values, cur ]
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
}, { keys: [], values: [] } as { keys: K[], values: T[] } ).values;
|
|
15
|
-
}
|
package/src/utils/uniqByKey.ts
DELETED
package/src/utils/upsert.ts
DELETED