@tutao/tutanota-utils 3.91.2 → 3.91.3
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/ArrayUtils.d.ts +148 -0
- package/dist/ArrayUtils.js +410 -0
- package/dist/AsyncResult.d.ts +23 -0
- package/dist/AsyncResult.js +31 -0
- package/dist/CollectionUtils.d.ts +5 -0
- package/dist/CollectionUtils.js +7 -0
- package/dist/DateUtils.d.ts +60 -0
- package/dist/DateUtils.js +114 -0
- package/dist/Encoding.d.ts +103 -0
- package/dist/Encoding.js +306 -0
- package/dist/LazyLoaded.d.ts +38 -0
- package/dist/LazyLoaded.js +72 -0
- package/dist/MapUtils.d.ts +9 -0
- package/dist/MapUtils.js +38 -0
- package/dist/MathUtils.d.ts +5 -0
- package/dist/MathUtils.js +9 -0
- package/dist/PromiseMap.d.ts +44 -0
- package/dist/PromiseMap.js +75 -0
- package/dist/PromiseUtils.d.ts +48 -0
- package/dist/PromiseUtils.js +127 -0
- package/dist/SortedArray.d.ts +16 -0
- package/dist/SortedArray.js +44 -0
- package/dist/StringUtils.d.ts +58 -0
- package/dist/StringUtils.js +110 -0
- package/dist/TypeRef.d.ts +12 -0
- package/dist/TypeRef.js +19 -0
- package/dist/Utils.d.ts +125 -0
- package/dist/Utils.js +359 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +14 -0
- package/package.json +2 -2
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Vendored version of p-map: https://github.com/sindresorhus/p-map/
|
|
3
|
+
* Vendored to avoid having dependency on AggregateError.
|
|
4
|
+
*
|
|
5
|
+
* Changed: default concurrency level is 1 and not Infinite
|
|
6
|
+
*/
|
|
7
|
+
export interface Options {
|
|
8
|
+
/**
|
|
9
|
+
Number of concurrently pending promises returned by `mapper`.
|
|
10
|
+
Must be an integer from 1 and up or `Infinity`.
|
|
11
|
+
@default 1
|
|
12
|
+
*/
|
|
13
|
+
readonly concurrency?: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
Function which is called for every item in `input`. Expected to return a `Promise` or value.
|
|
17
|
+
@param element - Iterated element.
|
|
18
|
+
@param index - Index of the element in the source array.
|
|
19
|
+
*/
|
|
20
|
+
export declare type Mapper<Element, NewElement> = (element: Element, index: number) => Promise<NewElement> | NewElement;
|
|
21
|
+
/**
|
|
22
|
+
@param iterable - Iterated over concurrently in the `mapper` function.
|
|
23
|
+
@param mapper - Function which is called for every item in `input`. Expected to return a `Promise` or value.
|
|
24
|
+
@param options
|
|
25
|
+
@returns A `Promise` that is fulfilled when all promises in `input` and ones returned from `mapper` are fulfilled, or rejects if any of the promises reject. The fulfilled value is an `Array` of the fulfilled values returned from `mapper` in `input` order.
|
|
26
|
+
@example
|
|
27
|
+
```
|
|
28
|
+
import pMap from 'p-map';
|
|
29
|
+
import got from 'got';
|
|
30
|
+
const sites = [
|
|
31
|
+
getWebsiteFromUsername('sindresorhus'), //=> Promise
|
|
32
|
+
'https://avajs.dev',
|
|
33
|
+
'https://github.com'
|
|
34
|
+
];
|
|
35
|
+
const mapper = async site => {
|
|
36
|
+
const {requestUrl} = await got.head(site);
|
|
37
|
+
return requestUrl;
|
|
38
|
+
};
|
|
39
|
+
const result = await pMap(sites, mapper, {concurrency: 2});
|
|
40
|
+
console.log(result);
|
|
41
|
+
//=> ['https://sindresorhus.com/', 'https://avajs.dev/', 'https://github.com/']
|
|
42
|
+
```
|
|
43
|
+
*/
|
|
44
|
+
export declare function pMap<Element, NewElement>(iterable: Iterable<Element>, mapper: Mapper<Element, NewElement>, options?: Options): Promise<Array<NewElement>>;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@param iterable - Iterated over concurrently in the `mapper` function.
|
|
3
|
+
@param mapper - Function which is called for every item in `input`. Expected to return a `Promise` or value.
|
|
4
|
+
@param options
|
|
5
|
+
@returns A `Promise` that is fulfilled when all promises in `input` and ones returned from `mapper` are fulfilled, or rejects if any of the promises reject. The fulfilled value is an `Array` of the fulfilled values returned from `mapper` in `input` order.
|
|
6
|
+
@example
|
|
7
|
+
```
|
|
8
|
+
import pMap from 'p-map';
|
|
9
|
+
import got from 'got';
|
|
10
|
+
const sites = [
|
|
11
|
+
getWebsiteFromUsername('sindresorhus'), //=> Promise
|
|
12
|
+
'https://avajs.dev',
|
|
13
|
+
'https://github.com'
|
|
14
|
+
];
|
|
15
|
+
const mapper = async site => {
|
|
16
|
+
const {requestUrl} = await got.head(site);
|
|
17
|
+
return requestUrl;
|
|
18
|
+
};
|
|
19
|
+
const result = await pMap(sites, mapper, {concurrency: 2});
|
|
20
|
+
console.log(result);
|
|
21
|
+
//=> ['https://sindresorhus.com/', 'https://avajs.dev/', 'https://github.com/']
|
|
22
|
+
```
|
|
23
|
+
*/
|
|
24
|
+
export async function pMap(iterable, mapper, options = {}) {
|
|
25
|
+
const { concurrency = 1 } = options;
|
|
26
|
+
return new Promise((resolve, reject) => {
|
|
27
|
+
if (typeof mapper !== "function") {
|
|
28
|
+
throw new TypeError("Mapper function is required");
|
|
29
|
+
}
|
|
30
|
+
if (!((Number.isSafeInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency >= 1)) {
|
|
31
|
+
throw new TypeError(`Expected \`concurrency\` to be an integer from 1 and up or \`Infinity\`, got \`${concurrency}\` (${typeof concurrency})`);
|
|
32
|
+
}
|
|
33
|
+
const result = [];
|
|
34
|
+
const errors = [];
|
|
35
|
+
const iterator = iterable[Symbol.iterator]();
|
|
36
|
+
let isRejected = false;
|
|
37
|
+
let isIterableDone = false;
|
|
38
|
+
let resolvingCount = 0;
|
|
39
|
+
let currentIndex = 0;
|
|
40
|
+
const next = () => {
|
|
41
|
+
if (isRejected) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const nextItem = iterator.next();
|
|
45
|
+
const index = currentIndex;
|
|
46
|
+
currentIndex++;
|
|
47
|
+
if (nextItem.done) {
|
|
48
|
+
isIterableDone = true;
|
|
49
|
+
if (resolvingCount === 0) {
|
|
50
|
+
resolve(result);
|
|
51
|
+
}
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
resolvingCount++;
|
|
55
|
+
(async () => {
|
|
56
|
+
try {
|
|
57
|
+
const element = await nextItem.value;
|
|
58
|
+
result[index] = await mapper(element, index);
|
|
59
|
+
resolvingCount--;
|
|
60
|
+
next();
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
isRejected = true;
|
|
64
|
+
reject(error);
|
|
65
|
+
}
|
|
66
|
+
})();
|
|
67
|
+
};
|
|
68
|
+
for (let index = 0; index < concurrency; index++) {
|
|
69
|
+
next();
|
|
70
|
+
if (isIterableDone) {
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Options as PromiseMapOptions } from "./PromiseMap.js";
|
|
2
|
+
export declare type $Promisable<T> = Promise<T> | T;
|
|
3
|
+
declare type PromiseMapCallback<T, U> = (el: T, index: number) => $Promisable<U>;
|
|
4
|
+
/**
|
|
5
|
+
* Map array of values to promise of arrays or array. Mapper function may return promise or value. If value is returned,
|
|
6
|
+
* we avoid promise scheduling.
|
|
7
|
+
*
|
|
8
|
+
* This is needed to run the whole operation in one microtask (e.g. keep IndexedDB transaction active, which is closed in
|
|
9
|
+
* some browsers (e.g. Safari) when event loop iteration ends).
|
|
10
|
+
*/
|
|
11
|
+
export declare function mapInCallContext<T, U>(values: T[], callback: PromiseMapCallback<T, U>): PromisableWrapper<Array<U>>;
|
|
12
|
+
export { pMap as promiseMap } from "./PromiseMap.js";
|
|
13
|
+
export declare type PromiseMapFn = <T, U>(values: T[], callback: PromiseMapCallback<T, U>, options?: PromiseMapOptions) => PromisableWrapper<U[]>;
|
|
14
|
+
/** Factory function which gives you ack promiseMap implementation. {@see mapInCallContext} for what it means. */
|
|
15
|
+
export declare function promiseMapCompat(useMapInCallContext: boolean): PromiseMapFn;
|
|
16
|
+
export declare class PromisableWrapper<T> {
|
|
17
|
+
static from<U>(value: $Promisable<U>): PromisableWrapper<U>;
|
|
18
|
+
value: $Promisable<T>;
|
|
19
|
+
constructor(value: $Promisable<PromisableWrapper<T> | T>);
|
|
20
|
+
thenOrApply<R>(onFulfill: (arg0: T) => $Promisable<PromisableWrapper<R> | R>, onReject?: (arg0: any) => $Promisable<R | PromisableWrapper<R>>): PromisableWrapper<R>;
|
|
21
|
+
toPromise(): Promise<T>;
|
|
22
|
+
}
|
|
23
|
+
export declare function delay(ms: number): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Pass to Promise.then to perform an action while forwarding on the result
|
|
26
|
+
* @param action
|
|
27
|
+
*/
|
|
28
|
+
export declare function tap<T>(action: (arg0: T) => unknown): (arg0: T) => T;
|
|
29
|
+
/**
|
|
30
|
+
* Helper utility intended to be used with typed exceptions and .catch() method of promise like so:
|
|
31
|
+
*
|
|
32
|
+
* ```js
|
|
33
|
+
* class SpecificError extends Error {}
|
|
34
|
+
*
|
|
35
|
+
* Promise.reject(new SpecificError())
|
|
36
|
+
* .catch(ofClass(SpecificError, (e) => console.log("some error", e)))
|
|
37
|
+
* .catch((e) => console.log("generic error", e))
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* @param cls Class which will be caught
|
|
41
|
+
* @param catcher to handle only errors of type cls
|
|
42
|
+
* @returns handler which either forwards to catcher or rethrows
|
|
43
|
+
*/
|
|
44
|
+
export declare function ofClass<E, R>(cls: Class<E>, catcher: (arg0: E) => $Promisable<R>): (arg0: any) => Promise<R>;
|
|
45
|
+
/**
|
|
46
|
+
* Filter iterable. Just like Array.prototype.filter but callback can return promises
|
|
47
|
+
*/
|
|
48
|
+
export declare function promiseFilter<T>(iterable: Iterable<T>, filter: (item: T, index: number) => $Promisable<boolean>): Promise<Array<T>>;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { pMap as promiseMap } from "./PromiseMap.js";
|
|
2
|
+
/**
|
|
3
|
+
* Map array of values to promise of arrays or array. Mapper function may return promise or value. If value is returned,
|
|
4
|
+
* we avoid promise scheduling.
|
|
5
|
+
*
|
|
6
|
+
* This is needed to run the whole operation in one microtask (e.g. keep IndexedDB transaction active, which is closed in
|
|
7
|
+
* some browsers (e.g. Safari) when event loop iteration ends).
|
|
8
|
+
*/
|
|
9
|
+
export function mapInCallContext(values, callback) {
|
|
10
|
+
return new PromisableWrapper(_mapInCallContext(values, callback, 0, []));
|
|
11
|
+
}
|
|
12
|
+
function _mapInCallContext(values, callback, index, acc) {
|
|
13
|
+
if (index >= values.length) {
|
|
14
|
+
return acc;
|
|
15
|
+
}
|
|
16
|
+
let mappedValue = callback(values[index], index);
|
|
17
|
+
if (mappedValue instanceof Promise) {
|
|
18
|
+
return mappedValue.then(v => {
|
|
19
|
+
acc.push(v);
|
|
20
|
+
return _mapInCallContext(values, callback, index + 1, acc);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
acc.push(mappedValue);
|
|
25
|
+
return _mapInCallContext(values, callback, index + 1, acc);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export { pMap as promiseMap } from "./PromiseMap.js";
|
|
29
|
+
function mapNoFallback(values, callback, options) {
|
|
30
|
+
return PromisableWrapper.from(promiseMap(values, callback, options));
|
|
31
|
+
}
|
|
32
|
+
/** Factory function which gives you ack promiseMap implementation. {@see mapInCallContext} for what it means. */
|
|
33
|
+
export function promiseMapCompat(useMapInCallContext) {
|
|
34
|
+
return useMapInCallContext ? mapInCallContext : mapNoFallback;
|
|
35
|
+
}
|
|
36
|
+
function flatWrapper(value) {
|
|
37
|
+
return value instanceof PromisableWrapper ? value.value : value;
|
|
38
|
+
}
|
|
39
|
+
// It kinda implements 'thenable' protocol so you can freely pass it around as a generic promise
|
|
40
|
+
export class PromisableWrapper {
|
|
41
|
+
constructor(value) {
|
|
42
|
+
this.value = value instanceof Promise ? value.then(flatWrapper) : flatWrapper(value);
|
|
43
|
+
}
|
|
44
|
+
static from(value) {
|
|
45
|
+
return new PromisableWrapper(value);
|
|
46
|
+
}
|
|
47
|
+
thenOrApply(onFulfill, onReject) {
|
|
48
|
+
if (this.value instanceof Promise) {
|
|
49
|
+
const v = this.value.then(onFulfill, onReject);
|
|
50
|
+
return new PromisableWrapper(v);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
try {
|
|
54
|
+
return new PromisableWrapper(onFulfill(this.value));
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
if (onReject) {
|
|
58
|
+
return new PromisableWrapper(onReject(e));
|
|
59
|
+
}
|
|
60
|
+
throw e;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
toPromise() {
|
|
65
|
+
return Promise.resolve(this.value);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export function delay(ms) {
|
|
69
|
+
if (Number.isNaN(ms) || ms < 0) {
|
|
70
|
+
throw new Error(`Invalid delay: ${ms}`);
|
|
71
|
+
}
|
|
72
|
+
return new Promise(resolve => {
|
|
73
|
+
setTimeout(resolve, ms);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Pass to Promise.then to perform an action while forwarding on the result
|
|
78
|
+
* @param action
|
|
79
|
+
*/
|
|
80
|
+
export function tap(action) {
|
|
81
|
+
return function (value) {
|
|
82
|
+
action(value);
|
|
83
|
+
return value;
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Helper utility intended to be used with typed exceptions and .catch() method of promise like so:
|
|
88
|
+
*
|
|
89
|
+
* ```js
|
|
90
|
+
* class SpecificError extends Error {}
|
|
91
|
+
*
|
|
92
|
+
* Promise.reject(new SpecificError())
|
|
93
|
+
* .catch(ofClass(SpecificError, (e) => console.log("some error", e)))
|
|
94
|
+
* .catch((e) => console.log("generic error", e))
|
|
95
|
+
* ```
|
|
96
|
+
*
|
|
97
|
+
* @param cls Class which will be caught
|
|
98
|
+
* @param catcher to handle only errors of type cls
|
|
99
|
+
* @returns handler which either forwards to catcher or rethrows
|
|
100
|
+
*/
|
|
101
|
+
export function ofClass(cls, catcher) {
|
|
102
|
+
return async (e) => {
|
|
103
|
+
if (e instanceof cls) {
|
|
104
|
+
return catcher(e);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
// It's okay to rethrow because:
|
|
108
|
+
// 1. It preserves the original stacktrace
|
|
109
|
+
// 2. Because of 1. it is not that expensive
|
|
110
|
+
throw e;
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Filter iterable. Just like Array.prototype.filter but callback can return promises
|
|
116
|
+
*/
|
|
117
|
+
export async function promiseFilter(iterable, filter) {
|
|
118
|
+
let index = 0;
|
|
119
|
+
const result = [];
|
|
120
|
+
for (let item of iterable) {
|
|
121
|
+
if (await filter(item, index)) {
|
|
122
|
+
result.push(item);
|
|
123
|
+
}
|
|
124
|
+
index++;
|
|
125
|
+
}
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare type CompareFn<T> = (arg0: T, arg1: T) => number;
|
|
2
|
+
/**
|
|
3
|
+
* An array that keeps itself sorted
|
|
4
|
+
*/
|
|
5
|
+
export declare class SortedArray<T> {
|
|
6
|
+
readonly _contents: Array<T>;
|
|
7
|
+
readonly _compareFn: CompareFn<T>;
|
|
8
|
+
constructor(compareFn?: CompareFn<T>);
|
|
9
|
+
static from<U>(array: ReadonlyArray<U>, compareFn?: CompareFn<U>): SortedArray<U>;
|
|
10
|
+
get length(): number;
|
|
11
|
+
get array(): ReadonlyArray<T>;
|
|
12
|
+
get(index: number): T;
|
|
13
|
+
insertAll(array: ReadonlyArray<T>): void;
|
|
14
|
+
insert(item: T): void;
|
|
15
|
+
removeFirst(finder: (arg0: T) => boolean): boolean;
|
|
16
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { findAndRemove, insertIntoSortedArray } from "./ArrayUtils.js";
|
|
2
|
+
/**
|
|
3
|
+
* Compared based on the type's natural ordering
|
|
4
|
+
* @param a
|
|
5
|
+
* @param b
|
|
6
|
+
* @returns {number}
|
|
7
|
+
*/
|
|
8
|
+
// It should be fine for 99% of use cases? worst case it just returns 0 always
|
|
9
|
+
function defaultCompare(a, b) {
|
|
10
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* An array that keeps itself sorted
|
|
14
|
+
*/
|
|
15
|
+
export class SortedArray {
|
|
16
|
+
constructor(compareFn = defaultCompare) {
|
|
17
|
+
this._contents = [];
|
|
18
|
+
this._compareFn = compareFn;
|
|
19
|
+
}
|
|
20
|
+
static from(array, compareFn) {
|
|
21
|
+
const list = new SortedArray(compareFn);
|
|
22
|
+
list.insertAll(array);
|
|
23
|
+
return list;
|
|
24
|
+
}
|
|
25
|
+
get length() {
|
|
26
|
+
return this._contents.length;
|
|
27
|
+
}
|
|
28
|
+
get array() {
|
|
29
|
+
return this._contents;
|
|
30
|
+
}
|
|
31
|
+
get(index) {
|
|
32
|
+
return this._contents[index];
|
|
33
|
+
}
|
|
34
|
+
insertAll(array) {
|
|
35
|
+
this._contents.push(...array);
|
|
36
|
+
this._contents.sort(this._compareFn);
|
|
37
|
+
}
|
|
38
|
+
insert(item) {
|
|
39
|
+
insertIntoSortedArray(item, this._contents, this._compareFn);
|
|
40
|
+
}
|
|
41
|
+
removeFirst(finder) {
|
|
42
|
+
return findAndRemove(this._contents, finder);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { lazy } from "./Utils.js";
|
|
2
|
+
/**
|
|
3
|
+
* Returns a string which contains the given number padded with 0s.
|
|
4
|
+
* @param num The number to pad.
|
|
5
|
+
* @param size The number of resulting digits.
|
|
6
|
+
* @return The padded number as string.
|
|
7
|
+
*/
|
|
8
|
+
export declare function pad(num: number, size: number): string;
|
|
9
|
+
/**
|
|
10
|
+
* Checks if a string starts with another string.
|
|
11
|
+
* @param string The string to test.
|
|
12
|
+
* @param substring If the other string begins with this one, we return true.
|
|
13
|
+
* @return True if string begins with substring, false otherwise.
|
|
14
|
+
*/
|
|
15
|
+
export declare function startsWith(string: string, substring: string): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* uppercase the first letter of a string, lowercase the rest
|
|
18
|
+
* @param str string to transform
|
|
19
|
+
* @returns {string} str in lowercase with first letter Capitalized
|
|
20
|
+
*/
|
|
21
|
+
export declare function capitalizeFirstLetter(str: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Checks if a string ends with another string.
|
|
24
|
+
* @param string The string to test.
|
|
25
|
+
* @param substring If the other string ends with this one, we return true.
|
|
26
|
+
* @return True if string ends with substring, false otherwise.
|
|
27
|
+
*/
|
|
28
|
+
export declare function endsWith(string: string, substring: string): boolean;
|
|
29
|
+
export declare function lazyStringValue(valueOrLazy: string | lazy<string>): string;
|
|
30
|
+
export declare function repeat(value: string, length: number): string;
|
|
31
|
+
export declare function cleanMatch(s1: string, s2: string): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Non-breaking space character
|
|
34
|
+
*/
|
|
35
|
+
export declare const NBSP = "\u00A0";
|
|
36
|
+
/**
|
|
37
|
+
* split a string at a given index
|
|
38
|
+
* @param str
|
|
39
|
+
* @param index
|
|
40
|
+
*/
|
|
41
|
+
export declare function splitAt(str: string, index: number): [string, string];
|
|
42
|
+
/**
|
|
43
|
+
* Wrapper around String.prototype.toLowerCase, nice for calls to Array.prototype.map
|
|
44
|
+
* @param str
|
|
45
|
+
*/
|
|
46
|
+
export declare function toLowerCase(str: string): string;
|
|
47
|
+
/**
|
|
48
|
+
* Wrapper around String.prototype.localeCompare, for passing to Array.prototype.sort
|
|
49
|
+
* @param a
|
|
50
|
+
* @param b
|
|
51
|
+
* @returns {number}
|
|
52
|
+
*/
|
|
53
|
+
export declare function localeCompare(a: string, b: string): number;
|
|
54
|
+
export declare function byteLength(str: string | null | undefined): number;
|
|
55
|
+
/**
|
|
56
|
+
* replace all instances of substr in str with replacement
|
|
57
|
+
*/
|
|
58
|
+
export declare function replaceAll(str: string, substr: string, replacement: string): string;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns a string which contains the given number padded with 0s.
|
|
3
|
+
* @param num The number to pad.
|
|
4
|
+
* @param size The number of resulting digits.
|
|
5
|
+
* @return The padded number as string.
|
|
6
|
+
*/
|
|
7
|
+
export function pad(num, size) {
|
|
8
|
+
var s = num + "";
|
|
9
|
+
while (s.length < size)
|
|
10
|
+
s = "0" + s;
|
|
11
|
+
return s;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Checks if a string starts with another string.
|
|
15
|
+
* @param string The string to test.
|
|
16
|
+
* @param substring If the other string begins with this one, we return true.
|
|
17
|
+
* @return True if string begins with substring, false otherwise.
|
|
18
|
+
*/
|
|
19
|
+
export function startsWith(string, substring) {
|
|
20
|
+
return string.startsWith(substring);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* uppercase the first letter of a string, lowercase the rest
|
|
24
|
+
* @param str string to transform
|
|
25
|
+
* @returns {string} str in lowercase with first letter Capitalized
|
|
26
|
+
*/
|
|
27
|
+
export function capitalizeFirstLetter(str) {
|
|
28
|
+
return str[0].toUpperCase() + str.toLowerCase().slice(1);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Checks if a string ends with another string.
|
|
32
|
+
* @param string The string to test.
|
|
33
|
+
* @param substring If the other string ends with this one, we return true.
|
|
34
|
+
* @return True if string ends with substring, false otherwise.
|
|
35
|
+
*/
|
|
36
|
+
export function endsWith(string, substring) {
|
|
37
|
+
return string.endsWith(substring);
|
|
38
|
+
}
|
|
39
|
+
export function lazyStringValue(valueOrLazy) {
|
|
40
|
+
return typeof valueOrLazy === "function" ? valueOrLazy() : valueOrLazy;
|
|
41
|
+
}
|
|
42
|
+
export function repeat(value, length) {
|
|
43
|
+
let result = "";
|
|
44
|
+
for (let i = 0; i < length; i++) {
|
|
45
|
+
result += value;
|
|
46
|
+
}
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
export function cleanMatch(s1, s2) {
|
|
50
|
+
return s1.toLowerCase().trim() === s2.toLowerCase().trim();
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Non-breaking space character
|
|
54
|
+
*/
|
|
55
|
+
export const NBSP = "\u00A0";
|
|
56
|
+
/**
|
|
57
|
+
* split a string at a given index
|
|
58
|
+
* @param str
|
|
59
|
+
* @param index
|
|
60
|
+
*/
|
|
61
|
+
export function splitAt(str, index) {
|
|
62
|
+
return [str.substring(0, index), str.substring(index)];
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Wrapper around String.prototype.toLowerCase, nice for calls to Array.prototype.map
|
|
66
|
+
* @param str
|
|
67
|
+
*/
|
|
68
|
+
export function toLowerCase(str) {
|
|
69
|
+
return str.toLowerCase();
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Wrapper around String.prototype.localeCompare, for passing to Array.prototype.sort
|
|
73
|
+
* @param a
|
|
74
|
+
* @param b
|
|
75
|
+
* @returns {number}
|
|
76
|
+
*/
|
|
77
|
+
export function localeCompare(a, b) {
|
|
78
|
+
return a.localeCompare(b);
|
|
79
|
+
}
|
|
80
|
+
export function byteLength(str) {
|
|
81
|
+
if (str == null)
|
|
82
|
+
return 0;
|
|
83
|
+
// returns the byte length of an utf8 string
|
|
84
|
+
var s = str.length;
|
|
85
|
+
for (var i = str.length - 1; i >= 0; i--) {
|
|
86
|
+
var code = str.charCodeAt(i);
|
|
87
|
+
if (code > 0x7f && code <= 0x7ff) {
|
|
88
|
+
s++;
|
|
89
|
+
}
|
|
90
|
+
else if (code > 0x7ff && code <= 0xffff)
|
|
91
|
+
s += 2;
|
|
92
|
+
if (code >= 0xdc00 && code <= 0xdfff)
|
|
93
|
+
i--; //trail surrogate
|
|
94
|
+
}
|
|
95
|
+
return s;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* replace all instances of substr in str with replacement
|
|
99
|
+
*/
|
|
100
|
+
export function replaceAll(str, substr, replacement) {
|
|
101
|
+
const regex = escapedStringRegExp(substr, "g");
|
|
102
|
+
return str.replace(regex, replacement);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Create a regex to exactly match a given string, by escaping any special regex characters
|
|
106
|
+
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
|
|
107
|
+
* */
|
|
108
|
+
function escapedStringRegExp(str, flags) {
|
|
109
|
+
return new RegExp(str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), flags);
|
|
110
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare class TypeRef<T> {
|
|
2
|
+
readonly app: string;
|
|
3
|
+
readonly type: string;
|
|
4
|
+
/**
|
|
5
|
+
* Field that is never set. Used to make two TypeRefs incompatible (they are structurally compared otherwise).
|
|
6
|
+
* Cannot be private.
|
|
7
|
+
*/
|
|
8
|
+
readonly phantom: T | null;
|
|
9
|
+
constructor(app: string, type: string);
|
|
10
|
+
}
|
|
11
|
+
export declare function isSameTypeRefByAttr(typeRef: TypeRef<any>, app: string, type: string): boolean;
|
|
12
|
+
export declare function isSameTypeRef(typeRef1: TypeRef<any>, typeRef2: TypeRef<any>): boolean;
|
package/dist/TypeRef.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// T should be restricted to Entity
|
|
2
|
+
export class TypeRef {
|
|
3
|
+
constructor(app, type) {
|
|
4
|
+
/**
|
|
5
|
+
* Field that is never set. Used to make two TypeRefs incompatible (they are structurally compared otherwise).
|
|
6
|
+
* Cannot be private.
|
|
7
|
+
*/
|
|
8
|
+
this.phantom = null;
|
|
9
|
+
this.app = app;
|
|
10
|
+
this.type = type;
|
|
11
|
+
Object.freeze(this);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export function isSameTypeRefByAttr(typeRef, app, type) {
|
|
15
|
+
return typeRef.app === app && typeRef.type === type;
|
|
16
|
+
}
|
|
17
|
+
export function isSameTypeRef(typeRef1, typeRef2) {
|
|
18
|
+
return isSameTypeRefByAttr(typeRef1, typeRef2.app, typeRef2.type);
|
|
19
|
+
}
|