@naturalcycles/js-lib 14.58.0 → 14.61.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/array/array.util.d.ts +1 -1
- package/dist/array/array.util.js +4 -3
- package/dist/index.d.ts +4 -2
- package/dist/index.js +6 -1
- package/dist/log/commonLogger.d.ts +49 -0
- package/dist/log/commonLogger.js +27 -0
- package/dist/number/number.util.d.ts +1 -1
- package/dist/number/number.util.js +3 -2
- package/dist/string/safeJsonStringify.d.ts +7 -0
- package/dist/string/safeJsonStringify.js +45 -0
- package/dist/string/stringifyAny.js +2 -2
- package/dist/types.d.ts +1 -1
- package/dist-esm/array/array.util.js +4 -3
- package/dist-esm/index.js +3 -1
- package/dist-esm/log/commonLogger.js +23 -0
- package/dist-esm/number/number.util.js +3 -2
- package/dist-esm/string/safeJsonStringify.js +41 -0
- package/dist-esm/string/stringifyAny.js +2 -2
- package/package.json +1 -1
- package/src/array/array.util.ts +9 -3
- package/src/index.ts +16 -0
- package/src/log/commonLogger.ts +65 -0
- package/src/number/number.util.ts +3 -2
- package/src/string/safeJsonStringify.ts +50 -0
- package/src/string/stringifyAny.ts +2 -4
- package/src/types.ts +1 -1
|
@@ -93,7 +93,7 @@ export declare function _groupBy<T>(items: readonly T[], mapper: Mapper<T, any>)
|
|
|
93
93
|
* Same:
|
|
94
94
|
* _sortBy([{age: 20}, {age: 10}], o => o.age)
|
|
95
95
|
*/
|
|
96
|
-
export declare function _sortBy<T>(items: T[], mapper: Mapper<T, any>, mutate?: boolean): T[];
|
|
96
|
+
export declare function _sortBy<T>(items: T[], mapper: Mapper<T, any>, mutate?: boolean, descending?: boolean): T[];
|
|
97
97
|
/**
|
|
98
98
|
* Like items.find(), but it tries to find from the END of the array.
|
|
99
99
|
*/
|
package/dist/array/array.util.js
CHANGED
|
@@ -140,12 +140,13 @@ exports._groupBy = _groupBy;
|
|
|
140
140
|
* Same:
|
|
141
141
|
* _sortBy([{age: 20}, {age: 10}], o => o.age)
|
|
142
142
|
*/
|
|
143
|
-
function _sortBy(items, mapper, mutate = false) {
|
|
143
|
+
function _sortBy(items, mapper, mutate = false, descending = false) {
|
|
144
|
+
const mod = descending ? -1 : 1;
|
|
144
145
|
return (mutate ? items : [...items]).sort((_a, _b) => {
|
|
145
146
|
const [a, b] = [_a, _b].map(mapper); // eslint-disable-line unicorn/no-array-callback-reference
|
|
146
147
|
if (typeof a === 'number' && typeof b === 'number')
|
|
147
|
-
return a - b;
|
|
148
|
-
return String(a).localeCompare(String(b));
|
|
148
|
+
return (a - b) * mod;
|
|
149
|
+
return String(a).localeCompare(String(b)) * mod;
|
|
149
150
|
});
|
|
150
151
|
}
|
|
151
152
|
exports._sortBy = _sortBy;
|
package/dist/index.d.ts
CHANGED
|
@@ -54,5 +54,7 @@ import { Class, ConditionalExcept, ConditionalPick, Merge, Promisable, PromiseVa
|
|
|
54
54
|
import { AsyncMapper, AsyncPredicate, BaseDBEntity, CreatedUpdated, CreatedUpdatedId, ObjectWithId, AnyObjectWithId, Saved, Unsaved, BatchResult, InstanceId, IsoDate, IsoDateTime, KeyValueTuple, Mapper, ObjectMapper, ObjectPredicate, Predicate, PromiseMap, AnyObject, AnyFunction, Reviver, SavedDBEntity, StringMap, UnixTimestamp, ValueOf, ValuesOf, _noop, _objectKeys, _passNothingPredicate, _passthroughMapper, _passthroughPredicate, _passUndefinedMapper, _stringMapEntries, _stringMapValues } from './types';
|
|
55
55
|
import { _gb, _hb, _kb, _mb } from './unit/size.util';
|
|
56
56
|
import { is } from './vendor/is';
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
import { CommonLogLevel, CommonLogFunction, CommonLogger, SimpleLogger, createSimpleLogger, noopLogger } from './log/commonLogger';
|
|
58
|
+
import { _safeJsonStringify } from './string/safeJsonStringify';
|
|
59
|
+
export type { MemoCache, PromiseDecoratorCfg, PromiseDecoratorResp, ErrorData, ErrorObject, HttpErrorData, HttpErrorResponse, Admin401ErrorData, Admin403ErrorData, StringMap, PromiseMap, AnyObject, AnyFunction, ValuesOf, ValueOf, KeyValueTuple, ObjectMapper, ObjectPredicate, InstanceId, IsoDate, IsoDateTime, Reviver, PMapOptions, Mapper, AsyncMapper, Predicate, AsyncPredicate, BatchResult, DeferredPromise, PRetryOptions, PTimeoutOptions, TryCatchOptions, StringifyAnyOptions, JsonStringifyFunction, Merge, ReadonlyDeep, Promisable, PromiseValue, Simplify, ConditionalPick, ConditionalExcept, Class, UnixTimestamp, BaseDBEntity, SavedDBEntity, Saved, Unsaved, CreatedUpdated, CreatedUpdatedId, ObjectWithId, AnyObjectWithId, JsonSchema, JsonSchemaAny, JsonSchemaOneOf, JsonSchemaAllOf, JsonSchemaAnyOf, JsonSchemaNot, JsonSchemaRef, JsonSchemaConst, JsonSchemaEnum, JsonSchemaString, JsonSchemaNumber, JsonSchemaBoolean, JsonSchemaNull, JsonSchemaRootObject, JsonSchemaObject, JsonSchemaArray, JsonSchemaTuple, JsonSchemaBuilder, CommonLogLevel, CommonLogFunction, CommonLogger, SimpleLogger, };
|
|
60
|
+
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, _defineLazyProperty, _defineLazyProps, _lazyValue, createSimpleLogger, noopLogger, _safeJsonStringify, };
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports._isObject = exports._undefinedIfEmpty = exports._filterObject = exports._filterEmptyValues = exports._filterEmptyArrays = exports._filterNullishValues = exports._filterUndefinedValues = exports._filterFalsyValues = exports._omit = exports._pick = exports._truncateMiddle = exports._truncate = exports._nl2br = exports._replaceAll = exports._substringBetweenLast = exports._substringAfterLast = exports._substringAfter = exports._substringBeforeLast = exports._substringBefore = exports._removeWhitespace = exports._split = exports._lowerFirst = exports._upperFirst = exports._capitalize = exports._objectKeys = exports._stringMapEntries = exports._stringMapValues = exports._inRange = exports._createDeterministicRandom = exports._randomArrayItem = exports._randomInt = exports._assertTypeOf = exports._assertIsNumber = exports._assertIsString = exports._assertIsError = exports._assertDeepEquals = exports._assertEquals = exports._assert = exports._isHttpErrorResponse = exports._isHttpErrorObject = exports._isErrorObject = exports.AssertionError = exports.HttpError = exports.AppError = exports._createPromiseDecorator = exports._getArgsSignature = exports._LogMethod = exports._memoFn = exports._Memo = exports.is = void 0;
|
|
4
4
|
exports._average = exports.SimpleMovingAverage = exports._chunk = exports._flattenDeep = exports._flatten = exports._uniqBy = exports._uniq = exports._range = exports._errorObjectToAppError = exports._errorToErrorObject = exports._anyToErrorObject = exports._anyToError = exports._findKeyByValue = exports._mapToObject = exports._shuffle = exports._difference = exports._intersection = exports._countBy = exports._dropRightWhile = exports._dropWhile = exports._takeRightWhile = exports._takeWhile = exports._findLast = exports._round = exports._toPrecision = exports._toFixed = exports._sortNumbers = exports._sortBy = exports._groupBy = exports._by = exports._invertMap = exports._invert = exports._mask = exports._unset = exports._has = exports._set = exports._get = exports._sortObject = exports._sortObjectDeep = exports._deepTrim = exports._merge = exports._isEmpty = exports._isEmptyObject = exports._deepCopy = exports._deepEquals = exports._objectNullValuesToUndefined = exports._mapObject = exports._mapValues = exports._mapKeys = exports._isPrimitive = void 0;
|
|
5
5
|
exports.JSON_SCHEMA_ORDER = exports.JsonSchemaAnyBuilder = exports.jsonSchema = exports.mergeJsonSchemaObjects = exports._last = exports._clamp = exports._sumBy = exports._sum = exports._kebabCase = exports._camelCase = exports._snakeCase = exports._kb = exports._mb = exports._gb = exports._hb = exports._since = exports._ms = exports._stringifyAny = exports._jsonParseIfPossible = exports.pTry = exports._try = exports._TryCatch = exports._tryCatch = exports._Timeout = exports._Retry = exports.pTuple = exports.pTimeout = exports.pRetry = exports.AggregatedError = exports.pState = exports.pHang = exports.pDefer = exports.pDelay = exports.pProps = exports.pFilter = exports.ErrorMode = exports.pBatch = exports._noop = exports._passNothingPredicate = exports._passthroughPredicate = exports._passUndefinedMapper = exports._passthroughMapper = exports.pMap = exports._Throttle = exports._Debounce = exports._throttle = exports._debounce = exports._median = exports._percentile = exports._averageWeighted = void 0;
|
|
6
|
-
exports._lazyValue = exports._defineLazyProps = exports._defineLazyProperty = exports._parseQueryString = exports.generateJsonSchemaFromData = void 0;
|
|
6
|
+
exports._safeJsonStringify = exports.noopLogger = exports.createSimpleLogger = exports._lazyValue = exports._defineLazyProps = exports._defineLazyProperty = exports._parseQueryString = exports.generateJsonSchemaFromData = void 0;
|
|
7
7
|
const array_util_1 = require("./array/array.util");
|
|
8
8
|
Object.defineProperty(exports, "_by", { enumerable: true, get: function () { return array_util_1._by; } });
|
|
9
9
|
Object.defineProperty(exports, "_chunk", { enumerable: true, get: function () { return array_util_1._chunk; } });
|
|
@@ -211,3 +211,8 @@ Object.defineProperty(exports, "_kb", { enumerable: true, get: function () { ret
|
|
|
211
211
|
Object.defineProperty(exports, "_mb", { enumerable: true, get: function () { return size_util_1._mb; } });
|
|
212
212
|
const is_1 = require("./vendor/is");
|
|
213
213
|
Object.defineProperty(exports, "is", { enumerable: true, get: function () { return is_1.is; } });
|
|
214
|
+
const commonLogger_1 = require("./log/commonLogger");
|
|
215
|
+
Object.defineProperty(exports, "createSimpleLogger", { enumerable: true, get: function () { return commonLogger_1.createSimpleLogger; } });
|
|
216
|
+
Object.defineProperty(exports, "noopLogger", { enumerable: true, get: function () { return commonLogger_1.noopLogger; } });
|
|
217
|
+
const safeJsonStringify_1 = require("./string/safeJsonStringify");
|
|
218
|
+
Object.defineProperty(exports, "_safeJsonStringify", { enumerable: true, get: function () { return safeJsonStringify_1._safeJsonStringify; } });
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* These levels follow console.* naming,
|
|
3
|
+
* so you can use console[level] safely.
|
|
4
|
+
*
|
|
5
|
+
* `log` is considered default level.
|
|
6
|
+
*
|
|
7
|
+
* For simplicity - only these 3 levels are kept.
|
|
8
|
+
*
|
|
9
|
+
* @experimental
|
|
10
|
+
*/
|
|
11
|
+
export declare type CommonLogLevel = 'log' | 'warn' | 'error';
|
|
12
|
+
/**
|
|
13
|
+
* Function that takes any number of arguments and logs them all.
|
|
14
|
+
* It is expected that logged arguments are separated by "space", like console.log does.
|
|
15
|
+
*
|
|
16
|
+
* @experimental
|
|
17
|
+
*/
|
|
18
|
+
export declare type CommonLogFunction = (...args: any[]) => void;
|
|
19
|
+
/**
|
|
20
|
+
* Interface is inspired/compatible with `console.*`
|
|
21
|
+
* So, `console` is a valid CommonLogger implementation as-is.
|
|
22
|
+
*
|
|
23
|
+
* @experimental
|
|
24
|
+
*/
|
|
25
|
+
export interface CommonLogger {
|
|
26
|
+
log: CommonLogFunction;
|
|
27
|
+
warn: CommonLogFunction;
|
|
28
|
+
error: CommonLogFunction;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Same as CommonLogger, but also is a "convenience function" itself.
|
|
32
|
+
* So you can do `logger('hey')` which is the same as `logger.log('hey')`
|
|
33
|
+
*
|
|
34
|
+
* @experimental
|
|
35
|
+
*/
|
|
36
|
+
export interface SimpleLogger extends CommonLogFunction, CommonLogger {
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Creates a SimpleLogger from CommonLogger.
|
|
40
|
+
*
|
|
41
|
+
* @experimental
|
|
42
|
+
*/
|
|
43
|
+
export declare function createSimpleLogger(logger: CommonLogger): SimpleLogger;
|
|
44
|
+
/**
|
|
45
|
+
* SimpleLogger that does nothing (noop).
|
|
46
|
+
*
|
|
47
|
+
* @experimental
|
|
48
|
+
*/
|
|
49
|
+
export declare const noopLogger: SimpleLogger;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.noopLogger = exports.createSimpleLogger = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Creates a SimpleLogger from CommonLogger.
|
|
6
|
+
*
|
|
7
|
+
* @experimental
|
|
8
|
+
*/
|
|
9
|
+
function createSimpleLogger(logger) {
|
|
10
|
+
return Object.assign(((...args) => logger.log(...args)), {
|
|
11
|
+
log: (...args) => logger.log(...args),
|
|
12
|
+
warn: (...args) => logger.warn(...args),
|
|
13
|
+
error: (...args) => logger.error(...args),
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
exports.createSimpleLogger = createSimpleLogger;
|
|
17
|
+
const noop = () => { };
|
|
18
|
+
/**
|
|
19
|
+
* SimpleLogger that does nothing (noop).
|
|
20
|
+
*
|
|
21
|
+
* @experimental
|
|
22
|
+
*/
|
|
23
|
+
exports.noopLogger = createSimpleLogger({
|
|
24
|
+
log: noop,
|
|
25
|
+
warn: noop,
|
|
26
|
+
error: noop,
|
|
27
|
+
});
|
|
@@ -23,7 +23,7 @@ export declare function _clamp(x: number, minIncl: number, maxIncl: number): num
|
|
|
23
23
|
* _sortNumbers([1, 3, 2])
|
|
24
24
|
* // [1, 2, 3]
|
|
25
25
|
*/
|
|
26
|
-
export declare function _sortNumbers(numbers: number[], mutate?: boolean): number[];
|
|
26
|
+
export declare function _sortNumbers(numbers: number[], mutate?: boolean, descending?: boolean): number[];
|
|
27
27
|
/**
|
|
28
28
|
* Same as .toFixed(), but conveniently casts the output to Number.
|
|
29
29
|
*
|
|
@@ -39,8 +39,9 @@ exports._clamp = _clamp;
|
|
|
39
39
|
* _sortNumbers([1, 3, 2])
|
|
40
40
|
* // [1, 2, 3]
|
|
41
41
|
*/
|
|
42
|
-
function _sortNumbers(numbers, mutate = false) {
|
|
43
|
-
|
|
42
|
+
function _sortNumbers(numbers, mutate = false, descending = false) {
|
|
43
|
+
const mod = descending ? -1 : 1;
|
|
44
|
+
return (mutate ? numbers : [...numbers]).sort((a, b) => (a - b) * mod);
|
|
44
45
|
}
|
|
45
46
|
exports._sortNumbers = _sortNumbers;
|
|
46
47
|
/**
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Reviver } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* JSON.stringify that avoids circular references, prints them as [Circular ~]
|
|
4
|
+
*
|
|
5
|
+
* Based on: https://github.com/moll/json-stringify-safe/
|
|
6
|
+
*/
|
|
7
|
+
export declare function _safeJsonStringify(obj: any, replacer?: Reviver, spaces?: number, cycleReplacer?: Reviver): string;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports._safeJsonStringify = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* JSON.stringify that avoids circular references, prints them as [Circular ~]
|
|
6
|
+
*
|
|
7
|
+
* Based on: https://github.com/moll/json-stringify-safe/
|
|
8
|
+
*/
|
|
9
|
+
function _safeJsonStringify(obj, replacer, spaces, cycleReplacer) {
|
|
10
|
+
try {
|
|
11
|
+
// Try native first (as it's ~3 times faster)
|
|
12
|
+
return JSON.stringify(obj, replacer, spaces);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
// Native failed - resort to the "safe" serializer
|
|
16
|
+
return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports._safeJsonStringify = _safeJsonStringify;
|
|
20
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions, no-bitwise */
|
|
21
|
+
function serializer(replacer, cycleReplacer) {
|
|
22
|
+
const stack = [];
|
|
23
|
+
const keys = [];
|
|
24
|
+
if (cycleReplacer == null) {
|
|
25
|
+
cycleReplacer = function (key, value) {
|
|
26
|
+
if (stack[0] === value)
|
|
27
|
+
return '[Circular ~]';
|
|
28
|
+
return '[Circular ~.' + keys.slice(0, stack.indexOf(value)).join('.') + ']';
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
return function (key, value) {
|
|
32
|
+
if (stack.length > 0) {
|
|
33
|
+
const thisPos = stack.indexOf(this);
|
|
34
|
+
~thisPos ? stack.splice(thisPos + 1) : stack.push(this);
|
|
35
|
+
~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key);
|
|
36
|
+
if (~stack.indexOf(value)) {
|
|
37
|
+
value = cycleReplacer.call(this, key, value);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
stack.push(value);
|
|
42
|
+
}
|
|
43
|
+
return replacer == null ? value : replacer.call(this, key, value);
|
|
44
|
+
};
|
|
45
|
+
}
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports._stringifyAny = void 0;
|
|
4
4
|
const error_util_1 = require("../error/error.util");
|
|
5
5
|
const json_util_1 = require("./json.util");
|
|
6
|
-
const
|
|
6
|
+
const safeJsonStringify_1 = require("./safeJsonStringify");
|
|
7
7
|
/**
|
|
8
8
|
* Inspired by inspectAny from nodejs-lib, which is based on util.inpect that is not available in the Browser.
|
|
9
9
|
* Potentially can do this (with extra 2Kb gz size): https://github.com/deecewan/browser-util-inspect
|
|
@@ -83,7 +83,7 @@ function _stringifyAny(obj, opt = {}) {
|
|
|
83
83
|
// Other
|
|
84
84
|
//
|
|
85
85
|
try {
|
|
86
|
-
const { stringifyFn =
|
|
86
|
+
const { stringifyFn = safeJsonStringify_1._safeJsonStringify } = opt;
|
|
87
87
|
s = stringifyFn(obj, undefined, 2);
|
|
88
88
|
}
|
|
89
89
|
catch {
|
package/dist/types.d.ts
CHANGED
|
@@ -136,7 +136,7 @@ export declare type BaseDBEntity = Partial<SavedDBEntity>;
|
|
|
136
136
|
export declare type Saved<E> = Merge<E, SavedDBEntity>;
|
|
137
137
|
export declare type Unsaved<E> = Merge<E, BaseDBEntity>;
|
|
138
138
|
/**
|
|
139
|
-
* Named type for JSON.parse second argument
|
|
139
|
+
* Named type for JSON.parse / JSON.stringify second argument
|
|
140
140
|
*/
|
|
141
141
|
export declare type Reviver = (this: any, key: string, value: any) => any;
|
|
142
142
|
/**
|
|
@@ -130,12 +130,13 @@ export function _groupBy(items, mapper) {
|
|
|
130
130
|
* Same:
|
|
131
131
|
* _sortBy([{age: 20}, {age: 10}], o => o.age)
|
|
132
132
|
*/
|
|
133
|
-
export function _sortBy(items, mapper, mutate = false) {
|
|
133
|
+
export function _sortBy(items, mapper, mutate = false, descending = false) {
|
|
134
|
+
const mod = descending ? -1 : 1;
|
|
134
135
|
return (mutate ? items : [...items]).sort((_a, _b) => {
|
|
135
136
|
const [a, b] = [_a, _b].map(mapper); // eslint-disable-line unicorn/no-array-callback-reference
|
|
136
137
|
if (typeof a === 'number' && typeof b === 'number')
|
|
137
|
-
return a - b;
|
|
138
|
-
return String(a).localeCompare(String(b));
|
|
138
|
+
return (a - b) * mod;
|
|
139
|
+
return String(a).localeCompare(String(b)) * mod;
|
|
139
140
|
});
|
|
140
141
|
}
|
|
141
142
|
/**
|
package/dist-esm/index.js
CHANGED
|
@@ -50,4 +50,6 @@ import { _ms, _since } from './time/time.util';
|
|
|
50
50
|
import { _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 { createSimpleLogger, noopLogger, } from './log/commonLogger';
|
|
54
|
+
import { _safeJsonStringify } from './string/safeJsonStringify';
|
|
55
|
+
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, _defineLazyProperty, _defineLazyProps, _lazyValue, createSimpleLogger, noopLogger, _safeJsonStringify, };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a SimpleLogger from CommonLogger.
|
|
3
|
+
*
|
|
4
|
+
* @experimental
|
|
5
|
+
*/
|
|
6
|
+
export function createSimpleLogger(logger) {
|
|
7
|
+
return Object.assign(((...args) => logger.log(...args)), {
|
|
8
|
+
log: (...args) => logger.log(...args),
|
|
9
|
+
warn: (...args) => logger.warn(...args),
|
|
10
|
+
error: (...args) => logger.error(...args),
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
const noop = () => { };
|
|
14
|
+
/**
|
|
15
|
+
* SimpleLogger that does nothing (noop).
|
|
16
|
+
*
|
|
17
|
+
* @experimental
|
|
18
|
+
*/
|
|
19
|
+
export const noopLogger = createSimpleLogger({
|
|
20
|
+
log: noop,
|
|
21
|
+
warn: noop,
|
|
22
|
+
error: noop,
|
|
23
|
+
});
|
|
@@ -32,8 +32,9 @@ export function _clamp(x, minIncl, maxIncl) {
|
|
|
32
32
|
* _sortNumbers([1, 3, 2])
|
|
33
33
|
* // [1, 2, 3]
|
|
34
34
|
*/
|
|
35
|
-
export function _sortNumbers(numbers, mutate = false) {
|
|
36
|
-
|
|
35
|
+
export function _sortNumbers(numbers, mutate = false, descending = false) {
|
|
36
|
+
const mod = descending ? -1 : 1;
|
|
37
|
+
return (mutate ? numbers : [...numbers]).sort((a, b) => (a - b) * mod);
|
|
37
38
|
}
|
|
38
39
|
/**
|
|
39
40
|
* Same as .toFixed(), but conveniently casts the output to Number.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON.stringify that avoids circular references, prints them as [Circular ~]
|
|
3
|
+
*
|
|
4
|
+
* Based on: https://github.com/moll/json-stringify-safe/
|
|
5
|
+
*/
|
|
6
|
+
export function _safeJsonStringify(obj, replacer, spaces, cycleReplacer) {
|
|
7
|
+
try {
|
|
8
|
+
// Try native first (as it's ~3 times faster)
|
|
9
|
+
return JSON.stringify(obj, replacer, spaces);
|
|
10
|
+
}
|
|
11
|
+
catch (_a) {
|
|
12
|
+
// Native failed - resort to the "safe" serializer
|
|
13
|
+
return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions, no-bitwise */
|
|
17
|
+
function serializer(replacer, cycleReplacer) {
|
|
18
|
+
const stack = [];
|
|
19
|
+
const keys = [];
|
|
20
|
+
if (cycleReplacer == null) {
|
|
21
|
+
cycleReplacer = function (key, value) {
|
|
22
|
+
if (stack[0] === value)
|
|
23
|
+
return '[Circular ~]';
|
|
24
|
+
return '[Circular ~.' + keys.slice(0, stack.indexOf(value)).join('.') + ']';
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return function (key, value) {
|
|
28
|
+
if (stack.length > 0) {
|
|
29
|
+
const thisPos = stack.indexOf(this);
|
|
30
|
+
~thisPos ? stack.splice(thisPos + 1) : stack.push(this);
|
|
31
|
+
~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key);
|
|
32
|
+
if (~stack.indexOf(value)) {
|
|
33
|
+
value = cycleReplacer.call(this, key, value);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
stack.push(value);
|
|
38
|
+
}
|
|
39
|
+
return replacer == null ? value : replacer.call(this, key, value);
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { _isErrorObject, _isHttpErrorObject, _isHttpErrorResponse } from '../error/error.util';
|
|
2
2
|
import { _jsonParseIfPossible } from './json.util';
|
|
3
|
-
|
|
3
|
+
import { _safeJsonStringify } from './safeJsonStringify';
|
|
4
4
|
/**
|
|
5
5
|
* Inspired by inspectAny from nodejs-lib, which is based on util.inpect that is not available in the Browser.
|
|
6
6
|
* Potentially can do this (with extra 2Kb gz size): https://github.com/deecewan/browser-util-inspect
|
|
@@ -80,7 +80,7 @@ export function _stringifyAny(obj, opt = {}) {
|
|
|
80
80
|
// Other
|
|
81
81
|
//
|
|
82
82
|
try {
|
|
83
|
-
const { stringifyFn =
|
|
83
|
+
const { stringifyFn = _safeJsonStringify } = opt;
|
|
84
84
|
s = stringifyFn(obj, undefined, 2);
|
|
85
85
|
}
|
|
86
86
|
catch (_a) {
|
package/package.json
CHANGED
package/src/array/array.util.ts
CHANGED
|
@@ -140,11 +140,17 @@ export function _groupBy<T>(items: readonly T[], mapper: Mapper<T, any>): String
|
|
|
140
140
|
* Same:
|
|
141
141
|
* _sortBy([{age: 20}, {age: 10}], o => o.age)
|
|
142
142
|
*/
|
|
143
|
-
export function _sortBy<T>(
|
|
143
|
+
export function _sortBy<T>(
|
|
144
|
+
items: T[],
|
|
145
|
+
mapper: Mapper<T, any>,
|
|
146
|
+
mutate = false,
|
|
147
|
+
descending = false,
|
|
148
|
+
): T[] {
|
|
149
|
+
const mod = descending ? -1 : 1
|
|
144
150
|
return (mutate ? items : [...items]).sort((_a, _b) => {
|
|
145
151
|
const [a, b] = [_a, _b].map(mapper) // eslint-disable-line unicorn/no-array-callback-reference
|
|
146
|
-
if (typeof a === 'number' && typeof b === 'number') return a - b
|
|
147
|
-
return String(a).localeCompare(String(b))
|
|
152
|
+
if (typeof a === 'number' && typeof b === 'number') return (a - b) * mod
|
|
153
|
+
return String(a).localeCompare(String(b)) * mod
|
|
148
154
|
})
|
|
149
155
|
}
|
|
150
156
|
|
package/src/index.ts
CHANGED
|
@@ -224,6 +224,15 @@ import {
|
|
|
224
224
|
} from './types'
|
|
225
225
|
import { _gb, _hb, _kb, _mb } from './unit/size.util'
|
|
226
226
|
import { is } from './vendor/is'
|
|
227
|
+
import {
|
|
228
|
+
CommonLogLevel,
|
|
229
|
+
CommonLogFunction,
|
|
230
|
+
CommonLogger,
|
|
231
|
+
SimpleLogger,
|
|
232
|
+
createSimpleLogger,
|
|
233
|
+
noopLogger,
|
|
234
|
+
} from './log/commonLogger'
|
|
235
|
+
import { _safeJsonStringify } from './string/safeJsonStringify'
|
|
227
236
|
|
|
228
237
|
export type {
|
|
229
238
|
MemoCache,
|
|
@@ -295,6 +304,10 @@ export type {
|
|
|
295
304
|
JsonSchemaArray,
|
|
296
305
|
JsonSchemaTuple,
|
|
297
306
|
JsonSchemaBuilder,
|
|
307
|
+
CommonLogLevel,
|
|
308
|
+
CommonLogFunction,
|
|
309
|
+
CommonLogger,
|
|
310
|
+
SimpleLogger,
|
|
298
311
|
}
|
|
299
312
|
|
|
300
313
|
export {
|
|
@@ -453,4 +466,7 @@ export {
|
|
|
453
466
|
_defineLazyProperty,
|
|
454
467
|
_defineLazyProps,
|
|
455
468
|
_lazyValue,
|
|
469
|
+
createSimpleLogger,
|
|
470
|
+
noopLogger,
|
|
471
|
+
_safeJsonStringify,
|
|
456
472
|
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* These levels follow console.* naming,
|
|
3
|
+
* so you can use console[level] safely.
|
|
4
|
+
*
|
|
5
|
+
* `log` is considered default level.
|
|
6
|
+
*
|
|
7
|
+
* For simplicity - only these 3 levels are kept.
|
|
8
|
+
*
|
|
9
|
+
* @experimental
|
|
10
|
+
*/
|
|
11
|
+
export type CommonLogLevel = 'log' | 'warn' | 'error'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Function that takes any number of arguments and logs them all.
|
|
15
|
+
* It is expected that logged arguments are separated by "space", like console.log does.
|
|
16
|
+
*
|
|
17
|
+
* @experimental
|
|
18
|
+
*/
|
|
19
|
+
export type CommonLogFunction = (...args: any[]) => void
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Interface is inspired/compatible with `console.*`
|
|
23
|
+
* So, `console` is a valid CommonLogger implementation as-is.
|
|
24
|
+
*
|
|
25
|
+
* @experimental
|
|
26
|
+
*/
|
|
27
|
+
export interface CommonLogger {
|
|
28
|
+
log: CommonLogFunction
|
|
29
|
+
warn: CommonLogFunction
|
|
30
|
+
error: CommonLogFunction
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Same as CommonLogger, but also is a "convenience function" itself.
|
|
35
|
+
* So you can do `logger('hey')` which is the same as `logger.log('hey')`
|
|
36
|
+
*
|
|
37
|
+
* @experimental
|
|
38
|
+
*/
|
|
39
|
+
export interface SimpleLogger extends CommonLogFunction, CommonLogger {}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Creates a SimpleLogger from CommonLogger.
|
|
43
|
+
*
|
|
44
|
+
* @experimental
|
|
45
|
+
*/
|
|
46
|
+
export function createSimpleLogger(logger: CommonLogger): SimpleLogger {
|
|
47
|
+
return Object.assign(((...args: any[]) => logger.log(...args)) as any, {
|
|
48
|
+
log: (...args: any[]) => logger.log(...args),
|
|
49
|
+
warn: (...args: any[]) => logger.warn(...args),
|
|
50
|
+
error: (...args: any[]) => logger.error(...args),
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const noop = () => {}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* SimpleLogger that does nothing (noop).
|
|
58
|
+
*
|
|
59
|
+
* @experimental
|
|
60
|
+
*/
|
|
61
|
+
export const noopLogger: SimpleLogger = createSimpleLogger({
|
|
62
|
+
log: noop,
|
|
63
|
+
warn: noop,
|
|
64
|
+
error: noop,
|
|
65
|
+
})
|
|
@@ -37,8 +37,9 @@ export function _clamp(x: number, minIncl: number, maxIncl: number): number {
|
|
|
37
37
|
* _sortNumbers([1, 3, 2])
|
|
38
38
|
* // [1, 2, 3]
|
|
39
39
|
*/
|
|
40
|
-
export function _sortNumbers(numbers: number[], mutate = false): number[] {
|
|
41
|
-
|
|
40
|
+
export function _sortNumbers(numbers: number[], mutate = false, descending = false): number[] {
|
|
41
|
+
const mod = descending ? -1 : 1
|
|
42
|
+
return (mutate ? numbers : [...numbers]).sort((a, b) => (a - b) * mod)
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
/**
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Reviver } from '../types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* JSON.stringify that avoids circular references, prints them as [Circular ~]
|
|
5
|
+
*
|
|
6
|
+
* Based on: https://github.com/moll/json-stringify-safe/
|
|
7
|
+
*/
|
|
8
|
+
export function _safeJsonStringify(
|
|
9
|
+
obj: any,
|
|
10
|
+
replacer?: Reviver,
|
|
11
|
+
spaces?: number,
|
|
12
|
+
cycleReplacer?: Reviver,
|
|
13
|
+
): string {
|
|
14
|
+
try {
|
|
15
|
+
// Try native first (as it's ~3 times faster)
|
|
16
|
+
return JSON.stringify(obj, replacer, spaces)
|
|
17
|
+
} catch {
|
|
18
|
+
// Native failed - resort to the "safe" serializer
|
|
19
|
+
return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions, no-bitwise */
|
|
24
|
+
|
|
25
|
+
function serializer(replacer?: Reviver, cycleReplacer?: Reviver): Reviver {
|
|
26
|
+
const stack: any[] = []
|
|
27
|
+
const keys: string[] = []
|
|
28
|
+
|
|
29
|
+
if (cycleReplacer == null) {
|
|
30
|
+
cycleReplacer = function (key, value) {
|
|
31
|
+
if (stack[0] === value) return '[Circular ~]'
|
|
32
|
+
return '[Circular ~.' + keys.slice(0, stack.indexOf(value)).join('.') + ']'
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return function (key, value) {
|
|
37
|
+
if (stack.length > 0) {
|
|
38
|
+
const thisPos = stack.indexOf(this)
|
|
39
|
+
~thisPos ? stack.splice(thisPos + 1) : stack.push(this)
|
|
40
|
+
~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key)
|
|
41
|
+
if (~stack.indexOf(value)) {
|
|
42
|
+
value = cycleReplacer!.call(this, key, value)
|
|
43
|
+
}
|
|
44
|
+
} else {
|
|
45
|
+
stack.push(value)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return replacer == null ? value : replacer.call(this, key, value)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { _isErrorObject, _isHttpErrorObject, _isHttpErrorResponse } from '../error/error.util'
|
|
2
2
|
import { Reviver } from '../types'
|
|
3
3
|
import { _jsonParseIfPossible } from './json.util'
|
|
4
|
+
import { _safeJsonStringify } from './safeJsonStringify'
|
|
4
5
|
|
|
5
6
|
export type JsonStringifyFunction = (obj: any, reviver?: Reviver, space?: number) => string
|
|
6
7
|
|
|
7
|
-
const jsonStringifyFn: JsonStringifyFunction = (obj, reviver, space) =>
|
|
8
|
-
JSON.stringify(obj, reviver, space)
|
|
9
|
-
|
|
10
8
|
export interface StringifyAnyOptions {
|
|
11
9
|
/**
|
|
12
10
|
* @default 10_000
|
|
@@ -116,7 +114,7 @@ export function _stringifyAny(obj: any, opt: StringifyAnyOptions = {}): string {
|
|
|
116
114
|
// Other
|
|
117
115
|
//
|
|
118
116
|
try {
|
|
119
|
-
const { stringifyFn =
|
|
117
|
+
const { stringifyFn = _safeJsonStringify } = opt
|
|
120
118
|
|
|
121
119
|
s = stringifyFn(obj, undefined, 2)
|
|
122
120
|
} catch {
|
package/src/types.ts
CHANGED
|
@@ -165,7 +165,7 @@ export type Saved<E> = Merge<E, SavedDBEntity>
|
|
|
165
165
|
export type Unsaved<E> = Merge<E, BaseDBEntity>
|
|
166
166
|
|
|
167
167
|
/**
|
|
168
|
-
* Named type for JSON.parse second argument
|
|
168
|
+
* Named type for JSON.parse / JSON.stringify second argument
|
|
169
169
|
*/
|
|
170
170
|
export type Reviver = (this: any, key: string, value: any) => any
|
|
171
171
|
|