@naturalcycles/js-lib 14.69.4 → 14.71.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/error/error.util.d.ts +6 -2
- package/dist/error/error.util.js +34 -18
- package/dist/error/try.d.ts +1 -1
- package/dist/error/try.js +2 -0
- package/dist/index.d.ts +6 -5
- package/dist/index.js +9 -12
- package/dist/promise/pBatch.d.ts +2 -3
- package/dist/promise/pFilter.d.ts +2 -2
- package/dist/promise/pMap.d.ts +2 -3
- package/dist/promise/pMap.js +13 -7
- package/dist/promise/pProps.d.ts +3 -1
- package/dist/promise/pProps.js +4 -5
- package/dist/seq/seq.d.ts +30 -0
- package/dist/seq/seq.js +141 -0
- package/dist/string/json.util.js +4 -1
- package/dist/typeFest.d.ts +0 -30
- package/dist/types.d.ts +13 -1
- package/dist/types.js +9 -1
- package/dist-esm/error/error.util.js +32 -16
- package/dist-esm/error/try.js +2 -0
- package/dist-esm/index.js +4 -3
- package/dist-esm/promise/pMap.js +14 -8
- package/dist-esm/promise/pProps.js +4 -5
- package/dist-esm/seq/seq.js +136 -0
- package/dist-esm/string/json.util.js +4 -1
- package/dist-esm/types.js +8 -0
- package/package.json +1 -1
- package/src/error/error.util.ts +44 -19
- package/src/error/try.ts +4 -1
- package/src/index.ts +14 -18
- package/src/promise/pBatch.ts +2 -3
- package/src/promise/pFilter.ts +2 -2
- package/src/promise/pMap.ts +16 -11
- package/src/promise/pProps.ts +6 -7
- package/src/seq/seq.ts +143 -0
- package/src/string/json.util.ts +5 -1
- package/src/typeFest.ts +0 -32
- package/src/types.ts +22 -1
|
@@ -7,13 +7,12 @@ import { AppError, _jsonParseIfPossible, _stringifyAny, } from '..';
|
|
|
7
7
|
*
|
|
8
8
|
* Alternatively, if you're sure it's Error - you can use `_assertIsError(err)`.
|
|
9
9
|
*/
|
|
10
|
-
export function _anyToError(o, opt) {
|
|
11
|
-
if (o instanceof
|
|
12
|
-
// Already an Error - return as-is
|
|
10
|
+
export function _anyToError(o, errorClass = Error, opt) {
|
|
11
|
+
if (o instanceof errorClass)
|
|
13
12
|
return o;
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
return
|
|
13
|
+
// If it's an instance of Error, but ErrorClass is something else (e.g AppError) - it'll be "repacked" into AppError
|
|
14
|
+
const errorObject = _isErrorObject(o) ? o : _anyToErrorObject(o, opt);
|
|
15
|
+
return _errorObjectToError(errorObject, errorClass);
|
|
17
16
|
}
|
|
18
17
|
/**
|
|
19
18
|
* Converts "anything" to ErrorObject.
|
|
@@ -22,8 +21,9 @@ export function _anyToError(o, opt) {
|
|
|
22
21
|
* Objects (not Errors) get converted to prettified JSON string (via `_stringifyAny`).
|
|
23
22
|
*/
|
|
24
23
|
export function _anyToErrorObject(o, opt) {
|
|
24
|
+
var _a;
|
|
25
25
|
if (o instanceof Error) {
|
|
26
|
-
return _errorToErrorObject(o, opt === null || opt === void 0 ? void 0 : opt.includeErrorStack);
|
|
26
|
+
return _errorToErrorObject(o, (_a = opt === null || opt === void 0 ? void 0 : opt.includeErrorStack) !== null && _a !== void 0 ? _a : true);
|
|
27
27
|
}
|
|
28
28
|
o = _jsonParseIfPossible(o);
|
|
29
29
|
if (_isHttpErrorResponse(o)) {
|
|
@@ -43,7 +43,7 @@ export function _anyToErrorObject(o, opt) {
|
|
|
43
43
|
data: {}, // empty
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
|
-
export function _errorToErrorObject(e, includeErrorStack =
|
|
46
|
+
export function _errorToErrorObject(e, includeErrorStack = true) {
|
|
47
47
|
const obj = {
|
|
48
48
|
name: e.name,
|
|
49
49
|
message: e.message,
|
|
@@ -55,17 +55,29 @@ export function _errorToErrorObject(e, includeErrorStack = false) {
|
|
|
55
55
|
return obj;
|
|
56
56
|
}
|
|
57
57
|
export function _errorObjectToAppError(o) {
|
|
58
|
-
|
|
58
|
+
return _errorObjectToError(o, AppError);
|
|
59
|
+
}
|
|
60
|
+
export function _errorObjectToError(o, errorClass = Error) {
|
|
61
|
+
if (o instanceof errorClass)
|
|
62
|
+
return o;
|
|
63
|
+
const err = new errorClass(o.message);
|
|
59
64
|
// name: err.name, // cannot be assigned to a readonly property like this
|
|
60
65
|
// stack: o.stack, // also readonly e.g in Firefox
|
|
61
|
-
});
|
|
62
66
|
Object.defineProperty(err, 'name', {
|
|
63
67
|
value: o.name,
|
|
64
68
|
configurable: true,
|
|
65
69
|
});
|
|
66
|
-
Object.defineProperty(err, '
|
|
67
|
-
value: o.
|
|
70
|
+
Object.defineProperty(err, 'data', {
|
|
71
|
+
value: o.data,
|
|
72
|
+
writable: true,
|
|
73
|
+
configurable: true,
|
|
74
|
+
enumerable: false,
|
|
68
75
|
});
|
|
76
|
+
if (o.stack) {
|
|
77
|
+
Object.defineProperty(err, 'stack', {
|
|
78
|
+
value: o.stack,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
69
81
|
return err;
|
|
70
82
|
}
|
|
71
83
|
export function _isHttpErrorResponse(o) {
|
|
@@ -73,10 +85,14 @@ export function _isHttpErrorResponse(o) {
|
|
|
73
85
|
}
|
|
74
86
|
export function _isHttpErrorObject(o) {
|
|
75
87
|
var _a;
|
|
76
|
-
return (
|
|
77
|
-
typeof
|
|
78
|
-
typeof
|
|
88
|
+
return (!!o &&
|
|
89
|
+
typeof o.name === 'string' &&
|
|
90
|
+
typeof o.message === 'string' &&
|
|
91
|
+
typeof ((_a = o.data) === null || _a === void 0 ? void 0 : _a.httpStatusCode) === 'number');
|
|
79
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Note: any instance of AppError is also automatically an ErrorObject
|
|
95
|
+
*/
|
|
80
96
|
export function _isErrorObject(o) {
|
|
81
|
-
return (
|
|
97
|
+
return (!!o && typeof o.name === 'string' && typeof o.message === 'string' && typeof o.data === 'object');
|
|
82
98
|
}
|
package/dist-esm/error/try.js
CHANGED
package/dist-esm/index.js
CHANGED
|
@@ -13,7 +13,7 @@ import { _Retry } from './decorators/retry.decorator';
|
|
|
13
13
|
import { _Timeout } from './decorators/timeout.decorator';
|
|
14
14
|
import { AppError } from './error/app.error';
|
|
15
15
|
import { AssertionError, _assert, _assertDeepEquals, _assertEquals, _assertIsError, _assertIsNumber, _assertIsString, _assertTypeOf, } from './error/assert';
|
|
16
|
-
|
|
16
|
+
export * from './error/error.util';
|
|
17
17
|
import { ErrorMode } from './error/errorMode';
|
|
18
18
|
import { HttpError } from './error/http.error';
|
|
19
19
|
import { _try, pTry } from './error/try';
|
|
@@ -47,10 +47,11 @@ import { _jsonParseIfPossible } from './string/json.util';
|
|
|
47
47
|
import { _capitalize, _lowerFirst, _nl2br, _removeWhitespace, _replaceAll, _split, _substringAfter, _substringAfterLast, _substringBefore, _substringBeforeLast, _substringBetweenLast, _truncate, _truncateMiddle, _upperFirst, } from './string/string.util';
|
|
48
48
|
import { _stringifyAny } from './string/stringifyAny';
|
|
49
49
|
import { _ms, _since } from './time/time.util';
|
|
50
|
-
import { _noop, _objectKeys, _passNothingPredicate, _passthroughMapper, _passthroughPredicate, _passUndefinedMapper, _stringMapEntries, _stringMapValues, } from './types';
|
|
50
|
+
import { END, SKIP, _noop, _objectKeys, _passNothingPredicate, _passthroughMapper, _passthroughPredicate, _passUndefinedMapper, _stringMapEntries, _stringMapValues, } from './types';
|
|
51
51
|
import { _gb, _hb, _kb, _mb } from './unit/size.util';
|
|
52
52
|
import { is } from './vendor/is';
|
|
53
53
|
import { commonLoggerMinLevel, commonLoggerNoop, commonLogLevelNumber, commonLoggerPipe, commonLoggerPrefix, commonLoggerCreate, } from './log/commonLogger';
|
|
54
54
|
import { _safeJsonStringify } from './string/safeJsonStringify';
|
|
55
55
|
import { PQueue } from './promise/pQueue';
|
|
56
|
-
export
|
|
56
|
+
export * from './seq/seq';
|
|
57
|
+
export { is, _Memo, _memoFn, _LogMethod, _getArgsSignature, _createPromiseDecorator, AppError, HttpError, AssertionError, _assert, _assertEquals, _assertDeepEquals, _assertIsError, _assertIsString, _assertIsNumber, _assertTypeOf, _randomInt, _randomArrayItem, _createDeterministicRandom, _inRange, _stringMapValues, _stringMapEntries, _objectKeys, _capitalize, _upperFirst, _lowerFirst, _split, _removeWhitespace, _substringBefore, _substringBeforeLast, _substringAfter, _substringAfterLast, _substringBetweenLast, _replaceAll, _nl2br, _truncate, _truncateMiddle, _pick, _omit, _filterFalsyValues, _filterUndefinedValues, _filterNullishValues, _filterEmptyArrays, _filterEmptyValues, _filterObject, _undefinedIfEmpty, _isObject, _isPrimitive, _mapKeys, _mapValues, _mapObject, _objectNullValuesToUndefined, _deepEquals, _deepCopy, _isEmptyObject, _isEmpty, _merge, _deepTrim, _sortObjectDeep, _sortObject, _get, _set, _has, _unset, _mask, _invert, _invertMap, _by, _groupBy, _sortBy, _sortNumbers, _toFixed, _toPrecision, _round, _findLast, _takeWhile, _takeRightWhile, _dropWhile, _dropRightWhile, _countBy, _intersection, _difference, _shuffle, _mapToObject, _findKeyByValue, _range, _uniq, _uniqBy, _flatten, _flattenDeep, _chunk, SimpleMovingAverage, _average, _averageWeighted, _percentile, _median, _debounce, _throttle, _Debounce, _Throttle, pMap, _passthroughMapper, _passUndefinedMapper, _passthroughPredicate, _passNothingPredicate, _noop, pBatch, ErrorMode, pFilter, pProps, pDelay, pDefer, pHang, pState, AggregatedError, pRetry, pTimeout, pTuple, _Retry, _Timeout, _tryCatch, _TryCatch, _try, pTry, _jsonParseIfPossible, _stringifyAny, _ms, _since, _hb, _gb, _mb, _kb, _snakeCase, _camelCase, _kebabCase, _sum, _sumBy, _clamp, _last, mergeJsonSchemaObjects, jsonSchema, JsonSchemaAnyBuilder, JSON_SCHEMA_ORDER, generateJsonSchemaFromData, _parseQueryString, _defineLazyProperty, _defineLazyProps, _lazyValue, commonLoggerMinLevel, commonLoggerNoop, commonLogLevelNumber, commonLoggerPipe, commonLoggerPrefix, commonLoggerCreate, _safeJsonStringify, PQueue, END, SKIP, };
|
package/dist-esm/promise/pMap.js
CHANGED
|
@@ -6,7 +6,7 @@ Improvements:
|
|
|
6
6
|
- Included Typescript typings (no need for @types/p-map)
|
|
7
7
|
- Compatible with pProps (that had typings issues)
|
|
8
8
|
*/
|
|
9
|
-
import { ErrorMode } from '..';
|
|
9
|
+
import { END, ErrorMode, SKIP } from '..';
|
|
10
10
|
import { AggregatedError } from './AggregatedError';
|
|
11
11
|
/**
|
|
12
12
|
* Returns a `Promise` that is fulfilled when all promises in `input` and ones returned from `mapper` are fulfilled,
|
|
@@ -40,25 +40,27 @@ export async function pMap(iterable, mapper, opt = {}) {
|
|
|
40
40
|
const ret = [];
|
|
41
41
|
const iterator = iterable[Symbol.iterator]();
|
|
42
42
|
const errors = [];
|
|
43
|
-
let
|
|
43
|
+
let isSettled = false;
|
|
44
44
|
let isIterableDone = false;
|
|
45
45
|
let resolvingCount = 0;
|
|
46
46
|
let currentIndex = 0;
|
|
47
|
-
const next = () => {
|
|
48
|
-
if (
|
|
47
|
+
const next = (skipped = false) => {
|
|
48
|
+
if (isSettled) {
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
51
|
const nextItem = iterator.next();
|
|
52
52
|
const i = currentIndex;
|
|
53
|
-
|
|
53
|
+
if (!skipped)
|
|
54
|
+
currentIndex++;
|
|
54
55
|
if (nextItem.done) {
|
|
55
56
|
isIterableDone = true;
|
|
56
57
|
if (resolvingCount === 0) {
|
|
58
|
+
const r = ret.filter(r => r !== SKIP);
|
|
57
59
|
if (errors.length && errorMode === ErrorMode.THROW_AGGREGATED) {
|
|
58
|
-
reject(new AggregatedError(errors,
|
|
60
|
+
reject(new AggregatedError(errors, r));
|
|
59
61
|
}
|
|
60
62
|
else {
|
|
61
|
-
resolve(
|
|
63
|
+
resolve(r);
|
|
62
64
|
}
|
|
63
65
|
}
|
|
64
66
|
return;
|
|
@@ -67,12 +69,16 @@ export async function pMap(iterable, mapper, opt = {}) {
|
|
|
67
69
|
Promise.resolve(nextItem.value)
|
|
68
70
|
.then(async (element) => await mapper(element, i))
|
|
69
71
|
.then(value => {
|
|
72
|
+
if (value === END) {
|
|
73
|
+
isSettled = true;
|
|
74
|
+
return resolve(ret.filter(r => r !== SKIP));
|
|
75
|
+
}
|
|
70
76
|
ret[i] = value;
|
|
71
77
|
resolvingCount--;
|
|
72
78
|
next();
|
|
73
79
|
}, err => {
|
|
74
80
|
if (errorMode === ErrorMode.THROW_IMMEDIATELY) {
|
|
75
|
-
|
|
81
|
+
isSettled = true;
|
|
76
82
|
reject(err);
|
|
77
83
|
}
|
|
78
84
|
else {
|
|
@@ -8,16 +8,15 @@ Improvements:
|
|
|
8
8
|
- Included Typescript typings (no need for @types/p-props)
|
|
9
9
|
*/
|
|
10
10
|
import { pMap } from './pMap';
|
|
11
|
+
// todo: remove when eslint starts to know about Awaited
|
|
12
|
+
/* eslint-disable no-undef */
|
|
11
13
|
/**
|
|
12
14
|
* Promise.all for Object instead of Array.
|
|
13
15
|
* Supports concurrency.
|
|
14
16
|
*/
|
|
15
17
|
export async function pProps(input, opt) {
|
|
16
|
-
const keys = Object.keys(input);
|
|
17
|
-
const values = await pMap(Object.values(input), r => r, opt);
|
|
18
18
|
const r = {};
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
});
|
|
19
|
+
const keys = Object.keys(input);
|
|
20
|
+
await pMap(Object.values(input), (v, i) => (r[keys[i]] = v), opt);
|
|
22
21
|
return r;
|
|
23
22
|
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { END, SKIP } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Inspired by Kotlin Sequences.
|
|
4
|
+
* Similar to arrays, but with lazy evaluation, abortable.
|
|
5
|
+
* Can be useful when it's not feasible/performant to create an array of values to iterate upfront
|
|
6
|
+
* (e.g to construct 1000 Dayjs instances only to find that 2 of them were needed).
|
|
7
|
+
*
|
|
8
|
+
* @experimental
|
|
9
|
+
*/
|
|
10
|
+
export class Seq {
|
|
11
|
+
constructor(initialValue, nextFn) {
|
|
12
|
+
this.nextFn = nextFn;
|
|
13
|
+
this.sentInitialValue = false;
|
|
14
|
+
this.i = -1;
|
|
15
|
+
this.currentValue = initialValue;
|
|
16
|
+
}
|
|
17
|
+
[Symbol.iterator]() {
|
|
18
|
+
return {
|
|
19
|
+
next: () => {
|
|
20
|
+
const value = this.next();
|
|
21
|
+
return value === END ? { done: true, value: undefined } : { value };
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
static create(initialValue, nextFn) {
|
|
26
|
+
return new Seq(initialValue, nextFn);
|
|
27
|
+
}
|
|
28
|
+
static range(minIncl, maxExcl, step = 1) {
|
|
29
|
+
const max = maxExcl - step;
|
|
30
|
+
return new Seq(minIncl, n => (n < max ? n + step : END));
|
|
31
|
+
}
|
|
32
|
+
static from(a) {
|
|
33
|
+
const it = a[Symbol.iterator]();
|
|
34
|
+
const v = it.next();
|
|
35
|
+
if (v.done)
|
|
36
|
+
return new Seq(END, () => { });
|
|
37
|
+
return new Seq(v.value, () => {
|
|
38
|
+
const v = it.next();
|
|
39
|
+
if (v.done)
|
|
40
|
+
return END;
|
|
41
|
+
return v.value;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
static empty() {
|
|
45
|
+
return new Seq(END, () => { });
|
|
46
|
+
}
|
|
47
|
+
next() {
|
|
48
|
+
if (this.currentValue === END)
|
|
49
|
+
return END;
|
|
50
|
+
this.i++;
|
|
51
|
+
let v;
|
|
52
|
+
if (!this.sentInitialValue) {
|
|
53
|
+
this.sentInitialValue = true;
|
|
54
|
+
v = this.currentValue;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
v = this.nextFn(this.currentValue, this.i);
|
|
58
|
+
}
|
|
59
|
+
// console.log(`_seq`, v)
|
|
60
|
+
if (v === SKIP)
|
|
61
|
+
return this.next();
|
|
62
|
+
return (this.currentValue = v);
|
|
63
|
+
}
|
|
64
|
+
// Chainable functions - return another (chained) Sequence
|
|
65
|
+
// map<OUT>(mapper: Mapper<T, OUT | typeof SKIP | typeof END>): Seq<OUT> {
|
|
66
|
+
// if (this.currentValue === END) return this as any
|
|
67
|
+
//
|
|
68
|
+
// // Iterate until first valid value, to have as `initialValue` of the new Sequence
|
|
69
|
+
// let v: OUT | typeof SKIP | typeof END
|
|
70
|
+
//
|
|
71
|
+
// while (true) {
|
|
72
|
+
// v = mapper(this.currentValue, ++this.i)
|
|
73
|
+
// if (v === SKIP) continue
|
|
74
|
+
// if (v === END) return this as any
|
|
75
|
+
// }
|
|
76
|
+
//
|
|
77
|
+
// return new Seq<OUT>(v as OUT, (current, i) => {
|
|
78
|
+
// const v = mapper(current, i)
|
|
79
|
+
//
|
|
80
|
+
// })
|
|
81
|
+
// }
|
|
82
|
+
// Final functions - return final value, not a chained sequence
|
|
83
|
+
find(predicate) {
|
|
84
|
+
do {
|
|
85
|
+
const v = this.next();
|
|
86
|
+
if (v === END)
|
|
87
|
+
return; // not found, end of sequence
|
|
88
|
+
const r = predicate(v, this.i);
|
|
89
|
+
if (r === END)
|
|
90
|
+
return;
|
|
91
|
+
if (r)
|
|
92
|
+
return v;
|
|
93
|
+
// otherwise proceed
|
|
94
|
+
} while (true); // eslint-disable-line no-constant-condition
|
|
95
|
+
}
|
|
96
|
+
some(predicate) {
|
|
97
|
+
do {
|
|
98
|
+
const v = this.next();
|
|
99
|
+
if (v === END)
|
|
100
|
+
return false;
|
|
101
|
+
const r = predicate(v, this.i);
|
|
102
|
+
if (r === END)
|
|
103
|
+
return false;
|
|
104
|
+
if (r)
|
|
105
|
+
return true;
|
|
106
|
+
} while (true); // eslint-disable-line no-constant-condition
|
|
107
|
+
}
|
|
108
|
+
every(predicate) {
|
|
109
|
+
do {
|
|
110
|
+
const v = this.next();
|
|
111
|
+
if (v === END)
|
|
112
|
+
return true;
|
|
113
|
+
const r = predicate(v, this.i);
|
|
114
|
+
if (r === END)
|
|
115
|
+
return true;
|
|
116
|
+
if (!r)
|
|
117
|
+
return false;
|
|
118
|
+
} while (true); // eslint-disable-line no-constant-condition
|
|
119
|
+
}
|
|
120
|
+
toArray() {
|
|
121
|
+
const a = [];
|
|
122
|
+
// eslint-disable-next-line no-constant-condition
|
|
123
|
+
while (true) {
|
|
124
|
+
const v = this.next();
|
|
125
|
+
if (v === END)
|
|
126
|
+
return a;
|
|
127
|
+
a.push(v);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Convenience function to create a Sequence.
|
|
133
|
+
*/
|
|
134
|
+
export function _seq(initialValue, nextFn) {
|
|
135
|
+
return Seq.create(initialValue, nextFn);
|
|
136
|
+
}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
// const possibleJsonStartTokens = ['{', '[', '"']
|
|
2
|
+
const DETECT_JSON = /^\s*[{["\-\d]/;
|
|
1
3
|
/**
|
|
2
4
|
* Attempts to parse object as JSON.
|
|
3
5
|
* Returns original object if JSON parse failed (silently).
|
|
4
6
|
*/
|
|
5
7
|
export function _jsonParseIfPossible(obj, reviver) {
|
|
6
|
-
if
|
|
8
|
+
// Optimization: only try to parse if it looks like JSON: starts with a json possible character
|
|
9
|
+
if (typeof obj === 'string' && obj && DETECT_JSON.test(obj)) {
|
|
7
10
|
try {
|
|
8
11
|
return JSON.parse(obj, reviver);
|
|
9
12
|
}
|
package/dist-esm/types.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Symbol to indicate END of Sequence.
|
|
3
|
+
*/
|
|
4
|
+
export const END = Symbol('END');
|
|
5
|
+
/**
|
|
6
|
+
* Symbol to indicate SKIP of item (e.g in AbortableMapper)
|
|
7
|
+
*/
|
|
8
|
+
export const SKIP = Symbol('SKIP');
|
|
1
9
|
export const _passthroughMapper = item => item;
|
|
2
10
|
export const _passUndefinedMapper = () => undefined;
|
|
3
11
|
/**
|
package/package.json
CHANGED
package/src/error/error.util.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
StringifyAnyOptions,
|
|
8
8
|
_jsonParseIfPossible,
|
|
9
9
|
_stringifyAny,
|
|
10
|
+
Class,
|
|
10
11
|
} from '..'
|
|
11
12
|
|
|
12
13
|
/**
|
|
@@ -17,14 +18,17 @@ import {
|
|
|
17
18
|
*
|
|
18
19
|
* Alternatively, if you're sure it's Error - you can use `_assertIsError(err)`.
|
|
19
20
|
*/
|
|
20
|
-
export function _anyToError
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
export function _anyToError<ERROR_TYPE extends Error = Error>(
|
|
22
|
+
o: any,
|
|
23
|
+
errorClass: Class<ERROR_TYPE> = Error as any,
|
|
24
|
+
opt?: StringifyAnyOptions,
|
|
25
|
+
): ERROR_TYPE {
|
|
26
|
+
if (o instanceof errorClass) return o
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
// If it's an instance of Error, but ErrorClass is something else (e.g AppError) - it'll be "repacked" into AppError
|
|
29
|
+
|
|
30
|
+
const errorObject = _isErrorObject(o) ? o : _anyToErrorObject(o, opt)
|
|
31
|
+
return _errorObjectToError(errorObject, errorClass)
|
|
28
32
|
}
|
|
29
33
|
|
|
30
34
|
/**
|
|
@@ -38,7 +42,7 @@ export function _anyToErrorObject<DATA_TYPE extends ErrorData = ErrorData>(
|
|
|
38
42
|
opt?: StringifyAnyOptions,
|
|
39
43
|
): ErrorObject<DATA_TYPE> {
|
|
40
44
|
if (o instanceof Error) {
|
|
41
|
-
return _errorToErrorObject<DATA_TYPE>(o, opt?.includeErrorStack)
|
|
45
|
+
return _errorToErrorObject<DATA_TYPE>(o, opt?.includeErrorStack ?? true)
|
|
42
46
|
}
|
|
43
47
|
|
|
44
48
|
o = _jsonParseIfPossible(o)
|
|
@@ -70,7 +74,7 @@ export function _anyToErrorObject<DATA_TYPE extends ErrorData = ErrorData>(
|
|
|
70
74
|
|
|
71
75
|
export function _errorToErrorObject<DATA_TYPE extends ErrorData = ErrorData>(
|
|
72
76
|
e: AppError<DATA_TYPE> | Error,
|
|
73
|
-
includeErrorStack =
|
|
77
|
+
includeErrorStack = true,
|
|
74
78
|
): ErrorObject<DATA_TYPE> {
|
|
75
79
|
const obj: ErrorObject<DATA_TYPE> = {
|
|
76
80
|
name: e.name,
|
|
@@ -86,20 +90,37 @@ export function _errorToErrorObject<DATA_TYPE extends ErrorData = ErrorData>(
|
|
|
86
90
|
}
|
|
87
91
|
|
|
88
92
|
export function _errorObjectToAppError<DATA_TYPE>(o: ErrorObject<DATA_TYPE>): AppError<DATA_TYPE> {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
+
return _errorObjectToError(o, AppError)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function _errorObjectToError<DATA_TYPE, ERROR_TYPE extends Error>(
|
|
97
|
+
o: ErrorObject<DATA_TYPE>,
|
|
98
|
+
errorClass: Class<ERROR_TYPE> = Error as any,
|
|
99
|
+
): ERROR_TYPE {
|
|
100
|
+
if (o instanceof errorClass) return o
|
|
101
|
+
|
|
102
|
+
const err = new errorClass(o.message)
|
|
103
|
+
// name: err.name, // cannot be assigned to a readonly property like this
|
|
104
|
+
// stack: o.stack, // also readonly e.g in Firefox
|
|
93
105
|
|
|
94
106
|
Object.defineProperty(err, 'name', {
|
|
95
107
|
value: o.name,
|
|
96
108
|
configurable: true,
|
|
97
109
|
})
|
|
98
110
|
|
|
99
|
-
Object.defineProperty(err, '
|
|
100
|
-
value: o.
|
|
111
|
+
Object.defineProperty(err, 'data', {
|
|
112
|
+
value: o.data,
|
|
113
|
+
writable: true,
|
|
114
|
+
configurable: true,
|
|
115
|
+
enumerable: false,
|
|
101
116
|
})
|
|
102
117
|
|
|
118
|
+
if (o.stack) {
|
|
119
|
+
Object.defineProperty(err, 'stack', {
|
|
120
|
+
value: o.stack,
|
|
121
|
+
})
|
|
122
|
+
}
|
|
123
|
+
|
|
103
124
|
return err
|
|
104
125
|
}
|
|
105
126
|
|
|
@@ -109,14 +130,18 @@ export function _isHttpErrorResponse(o: any): o is HttpErrorResponse {
|
|
|
109
130
|
|
|
110
131
|
export function _isHttpErrorObject(o: any): o is ErrorObject<HttpErrorData> {
|
|
111
132
|
return (
|
|
112
|
-
|
|
113
|
-
typeof o
|
|
114
|
-
typeof o
|
|
133
|
+
!!o &&
|
|
134
|
+
typeof o.name === 'string' &&
|
|
135
|
+
typeof o.message === 'string' &&
|
|
136
|
+
typeof o.data?.httpStatusCode === 'number'
|
|
115
137
|
)
|
|
116
138
|
}
|
|
117
139
|
|
|
140
|
+
/**
|
|
141
|
+
* Note: any instance of AppError is also automatically an ErrorObject
|
|
142
|
+
*/
|
|
118
143
|
export function _isErrorObject(o: any): o is ErrorObject {
|
|
119
144
|
return (
|
|
120
|
-
typeof o
|
|
145
|
+
!!o && typeof o.name === 'string' && typeof o.message === 'string' && typeof o.data === 'object'
|
|
121
146
|
)
|
|
122
147
|
}
|
package/src/error/try.ts
CHANGED
|
@@ -24,6 +24,9 @@ export function _try<ERR = unknown, RETURN = void>(
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
// todo: remove when eslint starts to know about Awaited
|
|
28
|
+
/* eslint-disable no-undef */
|
|
29
|
+
|
|
27
30
|
/**
|
|
28
31
|
* Like _try, but for Promises.
|
|
29
32
|
*
|
|
@@ -32,7 +35,7 @@ export function _try<ERR = unknown, RETURN = void>(
|
|
|
32
35
|
*/
|
|
33
36
|
export async function pTry<ERR = unknown, RETURN = void>(
|
|
34
37
|
promise: Promise<RETURN>,
|
|
35
|
-
): Promise<[err: ERR | null, value: RETURN]> {
|
|
38
|
+
): Promise<[err: ERR | null, value: Awaited<RETURN>]> {
|
|
36
39
|
try {
|
|
37
40
|
return [null, await promise]
|
|
38
41
|
} catch (err) {
|
package/src/index.ts
CHANGED
|
@@ -57,15 +57,7 @@ import {
|
|
|
57
57
|
HttpErrorData,
|
|
58
58
|
HttpErrorResponse,
|
|
59
59
|
} from './error/error.model'
|
|
60
|
-
|
|
61
|
-
_anyToError,
|
|
62
|
-
_anyToErrorObject,
|
|
63
|
-
_errorObjectToAppError,
|
|
64
|
-
_errorToErrorObject,
|
|
65
|
-
_isErrorObject,
|
|
66
|
-
_isHttpErrorObject,
|
|
67
|
-
_isHttpErrorResponse,
|
|
68
|
-
} from './error/error.util'
|
|
60
|
+
export * from './error/error.util'
|
|
69
61
|
import { ErrorMode } from './error/errorMode'
|
|
70
62
|
import { HttpError } from './error/http.error'
|
|
71
63
|
import { _try, pTry } from './error/try'
|
|
@@ -181,7 +173,6 @@ import {
|
|
|
181
173
|
ConditionalPick,
|
|
182
174
|
Merge,
|
|
183
175
|
Promisable,
|
|
184
|
-
PromiseValue,
|
|
185
176
|
ReadonlyDeep,
|
|
186
177
|
Simplify,
|
|
187
178
|
} from './typeFest'
|
|
@@ -213,6 +204,12 @@ import {
|
|
|
213
204
|
UnixTimestamp,
|
|
214
205
|
ValueOf,
|
|
215
206
|
ValuesOf,
|
|
207
|
+
AbortableMapper,
|
|
208
|
+
AbortableAsyncPredicate,
|
|
209
|
+
AbortableAsyncMapper,
|
|
210
|
+
AbortablePredicate,
|
|
211
|
+
END,
|
|
212
|
+
SKIP,
|
|
216
213
|
_noop,
|
|
217
214
|
_objectKeys,
|
|
218
215
|
_passNothingPredicate,
|
|
@@ -238,8 +235,13 @@ import {
|
|
|
238
235
|
} from './log/commonLogger'
|
|
239
236
|
import { _safeJsonStringify } from './string/safeJsonStringify'
|
|
240
237
|
import { PQueue, PQueueCfg } from './promise/pQueue'
|
|
238
|
+
export * from './seq/seq'
|
|
241
239
|
|
|
242
240
|
export type {
|
|
241
|
+
AbortableMapper,
|
|
242
|
+
AbortablePredicate,
|
|
243
|
+
AbortableAsyncPredicate,
|
|
244
|
+
AbortableAsyncMapper,
|
|
243
245
|
PQueueCfg,
|
|
244
246
|
MemoCache,
|
|
245
247
|
PromiseDecoratorCfg,
|
|
@@ -278,7 +280,6 @@ export type {
|
|
|
278
280
|
Merge,
|
|
279
281
|
ReadonlyDeep,
|
|
280
282
|
Promisable,
|
|
281
|
-
PromiseValue,
|
|
282
283
|
Simplify,
|
|
283
284
|
ConditionalPick,
|
|
284
285
|
ConditionalExcept,
|
|
@@ -326,9 +327,6 @@ export {
|
|
|
326
327
|
AppError,
|
|
327
328
|
HttpError,
|
|
328
329
|
AssertionError,
|
|
329
|
-
_isErrorObject,
|
|
330
|
-
_isHttpErrorObject,
|
|
331
|
-
_isHttpErrorResponse,
|
|
332
330
|
_assert,
|
|
333
331
|
_assertEquals,
|
|
334
332
|
_assertDeepEquals,
|
|
@@ -405,10 +403,6 @@ export {
|
|
|
405
403
|
_shuffle,
|
|
406
404
|
_mapToObject,
|
|
407
405
|
_findKeyByValue,
|
|
408
|
-
_anyToError,
|
|
409
|
-
_anyToErrorObject,
|
|
410
|
-
_errorToErrorObject,
|
|
411
|
-
_errorObjectToAppError,
|
|
412
406
|
_range,
|
|
413
407
|
_uniq,
|
|
414
408
|
_uniqBy,
|
|
@@ -480,4 +474,6 @@ export {
|
|
|
480
474
|
commonLoggerCreate,
|
|
481
475
|
_safeJsonStringify,
|
|
482
476
|
PQueue,
|
|
477
|
+
END,
|
|
478
|
+
SKIP,
|
|
483
479
|
}
|
package/src/promise/pBatch.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { BatchResult, ErrorMode } from '..'
|
|
2
|
-
import { AsyncMapper } from '../types'
|
|
1
|
+
import { AbortableAsyncMapper, BatchResult, ErrorMode } from '..'
|
|
3
2
|
import { AggregatedError } from './AggregatedError'
|
|
4
3
|
import { pMap } from './pMap'
|
|
5
4
|
|
|
@@ -8,7 +7,7 @@ import { pMap } from './pMap'
|
|
|
8
7
|
*/
|
|
9
8
|
export async function pBatch<IN, OUT>(
|
|
10
9
|
iterable: Iterable<IN | PromiseLike<IN>>,
|
|
11
|
-
mapper:
|
|
10
|
+
mapper: AbortableAsyncMapper<IN, OUT>,
|
|
12
11
|
opt?: { concurrency?: number },
|
|
13
12
|
): Promise<BatchResult<OUT>> {
|
|
14
13
|
try {
|
package/src/promise/pFilter.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AbortableAsyncPredicate } from '../types'
|
|
2
2
|
import { pMap, PMapOptions } from './pMap'
|
|
3
3
|
|
|
4
4
|
export async function pFilter<T>(
|
|
5
5
|
iterable: Iterable<T | PromiseLike<T>>,
|
|
6
|
-
filterFn:
|
|
6
|
+
filterFn: AbortableAsyncPredicate<T>,
|
|
7
7
|
opt?: PMapOptions,
|
|
8
8
|
): Promise<T[]> {
|
|
9
9
|
const values = await pMap(
|