@naturalcycles/js-lib 14.53.0 → 14.56.1
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/app.error.js +7 -3
- package/dist/error/assert.d.ts +1 -1
- package/dist/error/assert.js +1 -16
- package/dist/error/http.error.js +0 -15
- package/dist/error/try.d.ts +13 -1
- package/dist/error/try.js +22 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +5 -1
- package/dist/json-schema/from-data/generateJsonSchemaFromData.d.ts +2 -2
- package/dist/json-schema/jsonSchema.model.d.ts +3 -3
- package/dist/json-schema/jsonSchemaBuilder.d.ts +5 -5
- package/dist/object/object.util.d.ts +23 -23
- package/dist/object/sortObject.d.ts +2 -1
- package/dist/promise/AggregatedError.js +1 -2
- package/dist/promise/pTuple.d.ts +1 -1
- package/dist/promise/pTuple.js +1 -5
- package/dist/string/url.util.d.ts +15 -0
- package/dist/string/url.util.js +30 -0
- package/dist/types.d.ts +1 -1
- package/dist-esm/error/app.error.js +7 -3
- package/dist-esm/error/assert.js +1 -16
- package/dist-esm/error/http.error.js +0 -15
- package/dist-esm/error/try.js +20 -1
- package/dist-esm/index.js +3 -2
- package/dist-esm/promise/AggregatedError.js +1 -2
- package/dist-esm/promise/pTuple.js +1 -5
- package/dist-esm/string/url.util.js +26 -0
- package/package.json +2 -3
- package/src/error/app.error.ts +11 -3
- package/src/error/assert.ts +1 -17
- package/src/error/http.error.ts +0 -16
- package/src/error/try.ts +24 -3
- package/src/index.ts +4 -1
- package/src/json-schema/from-data/generateJsonSchemaFromData.ts +3 -2
- package/src/json-schema/jsonSchema.model.ts +3 -5
- package/src/json-schema/jsonSchemaBuilder.ts +5 -6
- package/src/object/object.util.ts +23 -31
- package/src/object/sortObject.ts +2 -2
- package/src/promise/AggregatedError.ts +1 -2
- package/src/promise/pTuple.ts +4 -8
- package/src/string/url.util.ts +27 -0
- package/src/types.ts +1 -1
- package/CHANGELOG.md +0 -1321
package/dist-esm/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { _by, _chunk, _countBy, _difference, _dropRightWhile, _dropWhile, _findLast, _flatten, _flattenDeep, _groupBy, _intersection, _last, _mapToObject, _shuffle, _sortBy, _sum, _sumBy, _takeRightWhile, _takeWhile, _uniq, _uniqBy, } from './array/array.util';
|
|
2
|
+
import { _parseQueryString } from './string/url.util';
|
|
2
3
|
import { _range } from './array/range';
|
|
3
4
|
import { _createPromiseDecorator, } from './decorators/createPromiseDecorator';
|
|
4
5
|
import { _debounce, _throttle } from './decorators/debounce';
|
|
@@ -14,7 +15,7 @@ import { AssertionError, _assert, _assertDeepEquals, _assertEquals, _assertIsErr
|
|
|
14
15
|
import { _anyToError, _anyToErrorObject, _errorObjectToAppError, _errorToErrorObject, _isErrorObject, _isHttpErrorObject, _isHttpErrorResponse, } from './error/error.util';
|
|
15
16
|
import { ErrorMode } from './error/errorMode';
|
|
16
17
|
import { HttpError } from './error/http.error';
|
|
17
|
-
import { _try } from './error/try';
|
|
18
|
+
import { _try, pTry } from './error/try';
|
|
18
19
|
import { _TryCatch, _tryCatch } from './error/tryCatch';
|
|
19
20
|
import { generateJsonSchemaFromData } from './json-schema/from-data/generateJsonSchemaFromData';
|
|
20
21
|
import { JSON_SCHEMA_ORDER } from './json-schema/jsonSchema.cnst';
|
|
@@ -48,4 +49,4 @@ import { _ms, _since } from './time/time.util';
|
|
|
48
49
|
import { _noop, _objectKeys, _passNothingPredicate, _passthroughMapper, _passthroughPredicate, _passUndefinedMapper, _stringMapEntries, _stringMapValues, } from './types';
|
|
49
50
|
import { _gb, _hb, _kb, _mb } from './unit/size.util';
|
|
50
51
|
import { is } from './vendor/is';
|
|
51
|
-
export { is, _Memo, _memoFn, _LogMethod, _getArgsSignature, _createPromiseDecorator, AppError, HttpError, AssertionError, _isErrorObject, _isHttpErrorObject, _isHttpErrorResponse, _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, _anyToError, _anyToErrorObject, _errorToErrorObject, _errorObjectToAppError, _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, _jsonParseIfPossible, _stringifyAny, _ms, _since, _hb, _gb, _mb, _kb, _snakeCase, _camelCase, _kebabCase, _sum, _sumBy, _clamp, _last, mergeJsonSchemaObjects, jsonSchema, JsonSchemaAnyBuilder, JSON_SCHEMA_ORDER, generateJsonSchemaFromData, };
|
|
52
|
+
export { is, _Memo, _memoFn, _LogMethod, _getArgsSignature, _createPromiseDecorator, AppError, HttpError, AssertionError, _isErrorObject, _isHttpErrorObject, _isHttpErrorResponse, _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, _anyToError, _anyToErrorObject, _errorToErrorObject, _errorObjectToAppError, _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, };
|
|
@@ -17,8 +17,6 @@ export class AggregatedError extends Error {
|
|
|
17
17
|
super(message);
|
|
18
18
|
this.errors = mappedErrors;
|
|
19
19
|
this.results = results;
|
|
20
|
-
this.constructor = AggregatedError;
|
|
21
|
-
this.__proto__ = AggregatedError.prototype;
|
|
22
20
|
Object.defineProperty(this, 'name', {
|
|
23
21
|
value: this.constructor.name,
|
|
24
22
|
configurable: true,
|
|
@@ -29,6 +27,7 @@ export class AggregatedError extends Error {
|
|
|
29
27
|
else {
|
|
30
28
|
Object.defineProperty(this, 'stack', {
|
|
31
29
|
value: new Error().stack,
|
|
30
|
+
writable: true,
|
|
32
31
|
configurable: true,
|
|
33
32
|
});
|
|
34
33
|
}
|
|
@@ -5,9 +5,5 @@
|
|
|
5
5
|
* source: https://github.com/scopsy/await-to-js/blob/master/src/await-to-js.ts
|
|
6
6
|
*/
|
|
7
7
|
export async function pTuple(promise) {
|
|
8
|
-
return promise
|
|
9
|
-
.then((data) => [null, data])
|
|
10
|
-
.catch((err) => {
|
|
11
|
-
return [err, undefined];
|
|
12
|
-
});
|
|
8
|
+
return promise.then(data => [null, data]).catch(err => [err, undefined]);
|
|
13
9
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses `location.search` string (e.g `?a=1&b=2`) into a StringMap, e.g:
|
|
3
|
+
* `{ a: '1', b: '2' }`
|
|
4
|
+
*
|
|
5
|
+
* Pass `location.search` to it in the Frontend, or any other string on the Backend (where `location.search` is not available).
|
|
6
|
+
*
|
|
7
|
+
* Works both with and without leading `?` character.
|
|
8
|
+
*
|
|
9
|
+
* Yes, there's `URLSearchParams` existing in the Frontend (not in Node yet), but it's API is not
|
|
10
|
+
* as convenient. And the implementation here is super-small.
|
|
11
|
+
*
|
|
12
|
+
* Goal of this function is to produce exactly same output as URLSearchParams would.
|
|
13
|
+
*/
|
|
14
|
+
export function _parseQueryString(search) {
|
|
15
|
+
const qs = {};
|
|
16
|
+
search
|
|
17
|
+
.substr(search[0] === '?' ? 1 : 0)
|
|
18
|
+
.split('&')
|
|
19
|
+
.forEach(p => {
|
|
20
|
+
const [k, v] = p.split('=');
|
|
21
|
+
if (!k)
|
|
22
|
+
return;
|
|
23
|
+
qs[decodeURIComponent(k)] = decodeURIComponent(v || '');
|
|
24
|
+
});
|
|
25
|
+
return qs;
|
|
26
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naturalcycles/js-lib",
|
|
3
|
-
"version": "14.
|
|
3
|
+
"version": "14.56.1",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"prepare": "husky install",
|
|
6
6
|
"build-prod": "build-prod-esm-cjs",
|
|
@@ -11,11 +11,10 @@
|
|
|
11
11
|
"tslib": "^2.0.0"
|
|
12
12
|
},
|
|
13
13
|
"devDependencies": {
|
|
14
|
+
"@naturalcycles/bench-lib": "^1.5.0",
|
|
14
15
|
"@naturalcycles/dev-lib": "^12.0.0",
|
|
15
16
|
"@naturalcycles/nodejs-lib": "^12.33.4",
|
|
16
|
-
"@types/benchmark": "^2.1.0",
|
|
17
17
|
"@types/node": "^16.0.0",
|
|
18
|
-
"benchmark": "^2.1.4",
|
|
19
18
|
"jest": "^27.0.1",
|
|
20
19
|
"patch-package": "^6.2.1",
|
|
21
20
|
"prettier": "^2.1.2",
|
package/src/error/app.error.ts
CHANGED
|
@@ -10,21 +10,29 @@ import { ErrorData } from './error.model'
|
|
|
10
10
|
* Based on: https://medium.com/@xpl/javascript-deriving-from-error-properly-8d2f8f315801
|
|
11
11
|
*/
|
|
12
12
|
export class AppError<DATA_TYPE extends ErrorData = ErrorData> extends Error {
|
|
13
|
-
|
|
13
|
+
data!: DATA_TYPE
|
|
14
|
+
|
|
15
|
+
constructor(message: string, data = {} as DATA_TYPE) {
|
|
14
16
|
super(message)
|
|
15
17
|
|
|
16
|
-
this.constructor = AppError
|
|
17
|
-
;(this as any).__proto__ = AppError.prototype
|
|
18
18
|
Object.defineProperty(this, 'name', {
|
|
19
19
|
value: this.constructor.name,
|
|
20
20
|
configurable: true,
|
|
21
21
|
})
|
|
22
22
|
|
|
23
|
+
Object.defineProperty(this, 'data', {
|
|
24
|
+
value: data,
|
|
25
|
+
writable: true,
|
|
26
|
+
configurable: true,
|
|
27
|
+
enumerable: false,
|
|
28
|
+
})
|
|
29
|
+
|
|
23
30
|
if (Error.captureStackTrace) {
|
|
24
31
|
Error.captureStackTrace(this, this.constructor)
|
|
25
32
|
} else {
|
|
26
33
|
Object.defineProperty(this, 'stack', {
|
|
27
34
|
value: new Error().stack, // eslint-disable-line unicorn/error-message
|
|
35
|
+
writable: true,
|
|
28
36
|
configurable: true,
|
|
29
37
|
})
|
|
30
38
|
}
|
package/src/error/assert.ts
CHANGED
|
@@ -123,23 +123,7 @@ export function _assertTypeOf<T>(v: any, expectedType: string, message?: string)
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
export class AssertionError extends AppError {
|
|
126
|
-
constructor(message: string, data
|
|
126
|
+
constructor(message: string, data = {} as ErrorData) {
|
|
127
127
|
super(message, data)
|
|
128
|
-
|
|
129
|
-
this.constructor = AssertionError
|
|
130
|
-
;(this as any).__proto__ = AssertionError.prototype
|
|
131
|
-
Object.defineProperty(this, 'name', {
|
|
132
|
-
value: this.constructor.name,
|
|
133
|
-
configurable: true, // otherwise throws with "TypeError: Cannot redefine property: name"
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
if (Error.captureStackTrace) {
|
|
137
|
-
Error.captureStackTrace(this, this.constructor)
|
|
138
|
-
} else {
|
|
139
|
-
Object.defineProperty(this, 'stack', {
|
|
140
|
-
value: new Error().stack, // eslint-disable-line unicorn/error-message
|
|
141
|
-
configurable: true,
|
|
142
|
-
})
|
|
143
|
-
}
|
|
144
128
|
}
|
|
145
129
|
}
|
package/src/error/http.error.ts
CHANGED
|
@@ -9,21 +9,5 @@ export class HttpError<
|
|
|
9
9
|
> extends AppError<DATA_TYPE> {
|
|
10
10
|
constructor(message: string, data: DATA_TYPE) {
|
|
11
11
|
super(message, data)
|
|
12
|
-
|
|
13
|
-
this.constructor = HttpError
|
|
14
|
-
;(this as any).__proto__ = HttpError.prototype
|
|
15
|
-
Object.defineProperty(this, 'name', {
|
|
16
|
-
value: this.constructor.name,
|
|
17
|
-
configurable: true, // otherwise throws with "TypeError: Cannot redefine property: name"
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
if (Error.captureStackTrace) {
|
|
21
|
-
Error.captureStackTrace(this, this.constructor)
|
|
22
|
-
} else {
|
|
23
|
-
Object.defineProperty(this, 'stack', {
|
|
24
|
-
value: new Error().stack, // eslint-disable-line unicorn/error-message
|
|
25
|
-
configurable: true,
|
|
26
|
-
})
|
|
27
|
-
}
|
|
28
12
|
}
|
|
29
13
|
}
|
package/src/error/try.ts
CHANGED
|
@@ -5,16 +5,37 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Similar to pTuple, but for sync functions.
|
|
7
7
|
*
|
|
8
|
+
* For convenience, second argument type is non-optional,
|
|
9
|
+
* so you can use it without `!`. But you SHOULD always check `if (err)` first!
|
|
10
|
+
*
|
|
8
11
|
* @example
|
|
9
12
|
*
|
|
10
13
|
* const [err, v] = _try(() => someFunction())
|
|
14
|
+
* if (err) ...do something...
|
|
15
|
+
* v // go ahead and use v
|
|
11
16
|
*/
|
|
12
17
|
export function _try<ERR = unknown, RETURN = void>(
|
|
13
18
|
fn: () => RETURN,
|
|
14
|
-
): [err: ERR |
|
|
19
|
+
): [err: ERR | null, value: RETURN] {
|
|
20
|
+
try {
|
|
21
|
+
return [null, fn()]
|
|
22
|
+
} catch (err) {
|
|
23
|
+
return [err as ERR, undefined as any]
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Like _try, but for Promises.
|
|
29
|
+
*
|
|
30
|
+
* Also, intentionally types second return item as non-optional,
|
|
31
|
+
* but you should check for `err` presense first!
|
|
32
|
+
*/
|
|
33
|
+
export async function pTry<ERR = unknown, RETURN = void>(
|
|
34
|
+
promise: Promise<RETURN>,
|
|
35
|
+
): Promise<[err: ERR | null, value: RETURN]> {
|
|
15
36
|
try {
|
|
16
|
-
return [
|
|
37
|
+
return [null, await promise]
|
|
17
38
|
} catch (err) {
|
|
18
|
-
return [err as ERR, undefined]
|
|
39
|
+
return [err as ERR, undefined as any]
|
|
19
40
|
}
|
|
20
41
|
}
|
package/src/index.ts
CHANGED
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
_uniq,
|
|
22
22
|
_uniqBy,
|
|
23
23
|
} from './array/array.util'
|
|
24
|
+
import { _parseQueryString } from './string/url.util'
|
|
24
25
|
import { _range } from './array/range'
|
|
25
26
|
import {
|
|
26
27
|
PromiseDecoratorCfg,
|
|
@@ -66,7 +67,7 @@ import {
|
|
|
66
67
|
} from './error/error.util'
|
|
67
68
|
import { ErrorMode } from './error/errorMode'
|
|
68
69
|
import { HttpError } from './error/http.error'
|
|
69
|
-
import { _try } from './error/try'
|
|
70
|
+
import { _try, pTry } from './error/try'
|
|
70
71
|
import { TryCatchOptions, _TryCatch, _tryCatch } from './error/tryCatch'
|
|
71
72
|
import { generateJsonSchemaFromData } from './json-schema/from-data/generateJsonSchemaFromData'
|
|
72
73
|
import { JSON_SCHEMA_ORDER } from './json-schema/jsonSchema.cnst'
|
|
@@ -426,6 +427,7 @@ export {
|
|
|
426
427
|
_tryCatch,
|
|
427
428
|
_TryCatch,
|
|
428
429
|
_try,
|
|
430
|
+
pTry,
|
|
429
431
|
_jsonParseIfPossible,
|
|
430
432
|
_stringifyAny,
|
|
431
433
|
_ms,
|
|
@@ -446,4 +448,5 @@ export {
|
|
|
446
448
|
JsonSchemaAnyBuilder,
|
|
447
449
|
JSON_SCHEMA_ORDER,
|
|
448
450
|
generateJsonSchemaFromData,
|
|
451
|
+
_parseQueryString,
|
|
449
452
|
}
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
StringMap,
|
|
11
11
|
_stringMapEntries,
|
|
12
12
|
_uniq,
|
|
13
|
+
AnyObject,
|
|
13
14
|
} from '../..'
|
|
14
15
|
|
|
15
16
|
type PrimitiveType = 'undefined' | 'null' | 'boolean' | 'string' | 'number'
|
|
@@ -20,11 +21,11 @@ type Type = PrimitiveType | 'array' | 'object'
|
|
|
20
21
|
*
|
|
21
22
|
* `additionalProperties` is set to `true`, cause it's safer.
|
|
22
23
|
*/
|
|
23
|
-
export function generateJsonSchemaFromData<T = unknown>(rows:
|
|
24
|
+
export function generateJsonSchemaFromData<T = unknown>(rows: AnyObject[]): JsonSchemaObject<T> {
|
|
24
25
|
return objectToJsonSchema(rows as any) as JsonSchemaObject<T>
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
function objectToJsonSchema(rows:
|
|
28
|
+
function objectToJsonSchema(rows: AnyObject[]): JsonSchemaObject {
|
|
28
29
|
const typesByKey: StringMap<Set<Type>> = {}
|
|
29
30
|
|
|
30
31
|
rows.forEach(r => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StringMap } from '../types'
|
|
1
|
+
import { AnyObject, StringMap } from '../types'
|
|
2
2
|
|
|
3
3
|
// eslint-disable-next-line unused-imports/no-unused-vars
|
|
4
4
|
export type JsonSchema<T = unknown> =
|
|
@@ -124,13 +124,11 @@ export interface JsonSchemaRef<T = unknown> extends JsonSchemaAny<T> {
|
|
|
124
124
|
$ref: string
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
export interface JsonSchemaRootObject<T extends
|
|
128
|
-
extends JsonSchemaObject<T> {
|
|
127
|
+
export interface JsonSchemaRootObject<T extends AnyObject = AnyObject> extends JsonSchemaObject<T> {
|
|
129
128
|
$id: string
|
|
130
129
|
}
|
|
131
130
|
|
|
132
|
-
export interface JsonSchemaObject<T extends
|
|
133
|
-
extends JsonSchemaAny<T> {
|
|
131
|
+
export interface JsonSchemaObject<T extends AnyObject = AnyObject> extends JsonSchemaAny<T> {
|
|
134
132
|
type: 'object'
|
|
135
133
|
// let's be strict and require all these
|
|
136
134
|
properties: {
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
SavedDBEntity,
|
|
10
10
|
_deepCopy,
|
|
11
11
|
_sortObject,
|
|
12
|
+
AnyObject,
|
|
12
13
|
} from '../index'
|
|
13
14
|
import { JSON_SCHEMA_ORDER } from './jsonSchema.cnst'
|
|
14
15
|
import {
|
|
@@ -86,12 +87,12 @@ export const jsonSchema = {
|
|
|
86
87
|
},
|
|
87
88
|
// email: () => new JsonSchemaStringBuilder().email(),
|
|
88
89
|
// complex types
|
|
89
|
-
object<T extends
|
|
90
|
+
object<T extends AnyObject>(props: {
|
|
90
91
|
[k in keyof T]: JsonSchemaAnyBuilder<T[k]>
|
|
91
92
|
}) {
|
|
92
93
|
return new JsonSchemaObjectBuilder<T>().addProperties(props)
|
|
93
94
|
},
|
|
94
|
-
rootObject<T extends
|
|
95
|
+
rootObject<T extends AnyObject>(props: {
|
|
95
96
|
[k in keyof T]: JsonSchemaAnyBuilder<T[k]>
|
|
96
97
|
}) {
|
|
97
98
|
return new JsonSchemaObjectBuilder<T>().addProperties(props).$schemaDraft7()
|
|
@@ -309,7 +310,7 @@ export class JsonSchemaStringBuilder extends JsonSchemaAnyBuilder<string, JsonSc
|
|
|
309
310
|
// contentEncoding?: string
|
|
310
311
|
}
|
|
311
312
|
|
|
312
|
-
export class JsonSchemaObjectBuilder<T extends
|
|
313
|
+
export class JsonSchemaObjectBuilder<T extends AnyObject> extends JsonSchemaAnyBuilder<
|
|
313
314
|
T,
|
|
314
315
|
JsonSchemaObject<T>
|
|
315
316
|
> {
|
|
@@ -378,9 +379,7 @@ export class JsonSchemaObjectBuilder<T extends Record<any, any>> extends JsonSch
|
|
|
378
379
|
return this.baseDBEntity().addRequired(['id', 'created', 'updated']) as any
|
|
379
380
|
}
|
|
380
381
|
|
|
381
|
-
extend<T2 extends
|
|
382
|
-
s2: JsonSchemaObjectBuilder<T2>,
|
|
383
|
-
): JsonSchemaObjectBuilder<T & T2> {
|
|
382
|
+
extend<T2 extends AnyObject>(s2: JsonSchemaObjectBuilder<T2>): JsonSchemaObjectBuilder<T & T2> {
|
|
384
383
|
const builder = new JsonSchemaObjectBuilder<T & T2>()
|
|
385
384
|
Object.assign(builder.schema, _deepCopy(this.schema))
|
|
386
385
|
mergeJsonSchemaObjects(builder.schema, s2.schema)
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { PropertyPath } from '../lodash.types'
|
|
2
|
-
import { ObjectMapper, ObjectPredicate, StringMap, ValueOf } from '../types'
|
|
2
|
+
import { AnyObject, ObjectMapper, ObjectPredicate, StringMap, ValueOf } from '../types'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Returns clone of `obj` with only `props` preserved.
|
|
6
6
|
* Opposite of Omit.
|
|
7
7
|
*/
|
|
8
|
-
export function _pick<T extends
|
|
8
|
+
export function _pick<T extends AnyObject, K extends keyof T>(
|
|
9
9
|
obj: T,
|
|
10
10
|
props: readonly K[],
|
|
11
11
|
mutate = false,
|
|
@@ -29,7 +29,7 @@ export function _pick<T extends Record<string, any>, K extends keyof T>(
|
|
|
29
29
|
* Returns clone of `obj` with `props` omitted.
|
|
30
30
|
* Opposite of Pick.
|
|
31
31
|
*/
|
|
32
|
-
export function _omit<T extends
|
|
32
|
+
export function _omit<T extends AnyObject, K extends keyof T>(
|
|
33
33
|
obj: T,
|
|
34
34
|
props: readonly K[],
|
|
35
35
|
mutate = false,
|
|
@@ -51,7 +51,7 @@ export function _omit<T extends Record<string, any>, K extends keyof T>(
|
|
|
51
51
|
* 'account.updated',
|
|
52
52
|
* ])
|
|
53
53
|
*/
|
|
54
|
-
export function _mask<T extends
|
|
54
|
+
export function _mask<T extends AnyObject>(obj: T, props: string[], mutate = false): T {
|
|
55
55
|
return props.reduce(
|
|
56
56
|
(r, prop) => {
|
|
57
57
|
_unset(r, prop)
|
|
@@ -64,14 +64,14 @@ export function _mask<T extends Record<string, any>>(obj: T, props: string[], mu
|
|
|
64
64
|
/**
|
|
65
65
|
* Removes "falsy" values from the object.
|
|
66
66
|
*/
|
|
67
|
-
export function _filterFalsyValues<T extends
|
|
67
|
+
export function _filterFalsyValues<T extends AnyObject>(obj: T, mutate = false): T {
|
|
68
68
|
return _filterObject(obj, (_k, v) => !!v, mutate)
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
/**
|
|
72
72
|
* Removes values from the object that are `null` or `undefined`.
|
|
73
73
|
*/
|
|
74
|
-
export function _filterNullishValues<T extends
|
|
74
|
+
export function _filterNullishValues<T extends AnyObject>(obj: T, mutate = false): T {
|
|
75
75
|
return _filterObject(obj, (_k, v) => v !== undefined && v !== null, mutate)
|
|
76
76
|
}
|
|
77
77
|
|
|
@@ -79,11 +79,11 @@ export function _filterNullishValues<T extends Record<string, any>>(obj: T, muta
|
|
|
79
79
|
* Removes values from the object that are `undefined`.
|
|
80
80
|
* Only `undefined` values are removed. `null` values are kept!
|
|
81
81
|
*/
|
|
82
|
-
export function _filterUndefinedValues<T extends
|
|
82
|
+
export function _filterUndefinedValues<T extends AnyObject>(obj: T, mutate = false): T {
|
|
83
83
|
return _filterObject(obj, (_k, v) => v !== undefined, mutate)
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
export function _filterEmptyArrays<T extends
|
|
86
|
+
export function _filterEmptyArrays<T extends AnyObject>(obj: T, mutate = false): T {
|
|
87
87
|
return _filterObject(obj, (_k, v) => !Array.isArray(v) || v.length > 0, mutate)
|
|
88
88
|
}
|
|
89
89
|
|
|
@@ -91,7 +91,7 @@ export function _filterEmptyArrays<T extends Record<string, any>>(obj: T, mutate
|
|
|
91
91
|
* Returns clone of `obj` without properties that does not pass `predicate`.
|
|
92
92
|
* Allows filtering by both key and value.
|
|
93
93
|
*/
|
|
94
|
-
export function _filterObject<T extends
|
|
94
|
+
export function _filterObject<T extends AnyObject>(
|
|
95
95
|
obj: T,
|
|
96
96
|
predicate: ObjectPredicate<T>,
|
|
97
97
|
mutate = false,
|
|
@@ -118,7 +118,7 @@ export function _filterObject<T extends Record<string, any>>(
|
|
|
118
118
|
* _.mapValues(users, 'age')
|
|
119
119
|
* // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
|
|
120
120
|
*/
|
|
121
|
-
export function _mapValues<T extends
|
|
121
|
+
export function _mapValues<T extends AnyObject, OUT = T>(
|
|
122
122
|
obj: T,
|
|
123
123
|
mapper: ObjectMapper<T, any>,
|
|
124
124
|
mutate = false,
|
|
@@ -135,7 +135,7 @@ export function _mapValues<T extends Record<string, any>, OUT = T>(
|
|
|
135
135
|
*
|
|
136
136
|
* Does not support `mutate` flag.
|
|
137
137
|
*/
|
|
138
|
-
export function _mapKeys<T extends
|
|
138
|
+
export function _mapKeys<T extends AnyObject>(
|
|
139
139
|
obj: T,
|
|
140
140
|
mapper: ObjectMapper<T, string>,
|
|
141
141
|
): StringMap<T[keyof T]> {
|
|
@@ -162,7 +162,7 @@ export function _mapKeys<T extends Record<string, any>>(
|
|
|
162
162
|
*
|
|
163
163
|
* Non-string keys are passed via String(...)
|
|
164
164
|
*/
|
|
165
|
-
export function _mapObject<IN extends
|
|
165
|
+
export function _mapObject<IN extends AnyObject, OUT>(
|
|
166
166
|
obj: IN,
|
|
167
167
|
mapper: ObjectMapper<IN, [key: string, value: any]>,
|
|
168
168
|
): { [P in keyof IN]: OUT } {
|
|
@@ -175,17 +175,11 @@ export function _mapObject<IN extends Record<string, any>, OUT>(
|
|
|
175
175
|
}, {} as { [P in keyof IN]: OUT })
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
-
export function _findKeyByValue<T extends
|
|
179
|
-
obj: T,
|
|
180
|
-
v: ValueOf<T>,
|
|
181
|
-
): keyof T | undefined {
|
|
178
|
+
export function _findKeyByValue<T extends AnyObject>(obj: T, v: ValueOf<T>): keyof T | undefined {
|
|
182
179
|
return Object.entries(obj).find(([_, value]) => value === v)?.[0] as keyof T
|
|
183
180
|
}
|
|
184
181
|
|
|
185
|
-
export function _objectNullValuesToUndefined<T extends
|
|
186
|
-
obj: T,
|
|
187
|
-
mutate = false,
|
|
188
|
-
): T {
|
|
182
|
+
export function _objectNullValuesToUndefined<T extends AnyObject>(obj: T, mutate = false): T {
|
|
189
183
|
return _mapValues(obj, (_k, v) => (v === null ? undefined : v), mutate)
|
|
190
184
|
}
|
|
191
185
|
|
|
@@ -199,7 +193,7 @@ export function _deepCopy<T>(o: T): T {
|
|
|
199
193
|
/**
|
|
200
194
|
* Returns true if item is Object, not null and not Array.
|
|
201
195
|
*/
|
|
202
|
-
export function _isObject(item: any): item is
|
|
196
|
+
export function _isObject(item: any): item is AnyObject {
|
|
203
197
|
return (typeof item === 'object' && item !== null && !Array.isArray(item)) || false
|
|
204
198
|
}
|
|
205
199
|
|
|
@@ -256,7 +250,7 @@ export function _undefinedIfEmpty<T>(obj: T | undefined): T | undefined {
|
|
|
256
250
|
/**
|
|
257
251
|
* Filters the object by removing all key-value pairs where Value is Empty (according to _isEmpty() specification).
|
|
258
252
|
*/
|
|
259
|
-
export function _filterEmptyValues<T extends
|
|
253
|
+
export function _filterEmptyValues<T extends AnyObject>(obj: T, mutate = false): T {
|
|
260
254
|
return _filterObject(obj, (_k, v) => !_isEmpty(v), mutate)
|
|
261
255
|
}
|
|
262
256
|
|
|
@@ -289,7 +283,7 @@ export function _filterEmptyValues<T extends Record<string, any>>(obj: T, mutate
|
|
|
289
283
|
*
|
|
290
284
|
* Based on: https://gist.github.com/Salakar/1d7137de9cb8b704e48a
|
|
291
285
|
*/
|
|
292
|
-
export function _merge<T extends
|
|
286
|
+
export function _merge<T extends AnyObject>(target: T, ...sources: any[]): T {
|
|
293
287
|
sources.forEach(source => {
|
|
294
288
|
if (_isObject(source)) {
|
|
295
289
|
Object.keys(source).forEach(key => {
|
|
@@ -311,7 +305,7 @@ export function _merge<T extends Record<string, any>>(target: T, ...sources: any
|
|
|
311
305
|
* Doesn't touch object KEYS.
|
|
312
306
|
* Mutates.
|
|
313
307
|
*/
|
|
314
|
-
export function _deepTrim<T extends
|
|
308
|
+
export function _deepTrim<T extends AnyObject | string>(o: T): T {
|
|
315
309
|
if (!o) return o
|
|
316
310
|
|
|
317
311
|
if (typeof o === 'string') {
|
|
@@ -327,7 +321,7 @@ export function _deepTrim<T extends Record<string, any> | string>(o: T): T {
|
|
|
327
321
|
|
|
328
322
|
// from: https://github.com/jonschlinkert/unset-value
|
|
329
323
|
// mutates obj
|
|
330
|
-
export function _unset<T extends
|
|
324
|
+
export function _unset<T extends AnyObject>(obj: T, prop: string): void {
|
|
331
325
|
if (!_isObject(obj)) {
|
|
332
326
|
return
|
|
333
327
|
}
|
|
@@ -350,9 +344,7 @@ export function _unset<T extends Record<string, any>>(obj: T, prop: string): voi
|
|
|
350
344
|
delete obj[last!]
|
|
351
345
|
}
|
|
352
346
|
|
|
353
|
-
export function _invert<T extends
|
|
354
|
-
o: T,
|
|
355
|
-
): { [k in ValueOf<T>]: keyof T | undefined } {
|
|
347
|
+
export function _invert<T extends AnyObject>(o: T): { [k in ValueOf<T>]: keyof T | undefined } {
|
|
356
348
|
const inv = {} as { [k in ValueOf<T>]: keyof T }
|
|
357
349
|
Object.keys(o).forEach(k => {
|
|
358
350
|
inv[o[k]] = k
|
|
@@ -375,7 +367,7 @@ export function _invertMap<K, V>(m: ReadonlyMap<K, V>): Map<V, K> {
|
|
|
375
367
|
* @param def The value returned if the resolved value is undefined.
|
|
376
368
|
* @return Returns the resolved value.
|
|
377
369
|
*/
|
|
378
|
-
export function _get<T extends
|
|
370
|
+
export function _get<T extends AnyObject>(obj = {} as T, path = '', def?: any): any {
|
|
379
371
|
const res = path
|
|
380
372
|
.replace(/\[([^\]]+)]/g, '.$1')
|
|
381
373
|
.split('.')
|
|
@@ -396,7 +388,7 @@ export function _get<T extends Record<string, any>>(obj = {} as T, path = '', de
|
|
|
396
388
|
*
|
|
397
389
|
* Based on: https://stackoverflow.com/a/54733755/4919972
|
|
398
390
|
*/
|
|
399
|
-
export function _set<IN extends
|
|
391
|
+
export function _set<IN extends AnyObject, OUT = IN>(
|
|
400
392
|
obj: IN,
|
|
401
393
|
path: PropertyPath,
|
|
402
394
|
value?: any,
|
|
@@ -455,7 +447,7 @@ export function _set<IN extends Record<string, any>, OUT = IN>(
|
|
|
455
447
|
* _.has(other, 'a');
|
|
456
448
|
* // => false
|
|
457
449
|
*/
|
|
458
|
-
export function _has<T extends
|
|
450
|
+
export function _has<T extends AnyObject>(obj: T, path?: string): boolean {
|
|
459
451
|
const v = _get(obj, path)
|
|
460
452
|
return v !== undefined && v !== null
|
|
461
453
|
}
|
package/src/object/sortObject.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { _omit } from '../index'
|
|
1
|
+
import { _omit, AnyObject } from '../index'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Returns new object with keys sorder in the given order.
|
|
5
5
|
* All keys that are not listed in `keyOrder` go last.
|
|
6
6
|
* Does not mutate original object.
|
|
7
7
|
*/
|
|
8
|
-
export function _sortObject<T extends
|
|
8
|
+
export function _sortObject<T extends AnyObject>(obj: T, keyOrder: (keyof T)[]): T {
|
|
9
9
|
const r = {} as T
|
|
10
10
|
|
|
11
11
|
keyOrder.forEach(key => {
|
|
@@ -23,8 +23,6 @@ export class AggregatedError<RESULT = any> extends Error {
|
|
|
23
23
|
this.errors = mappedErrors
|
|
24
24
|
this.results = results
|
|
25
25
|
|
|
26
|
-
this.constructor = AggregatedError
|
|
27
|
-
;(this as any).__proto__ = AggregatedError.prototype
|
|
28
26
|
Object.defineProperty(this, 'name', {
|
|
29
27
|
value: this.constructor.name,
|
|
30
28
|
configurable: true,
|
|
@@ -35,6 +33,7 @@ export class AggregatedError<RESULT = any> extends Error {
|
|
|
35
33
|
} else {
|
|
36
34
|
Object.defineProperty(this, 'stack', {
|
|
37
35
|
value: new Error().stack, // eslint-disable-line unicorn/error-message
|
|
36
|
+
writable: true,
|
|
38
37
|
configurable: true,
|
|
39
38
|
})
|
|
40
39
|
}
|
package/src/promise/pTuple.ts
CHANGED
|
@@ -4,12 +4,8 @@
|
|
|
4
4
|
*
|
|
5
5
|
* source: https://github.com/scopsy/await-to-js/blob/master/src/await-to-js.ts
|
|
6
6
|
*/
|
|
7
|
-
export async function pTuple<
|
|
8
|
-
promise: Promise<
|
|
9
|
-
): Promise<[
|
|
10
|
-
return promise
|
|
11
|
-
.then<[null, T]>((data: T) => [null, data])
|
|
12
|
-
.catch<[U, undefined]>((err: U) => {
|
|
13
|
-
return [err, undefined]
|
|
14
|
-
})
|
|
7
|
+
export async function pTuple<RETURN, ERR = Error>(
|
|
8
|
+
promise: Promise<RETURN>,
|
|
9
|
+
): Promise<[ERR, undefined] | [null, RETURN]> {
|
|
10
|
+
return promise.then(data => [null, data] as [null, RETURN]).catch(err => [err as ERR, undefined])
|
|
15
11
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { StringMap } from '../types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Parses `location.search` string (e.g `?a=1&b=2`) into a StringMap, e.g:
|
|
5
|
+
* `{ a: '1', b: '2' }`
|
|
6
|
+
*
|
|
7
|
+
* Pass `location.search` to it in the Frontend, or any other string on the Backend (where `location.search` is not available).
|
|
8
|
+
*
|
|
9
|
+
* Works both with and without leading `?` character.
|
|
10
|
+
*
|
|
11
|
+
* Yes, there's `URLSearchParams` existing in the Frontend (not in Node yet), but it's API is not
|
|
12
|
+
* as convenient. And the implementation here is super-small.
|
|
13
|
+
*
|
|
14
|
+
* Goal of this function is to produce exactly same output as URLSearchParams would.
|
|
15
|
+
*/
|
|
16
|
+
export function _parseQueryString(search: string): StringMap {
|
|
17
|
+
const qs = {}
|
|
18
|
+
search
|
|
19
|
+
.substr(search[0] === '?' ? 1 : 0)
|
|
20
|
+
.split('&')
|
|
21
|
+
.forEach(p => {
|
|
22
|
+
const [k, v] = p.split('=')
|
|
23
|
+
if (!k) return
|
|
24
|
+
qs[decodeURIComponent(k)] = decodeURIComponent(v || '')
|
|
25
|
+
})
|
|
26
|
+
return qs
|
|
27
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -191,6 +191,6 @@ export function _stringMapEntries<T>(m: StringMap<T>): [k: string, v: T][] {
|
|
|
191
191
|
*
|
|
192
192
|
* @experimental
|
|
193
193
|
*/
|
|
194
|
-
export function _objectKeys<T extends
|
|
194
|
+
export function _objectKeys<T extends AnyObject>(obj: T): (keyof T)[] {
|
|
195
195
|
return Object.keys(obj)
|
|
196
196
|
}
|