@naturalcycles/js-lib 14.100.0 → 14.103.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.
@@ -1,5 +1,5 @@
1
1
  import { RecursiveArray } from '../lodash.types';
2
- import { Mapper, Predicate, StringMap } from '../types';
2
+ import { FalsyValue, Mapper, Predicate, StringMap } from '../types';
3
3
  /**
4
4
  * Creates an array of elements split into groups the length of size. If collection can’t be split evenly, the
5
5
  * final chunk will be the remaining elements.
@@ -115,6 +115,9 @@ export declare function _intersection<T>(...arrays: T[][]): T[];
115
115
  * // [1]
116
116
  */
117
117
  export declare function _difference<T>(source: T[], ...diffs: T[][]): T[];
118
+ /**
119
+ * Returns the sum of items, or 0 for empty array.
120
+ */
118
121
  export declare function _sum(items: number[]): number;
119
122
  export declare function _sumBy<T>(items: T[], mapper: Mapper<T, number | undefined>): number;
120
123
  /**
@@ -130,7 +133,7 @@ export declare function _sumBy<T>(items: T[], mapper: Mapper<T, number | undefin
130
133
  * _mapToObject([1, 2, 3], n => [n, `id${n}`])
131
134
  * // { '1': 'id1, '2': 'id2', '3': 'id3' }
132
135
  */
133
- export declare function _mapToObject<T, V>(array: T[], mapper: (item: T) => [key: any, value: V] | undefined | null | false | 0 | void): StringMap<V>;
136
+ export declare function _mapToObject<T, V>(array: T[], mapper: (item: T) => [key: any, value: V] | FalsyValue): StringMap<V>;
134
137
  /**
135
138
  * Randomly shuffle an array values.
136
139
  * Fisher–Yates algorithm.
@@ -146,7 +149,13 @@ export declare function _last<T>(array: T[]): T;
146
149
  * Returns last item of the array (or undefined if array is empty).
147
150
  */
148
151
  export declare function _lastOrUndefined<T>(array: T[]): T | undefined;
149
- export declare function _minOrUndefined<T>(array: T[]): T | undefined;
150
- export declare function _min<T>(array: T[]): T;
151
- export declare function _maxOrUndefined<T>(array: T[]): T | undefined;
152
- export declare function _max<T>(array: T[]): T;
152
+ export declare function _minOrUndefined<T>(array: T[]): NonNullable<T> | undefined;
153
+ /**
154
+ * Filters out nullish values (undefined and null).
155
+ */
156
+ export declare function _min<T>(array: T[]): NonNullable<T>;
157
+ export declare function _maxOrUndefined<T>(array: T[]): NonNullable<T> | undefined;
158
+ /**
159
+ * Filters out nullish values (undefined and null).
160
+ */
161
+ export declare function _max<T>(array: T[]): NonNullable<T>;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports._max = exports._maxOrUndefined = exports._min = exports._minOrUndefined = exports._lastOrUndefined = exports._last = exports._shuffle = exports._mapToObject = exports._sumBy = exports._sum = exports._difference = exports._intersection = exports._countBy = exports._dropRightWhile = exports._dropWhile = exports._takeRightWhile = exports._takeWhile = exports._findLast = exports._sortBy = exports._groupBy = exports._by = exports._uniqBy = exports._uniq = exports._flattenDeep = exports._flatten = exports._chunk = void 0;
4
+ const is_util_1 = require("../is.util");
4
5
  /**
5
6
  * Creates an array of elements split into groups the length of size. If collection can’t be split evenly, the
6
7
  * final chunk will be the remaining elements.
@@ -210,6 +211,9 @@ function _difference(source, ...diffs) {
210
211
  return diffs.reduce((a, b) => a.filter(c => !b.includes(c)), source);
211
212
  }
212
213
  exports._difference = _difference;
214
+ /**
215
+ * Returns the sum of items, or 0 for empty array.
216
+ */
213
217
  function _sum(items) {
214
218
  return items.reduce((sum, n) => sum + n, 0);
215
219
  }
@@ -277,26 +281,36 @@ function _lastOrUndefined(array) {
277
281
  }
278
282
  exports._lastOrUndefined = _lastOrUndefined;
279
283
  function _minOrUndefined(array) {
280
- if (!array.length)
284
+ const a = array.filter(is_util_1._isNotNullish);
285
+ if (!a.length)
281
286
  return;
282
- return _min(array);
287
+ return _min(a);
283
288
  }
284
289
  exports._minOrUndefined = _minOrUndefined;
290
+ /**
291
+ * Filters out nullish values (undefined and null).
292
+ */
285
293
  function _min(array) {
286
- if (!array.length)
294
+ const a = array.filter(is_util_1._isNotNullish);
295
+ if (!a.length)
287
296
  throw new Error('_min called on empty array');
288
- return array.reduce((min, item) => (min <= item ? min : item));
297
+ return a.reduce((min, item) => (min <= item ? min : item));
289
298
  }
290
299
  exports._min = _min;
291
300
  function _maxOrUndefined(array) {
292
- if (!array.length)
301
+ const a = array.filter(is_util_1._isNotNullish);
302
+ if (!a.length)
293
303
  return;
294
- return _max(array);
304
+ return _max(a);
295
305
  }
296
306
  exports._maxOrUndefined = _maxOrUndefined;
307
+ /**
308
+ * Filters out nullish values (undefined and null).
309
+ */
297
310
  function _max(array) {
298
- if (!array.length)
311
+ const a = array.filter(is_util_1._isNotNullish);
312
+ if (!a.length)
299
313
  throw new Error('_max called on empty array');
300
- return array.reduce((max, item) => (max >= item ? max : item));
314
+ return a.reduce((max, item) => (max >= item ? max : item));
301
315
  }
302
316
  exports._max = _max;
@@ -1,4 +1,4 @@
1
- import { IsoDateString, IsoDateTimeString, UnixTimestampNumber } from '../types';
1
+ import { IsoDateString, IsoDateTimeString, UnixTimestampMillisNumber, UnixTimestampNumber } from '../types';
2
2
  import { LocalTime } from './localTime';
3
3
  export declare type LocalDateUnit = LocalDateUnitStrict | 'week';
4
4
  export declare type LocalDateUnitStrict = 'year' | 'month' | 'day';
@@ -89,7 +89,7 @@ export declare class LocalDate {
89
89
  toString(): IsoDateString;
90
90
  toStringCompact(): string;
91
91
  unix(): UnixTimestampNumber;
92
- unixMillis(): number;
92
+ unixMillis(): UnixTimestampMillisNumber;
93
93
  toJSON(): IsoDateString;
94
94
  format(fmt: LocalDateFormatter): string;
95
95
  }
@@ -1,4 +1,4 @@
1
- import { IsoDateString, IsoDateTimeString, UnixTimestampNumber } from '../types';
1
+ import { IsoDateString, IsoDateTimeString, UnixTimestampMillisNumber, UnixTimestampNumber } from '../types';
2
2
  import { Inclusiveness, LocalDate } from './localDate';
3
3
  export declare type LocalTimeUnit = 'year' | 'month' | 'week' | 'day' | 'hour' | 'minute' | 'second';
4
4
  export declare enum ISODayOfWeek {
@@ -34,7 +34,7 @@ export declare class LocalTime {
34
34
  /**
35
35
  * Create LocalTime from unixTimestamp in milliseconds (not in seconds).
36
36
  */
37
- static ofMillis(millis: number): LocalTime;
37
+ static ofMillis(millis: UnixTimestampMillisNumber): LocalTime;
38
38
  /**
39
39
  * Returns null if invalid
40
40
  */
@@ -97,7 +97,7 @@ export declare class LocalTime {
97
97
  getDate(): Date;
98
98
  clone(): LocalTime;
99
99
  unix(): UnixTimestampNumber;
100
- unixMillis(): number;
100
+ unixMillis(): UnixTimestampMillisNumber;
101
101
  valueOf(): UnixTimestampNumber;
102
102
  toLocalDate(): LocalDate;
103
103
  toPretty(seconds?: boolean): IsoDateTimeString;
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MapMemoCache = exports.jsonMemoSerializer = void 0;
4
- const object_util_1 = require("../object/object.util");
4
+ const __1 = require("..");
5
5
  const jsonMemoSerializer = args => {
6
6
  if (args.length === 0)
7
7
  return undefined;
8
- if (args.length === 1 && (0, object_util_1._isPrimitive)(args[0]))
8
+ if (args.length === 1 && (0, __1._isPrimitive)(args[0]))
9
9
  return args[0];
10
10
  return JSON.stringify(args);
11
11
  };
package/dist/index.d.ts CHANGED
@@ -50,8 +50,9 @@ export * from './string/json.util';
50
50
  export * from './string/string.util';
51
51
  import { JsonStringifyFunction, StringifyAnyOptions, _stringifyAny } from './string/stringifyAny';
52
52
  export * from './time/time.util';
53
+ export * from './is.util';
53
54
  import { Class, ConditionalExcept, ConditionalPick, Merge, Promisable, ReadonlyDeep, Simplify } from './typeFest';
54
- import { AsyncMapper, AsyncPredicate, BaseDBEntity, CreatedUpdated, CreatedUpdatedId, ObjectWithId, AnyObjectWithId, Saved, Unsaved, UnsavedId, BatchResult, InstanceId, IsoDate, IsoDateString, IsoDateTimeString, KeyValueTuple, Mapper, ObjectMapper, ObjectPredicate, Predicate, PromiseMap, AnyObject, AnyFunction, Reviver, SavedDBEntity, StringMap, UnixTimestampNumber, UnixTimestamp, Integer, ValueOf, ValuesOf, AbortableMapper, AbortableAsyncPredicate, AbortableAsyncMapper, AbortablePredicate, END, SKIP, _noop, _objectKeys, _passNothingPredicate, _passthroughMapper, _passthroughPredicate, _passUndefinedMapper, _stringMapEntries, _stringMapValues } from './types';
55
+ import { AsyncMapper, AsyncPredicate, BaseDBEntity, CreatedUpdated, CreatedUpdatedId, ObjectWithId, AnyObjectWithId, Saved, Unsaved, UnsavedId, BatchResult, InstanceId, IsoDate, IsoDateString, IsoDateTimeString, KeyValueTuple, Mapper, ObjectMapper, ObjectPredicate, Predicate, PromiseMap, AnyObject, AnyFunction, Reviver, SavedDBEntity, StringMap, UnixTimestampNumber, UnixTimestampMillisNumber, UnixTimestamp, Integer, ValueOf, ValuesOf, AbortableMapper, AbortableAsyncPredicate, AbortableAsyncMapper, AbortablePredicate, NullishValue, FalsyValue, END, SKIP, _noop, _objectKeys, _passNothingPredicate, _passthroughMapper, _passthroughPredicate, _passUndefinedMapper, _stringMapEntries, _stringMapValues } from './types';
55
56
  export * from './unit/size.util';
56
57
  import { is } from './vendor/is';
57
58
  import { CommonLogLevel, CommonLogFunction, CommonLogger, commonLoggerMinLevel, commonLoggerNoop, commonLogLevelNumber, commonLoggerPipe, commonLoggerPrefix, CommonLogWithLevelFunction, commonLoggerCreate } from './log/commonLogger';
@@ -68,5 +69,5 @@ import { LocalDateConfig, LocalDateFormatter, LocalDateUnit, LocalDateUnitStrict
68
69
  import { LocalTimeConfig, LocalTimeFormatter, LocalTimeUnit, LocalTimeComponents, ISODayOfWeek } from './datetime/localTime';
69
70
  import { DateIntervalConfig, DateIntervalString } from './datetime/dateInterval';
70
71
  import { TimeIntervalConfig, TimeIntervalString } from './datetime/timeInterval';
71
- export type { DateIntervalConfig, DateIntervalString, TimeIntervalConfig, TimeIntervalString, LocalDateConfig, LocalDateFormatter, LocalDateUnit, LocalDateUnitStrict, Inclusiveness, LocalTimeConfig, LocalTimeFormatter, LocalTimeUnit, ISODayOfWeek, LocalTimeComponents, AbortableMapper, AbortablePredicate, AbortableAsyncPredicate, AbortableAsyncMapper, PQueueCfg, MemoCache, AsyncMemoCache, PromiseDecoratorCfg, PromiseDecoratorResp, ErrorData, ErrorObject, HttpErrorData, HttpErrorResponse, Admin401ErrorData, Admin403ErrorData, StringMap, PromiseMap, AnyObject, AnyFunction, ValuesOf, ValueOf, KeyValueTuple, ObjectMapper, ObjectPredicate, InstanceId, IsoDate, IsoDateString, IsoDateTimeString, Reviver, PMapOptions, Mapper, AsyncMapper, Predicate, AsyncPredicate, BatchResult, DeferredPromise, PRetryOptions, PTimeoutOptions, TryCatchOptions, StringifyAnyOptions, JsonStringifyFunction, Merge, ReadonlyDeep, Promisable, Simplify, ConditionalPick, ConditionalExcept, Class, UnixTimestampNumber, UnixTimestamp, Integer, BaseDBEntity, SavedDBEntity, Saved, Unsaved, UnsavedId, CreatedUpdated, CreatedUpdatedId, ObjectWithId, AnyObjectWithId, JsonSchema, JsonSchemaAny, JsonSchemaOneOf, JsonSchemaAllOf, JsonSchemaAnyOf, JsonSchemaNot, JsonSchemaRef, JsonSchemaConst, JsonSchemaEnum, JsonSchemaString, JsonSchemaNumber, JsonSchemaBoolean, JsonSchemaNull, JsonSchemaRootObject, JsonSchemaObject, JsonSchemaArray, JsonSchemaTuple, JsonSchemaBuilder, CommonLogLevel, CommonLogWithLevelFunction, CommonLogFunction, CommonLogger, };
72
+ export type { DateIntervalConfig, DateIntervalString, TimeIntervalConfig, TimeIntervalString, LocalDateConfig, LocalDateFormatter, LocalDateUnit, LocalDateUnitStrict, Inclusiveness, LocalTimeConfig, LocalTimeFormatter, LocalTimeUnit, ISODayOfWeek, LocalTimeComponents, AbortableMapper, AbortablePredicate, AbortableAsyncPredicate, AbortableAsyncMapper, PQueueCfg, MemoCache, AsyncMemoCache, PromiseDecoratorCfg, PromiseDecoratorResp, ErrorData, ErrorObject, HttpErrorData, HttpErrorResponse, Admin401ErrorData, Admin403ErrorData, StringMap, PromiseMap, AnyObject, AnyFunction, ValuesOf, ValueOf, KeyValueTuple, ObjectMapper, ObjectPredicate, InstanceId, IsoDate, IsoDateString, IsoDateTimeString, Reviver, FalsyValue, NullishValue, PMapOptions, Mapper, AsyncMapper, Predicate, AsyncPredicate, BatchResult, DeferredPromise, PRetryOptions, PTimeoutOptions, TryCatchOptions, StringifyAnyOptions, JsonStringifyFunction, Merge, ReadonlyDeep, Promisable, Simplify, ConditionalPick, ConditionalExcept, Class, UnixTimestampNumber, UnixTimestampMillisNumber, UnixTimestamp, Integer, BaseDBEntity, SavedDBEntity, Saved, Unsaved, UnsavedId, CreatedUpdated, CreatedUpdatedId, ObjectWithId, AnyObjectWithId, JsonSchema, JsonSchemaAny, JsonSchemaOneOf, JsonSchemaAllOf, JsonSchemaAnyOf, JsonSchemaNot, JsonSchemaRef, JsonSchemaConst, JsonSchemaEnum, JsonSchemaString, JsonSchemaNumber, JsonSchemaBoolean, JsonSchemaNull, JsonSchemaRootObject, JsonSchemaObject, JsonSchemaArray, JsonSchemaTuple, JsonSchemaBuilder, CommonLogLevel, CommonLogWithLevelFunction, CommonLogFunction, CommonLogger, };
72
73
  export { is, _createPromiseDecorator, _stringMapValues, _stringMapEntries, _objectKeys, pMap, _passthroughMapper, _passUndefinedMapper, _passthroughPredicate, _passNothingPredicate, _noop, ErrorMode, pDefer, AggregatedError, pRetry, pRetryFn, pTimeout, pTimeoutFn, _tryCatch, _TryCatch, _stringifyAny, jsonSchema, JsonSchemaAnyBuilder, commonLoggerMinLevel, commonLoggerNoop, commonLogLevelNumber, commonLoggerPipe, commonLoggerPrefix, commonLoggerCreate, PQueue, END, SKIP, };
package/dist/index.js CHANGED
@@ -65,6 +65,7 @@ tslib_1.__exportStar(require("./string/string.util"), exports);
65
65
  const stringifyAny_1 = require("./string/stringifyAny");
66
66
  Object.defineProperty(exports, "_stringifyAny", { enumerable: true, get: function () { return stringifyAny_1._stringifyAny; } });
67
67
  tslib_1.__exportStar(require("./time/time.util"), exports);
68
+ tslib_1.__exportStar(require("./is.util"), exports);
68
69
  const types_1 = require("./types");
69
70
  Object.defineProperty(exports, "END", { enumerable: true, get: function () { return types_1.END; } });
70
71
  Object.defineProperty(exports, "SKIP", { enumerable: true, get: function () { return types_1.SKIP; } });
@@ -0,0 +1,40 @@
1
+ import { Primitive } from './typeFest';
2
+ import { AnyObject, FalsyValue, NullishValue } from './types';
3
+ declare type Nullish<T> = T extends NullishValue ? T : never;
4
+ declare type Truthy<T> = T extends FalsyValue ? never : T;
5
+ declare type Falsy<T> = T extends FalsyValue ? T : never;
6
+ export declare const _isNull: <T>(v: T) => v is T extends null ? T : never;
7
+ export declare const _isUndefined: <T>(v: T) => v is T extends undefined ? T : never;
8
+ export declare const _isNullish: <T>(v: T) => v is Nullish<T>;
9
+ export declare const _isNotNullish: <T>(v: T) => v is NonNullable<T>;
10
+ /**
11
+ * Same as Boolean, but with correct type output.
12
+ * Related:
13
+ * https://github.com/microsoft/TypeScript/issues/16655
14
+ * https://www.karltarvas.com/2021/03/11/typescript-array-filter-boolean.html
15
+ *
16
+ * @example
17
+ *
18
+ * [1, 2, undefined].filter(_isTruthy)
19
+ * // => [1, 2]
20
+ */
21
+ export declare const _isTruthy: <T>(v: T) => v is Truthy<T>;
22
+ export declare const _isFalsy: <T>(v: T) => v is Falsy<T>;
23
+ /**
24
+ * Returns true if item is Object, not null and not Array.
25
+ */
26
+ export declare function _isObject(item: any): item is AnyObject;
27
+ export declare function _isPrimitive(v: any): v is Primitive;
28
+ export declare function _isEmptyObject(obj: any): boolean;
29
+ /**
30
+ * Object is considered empty if it's one of:
31
+ * undefined
32
+ * null
33
+ * '' (empty string)
34
+ * [] (empty array)
35
+ * {} (empty object)
36
+ * new Map() (empty Map)
37
+ * new Set() (empty Set)
38
+ */
39
+ export declare function _isEmpty(obj: any): boolean;
40
+ export {};
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports._isEmpty = exports._isEmptyObject = exports._isPrimitive = exports._isObject = exports._isFalsy = exports._isTruthy = exports._isNotNullish = exports._isNullish = exports._isUndefined = exports._isNull = void 0;
4
+ const _isNull = (v) => v === null;
5
+ exports._isNull = _isNull;
6
+ const _isUndefined = (v) => typeof v === 'undefined';
7
+ exports._isUndefined = _isUndefined;
8
+ const _isNullish = (v) => typeof v === 'undefined' || v === null;
9
+ exports._isNullish = _isNullish;
10
+ const _isNotNullish = (v) => v !== undefined && v !== null;
11
+ exports._isNotNullish = _isNotNullish;
12
+ /**
13
+ * Same as Boolean, but with correct type output.
14
+ * Related:
15
+ * https://github.com/microsoft/TypeScript/issues/16655
16
+ * https://www.karltarvas.com/2021/03/11/typescript-array-filter-boolean.html
17
+ *
18
+ * @example
19
+ *
20
+ * [1, 2, undefined].filter(_isTruthy)
21
+ * // => [1, 2]
22
+ */
23
+ const _isTruthy = (v) => !!v;
24
+ exports._isTruthy = _isTruthy;
25
+ const _isFalsy = (v) => !v;
26
+ exports._isFalsy = _isFalsy;
27
+ /**
28
+ * Returns true if item is Object, not null and not Array.
29
+ */
30
+ function _isObject(item) {
31
+ return (typeof item === 'object' && item !== null && !Array.isArray(item)) || false;
32
+ }
33
+ exports._isObject = _isObject;
34
+ function _isPrimitive(v) {
35
+ return (v === null ||
36
+ v === undefined ||
37
+ typeof v === 'number' ||
38
+ typeof v === 'boolean' ||
39
+ typeof v === 'string' ||
40
+ typeof v === 'bigint' ||
41
+ typeof v === 'symbol');
42
+ }
43
+ exports._isPrimitive = _isPrimitive;
44
+ function _isEmptyObject(obj) {
45
+ return obj && obj.constructor === Object && Object.keys(obj).length === 0;
46
+ }
47
+ exports._isEmptyObject = _isEmptyObject;
48
+ /**
49
+ * Object is considered empty if it's one of:
50
+ * undefined
51
+ * null
52
+ * '' (empty string)
53
+ * [] (empty array)
54
+ * {} (empty object)
55
+ * new Map() (empty Map)
56
+ * new Set() (empty Set)
57
+ */
58
+ function _isEmpty(obj) {
59
+ if (obj === undefined || obj === null)
60
+ return true;
61
+ if (typeof obj === 'string' || Array.isArray(obj)) {
62
+ return obj.length === 0;
63
+ }
64
+ if (obj instanceof Map || obj instanceof Set) {
65
+ return obj.size === 0;
66
+ }
67
+ if (typeof obj === 'object') {
68
+ return Object.keys(obj).length === 0;
69
+ }
70
+ return false;
71
+ }
72
+ exports._isEmpty = _isEmpty;
@@ -19,6 +19,7 @@ export declare const jsonSchema: {
19
19
  number(): JsonSchemaNumberBuilder;
20
20
  integer(): JsonSchemaNumberBuilder;
21
21
  unixTimestamp(): JsonSchemaNumberBuilder;
22
+ unixTimestamp2000(): JsonSchemaNumberBuilder;
22
23
  string(): JsonSchemaStringBuilder;
23
24
  dateString(): JsonSchemaStringBuilder;
24
25
  object<T_4 extends AnyObject>(props: { [k in keyof T_4]: JsonSchemaAnyBuilder<T_4[k], JsonSchema<T_4[k]>>; }): JsonSchemaObjectBuilder<T_4>;
@@ -72,7 +73,9 @@ export declare class JsonSchemaNumberBuilder extends JsonSchemaAnyBuilder<number
72
73
  float: () => this;
73
74
  double: () => this;
74
75
  unixTimestamp: () => this;
76
+ unixTimestamp2000: () => this;
75
77
  unixTimestampMillis: () => this;
78
+ unixTimestampMillis2000: () => this;
76
79
  utcOffset: () => this;
77
80
  utcOffsetHours: () => this;
78
81
  }
@@ -50,6 +50,9 @@ exports.jsonSchema = {
50
50
  unixTimestamp() {
51
51
  return new JsonSchemaNumberBuilder().unixTimestamp();
52
52
  },
53
+ unixTimestamp2000() {
54
+ return new JsonSchemaNumberBuilder().unixTimestamp2000();
55
+ },
53
56
  // string types
54
57
  string() {
55
58
  return new JsonSchemaStringBuilder();
@@ -167,7 +170,9 @@ class JsonSchemaNumberBuilder extends JsonSchemaAnyBuilder {
167
170
  this.float = () => this.format('float');
168
171
  this.double = () => this.format('double');
169
172
  this.unixTimestamp = () => this.format('unixTimestamp');
173
+ this.unixTimestamp2000 = () => this.format('unixTimestamp2000');
170
174
  this.unixTimestampMillis = () => this.format('unixTimestampMillis');
175
+ this.unixTimestampMillis2000 = () => this.format('unixTimestampMillis2000');
171
176
  this.utcOffset = () => this.format('utcOffset');
172
177
  this.utcOffsetHours = () => this.format('utcOffsetHours');
173
178
  }
@@ -309,8 +314,8 @@ class JsonSchemaObjectBuilder extends JsonSchemaAnyBuilder {
309
314
  baseDBEntity(idType = 'string') {
310
315
  Object.assign(this.schema.properties, {
311
316
  id: { type: idType },
312
- created: { type: 'number', format: 'unixTimestamp' },
313
- updated: { type: 'number', format: 'unixTimestamp' },
317
+ created: { type: 'number', format: 'unixTimestamp2000' },
318
+ updated: { type: 'number', format: 'unixTimestamp2000' },
314
319
  });
315
320
  return this;
316
321
  }
@@ -4,11 +4,11 @@ exports.savedDBEntityJsonSchema = exports.baseDBEntityJsonSchema = void 0;
4
4
  const jsonSchemaBuilder_1 = require("./jsonSchemaBuilder");
5
5
  exports.baseDBEntityJsonSchema = jsonSchemaBuilder_1.jsonSchema.object({
6
6
  id: jsonSchemaBuilder_1.jsonSchema.string().optional(),
7
- created: jsonSchemaBuilder_1.jsonSchema.unixTimestamp().optional(),
8
- updated: jsonSchemaBuilder_1.jsonSchema.unixTimestamp().optional(),
7
+ created: jsonSchemaBuilder_1.jsonSchema.unixTimestamp2000().optional(),
8
+ updated: jsonSchemaBuilder_1.jsonSchema.unixTimestamp2000().optional(),
9
9
  });
10
10
  exports.savedDBEntityJsonSchema = jsonSchemaBuilder_1.jsonSchema.object({
11
11
  id: jsonSchemaBuilder_1.jsonSchema.string(),
12
- created: jsonSchemaBuilder_1.jsonSchema.unixTimestamp(),
13
- updated: jsonSchemaBuilder_1.jsonSchema.unixTimestamp(),
12
+ created: jsonSchemaBuilder_1.jsonSchema.unixTimestamp2000(),
13
+ updated: jsonSchemaBuilder_1.jsonSchema.unixTimestamp2000(),
14
14
  });
@@ -84,23 +84,6 @@ export declare function _objectNullValuesToUndefined<T extends AnyObject>(obj: T
84
84
  * Deep copy object (by json parse/stringify, since it has unbeatable performance+simplicity combo).
85
85
  */
86
86
  export declare function _deepCopy<T>(o: T): T;
87
- /**
88
- * Returns true if item is Object, not null and not Array.
89
- */
90
- export declare function _isObject(item: any): item is AnyObject;
91
- export declare function _isPrimitive(v: any): v is null | undefined | number | boolean | string;
92
- export declare function _isEmptyObject(obj: any): boolean;
93
- /**
94
- * Object is considered empty if it's one of:
95
- * undefined
96
- * null
97
- * '' (empty string)
98
- * [] (empty array)
99
- * {} (empty object)
100
- * new Map() (empty Map)
101
- * new Set() (empty Set)
102
- */
103
- export declare function _isEmpty(obj: any): boolean;
104
87
  /**
105
88
  * Returns `undefined` if it's empty (according to `_isEmpty()` specification),
106
89
  * otherwise returns the original object.
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports._has = exports._set = exports._get = exports._invertMap = exports._invert = exports._unset = exports._deepTrim = exports._merge = exports._filterEmptyValues = exports._undefinedIfEmpty = exports._isEmpty = exports._isEmptyObject = exports._isPrimitive = exports._isObject = exports._deepCopy = exports._objectNullValuesToUndefined = exports._findKeyByValue = exports._mapObject = exports._mapKeys = exports._mapValues = exports._filterObject = exports._filterEmptyArrays = exports._filterUndefinedValues = exports._filterNullishValues = exports._filterFalsyValues = exports._mask = exports._omit = exports._pick = void 0;
3
+ exports._has = exports._set = exports._get = exports._invertMap = exports._invert = exports._unset = exports._deepTrim = exports._merge = exports._filterEmptyValues = exports._undefinedIfEmpty = exports._deepCopy = exports._objectNullValuesToUndefined = exports._findKeyByValue = exports._mapObject = exports._mapKeys = exports._mapValues = exports._filterObject = exports._filterEmptyArrays = exports._filterUndefinedValues = exports._filterNullishValues = exports._filterFalsyValues = exports._mask = exports._omit = exports._pick = void 0;
4
+ const is_util_1 = require("../is.util");
4
5
  /**
5
6
  * Returns clone of `obj` with only `props` preserved.
6
7
  * Opposite of Omit.
@@ -164,63 +165,19 @@ function _deepCopy(o) {
164
165
  return JSON.parse(JSON.stringify(o));
165
166
  }
166
167
  exports._deepCopy = _deepCopy;
167
- /**
168
- * Returns true if item is Object, not null and not Array.
169
- */
170
- function _isObject(item) {
171
- return (typeof item === 'object' && item !== null && !Array.isArray(item)) || false;
172
- }
173
- exports._isObject = _isObject;
174
- function _isPrimitive(v) {
175
- return (v === null ||
176
- v === undefined ||
177
- typeof v === 'number' ||
178
- typeof v === 'boolean' ||
179
- typeof v === 'string');
180
- }
181
- exports._isPrimitive = _isPrimitive;
182
- function _isEmptyObject(obj) {
183
- return obj && obj.constructor === Object && Object.keys(obj).length === 0;
184
- }
185
- exports._isEmptyObject = _isEmptyObject;
186
- /**
187
- * Object is considered empty if it's one of:
188
- * undefined
189
- * null
190
- * '' (empty string)
191
- * [] (empty array)
192
- * {} (empty object)
193
- * new Map() (empty Map)
194
- * new Set() (empty Set)
195
- */
196
- function _isEmpty(obj) {
197
- if (obj === undefined || obj === null)
198
- return true;
199
- if (typeof obj === 'string' || Array.isArray(obj)) {
200
- return obj.length === 0;
201
- }
202
- if (obj instanceof Map || obj instanceof Set) {
203
- return obj.size === 0;
204
- }
205
- if (typeof obj === 'object') {
206
- return Object.keys(obj).length === 0;
207
- }
208
- return false;
209
- }
210
- exports._isEmpty = _isEmpty;
211
168
  /**
212
169
  * Returns `undefined` if it's empty (according to `_isEmpty()` specification),
213
170
  * otherwise returns the original object.
214
171
  */
215
172
  function _undefinedIfEmpty(obj) {
216
- return _isEmpty(obj) ? undefined : obj;
173
+ return (0, is_util_1._isEmpty)(obj) ? undefined : obj;
217
174
  }
218
175
  exports._undefinedIfEmpty = _undefinedIfEmpty;
219
176
  /**
220
177
  * Filters the object by removing all key-value pairs where Value is Empty (according to _isEmpty() specification).
221
178
  */
222
179
  function _filterEmptyValues(obj, mutate = false) {
223
- return _filterObject(obj, (_k, v) => !_isEmpty(v), mutate);
180
+ return _filterObject(obj, (_k, v) => !(0, is_util_1._isEmpty)(v), mutate);
224
181
  }
225
182
  exports._filterEmptyValues = _filterEmptyValues;
226
183
  /**
@@ -254,9 +211,9 @@ exports._filterEmptyValues = _filterEmptyValues;
254
211
  */
255
212
  function _merge(target, ...sources) {
256
213
  sources.forEach(source => {
257
- if (_isObject(source)) {
214
+ if ((0, is_util_1._isObject)(source)) {
258
215
  Object.keys(source).forEach(key => {
259
- if (_isObject(source[key])) {
216
+ if ((0, is_util_1._isObject)(source[key])) {
260
217
  if (!target[key])
261
218
  Object.assign(target, { [key]: {} });
262
219
  _merge(target[key], source[key]);
@@ -292,7 +249,7 @@ exports._deepTrim = _deepTrim;
292
249
  // from: https://github.com/jonschlinkert/unset-value
293
250
  // mutates obj
294
251
  function _unset(obj, prop) {
295
- if (!_isObject(obj)) {
252
+ if (!(0, is_util_1._isObject)(obj)) {
296
253
  return;
297
254
  }
298
255
  // eslint-disable-next-line no-prototype-builtins
@@ -305,11 +262,11 @@ function _unset(obj, prop) {
305
262
  while (segs.length && segs[segs.length - 1].slice(-1) === '\\') {
306
263
  last = segs.pop().slice(0, -1) + '.' + last;
307
264
  }
308
- while (segs.length && _isObject(obj)) {
265
+ while (segs.length && (0, is_util_1._isObject)(obj)) {
309
266
  const k = (prop = segs.shift());
310
267
  obj = obj[k];
311
268
  }
312
- if (!_isObject(obj))
269
+ if (!(0, is_util_1._isObject)(obj))
313
270
  return;
314
271
  delete obj[last];
315
272
  }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports._sortObjectDeep = void 0;
4
- const object_util_1 = require("./object.util");
4
+ const __1 = require("..");
5
5
  /**
6
6
  * based on: https://github.com/IndigoUnited/js-deep-sort-object
7
7
  */
@@ -11,7 +11,7 @@ function _sortObjectDeep(o) {
11
11
  // eslint-disable-next-line unicorn/no-array-callback-reference
12
12
  return o.map(_sortObjectDeep);
13
13
  }
14
- if ((0, object_util_1._isObject)(o)) {
14
+ if ((0, __1._isObject)(o)) {
15
15
  const out = {};
16
16
  Object.keys(o)
17
17
  .sort((a, b) => a.localeCompare(b))
package/dist/types.d.ts CHANGED
@@ -154,6 +154,12 @@ export declare type IsoDateTimeString = string;
154
154
  * @example 1628945450
155
155
  */
156
156
  export declare type UnixTimestampNumber = number;
157
+ /**
158
+ * Interface explicitly states that the value is a "Unix timestamp in **milleseconds**" (not seconds)
159
+ *
160
+ * @example 1628945450000
161
+ */
162
+ export declare type UnixTimestampMillisNumber = number;
157
163
  /**
158
164
  * @deprecated use UnixTimestampNumber
159
165
  */
@@ -183,3 +189,5 @@ export declare function _stringMapEntries<T>(m: StringMap<T>): [k: string, v: T]
183
189
  * @experimental
184
190
  */
185
191
  export declare function _objectKeys<T extends AnyObject>(obj: T): (keyof T)[];
192
+ export declare type NullishValue = null | undefined;
193
+ export declare type FalsyValue = false | '' | 0 | null | undefined;
@@ -1,3 +1,4 @@
1
+ import { _isNotNullish } from '../is.util';
1
2
  /**
2
3
  * Creates an array of elements split into groups the length of size. If collection can’t be split evenly, the
3
4
  * final chunk will be the remaining elements.
@@ -191,6 +192,9 @@ export function _intersection(...arrays) {
191
192
  export function _difference(source, ...diffs) {
192
193
  return diffs.reduce((a, b) => a.filter(c => !b.includes(c)), source);
193
194
  }
195
+ /**
196
+ * Returns the sum of items, or 0 for empty array.
197
+ */
194
198
  export function _sum(items) {
195
199
  return items.reduce((sum, n) => sum + n, 0);
196
200
  }
@@ -252,22 +256,32 @@ export function _lastOrUndefined(array) {
252
256
  return array[array.length - 1];
253
257
  }
254
258
  export function _minOrUndefined(array) {
255
- if (!array.length)
259
+ const a = array.filter(_isNotNullish);
260
+ if (!a.length)
256
261
  return;
257
- return _min(array);
262
+ return _min(a);
258
263
  }
264
+ /**
265
+ * Filters out nullish values (undefined and null).
266
+ */
259
267
  export function _min(array) {
260
- if (!array.length)
268
+ const a = array.filter(_isNotNullish);
269
+ if (!a.length)
261
270
  throw new Error('_min called on empty array');
262
- return array.reduce((min, item) => (min <= item ? min : item));
271
+ return a.reduce((min, item) => (min <= item ? min : item));
263
272
  }
264
273
  export function _maxOrUndefined(array) {
265
- if (!array.length)
274
+ const a = array.filter(_isNotNullish);
275
+ if (!a.length)
266
276
  return;
267
- return _max(array);
277
+ return _max(a);
268
278
  }
279
+ /**
280
+ * Filters out nullish values (undefined and null).
281
+ */
269
282
  export function _max(array) {
270
- if (!array.length)
283
+ const a = array.filter(_isNotNullish);
284
+ if (!a.length)
271
285
  throw new Error('_max called on empty array');
272
- return array.reduce((max, item) => (max >= item ? max : item));
286
+ return a.reduce((max, item) => (max >= item ? max : item));
273
287
  }
@@ -1,4 +1,4 @@
1
- import { _isPrimitive } from '../object/object.util';
1
+ import { _isPrimitive } from '..';
2
2
  export const jsonMemoSerializer = args => {
3
3
  if (args.length === 0)
4
4
  return undefined;
package/dist-esm/index.js CHANGED
@@ -47,6 +47,7 @@ export * from './string/json.util';
47
47
  export * from './string/string.util';
48
48
  import { _stringifyAny } from './string/stringifyAny';
49
49
  export * from './time/time.util';
50
+ export * from './is.util';
50
51
  import { END, SKIP, _noop, _objectKeys, _passNothingPredicate, _passthroughMapper, _passthroughPredicate, _passUndefinedMapper, _stringMapEntries, _stringMapValues, } from './types';
51
52
  export * from './unit/size.util';
52
53
  import { is } from './vendor/is';
@@ -0,0 +1,59 @@
1
+ export const _isNull = (v) => v === null;
2
+ export const _isUndefined = (v) => typeof v === 'undefined';
3
+ export const _isNullish = (v) => typeof v === 'undefined' || v === null;
4
+ export const _isNotNullish = (v) => v !== undefined && v !== null;
5
+ /**
6
+ * Same as Boolean, but with correct type output.
7
+ * Related:
8
+ * https://github.com/microsoft/TypeScript/issues/16655
9
+ * https://www.karltarvas.com/2021/03/11/typescript-array-filter-boolean.html
10
+ *
11
+ * @example
12
+ *
13
+ * [1, 2, undefined].filter(_isTruthy)
14
+ * // => [1, 2]
15
+ */
16
+ export const _isTruthy = (v) => !!v;
17
+ export const _isFalsy = (v) => !v;
18
+ /**
19
+ * Returns true if item is Object, not null and not Array.
20
+ */
21
+ export function _isObject(item) {
22
+ return (typeof item === 'object' && item !== null && !Array.isArray(item)) || false;
23
+ }
24
+ export function _isPrimitive(v) {
25
+ return (v === null ||
26
+ v === undefined ||
27
+ typeof v === 'number' ||
28
+ typeof v === 'boolean' ||
29
+ typeof v === 'string' ||
30
+ typeof v === 'bigint' ||
31
+ typeof v === 'symbol');
32
+ }
33
+ export function _isEmptyObject(obj) {
34
+ return obj && obj.constructor === Object && Object.keys(obj).length === 0;
35
+ }
36
+ /**
37
+ * Object is considered empty if it's one of:
38
+ * undefined
39
+ * null
40
+ * '' (empty string)
41
+ * [] (empty array)
42
+ * {} (empty object)
43
+ * new Map() (empty Map)
44
+ * new Set() (empty Set)
45
+ */
46
+ export function _isEmpty(obj) {
47
+ if (obj === undefined || obj === null)
48
+ return true;
49
+ if (typeof obj === 'string' || Array.isArray(obj)) {
50
+ return obj.length === 0;
51
+ }
52
+ if (obj instanceof Map || obj instanceof Set) {
53
+ return obj.size === 0;
54
+ }
55
+ if (typeof obj === 'object') {
56
+ return Object.keys(obj).length === 0;
57
+ }
58
+ return false;
59
+ }
@@ -47,6 +47,9 @@ export const jsonSchema = {
47
47
  unixTimestamp() {
48
48
  return new JsonSchemaNumberBuilder().unixTimestamp();
49
49
  },
50
+ unixTimestamp2000() {
51
+ return new JsonSchemaNumberBuilder().unixTimestamp2000();
52
+ },
50
53
  // string types
51
54
  string() {
52
55
  return new JsonSchemaStringBuilder();
@@ -163,7 +166,9 @@ export class JsonSchemaNumberBuilder extends JsonSchemaAnyBuilder {
163
166
  this.float = () => this.format('float');
164
167
  this.double = () => this.format('double');
165
168
  this.unixTimestamp = () => this.format('unixTimestamp');
169
+ this.unixTimestamp2000 = () => this.format('unixTimestamp2000');
166
170
  this.unixTimestampMillis = () => this.format('unixTimestampMillis');
171
+ this.unixTimestampMillis2000 = () => this.format('unixTimestampMillis2000');
167
172
  this.utcOffset = () => this.format('utcOffset');
168
173
  this.utcOffsetHours = () => this.format('utcOffsetHours');
169
174
  }
@@ -304,8 +309,8 @@ export class JsonSchemaObjectBuilder extends JsonSchemaAnyBuilder {
304
309
  baseDBEntity(idType = 'string') {
305
310
  Object.assign(this.schema.properties, {
306
311
  id: { type: idType },
307
- created: { type: 'number', format: 'unixTimestamp' },
308
- updated: { type: 'number', format: 'unixTimestamp' },
312
+ created: { type: 'number', format: 'unixTimestamp2000' },
313
+ updated: { type: 'number', format: 'unixTimestamp2000' },
309
314
  });
310
315
  return this;
311
316
  }
@@ -1,11 +1,11 @@
1
1
  import { jsonSchema } from './jsonSchemaBuilder';
2
2
  export const baseDBEntityJsonSchema = jsonSchema.object({
3
3
  id: jsonSchema.string().optional(),
4
- created: jsonSchema.unixTimestamp().optional(),
5
- updated: jsonSchema.unixTimestamp().optional(),
4
+ created: jsonSchema.unixTimestamp2000().optional(),
5
+ updated: jsonSchema.unixTimestamp2000().optional(),
6
6
  });
7
7
  export const savedDBEntityJsonSchema = jsonSchema.object({
8
8
  id: jsonSchema.string(),
9
- created: jsonSchema.unixTimestamp(),
10
- updated: jsonSchema.unixTimestamp(),
9
+ created: jsonSchema.unixTimestamp2000(),
10
+ updated: jsonSchema.unixTimestamp2000(),
11
11
  });
@@ -1,3 +1,4 @@
1
+ import { _isEmpty, _isObject } from '../is.util';
1
2
  /**
2
3
  * Returns clone of `obj` with only `props` preserved.
3
4
  * Opposite of Omit.
@@ -148,46 +149,6 @@ export function _objectNullValuesToUndefined(obj, mutate = false) {
148
149
  export function _deepCopy(o) {
149
150
  return JSON.parse(JSON.stringify(o));
150
151
  }
151
- /**
152
- * Returns true if item is Object, not null and not Array.
153
- */
154
- export function _isObject(item) {
155
- return (typeof item === 'object' && item !== null && !Array.isArray(item)) || false;
156
- }
157
- export function _isPrimitive(v) {
158
- return (v === null ||
159
- v === undefined ||
160
- typeof v === 'number' ||
161
- typeof v === 'boolean' ||
162
- typeof v === 'string');
163
- }
164
- export function _isEmptyObject(obj) {
165
- return obj && obj.constructor === Object && Object.keys(obj).length === 0;
166
- }
167
- /**
168
- * Object is considered empty if it's one of:
169
- * undefined
170
- * null
171
- * '' (empty string)
172
- * [] (empty array)
173
- * {} (empty object)
174
- * new Map() (empty Map)
175
- * new Set() (empty Set)
176
- */
177
- export function _isEmpty(obj) {
178
- if (obj === undefined || obj === null)
179
- return true;
180
- if (typeof obj === 'string' || Array.isArray(obj)) {
181
- return obj.length === 0;
182
- }
183
- if (obj instanceof Map || obj instanceof Set) {
184
- return obj.size === 0;
185
- }
186
- if (typeof obj === 'object') {
187
- return Object.keys(obj).length === 0;
188
- }
189
- return false;
190
- }
191
152
  /**
192
153
  * Returns `undefined` if it's empty (according to `_isEmpty()` specification),
193
154
  * otherwise returns the original object.
@@ -1,4 +1,4 @@
1
- import { _isObject } from './object.util';
1
+ import { _isObject } from '..';
2
2
  /**
3
3
  * based on: https://github.com/IndigoUnited/js-deep-sort-object
4
4
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
- "version": "14.100.0",
3
+ "version": "14.103.0",
4
4
  "scripts": {
5
5
  "prepare": "husky install",
6
6
  "build-prod": "build-prod-esm-cjs",
@@ -1,5 +1,6 @@
1
+ import { _isNotNullish } from '../is.util'
1
2
  import { RecursiveArray } from '../lodash.types'
2
- import { Mapper, Predicate, StringMap } from '../types'
3
+ import { FalsyValue, Mapper, Predicate, StringMap } from '../types'
3
4
 
4
5
  /**
5
6
  * Creates an array of elements split into groups the length of size. If collection can’t be split evenly, the
@@ -216,6 +217,9 @@ export function _difference<T>(source: T[], ...diffs: T[][]): T[] {
216
217
  return diffs.reduce((a, b) => a.filter(c => !b.includes(c)), source)
217
218
  }
218
219
 
220
+ /**
221
+ * Returns the sum of items, or 0 for empty array.
222
+ */
219
223
  export function _sum(items: number[]): number {
220
224
  return items.reduce((sum, n) => sum + n, 0)
221
225
  }
@@ -242,7 +246,7 @@ export function _sumBy<T>(items: T[], mapper: Mapper<T, number | undefined>): nu
242
246
  */
243
247
  export function _mapToObject<T, V>(
244
248
  array: T[],
245
- mapper: (item: T) => [key: any, value: V] | undefined | null | false | 0 | void,
249
+ mapper: (item: T) => [key: any, value: V] | FalsyValue,
246
250
  ): StringMap<V> {
247
251
  const m: StringMap<V> = {}
248
252
 
@@ -288,22 +292,32 @@ export function _lastOrUndefined<T>(array: T[]): T | undefined {
288
292
  return array[array.length - 1]
289
293
  }
290
294
 
291
- export function _minOrUndefined<T>(array: T[]): T | undefined {
292
- if (!array.length) return
293
- return _min(array)
295
+ export function _minOrUndefined<T>(array: T[]): NonNullable<T> | undefined {
296
+ const a = array.filter(_isNotNullish)
297
+ if (!a.length) return
298
+ return _min(a)
294
299
  }
295
300
 
296
- export function _min<T>(array: T[]): T {
297
- if (!array.length) throw new Error('_min called on empty array')
298
- return array.reduce((min, item) => (min <= item ? min : item))
301
+ /**
302
+ * Filters out nullish values (undefined and null).
303
+ */
304
+ export function _min<T>(array: T[]): NonNullable<T> {
305
+ const a = array.filter(_isNotNullish)
306
+ if (!a.length) throw new Error('_min called on empty array')
307
+ return a.reduce((min, item) => (min <= item ? min : item))
299
308
  }
300
309
 
301
- export function _maxOrUndefined<T>(array: T[]): T | undefined {
302
- if (!array.length) return
303
- return _max(array)
310
+ export function _maxOrUndefined<T>(array: T[]): NonNullable<T> | undefined {
311
+ const a = array.filter(_isNotNullish)
312
+ if (!a.length) return
313
+ return _max(a)
304
314
  }
305
315
 
306
- export function _max<T>(array: T[]): T {
307
- if (!array.length) throw new Error('_max called on empty array')
308
- return array.reduce((max, item) => (max >= item ? max : item))
316
+ /**
317
+ * Filters out nullish values (undefined and null).
318
+ */
319
+ export function _max<T>(array: T[]): NonNullable<T> {
320
+ const a = array.filter(_isNotNullish)
321
+ if (!a.length) throw new Error('_max called on empty array')
322
+ return a.reduce((max, item) => (max >= item ? max : item))
309
323
  }
@@ -1,5 +1,10 @@
1
1
  import { _assert } from '../error/assert'
2
- import { IsoDateString, IsoDateTimeString, UnixTimestampNumber } from '../types'
2
+ import {
3
+ IsoDateString,
4
+ IsoDateTimeString,
5
+ UnixTimestampMillisNumber,
6
+ UnixTimestampNumber,
7
+ } from '../types'
3
8
  import { LocalTime } from './localTime'
4
9
 
5
10
  export type LocalDateUnit = LocalDateUnitStrict | 'week'
@@ -477,7 +482,7 @@ export class LocalDate {
477
482
  return Math.floor(this.toDate().valueOf() / 1000)
478
483
  }
479
484
 
480
- unixMillis(): number {
485
+ unixMillis(): UnixTimestampMillisNumber {
481
486
  return this.toDate().valueOf()
482
487
  }
483
488
 
@@ -1,6 +1,11 @@
1
1
  import { _assert } from '../error/assert'
2
2
  import { _ms } from '../time/time.util'
3
- import { IsoDateString, IsoDateTimeString, UnixTimestampNumber } from '../types'
3
+ import {
4
+ IsoDateString,
5
+ IsoDateTimeString,
6
+ UnixTimestampMillisNumber,
7
+ UnixTimestampNumber,
8
+ } from '../types'
4
9
  import { Inclusiveness, LocalDate } from './localDate'
5
10
 
6
11
  export type LocalTimeUnit = 'year' | 'month' | 'week' | 'day' | 'hour' | 'minute' | 'second'
@@ -59,7 +64,7 @@ export class LocalTime {
59
64
  /**
60
65
  * Create LocalTime from unixTimestamp in milliseconds (not in seconds).
61
66
  */
62
- static ofMillis(millis: number): LocalTime {
67
+ static ofMillis(millis: UnixTimestampMillisNumber): LocalTime {
63
68
  return LocalTime.of(new Date(millis))
64
69
  }
65
70
 
@@ -478,7 +483,7 @@ export class LocalTime {
478
483
  return Math.floor(this.$date.valueOf() / 1000)
479
484
  }
480
485
 
481
- unixMillis(): number {
486
+ unixMillis(): UnixTimestampMillisNumber {
482
487
  return this.$date.valueOf()
483
488
  }
484
489
 
@@ -1,4 +1,4 @@
1
- import { _isPrimitive } from '../object/object.util'
1
+ import { _isPrimitive } from '..'
2
2
  import { Promisable } from '../typeFest'
3
3
 
4
4
  export type MemoSerializer = (args: any[]) => any
package/src/index.ts CHANGED
@@ -83,6 +83,8 @@ export * from './string/json.util'
83
83
  export * from './string/string.util'
84
84
  import { JsonStringifyFunction, StringifyAnyOptions, _stringifyAny } from './string/stringifyAny'
85
85
  export * from './time/time.util'
86
+ export * from './is.util'
87
+
86
88
  import {
87
89
  Class,
88
90
  ConditionalExcept,
@@ -120,6 +122,7 @@ import {
120
122
  SavedDBEntity,
121
123
  StringMap,
122
124
  UnixTimestampNumber,
125
+ UnixTimestampMillisNumber,
123
126
  UnixTimestamp,
124
127
  Integer,
125
128
  ValueOf,
@@ -128,6 +131,8 @@ import {
128
131
  AbortableAsyncPredicate,
129
132
  AbortableAsyncMapper,
130
133
  AbortablePredicate,
134
+ NullishValue,
135
+ FalsyValue,
131
136
  END,
132
137
  SKIP,
133
138
  _noop,
@@ -223,6 +228,8 @@ export type {
223
228
  IsoDateString,
224
229
  IsoDateTimeString,
225
230
  Reviver,
231
+ FalsyValue,
232
+ NullishValue,
226
233
  PMapOptions,
227
234
  Mapper,
228
235
  AsyncMapper,
@@ -243,6 +250,7 @@ export type {
243
250
  ConditionalExcept,
244
251
  Class,
245
252
  UnixTimestampNumber,
253
+ UnixTimestampMillisNumber,
246
254
  UnixTimestamp,
247
255
  Integer,
248
256
  BaseDBEntity,
package/src/is.util.ts ADDED
@@ -0,0 +1,77 @@
1
+ import { Primitive } from './typeFest'
2
+ import { AnyObject, FalsyValue, NullishValue } from './types'
3
+
4
+ type Nullish<T> = T extends NullishValue ? T : never
5
+ type Truthy<T> = T extends FalsyValue ? never : T
6
+ type Falsy<T> = T extends FalsyValue ? T : never
7
+
8
+ export const _isNull = <T>(v: T): v is T extends null ? T : never => v === null
9
+ export const _isUndefined = <T>(v: T): v is T extends undefined ? T : never =>
10
+ typeof v === 'undefined'
11
+ export const _isNullish = <T>(v: T): v is Nullish<T> => typeof v === 'undefined' || v === null
12
+ export const _isNotNullish = <T>(v: T): v is NonNullable<T> => v !== undefined && v !== null
13
+
14
+ /**
15
+ * Same as Boolean, but with correct type output.
16
+ * Related:
17
+ * https://github.com/microsoft/TypeScript/issues/16655
18
+ * https://www.karltarvas.com/2021/03/11/typescript-array-filter-boolean.html
19
+ *
20
+ * @example
21
+ *
22
+ * [1, 2, undefined].filter(_isTruthy)
23
+ * // => [1, 2]
24
+ */
25
+ export const _isTruthy = <T>(v: T): v is Truthy<T> => !!v
26
+ export const _isFalsy = <T>(v: T): v is Falsy<T> => !v
27
+
28
+ /**
29
+ * Returns true if item is Object, not null and not Array.
30
+ */
31
+ export function _isObject(item: any): item is AnyObject {
32
+ return (typeof item === 'object' && item !== null && !Array.isArray(item)) || false
33
+ }
34
+
35
+ export function _isPrimitive(v: any): v is Primitive {
36
+ return (
37
+ v === null ||
38
+ v === undefined ||
39
+ typeof v === 'number' ||
40
+ typeof v === 'boolean' ||
41
+ typeof v === 'string' ||
42
+ typeof v === 'bigint' ||
43
+ typeof v === 'symbol'
44
+ )
45
+ }
46
+
47
+ export function _isEmptyObject(obj: any): boolean {
48
+ return obj && obj.constructor === Object && Object.keys(obj).length === 0
49
+ }
50
+
51
+ /**
52
+ * Object is considered empty if it's one of:
53
+ * undefined
54
+ * null
55
+ * '' (empty string)
56
+ * [] (empty array)
57
+ * {} (empty object)
58
+ * new Map() (empty Map)
59
+ * new Set() (empty Set)
60
+ */
61
+ export function _isEmpty(obj: any): boolean {
62
+ if (obj === undefined || obj === null) return true
63
+
64
+ if (typeof obj === 'string' || Array.isArray(obj)) {
65
+ return obj.length === 0
66
+ }
67
+
68
+ if (obj instanceof Map || obj instanceof Set) {
69
+ return obj.size === 0
70
+ }
71
+
72
+ if (typeof obj === 'object') {
73
+ return Object.keys(obj).length === 0
74
+ }
75
+
76
+ return false
77
+ }
@@ -78,6 +78,9 @@ export const jsonSchema = {
78
78
  unixTimestamp() {
79
79
  return new JsonSchemaNumberBuilder().unixTimestamp()
80
80
  },
81
+ unixTimestamp2000() {
82
+ return new JsonSchemaNumberBuilder().unixTimestamp2000()
83
+ },
81
84
  // string types
82
85
  string() {
83
86
  return new JsonSchemaStringBuilder()
@@ -246,7 +249,9 @@ export class JsonSchemaNumberBuilder extends JsonSchemaAnyBuilder<number, JsonSc
246
249
  float = () => this.format('float')
247
250
  double = () => this.format('double')
248
251
  unixTimestamp = () => this.format('unixTimestamp')
252
+ unixTimestamp2000 = () => this.format('unixTimestamp2000')
249
253
  unixTimestampMillis = () => this.format('unixTimestampMillis')
254
+ unixTimestampMillis2000 = () => this.format('unixTimestampMillis2000')
250
255
  utcOffset = () => this.format('utcOffset')
251
256
  utcOffsetHours = () => this.format('utcOffsetHours')
252
257
  }
@@ -370,8 +375,8 @@ export class JsonSchemaObjectBuilder<T extends AnyObject> extends JsonSchemaAnyB
370
375
  ): JsonSchemaObjectBuilder<T & BaseDBEntity<ID>> {
371
376
  Object.assign(this.schema.properties, {
372
377
  id: { type: idType },
373
- created: { type: 'number', format: 'unixTimestamp' },
374
- updated: { type: 'number', format: 'unixTimestamp' },
378
+ created: { type: 'number', format: 'unixTimestamp2000' },
379
+ updated: { type: 'number', format: 'unixTimestamp2000' },
375
380
  })
376
381
 
377
382
  return this
@@ -3,12 +3,12 @@ import { jsonSchema } from './jsonSchemaBuilder'
3
3
 
4
4
  export const baseDBEntityJsonSchema = jsonSchema.object<BaseDBEntity>({
5
5
  id: jsonSchema.string().optional(),
6
- created: jsonSchema.unixTimestamp().optional(),
7
- updated: jsonSchema.unixTimestamp().optional(),
6
+ created: jsonSchema.unixTimestamp2000().optional(),
7
+ updated: jsonSchema.unixTimestamp2000().optional(),
8
8
  })
9
9
 
10
10
  export const savedDBEntityJsonSchema = jsonSchema.object<SavedDBEntity>({
11
11
  id: jsonSchema.string(),
12
- created: jsonSchema.unixTimestamp(),
13
- updated: jsonSchema.unixTimestamp(),
12
+ created: jsonSchema.unixTimestamp2000(),
13
+ updated: jsonSchema.unixTimestamp2000(),
14
14
  })
@@ -1,3 +1,4 @@
1
+ import { _isEmpty, _isObject } from '../is.util'
1
2
  import { PropertyPath } from '../lodash.types'
2
3
  import { AnyObject, ObjectMapper, ObjectPredicate, StringMap, ValueOf } from '../types'
3
4
 
@@ -190,55 +191,6 @@ export function _deepCopy<T>(o: T): T {
190
191
  return JSON.parse(JSON.stringify(o))
191
192
  }
192
193
 
193
- /**
194
- * Returns true if item is Object, not null and not Array.
195
- */
196
- export function _isObject(item: any): item is AnyObject {
197
- return (typeof item === 'object' && item !== null && !Array.isArray(item)) || false
198
- }
199
-
200
- export function _isPrimitive(v: any): v is null | undefined | number | boolean | string {
201
- return (
202
- v === null ||
203
- v === undefined ||
204
- typeof v === 'number' ||
205
- typeof v === 'boolean' ||
206
- typeof v === 'string'
207
- )
208
- }
209
-
210
- export function _isEmptyObject(obj: any): boolean {
211
- return obj && obj.constructor === Object && Object.keys(obj).length === 0
212
- }
213
-
214
- /**
215
- * Object is considered empty if it's one of:
216
- * undefined
217
- * null
218
- * '' (empty string)
219
- * [] (empty array)
220
- * {} (empty object)
221
- * new Map() (empty Map)
222
- * new Set() (empty Set)
223
- */
224
- export function _isEmpty(obj: any): boolean {
225
- if (obj === undefined || obj === null) return true
226
-
227
- if (typeof obj === 'string' || Array.isArray(obj)) {
228
- return obj.length === 0
229
- }
230
-
231
- if (obj instanceof Map || obj instanceof Set) {
232
- return obj.size === 0
233
- }
234
-
235
- if (typeof obj === 'object') {
236
- return Object.keys(obj).length === 0
237
- }
238
-
239
- return false
240
- }
241
-
242
194
  /**
243
195
  * Returns `undefined` if it's empty (according to `_isEmpty()` specification),
244
196
  * otherwise returns the original object.
@@ -1,4 +1,4 @@
1
- import { _isObject } from './object.util'
1
+ import { _isObject } from '..'
2
2
 
3
3
  /**
4
4
  * based on: https://github.com/IndigoUnited/js-deep-sort-object
package/src/types.ts CHANGED
@@ -213,6 +213,13 @@ export type IsoDateTimeString = string
213
213
  */
214
214
  export type UnixTimestampNumber = number
215
215
 
216
+ /**
217
+ * Interface explicitly states that the value is a "Unix timestamp in **milleseconds**" (not seconds)
218
+ *
219
+ * @example 1628945450000
220
+ */
221
+ export type UnixTimestampMillisNumber = number
222
+
216
223
  /**
217
224
  * @deprecated use UnixTimestampNumber
218
225
  */
@@ -253,3 +260,6 @@ export function _stringMapEntries<T>(m: StringMap<T>): [k: string, v: T][] {
253
260
  export function _objectKeys<T extends AnyObject>(obj: T): (keyof T)[] {
254
261
  return Object.keys(obj)
255
262
  }
263
+
264
+ export type NullishValue = null | undefined
265
+ export type FalsyValue = false | '' | 0 | null | undefined