@naturalcycles/js-lib 14.51.0 → 14.55.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/CHANGELOG.md CHANGED
@@ -1,3 +1,31 @@
1
+ # [14.55.0](https://github.com/NaturalCycles/js-lib/compare/v14.54.0...v14.55.0) (2021-10-25)
2
+
3
+
4
+ ### Features
5
+
6
+ * _parseQueryString ([ed996de](https://github.com/NaturalCycles/js-lib/commit/ed996de1cfa817071daef9080be6be2c988cab2b))
7
+
8
+ # [14.54.0](https://github.com/NaturalCycles/js-lib/compare/v14.53.0...v14.54.0) (2021-10-22)
9
+
10
+
11
+ ### Features
12
+
13
+ * pTry (variation of pTuple), _try with non-optional RESULT type ([2c1dfdb](https://github.com/NaturalCycles/js-lib/commit/2c1dfdb9e1bad19de17280f181b7a75bcd0971bc))
14
+
15
+ # [14.53.0](https://github.com/NaturalCycles/js-lib/compare/v14.52.0...v14.53.0) (2021-10-21)
16
+
17
+
18
+ ### Features
19
+
20
+ * _ms to support "days" ([6329afe](https://github.com/NaturalCycles/js-lib/commit/6329afe2a319de68e0d4362d865db88e4b26e388))
21
+
22
+ # [14.52.0](https://github.com/NaturalCycles/js-lib/compare/v14.51.0...v14.52.0) (2021-10-19)
23
+
24
+
25
+ ### Features
26
+
27
+ * ObjectWithId, AnyObjectWithId, CreatedUpdated, CreatedUpdatedId ([d7ca213](https://github.com/NaturalCycles/js-lib/commit/d7ca2137d80ea08af55c83b5e7ce02e49e558f2c))
28
+
1
29
  # [14.51.0](https://github.com/NaturalCycles/js-lib/compare/v14.50.0...v14.51.0) (2021-10-18)
2
30
 
3
31
 
@@ -5,8 +5,20 @@
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
16
+ */
17
+ export declare function _try<ERR = unknown, RETURN = void>(fn: () => RETURN): [err: ERR | null, value: RETURN];
18
+ /**
19
+ * Like _try, but for Promises.
20
+ *
21
+ * Also, intentionally types second return item as non-optional,
22
+ * but you should check for `err` presense first!
11
23
  */
12
- export declare function _try<ERR = unknown, RETURN = void>(fn: () => RETURN): [err: ERR | undefined, value: RETURN | undefined];
24
+ export declare function pTry<ERR = unknown, RETURN = void>(promise: Promise<RETURN>): Promise<[err: ERR | null, value: RETURN]>;
package/dist/error/try.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports._try = void 0;
3
+ exports.pTry = exports._try = void 0;
4
4
  /**
5
5
  * Calls a function, returns a Tuple of [error, value].
6
6
  * Allows to write shorter code that avoids `try/catch`.
@@ -8,16 +8,36 @@ exports._try = void 0;
8
8
  *
9
9
  * Similar to pTuple, but for sync functions.
10
10
  *
11
+ * For convenience, second argument type is non-optional,
12
+ * so you can use it without `!`. But you SHOULD always check `if (err)` first!
13
+ *
11
14
  * @example
12
15
  *
13
16
  * const [err, v] = _try(() => someFunction())
17
+ * if (err) ...do something...
18
+ * v // go ahead and use v
14
19
  */
15
20
  function _try(fn) {
16
21
  try {
17
- return [undefined, fn()];
22
+ return [null, fn()];
18
23
  }
19
24
  catch (err) {
20
25
  return [err, undefined];
21
26
  }
22
27
  }
23
28
  exports._try = _try;
29
+ /**
30
+ * Like _try, but for Promises.
31
+ *
32
+ * Also, intentionally types second return item as non-optional,
33
+ * but you should check for `err` presense first!
34
+ */
35
+ async function pTry(promise) {
36
+ try {
37
+ return [null, await promise];
38
+ }
39
+ catch (err) {
40
+ return [err, undefined];
41
+ }
42
+ }
43
+ exports.pTry = pTry;
package/dist/index.d.ts 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 { PromiseDecoratorCfg, PromiseDecoratorResp, _createPromiseDecorator } from './decorators/createPromiseDecorator';
4
5
  import { _debounce, _throttle } from './decorators/debounce';
@@ -16,7 +17,7 @@ import { Admin401ErrorData, Admin403ErrorData, ErrorData, ErrorObject, HttpError
16
17
  import { _anyToError, _anyToErrorObject, _errorObjectToAppError, _errorToErrorObject, _isErrorObject, _isHttpErrorObject, _isHttpErrorResponse } from './error/error.util';
17
18
  import { ErrorMode } from './error/errorMode';
18
19
  import { HttpError } from './error/http.error';
19
- import { _try } from './error/try';
20
+ import { _try, pTry } from './error/try';
20
21
  import { TryCatchOptions, _TryCatch, _tryCatch } from './error/tryCatch';
21
22
  import { generateJsonSchemaFromData } from './json-schema/from-data/generateJsonSchemaFromData';
22
23
  import { JSON_SCHEMA_ORDER } from './json-schema/jsonSchema.cnst';
@@ -49,8 +50,8 @@ import { _capitalize, _lowerFirst, _nl2br, _removeWhitespace, _replaceAll, _spli
49
50
  import { JsonStringifyFunction, StringifyAnyOptions, _stringifyAny } from './string/stringifyAny';
50
51
  import { _ms, _since } from './time/time.util';
51
52
  import { Class, ConditionalExcept, ConditionalPick, Merge, Promisable, PromiseValue, ReadonlyDeep, Simplify } from './typeFest';
52
- import { AsyncMapper, AsyncPredicate, BaseDBEntity, 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';
53
+ 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';
53
54
  import { _gb, _hb, _kb, _mb } from './unit/size.util';
54
55
  import { is } from './vendor/is';
55
- 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, JsonSchema, JsonSchemaAny, JsonSchemaOneOf, JsonSchemaAllOf, JsonSchemaAnyOf, JsonSchemaNot, JsonSchemaRef, JsonSchemaConst, JsonSchemaEnum, JsonSchemaString, JsonSchemaNumber, JsonSchemaBoolean, JsonSchemaNull, JsonSchemaRootObject, JsonSchemaObject, JsonSchemaArray, JsonSchemaTuple, JsonSchemaBuilder, };
56
- 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, };
56
+ 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, };
57
+ 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, };
package/dist/index.js CHANGED
@@ -2,7 +2,8 @@
2
2
  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
- exports.generateJsonSchemaFromData = 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._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;
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._parseQueryString = exports.generateJsonSchemaFromData = void 0;
6
7
  const array_util_1 = require("./array/array.util");
7
8
  Object.defineProperty(exports, "_by", { enumerable: true, get: function () { return array_util_1._by; } });
8
9
  Object.defineProperty(exports, "_chunk", { enumerable: true, get: function () { return array_util_1._chunk; } });
@@ -25,6 +26,8 @@ Object.defineProperty(exports, "_takeRightWhile", { enumerable: true, get: funct
25
26
  Object.defineProperty(exports, "_takeWhile", { enumerable: true, get: function () { return array_util_1._takeWhile; } });
26
27
  Object.defineProperty(exports, "_uniq", { enumerable: true, get: function () { return array_util_1._uniq; } });
27
28
  Object.defineProperty(exports, "_uniqBy", { enumerable: true, get: function () { return array_util_1._uniqBy; } });
29
+ const url_util_1 = require("./string/url.util");
30
+ Object.defineProperty(exports, "_parseQueryString", { enumerable: true, get: function () { return url_util_1._parseQueryString; } });
28
31
  const range_1 = require("./array/range");
29
32
  Object.defineProperty(exports, "_range", { enumerable: true, get: function () { return range_1._range; } });
30
33
  const createPromiseDecorator_1 = require("./decorators/createPromiseDecorator");
@@ -72,6 +75,7 @@ const http_error_1 = require("./error/http.error");
72
75
  Object.defineProperty(exports, "HttpError", { enumerable: true, get: function () { return http_error_1.HttpError; } });
73
76
  const try_1 = require("./error/try");
74
77
  Object.defineProperty(exports, "_try", { enumerable: true, get: function () { return try_1._try; } });
78
+ Object.defineProperty(exports, "pTry", { enumerable: true, get: function () { return try_1.pTry; } });
75
79
  const tryCatch_1 = require("./error/tryCatch");
76
80
  Object.defineProperty(exports, "_TryCatch", { enumerable: true, get: function () { return tryCatch_1._TryCatch; } });
77
81
  Object.defineProperty(exports, "_tryCatch", { enumerable: true, get: function () { return tryCatch_1._tryCatch; } });
@@ -1,7 +1,7 @@
1
- import { JsonSchemaObject } from '../..';
1
+ import { JsonSchemaObject, AnyObject } from '../..';
2
2
  /**
3
3
  * Each row must be an object (current limitation).
4
4
  *
5
5
  * `additionalProperties` is set to `true`, cause it's safer.
6
6
  */
7
- export declare function generateJsonSchemaFromData<T = unknown>(rows: any[]): JsonSchemaObject<T>;
7
+ export declare function generateJsonSchemaFromData<T = unknown>(rows: AnyObject[]): JsonSchemaObject<T>;
@@ -1,4 +1,4 @@
1
- import { StringMap } from '../types';
1
+ import { AnyObject, StringMap } from '../types';
2
2
  export declare type JsonSchema<T = unknown> = JsonSchemaAny<T> | JsonSchemaOneOf<T> | JsonSchemaAllOf<T> | JsonSchemaAnyOf<T> | JsonSchemaNot<T> | JsonSchemaRef<T> | JsonSchemaConst<T> | JsonSchemaEnum<T> | JsonSchemaString | JsonSchemaNumber | JsonSchemaBoolean | JsonSchemaNull | JsonSchemaObject<T> | JsonSchemaArray<T> | JsonSchemaTuple<T>;
3
3
  export interface JsonSchemaAny<T = unknown> {
4
4
  $schema?: string;
@@ -81,10 +81,10 @@ export interface JsonSchemaEnum<T = unknown> extends JsonSchemaAny<T> {
81
81
  export interface JsonSchemaRef<T = unknown> extends JsonSchemaAny<T> {
82
82
  $ref: string;
83
83
  }
84
- export interface JsonSchemaRootObject<T extends Record<any, any> = Record<any, unknown>> extends JsonSchemaObject<T> {
84
+ export interface JsonSchemaRootObject<T extends AnyObject = AnyObject> extends JsonSchemaObject<T> {
85
85
  $id: string;
86
86
  }
87
- export interface JsonSchemaObject<T extends Record<any, any> = Record<any, unknown>> extends JsonSchemaAny<T> {
87
+ export interface JsonSchemaObject<T extends AnyObject = AnyObject> extends JsonSchemaAny<T> {
88
88
  type: 'object';
89
89
  properties: {
90
90
  [k in keyof T]: JsonSchema;
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import { BaseDBEntity, JsonSchemaAllOf, JsonSchemaArray, JsonSchemaOneOf, JsonSchemaTuple, SavedDBEntity } from '../index';
2
+ import { BaseDBEntity, JsonSchemaAllOf, JsonSchemaArray, JsonSchemaOneOf, JsonSchemaTuple, SavedDBEntity, AnyObject } from '../index';
3
3
  import { JsonSchema, JsonSchemaAny, JsonSchemaBoolean, JsonSchemaConst, JsonSchemaEnum, JsonSchemaNull, JsonSchemaNumber, JsonSchemaObject, JsonSchemaRef, JsonSchemaString } from './jsonSchema.model';
4
4
  export interface JsonSchemaBuilder<T = unknown> {
5
5
  build(): JsonSchema<T>;
@@ -21,8 +21,8 @@ export declare const jsonSchema: {
21
21
  unixTimestamp(): JsonSchemaNumberBuilder;
22
22
  string(): JsonSchemaStringBuilder;
23
23
  dateString(): JsonSchemaStringBuilder;
24
- object<T_4 extends Record<any, any>>(props: { [k in keyof T_4]: JsonSchemaAnyBuilder<T_4[k], JsonSchema<T_4[k]>>; }): JsonSchemaObjectBuilder<T_4>;
25
- rootObject<T_5 extends Record<any, any>>(props: { [k_1 in keyof T_5]: JsonSchemaAnyBuilder<T_5[k_1], JsonSchema<T_5[k_1]>>; }): JsonSchemaObjectBuilder<T_5>;
24
+ object<T_4 extends AnyObject>(props: { [k in keyof T_4]: JsonSchemaAnyBuilder<T_4[k], JsonSchema<T_4[k]>>; }): JsonSchemaObjectBuilder<T_4>;
25
+ rootObject<T_5 extends AnyObject>(props: { [k_1 in keyof T_5]: JsonSchemaAnyBuilder<T_5[k_1], JsonSchema<T_5[k_1]>>; }): JsonSchemaObjectBuilder<T_5>;
26
26
  array<ITEM = unknown>(itemSchema: JsonSchemaAnyBuilder<ITEM, JsonSchema<ITEM>>): JsonSchemaArrayBuilder<ITEM>;
27
27
  tuple<T_6 extends any[] = unknown[]>(items: JsonSchemaAnyBuilder[]): JsonSchemaTupleBuilder<T_6>;
28
28
  oneOf<T_7 = unknown>(items: JsonSchemaAnyBuilder[]): JsonSchemaAnyBuilder<T_7, JsonSchemaOneOf<T_7>>;
@@ -100,7 +100,7 @@ export declare class JsonSchemaStringBuilder extends JsonSchemaAnyBuilder<string
100
100
  toUpperCase: (toUpperCase?: boolean) => this;
101
101
  private transformModify;
102
102
  }
103
- export declare class JsonSchemaObjectBuilder<T extends Record<any, any>> extends JsonSchemaAnyBuilder<T, JsonSchemaObject<T>> {
103
+ export declare class JsonSchemaObjectBuilder<T extends AnyObject> extends JsonSchemaAnyBuilder<T, JsonSchemaObject<T>> {
104
104
  constructor();
105
105
  addProperties(props: {
106
106
  [k in keyof T]: JsonSchemaBuilder<T[k]>;
@@ -115,7 +115,7 @@ export declare class JsonSchemaObjectBuilder<T extends Record<any, any>> extends
115
115
  additionalProps(additionalProperties: boolean): this;
116
116
  baseDBEntity(): JsonSchemaObjectBuilder<T & BaseDBEntity>;
117
117
  savedDBEntity(): JsonSchemaObjectBuilder<T & SavedDBEntity>;
118
- extend<T2 extends Record<any, any>>(s2: JsonSchemaObjectBuilder<T2>): JsonSchemaObjectBuilder<T & T2>;
118
+ extend<T2 extends AnyObject>(s2: JsonSchemaObjectBuilder<T2>): JsonSchemaObjectBuilder<T & T2>;
119
119
  }
120
120
  export declare class JsonSchemaArrayBuilder<ITEM> extends JsonSchemaAnyBuilder<ITEM[], JsonSchemaArray<ITEM>> {
121
121
  constructor(itemsSchema: JsonSchemaBuilder<ITEM>);
@@ -1,15 +1,15 @@
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
  * Returns clone of `obj` with only `props` preserved.
5
5
  * Opposite of Omit.
6
6
  */
7
- export declare function _pick<T extends Record<string, any>, K extends keyof T>(obj: T, props: readonly K[], mutate?: boolean): T;
7
+ export declare function _pick<T extends AnyObject, K extends keyof T>(obj: T, props: readonly K[], mutate?: boolean): T;
8
8
  /**
9
9
  * Returns clone of `obj` with `props` omitted.
10
10
  * Opposite of Pick.
11
11
  */
12
- export declare function _omit<T extends Record<string, any>, K extends keyof T>(obj: T, props: readonly K[], mutate?: boolean): T;
12
+ export declare function _omit<T extends AnyObject, K extends keyof T>(obj: T, props: readonly K[], mutate?: boolean): T;
13
13
  /**
14
14
  * Returns object with filtered keys from `props` array.
15
15
  * E.g:
@@ -18,26 +18,26 @@ export declare function _omit<T extends Record<string, any>, K extends keyof T>(
18
18
  * 'account.updated',
19
19
  * ])
20
20
  */
21
- export declare function _mask<T extends Record<string, any>>(obj: T, props: string[], mutate?: boolean): T;
21
+ export declare function _mask<T extends AnyObject>(obj: T, props: string[], mutate?: boolean): T;
22
22
  /**
23
23
  * Removes "falsy" values from the object.
24
24
  */
25
- export declare function _filterFalsyValues<T extends Record<string, any>>(obj: T, mutate?: boolean): T;
25
+ export declare function _filterFalsyValues<T extends AnyObject>(obj: T, mutate?: boolean): T;
26
26
  /**
27
27
  * Removes values from the object that are `null` or `undefined`.
28
28
  */
29
- export declare function _filterNullishValues<T extends Record<string, any>>(obj: T, mutate?: boolean): T;
29
+ export declare function _filterNullishValues<T extends AnyObject>(obj: T, mutate?: boolean): T;
30
30
  /**
31
31
  * Removes values from the object that are `undefined`.
32
32
  * Only `undefined` values are removed. `null` values are kept!
33
33
  */
34
- export declare function _filterUndefinedValues<T extends Record<string, any>>(obj: T, mutate?: boolean): T;
35
- export declare function _filterEmptyArrays<T extends Record<string, any>>(obj: T, mutate?: boolean): T;
34
+ export declare function _filterUndefinedValues<T extends AnyObject>(obj: T, mutate?: boolean): T;
35
+ export declare function _filterEmptyArrays<T extends AnyObject>(obj: T, mutate?: boolean): T;
36
36
  /**
37
37
  * Returns clone of `obj` without properties that does not pass `predicate`.
38
38
  * Allows filtering by both key and value.
39
39
  */
40
- export declare function _filterObject<T extends Record<string, any>>(obj: T, predicate: ObjectPredicate<T>, mutate?: boolean): T;
40
+ export declare function _filterObject<T extends AnyObject>(obj: T, predicate: ObjectPredicate<T>, mutate?: boolean): T;
41
41
  /**
42
42
  * var users = {
43
43
  * 'fred': { 'user': 'fred', 'age': 40 },
@@ -51,14 +51,14 @@ export declare function _filterObject<T extends Record<string, any>>(obj: T, pre
51
51
  * _.mapValues(users, 'age')
52
52
  * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
53
53
  */
54
- export declare function _mapValues<T extends Record<string, any>, OUT = T>(obj: T, mapper: ObjectMapper<T, any>, mutate?: boolean): OUT;
54
+ export declare function _mapValues<T extends AnyObject, OUT = T>(obj: T, mapper: ObjectMapper<T, any>, mutate?: boolean): OUT;
55
55
  /**
56
56
  * _.mapKeys({ 'a': 1, 'b': 2 }, (key, value) => key + value)
57
57
  * // => { 'a1': 1, 'b2': 2 }
58
58
  *
59
59
  * Does not support `mutate` flag.
60
60
  */
61
- export declare function _mapKeys<T extends Record<string, any>>(obj: T, mapper: ObjectMapper<T, string>): StringMap<T[keyof T]>;
61
+ export declare function _mapKeys<T extends AnyObject>(obj: T, mapper: ObjectMapper<T, string>): StringMap<T[keyof T]>;
62
62
  /**
63
63
  * Maps object through predicate - a function that receives (k, v, obj)
64
64
  * k - key
@@ -75,11 +75,11 @@ export declare function _mapKeys<T extends Record<string, any>>(obj: T, mapper:
75
75
  *
76
76
  * Non-string keys are passed via String(...)
77
77
  */
78
- export declare function _mapObject<IN extends Record<string, any>, OUT>(obj: IN, mapper: ObjectMapper<IN, [key: string, value: any]>): {
78
+ export declare function _mapObject<IN extends AnyObject, OUT>(obj: IN, mapper: ObjectMapper<IN, [key: string, value: any]>): {
79
79
  [P in keyof IN]: OUT;
80
80
  };
81
- export declare function _findKeyByValue<T extends Record<any, any>>(obj: T, v: ValueOf<T>): keyof T | undefined;
82
- export declare function _objectNullValuesToUndefined<T extends Record<string, any>>(obj: T, mutate?: boolean): T;
81
+ export declare function _findKeyByValue<T extends AnyObject>(obj: T, v: ValueOf<T>): keyof T | undefined;
82
+ export declare function _objectNullValuesToUndefined<T extends AnyObject>(obj: T, mutate?: boolean): T;
83
83
  /**
84
84
  * Deep copy object (by json parse/stringify, since it has unbeatable performance+simplicity combo).
85
85
  */
@@ -87,7 +87,7 @@ export declare function _deepCopy<T>(o: T): T;
87
87
  /**
88
88
  * Returns true if item is Object, not null and not Array.
89
89
  */
90
- export declare function _isObject(item: any): item is Record<string, any>;
90
+ export declare function _isObject(item: any): item is AnyObject;
91
91
  export declare function _isPrimitive(v: any): v is null | undefined | number | boolean | string;
92
92
  export declare function _isEmptyObject(obj: any): boolean;
93
93
  /**
@@ -109,7 +109,7 @@ export declare function _undefinedIfEmpty<T>(obj: T | undefined): T | undefined;
109
109
  /**
110
110
  * Filters the object by removing all key-value pairs where Value is Empty (according to _isEmpty() specification).
111
111
  */
112
- export declare function _filterEmptyValues<T extends Record<string, any>>(obj: T, mutate?: boolean): T;
112
+ export declare function _filterEmptyValues<T extends AnyObject>(obj: T, mutate?: boolean): T;
113
113
  /**
114
114
  * Recursively merges own and inherited enumerable properties of source
115
115
  * objects into the destination object, skipping source properties that resolve
@@ -139,15 +139,15 @@ export declare function _filterEmptyValues<T extends Record<string, any>>(obj: T
139
139
  *
140
140
  * Based on: https://gist.github.com/Salakar/1d7137de9cb8b704e48a
141
141
  */
142
- export declare function _merge<T extends Record<string, any>>(target: T, ...sources: any[]): T;
142
+ export declare function _merge<T extends AnyObject>(target: T, ...sources: any[]): T;
143
143
  /**
144
144
  * Trims all object VALUES deeply.
145
145
  * Doesn't touch object KEYS.
146
146
  * Mutates.
147
147
  */
148
- export declare function _deepTrim<T extends Record<string, any> | string>(o: T): T;
149
- export declare function _unset<T extends Record<string, any>>(obj: T, prop: string): void;
150
- export declare function _invert<T extends Record<any, any>>(o: T): {
148
+ export declare function _deepTrim<T extends AnyObject | string>(o: T): T;
149
+ export declare function _unset<T extends AnyObject>(obj: T, prop: string): void;
150
+ export declare function _invert<T extends AnyObject>(o: T): {
151
151
  [k in ValueOf<T>]: keyof T | undefined;
152
152
  };
153
153
  export declare function _invertMap<K, V>(m: ReadonlyMap<K, V>): Map<V, K>;
@@ -160,7 +160,7 @@ export declare function _invertMap<K, V>(m: ReadonlyMap<K, V>): Map<V, K>;
160
160
  * @param def The value returned if the resolved value is undefined.
161
161
  * @return Returns the resolved value.
162
162
  */
163
- export declare function _get<T extends Record<string, any>>(obj?: T, path?: string, def?: any): any;
163
+ export declare function _get<T extends AnyObject>(obj?: T, path?: string, def?: any): any;
164
164
  /**
165
165
  * Sets the value at path of object. If a portion of path doesn’t exist it’s created. Arrays are created for
166
166
  * missing index properties while objects are created for all other missing properties. Use _.setWith to
@@ -173,7 +173,7 @@ export declare function _get<T extends Record<string, any>>(obj?: T, path?: stri
173
173
  *
174
174
  * Based on: https://stackoverflow.com/a/54733755/4919972
175
175
  */
176
- export declare function _set<IN extends Record<string, any>, OUT = IN>(obj: IN, path: PropertyPath, value?: any): OUT;
176
+ export declare function _set<IN extends AnyObject, OUT = IN>(obj: IN, path: PropertyPath, value?: any): OUT;
177
177
  /**
178
178
  * Checks if `path` is a direct property of `object` (not null, not undefined).
179
179
  *
@@ -198,4 +198,4 @@ export declare function _set<IN extends Record<string, any>, OUT = IN>(obj: IN,
198
198
  * _.has(other, 'a');
199
199
  * // => false
200
200
  */
201
- export declare function _has<T extends Record<string, any>>(obj: T, path?: string): boolean;
201
+ export declare function _has<T extends AnyObject>(obj: T, path?: string): boolean;
@@ -1,6 +1,7 @@
1
+ import { AnyObject } from '../index';
1
2
  /**
2
3
  * Returns new object with keys sorder in the given order.
3
4
  * All keys that are not listed in `keyOrder` go last.
4
5
  * Does not mutate original object.
5
6
  */
6
- export declare function _sortObject<T extends Record<any, any>>(obj: T, keyOrder: (keyof T)[]): T;
7
+ export declare function _sortObject<T extends AnyObject>(obj: T, keyOrder: (keyof T)[]): T;
@@ -4,4 +4,4 @@
4
4
  *
5
5
  * source: https://github.com/scopsy/await-to-js/blob/master/src/await-to-js.ts
6
6
  */
7
- export declare function pTuple<T, U = Error>(promise: Promise<T>): Promise<[U, undefined] | [null, T]>;
7
+ export declare function pTuple<RETURN, ERR = Error>(promise: Promise<RETURN>): Promise<[ERR, undefined] | [null, RETURN]>;
@@ -8,10 +8,6 @@ exports.pTuple = void 0;
8
8
  * source: https://github.com/scopsy/await-to-js/blob/master/src/await-to-js.ts
9
9
  */
10
10
  async function pTuple(promise) {
11
- return promise
12
- .then((data) => [null, data])
13
- .catch((err) => {
14
- return [err, undefined];
15
- });
11
+ return promise.then(data => [null, data]).catch(err => [err, undefined]);
16
12
  }
17
13
  exports.pTuple = pTuple;
@@ -0,0 +1,15 @@
1
+ import { StringMap } from '../types';
2
+ /**
3
+ * Parses `location.search` string (e.g `?a=1&b=2`) into a StringMap, e.g:
4
+ * `{ a: '1', b: '2' }`
5
+ *
6
+ * Pass `location.search` to it in the Frontend, or any other string on the Backend (where `location.search` is not available).
7
+ *
8
+ * Works both with and without leading `?` character.
9
+ *
10
+ * Yes, there's `URLSearchParams` existing in the Frontend (not in Node yet), but it's API is not
11
+ * as convenient. And the implementation here is super-small.
12
+ *
13
+ * Goal of this function is to produce exactly same output as URLSearchParams would.
14
+ */
15
+ export declare function _parseQueryString(search: string): StringMap;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports._parseQueryString = void 0;
4
+ /**
5
+ * Parses `location.search` string (e.g `?a=1&b=2`) into a StringMap, e.g:
6
+ * `{ a: '1', b: '2' }`
7
+ *
8
+ * Pass `location.search` to it in the Frontend, or any other string on the Backend (where `location.search` is not available).
9
+ *
10
+ * Works both with and without leading `?` character.
11
+ *
12
+ * Yes, there's `URLSearchParams` existing in the Frontend (not in Node yet), but it's API is not
13
+ * as convenient. And the implementation here is super-small.
14
+ *
15
+ * Goal of this function is to produce exactly same output as URLSearchParams would.
16
+ */
17
+ function _parseQueryString(search) {
18
+ const qs = {};
19
+ search
20
+ .substr(search[0] === '?' ? 1 : 0)
21
+ .split('&')
22
+ .forEach(p => {
23
+ const [k, v] = p.split('=');
24
+ if (!k)
25
+ return;
26
+ qs[decodeURIComponent(k)] = decodeURIComponent(v || '');
27
+ });
28
+ return qs;
29
+ }
30
+ exports._parseQueryString = _parseQueryString;
@@ -37,7 +37,11 @@ function _ms(millis) {
37
37
  if (hrs < 24) {
38
38
  return `${hrs}h${min}m`;
39
39
  }
40
- // >= 24h
41
- return `${Math.round(hrs + min / 60)}h`;
40
+ if (hrs < 48) {
41
+ return `${Math.round(hrs + min / 60)}h`;
42
+ }
43
+ // >= 48 hours
44
+ const days = Math.floor(hrs / 24);
45
+ return `${days} days`;
42
46
  }
43
47
  exports._ms = _ms;
package/dist/types.d.ts CHANGED
@@ -20,6 +20,18 @@ export interface PromiseMap {
20
20
  * Because `object` type is not safe/recommended to be used (e.g discouraged by eslint-typescript due to: https://github.com/microsoft/TypeScript/issues/21732)
21
21
  */
22
22
  export declare type AnyObject = Record<string, any>;
23
+ export interface CreatedUpdated {
24
+ created: number;
25
+ updated: number;
26
+ }
27
+ export interface CreatedUpdatedId extends CreatedUpdated {
28
+ id: string;
29
+ }
30
+ export interface ObjectWithId {
31
+ id: string;
32
+ }
33
+ export interface AnyObjectWithId extends AnyObject, ObjectWithId {
34
+ }
23
35
  /**
24
36
  * Convenience type shorthand.
25
37
  * Because `Function` type is discouraged by eslint.
@@ -143,4 +155,4 @@ export declare function _stringMapEntries<T>(m: StringMap<T>): [k: string, v: T]
143
155
  *
144
156
  * @experimental
145
157
  */
146
- export declare function _objectKeys<T extends Record<string, any>>(obj: T): (keyof T)[];
158
+ export declare function _objectKeys<T extends AnyObject>(obj: T): (keyof T)[];
@@ -5,13 +5,32 @@
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(fn) {
13
18
  try {
14
- return [undefined, fn()];
19
+ return [null, fn()];
20
+ }
21
+ catch (err) {
22
+ return [err, undefined];
23
+ }
24
+ }
25
+ /**
26
+ * Like _try, but for Promises.
27
+ *
28
+ * Also, intentionally types second return item as non-optional,
29
+ * but you should check for `err` presense first!
30
+ */
31
+ export async function pTry(promise) {
32
+ try {
33
+ return [null, await promise];
15
34
  }
16
35
  catch (err) {
17
36
  return [err, undefined];
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, };
@@ -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
+ }
@@ -33,6 +33,10 @@ export function _ms(millis) {
33
33
  if (hrs < 24) {
34
34
  return `${hrs}h${min}m`;
35
35
  }
36
- // >= 24h
37
- return `${Math.round(hrs + min / 60)}h`;
36
+ if (hrs < 48) {
37
+ return `${Math.round(hrs + min / 60)}h`;
38
+ }
39
+ // >= 48 hours
40
+ const days = Math.floor(hrs / 24);
41
+ return `${days} days`;
38
42
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
- "version": "14.51.0",
3
+ "version": "14.55.0",
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/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 | undefined, value: RETURN | undefined] {
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 [undefined, fn()]
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'
@@ -187,6 +188,10 @@ import {
187
188
  AsyncMapper,
188
189
  AsyncPredicate,
189
190
  BaseDBEntity,
191
+ CreatedUpdated,
192
+ CreatedUpdatedId,
193
+ ObjectWithId,
194
+ AnyObjectWithId,
190
195
  Saved,
191
196
  Unsaved,
192
197
  BatchResult,
@@ -267,6 +272,10 @@ export type {
267
272
  SavedDBEntity,
268
273
  Saved,
269
274
  Unsaved,
275
+ CreatedUpdated,
276
+ CreatedUpdatedId,
277
+ ObjectWithId,
278
+ AnyObjectWithId,
270
279
  JsonSchema,
271
280
  JsonSchemaAny,
272
281
  JsonSchemaOneOf,
@@ -418,6 +427,7 @@ export {
418
427
  _tryCatch,
419
428
  _TryCatch,
420
429
  _try,
430
+ pTry,
421
431
  _jsonParseIfPossible,
422
432
  _stringifyAny,
423
433
  _ms,
@@ -438,4 +448,5 @@ export {
438
448
  JsonSchemaAnyBuilder,
439
449
  JSON_SCHEMA_ORDER,
440
450
  generateJsonSchemaFromData,
451
+ _parseQueryString,
441
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: any[]): JsonSchemaObject<T> {
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: Record<string, any>[]): JsonSchemaObject {
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 Record<any, any> = Record<any, unknown>>
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 Record<any, any> = Record<any, unknown>>
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 Record<any, any>>(props: {
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 Record<any, any>>(props: {
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 Record<any, any>> extends JsonSchemaAnyBuilder<
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 Record<any, any>>(
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 Record<string, any>, K extends keyof T>(
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 Record<string, any>, K extends keyof T>(
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 Record<string, any>>(obj: T, props: string[], mutate = false): T {
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 Record<string, any>>(obj: T, mutate = false): T {
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 Record<string, any>>(obj: T, mutate = false): T {
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 Record<string, any>>(obj: T, mutate = false): T {
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 Record<string, any>>(obj: T, mutate = false): T {
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 Record<string, any>>(
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 Record<string, any>, OUT = T>(
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 Record<string, any>>(
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 Record<string, any>, OUT>(
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 Record<any, any>>(
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 Record<string, any>>(
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 Record<string, any> {
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 Record<string, any>>(obj: T, mutate = false): T {
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 Record<string, any>>(target: T, ...sources: any[]): T {
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 Record<string, any> | string>(o: T): T {
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 Record<string, any>>(obj: T, prop: string): void {
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 Record<any, any>>(
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 Record<string, any>>(obj = {} as T, path = '', def?: any): any {
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 Record<string, any>, OUT = IN>(
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 Record<string, any>>(obj: T, path?: string): boolean {
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
  }
@@ -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 Record<any, any>>(obj: T, keyOrder: (keyof T)[]): T {
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 => {
@@ -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<T, U = Error>(
8
- promise: Promise<T>,
9
- ): Promise<[U, undefined] | [null, T]> {
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
+ }
@@ -37,6 +37,12 @@ export function _ms(millis: number): string {
37
37
  return `${hrs}h${min}m`
38
38
  }
39
39
 
40
- // >= 24h
41
- return `${Math.round(hrs + min / 60)}h`
40
+ if (hrs < 48) {
41
+ return `${Math.round(hrs + min / 60)}h`
42
+ }
43
+
44
+ // >= 48 hours
45
+
46
+ const days = Math.floor(hrs / 24)
47
+ return `${days} days`
42
48
  }
package/src/types.ts CHANGED
@@ -24,6 +24,21 @@ export interface PromiseMap {
24
24
  */
25
25
  export type AnyObject = Record<string, any>
26
26
 
27
+ export interface CreatedUpdated {
28
+ created: number
29
+ updated: number
30
+ }
31
+
32
+ export interface CreatedUpdatedId extends CreatedUpdated {
33
+ id: string
34
+ }
35
+
36
+ export interface ObjectWithId {
37
+ id: string
38
+ }
39
+
40
+ export interface AnyObjectWithId extends AnyObject, ObjectWithId {}
41
+
27
42
  /**
28
43
  * Convenience type shorthand.
29
44
  * Because `Function` type is discouraged by eslint.
@@ -176,6 +191,6 @@ export function _stringMapEntries<T>(m: StringMap<T>): [k: string, v: T][] {
176
191
  *
177
192
  * @experimental
178
193
  */
179
- export function _objectKeys<T extends Record<string, any>>(obj: T): (keyof T)[] {
194
+ export function _objectKeys<T extends AnyObject>(obj: T): (keyof T)[] {
180
195
  return Object.keys(obj)
181
196
  }