@naturalcycles/js-lib 14.258.0 → 14.259.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 { Iterable2 } from '../iter/iterable2';
2
- import type { Inclusiveness, IsoDateString, IsoDateTimeString, MonthId, SortDirection, UnixTimestampMillisNumber, UnixTimestampNumber } from '../types';
2
+ import type { Inclusiveness, IsoDateString, IsoDateTimeString, MonthId, SortDirection, UnixTimestamp, UnixTimestampMillis } from '../types';
3
3
  import { DateObject, ISODayOfWeek, LocalTime } from './localTime';
4
4
  export type LocalDateUnit = LocalDateUnitStrict | 'week';
5
5
  export type LocalDateUnitStrict = 'year' | 'month' | 'day';
@@ -142,11 +142,11 @@ export declare class LocalDate {
142
142
  /**
143
143
  * Returns unix timestamp of 00:00:00 of that date (in UTC, because unix timestamp always reflects UTC).
144
144
  */
145
- get unix(): UnixTimestampNumber;
145
+ get unix(): UnixTimestamp;
146
146
  /**
147
147
  * Same as .unix(), but in milliseconds.
148
148
  */
149
- get unixMillis(): UnixTimestampMillisNumber;
149
+ get unixMillis(): UnixTimestampMillis;
150
150
  toJSON(): IsoDateString;
151
151
  format(fmt: Intl.DateTimeFormat | LocalDateFormatter): string;
152
152
  }
@@ -1,4 +1,4 @@
1
- import type { Inclusiveness, IsoDateString, IsoDateTimeString, MonthId, NumberOfHours, NumberOfMinutes, SortDirection, UnixTimestampMillisNumber, UnixTimestampNumber } from '../types';
1
+ import type { Inclusiveness, IsoDateString, IsoDateTimeString, MonthId, NumberOfHours, NumberOfMinutes, SortDirection, UnixTimestamp, UnixTimestampMillis } from '../types';
2
2
  import { LocalDate } from './localDate';
3
3
  import { WallTime } from './wallTime';
4
4
  export type LocalTimeUnit = 'year' | 'month' | 'week' | 'day' | 'hour' | 'minute' | 'second';
@@ -11,7 +11,7 @@ export declare enum ISODayOfWeek {
11
11
  SATURDAY = 6,
12
12
  SUNDAY = 7
13
13
  }
14
- export type LocalTimeInput = LocalTime | Date | IsoDateTimeString | UnixTimestampNumber;
14
+ export type LocalTimeInput = LocalTime | Date | IsoDateTimeString | UnixTimestamp;
15
15
  export type LocalTimeInputNullable = LocalTimeInput | null | undefined;
16
16
  export type LocalTimeFormatter = (ld: LocalTime) => string;
17
17
  export type DateTimeObject = DateObject & TimeObject;
@@ -186,9 +186,9 @@ export declare class LocalTime {
186
186
  toFromNowString(now?: LocalTimeInput): string;
187
187
  toDate(): Date;
188
188
  clone(): LocalTime;
189
- get unix(): UnixTimestampNumber;
190
- get unixMillis(): UnixTimestampMillisNumber;
191
- valueOf(): UnixTimestampNumber;
189
+ get unix(): UnixTimestamp;
190
+ get unixMillis(): UnixTimestampMillis;
191
+ valueOf(): UnixTimestamp;
192
192
  toLocalDate(): LocalDate;
193
193
  /**
194
194
  * Returns e.g: `1984-06-21 17:56:21`
@@ -213,7 +213,7 @@ export declare class LocalTime {
213
213
  */
214
214
  toStringCompact(seconds?: boolean): string;
215
215
  toString(): string;
216
- toJSON(): UnixTimestampNumber;
216
+ toJSON(): UnixTimestamp;
217
217
  toMonthId(): MonthId;
218
218
  format(fmt: Intl.DateTimeFormat | LocalTimeFormatter): string;
219
219
  }
@@ -233,7 +233,7 @@ declare class LocalTimeFactory {
233
233
  Convenience function to return current Unix timestamp in seconds.
234
234
  Like Date.now(), but in seconds.
235
235
  */
236
- nowUnix(): UnixTimestampNumber;
236
+ nowUnix(): UnixTimestamp;
237
237
  /**
238
238
  * Create LocalTime from LocalTimeInput.
239
239
  * Input can already be a LocalTime - it is returned as-is in that case.
@@ -277,11 +277,11 @@ declare class LocalTimeFactory {
277
277
  isDateTimeObjectValid(o: DateTimeObject): boolean;
278
278
  isTimeObjectValid({ hour, minute, second }: TimeObject): boolean;
279
279
  fromDate(date: Date): LocalTime;
280
- fromUnix(ts: UnixTimestampNumber): LocalTime;
280
+ fromUnix(ts: UnixTimestamp): LocalTime;
281
281
  /**
282
282
  * Create LocalTime from unixTimestamp in milliseconds (not in seconds).
283
283
  */
284
- fromMillis(millis: UnixTimestampMillisNumber): LocalTime;
284
+ fromMillis(millis: UnixTimestampMillis): LocalTime;
285
285
  fromDateTimeObject(o: DateTimeObjectInput): LocalTime;
286
286
  private createDateFromDateTimeObject;
287
287
  /**
@@ -1,4 +1,4 @@
1
- import type { Inclusiveness, UnixTimestampNumber } from '../types';
1
+ import type { Inclusiveness, UnixTimestamp } from '../types';
2
2
  import { LocalTime, LocalTimeInput } from './localTime';
3
3
  export type TimeIntervalConfig = TimeInterval | TimeIntervalString;
4
4
  export type TimeIntervalString = string;
@@ -13,8 +13,8 @@ export declare class TimeInterval {
13
13
  private $end;
14
14
  private constructor();
15
15
  static of(start: LocalTimeInput, end: LocalTimeInput): TimeInterval;
16
- get start(): UnixTimestampNumber;
17
- get end(): UnixTimestampNumber;
16
+ get start(): UnixTimestamp;
17
+ get end(): UnixTimestamp;
18
18
  get startTime(): LocalTime;
19
19
  get endTime(): LocalTime;
20
20
  /**
@@ -1,4 +1,4 @@
1
- import type { UnixTimestampNumber } from '../types';
1
+ import type { UnixTimestamp } from '../types';
2
2
  import { MISS } from '../types';
3
3
  export type MemoSerializer = (args: any[]) => any;
4
4
  export declare const jsonMemoSerializer: MemoSerializer;
@@ -7,7 +7,7 @@ export interface MemoCacheOptions {
7
7
  * If set (and if it's implemented by the driver) - will set expiry TTL for each key of the batch.
8
8
  * E.g EXAT in Redis.
9
9
  */
10
- expireAt?: UnixTimestampNumber;
10
+ expireAt?: UnixTimestamp;
11
11
  }
12
12
  export interface MemoCache<KEY = any, VALUE = any> {
13
13
  has: (k: KEY) => boolean;
@@ -1,13 +1,13 @@
1
- import type { UnixTimestampNumber } from '../types';
1
+ import type { UnixTimestamp } from '../types';
2
2
  export interface BuildInfo {
3
3
  /**
4
4
  * Unix timestamp of when the build was made.
5
5
  */
6
- ts: UnixTimestampNumber;
6
+ ts: UnixTimestamp;
7
7
  /**
8
8
  * Unix timestamp of commit ("committer date", not "author date")
9
9
  */
10
- tsCommit: UnixTimestampNumber;
10
+ tsCommit: UnixTimestamp;
11
11
  repoName: string;
12
12
  branchName: string;
13
13
  /**
@@ -1,4 +1,5 @@
1
1
  import type { Class } from '../typeFest';
2
+ import type { UnixTimestamp } from '../types';
2
3
  import type { BackendErrorResponseObject, ErrorData, ErrorObject } from './error.model';
3
4
  /**
4
5
  * Evaluates the `condition` (casts it to Boolean).
@@ -44,3 +45,15 @@ export declare function _assertIsBackendErrorResponseObject<DATA_TYPE extends Er
44
45
  export declare function _assertIsString(v: any, message?: string): asserts v is string;
45
46
  export declare function _assertIsNumber(v: any, message?: string): asserts v is number;
46
47
  export declare function _assertTypeOf<T>(v: any, expectedType: string, message?: string): asserts v is T;
48
+ /**
49
+ * Casts an arbitrary number as UnixTimestamp.
50
+ * Right now does not perform any validation (unlike `asUnixTimestamp2000`),
51
+ * but only type casting.
52
+ */
53
+ export declare function asUnixTimestamp(n: number): UnixTimestamp;
54
+ /**
55
+ * Casts an arbitrary number as UnixTimestamp2000.
56
+ * Throws if the number is not inside 2000-01-01 and 2500-01-01 time interval,
57
+ * which would indicate a bug.
58
+ */
59
+ export declare function asUnixTimestamp2000(n: number): UnixTimestamp;
@@ -10,8 +10,11 @@ exports._assertIsBackendErrorResponseObject = _assertIsBackendErrorResponseObjec
10
10
  exports._assertIsString = _assertIsString;
11
11
  exports._assertIsNumber = _assertIsNumber;
12
12
  exports._assertTypeOf = _assertTypeOf;
13
+ exports.asUnixTimestamp = asUnixTimestamp;
14
+ exports.asUnixTimestamp2000 = asUnixTimestamp2000;
13
15
  const deepEquals_1 = require("../object/deepEquals");
14
16
  const stringify_1 = require("../string/stringify");
17
+ const zod_shared_schemas_1 = require("../zod/zod.shared.schemas");
15
18
  const error_util_1 = require("./error.util");
16
19
  /**
17
20
  * Evaluates the `condition` (casts it to Boolean).
@@ -110,3 +113,24 @@ function _assertTypeOf(v, expectedType, message) {
110
113
  throw new error_util_1.AssertionError(msg);
111
114
  }
112
115
  }
116
+ /**
117
+ * Casts an arbitrary number as UnixTimestamp.
118
+ * Right now does not perform any validation (unlike `asUnixTimestamp2000`),
119
+ * but only type casting.
120
+ */
121
+ function asUnixTimestamp(n) {
122
+ return n;
123
+ }
124
+ /**
125
+ * Casts an arbitrary number as UnixTimestamp2000.
126
+ * Throws if the number is not inside 2000-01-01 and 2500-01-01 time interval,
127
+ * which would indicate a bug.
128
+ */
129
+ function asUnixTimestamp2000(n) {
130
+ if (!n || n < zod_shared_schemas_1.TS_2000 || n > zod_shared_schemas_1.TS_2500) {
131
+ throw new error_util_1.AssertionError(`Number is not a valid UnixTimestamp2000: ${n}`, {
132
+ fingerprint: 'asUnixTimestamp2000',
133
+ });
134
+ }
135
+ return n;
136
+ }
@@ -3,7 +3,7 @@
3
3
  import type { ErrorData } from '../error/error.model';
4
4
  import type { CommonLogger } from '../log/commonLogger';
5
5
  import type { Promisable } from '../typeFest';
6
- import type { AnyObject, NumberOfMilliseconds, Reviver, UnixTimestampMillisNumber } from '../types';
6
+ import type { AnyObject, NumberOfMilliseconds, Reviver, UnixTimestampMillis } from '../types';
7
7
  import type { HttpMethod, HttpStatusFamily } from './http.model';
8
8
  export interface FetcherNormalizedCfg extends Required<FetcherCfg>, Omit<FetcherRequest, 'started' | 'fullUrl' | 'logRequest' | 'logRequestBody' | 'logResponse' | 'logResponseBody' | 'debug' | 'redirect' | 'credentials' | 'throwHttpErrors' | 'errorData'> {
9
9
  logger: CommonLogger;
@@ -114,7 +114,7 @@ export interface FetcherRequest extends Omit<FetcherOptions, 'method' | 'headers
114
114
  retry3xx: boolean;
115
115
  retry4xx: boolean;
116
116
  retry5xx: boolean;
117
- started: UnixTimestampMillisNumber;
117
+ started: UnixTimestampMillis;
118
118
  }
119
119
  export interface FetcherOptions {
120
120
  method?: HttpMethod;
@@ -1,3 +1,4 @@
1
+ import type { NumberOfMilliseconds, UnixTimestampMillis } from '../types';
1
2
  /**
2
3
  * using _ = blockTimer()
3
4
  * // will log "took 1.234 sec" on dispose
@@ -11,7 +12,7 @@ export declare function _blockTimer(name?: string): Disposable;
11
12
  /**
12
13
  * Returns time passed since `from` until `until` (default to Date.now())
13
14
  */
14
- export declare function _since(from: number, until?: number): string;
15
+ export declare function _since(from: UnixTimestampMillis, until?: UnixTimestampMillis): string;
15
16
  /**
16
17
  * Returns, e.g:
17
18
  * 125 ms
@@ -21,4 +22,4 @@ export declare function _since(from: number, until?: number): string;
21
22
  * 59m2s
22
23
  * 1h3m12s
23
24
  */
24
- export declare function _ms(millis: number): string;
25
+ export declare function _ms(millis: NumberOfMilliseconds): string;
package/dist/types.d.ts CHANGED
@@ -54,24 +54,24 @@ export type BaseDBEntity = {
54
54
  /**
55
55
  * unixTimestamp of when the entity was first created (in the DB).
56
56
  */
57
- created: UnixTimestampNumber;
57
+ created: UnixTimestamp;
58
58
  /**
59
59
  * unixTimestamp of when the entity was last updated (in the DB).
60
60
  */
61
- updated: UnixTimestampNumber;
61
+ updated: UnixTimestamp;
62
62
  };
63
63
  export type Saved<T> = T & {
64
64
  id: string;
65
- created: UnixTimestampNumber;
66
- updated: UnixTimestampNumber;
65
+ created: UnixTimestamp;
66
+ updated: UnixTimestamp;
67
67
  };
68
68
  export type SavedId<T> = T & {
69
69
  id: string;
70
70
  };
71
71
  export type Unsaved<T> = Omit<T, 'id' | 'created' | 'updated'> & {
72
72
  id?: string;
73
- created?: UnixTimestampNumber;
74
- updated?: UnixTimestampNumber;
73
+ created?: UnixTimestamp;
74
+ updated?: UnixTimestamp;
75
75
  };
76
76
  export type UnsavedId<T> = Omit<T, 'id'> & {
77
77
  id?: string;
@@ -191,17 +191,19 @@ export type IsoDateTimeString = string;
191
191
  */
192
192
  export type MonthId = string;
193
193
  /**
194
- * Interface explicitly states that the value is a Unix timestamp (in seconds).
194
+ * Branded UnixTimestamp in seconds.
195
+ * Extends (compatible with) `number`.
195
196
  *
196
197
  * @example 1628945450
197
198
  */
198
- export type UnixTimestampNumber = number;
199
+ export type UnixTimestamp = Branded<number, 'UnixTimestamp'>;
199
200
  /**
200
- * Interface explicitly states that the value is a "Unix timestamp in **milleseconds**" (not seconds)
201
+ * Branded UnixTimestamp in milliseconds (not seconds).
202
+ * Extends (compatible with) `number`.
201
203
  *
202
204
  * @example 1628945450000
203
205
  */
204
- export type UnixTimestampMillisNumber = number;
206
+ export type UnixTimestampMillis = Branded<number, 'UnixTimestampMillis'>;
205
207
  export type NumberOfHours = number;
206
208
  export type NumberOfMinutes = number;
207
209
  export type NumberOfSeconds = number;
@@ -1,5 +1,6 @@
1
1
  import { _deepEquals } from '../object/deepEquals';
2
2
  import { _stringify } from '../string/stringify';
3
+ import { TS_2000, TS_2500 } from '../zod/zod.shared.schemas';
3
4
  import { _isBackendErrorResponseObject, _isErrorObject, AssertionError } from './error.util';
4
5
  /**
5
6
  * Evaluates the `condition` (casts it to Boolean).
@@ -98,3 +99,24 @@ export function _assertTypeOf(v, expectedType, message) {
98
99
  throw new AssertionError(msg);
99
100
  }
100
101
  }
102
+ /**
103
+ * Casts an arbitrary number as UnixTimestamp.
104
+ * Right now does not perform any validation (unlike `asUnixTimestamp2000`),
105
+ * but only type casting.
106
+ */
107
+ export function asUnixTimestamp(n) {
108
+ return n;
109
+ }
110
+ /**
111
+ * Casts an arbitrary number as UnixTimestamp2000.
112
+ * Throws if the number is not inside 2000-01-01 and 2500-01-01 time interval,
113
+ * which would indicate a bug.
114
+ */
115
+ export function asUnixTimestamp2000(n) {
116
+ if (!n || n < TS_2000 || n > TS_2500) {
117
+ throw new AssertionError(`Number is not a valid UnixTimestamp2000: ${n}`, {
118
+ fingerprint: 'asUnixTimestamp2000',
119
+ });
120
+ }
121
+ return n;
122
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
- "version": "14.258.0",
3
+ "version": "14.259.0",
4
4
  "scripts": {
5
5
  "prepare": "husky",
6
6
  "build": "dev-lib build-esm-cjs",
@@ -6,8 +6,8 @@ import type {
6
6
  IsoDateTimeString,
7
7
  MonthId,
8
8
  SortDirection,
9
- UnixTimestampMillisNumber,
10
- UnixTimestampNumber,
9
+ UnixTimestamp,
10
+ UnixTimestampMillis,
11
11
  } from '../types'
12
12
  import { DateObject, ISODayOfWeek, LocalTime, localTime } from './localTime'
13
13
 
@@ -491,15 +491,15 @@ export class LocalDate {
491
491
  /**
492
492
  * Returns unix timestamp of 00:00:00 of that date (in UTC, because unix timestamp always reflects UTC).
493
493
  */
494
- get unix(): UnixTimestampNumber {
495
- return Math.floor(this.toDate().valueOf() / 1000)
494
+ get unix(): UnixTimestamp {
495
+ return Math.floor(this.toDate().valueOf() / 1000) as UnixTimestamp
496
496
  }
497
497
 
498
498
  /**
499
499
  * Same as .unix(), but in milliseconds.
500
500
  */
501
- get unixMillis(): UnixTimestampMillisNumber {
502
- return this.toDate().valueOf()
501
+ get unixMillis(): UnixTimestampMillis {
502
+ return this.toDate().valueOf() as UnixTimestampMillis
503
503
  }
504
504
 
505
505
  toJSON(): IsoDateString {
@@ -8,8 +8,8 @@ import type {
8
8
  NumberOfHours,
9
9
  NumberOfMinutes,
10
10
  SortDirection,
11
- UnixTimestampMillisNumber,
12
- UnixTimestampNumber,
11
+ UnixTimestamp,
12
+ UnixTimestampMillis,
13
13
  } from '../types'
14
14
  import { LocalDate, localDate } from './localDate'
15
15
  import { WallTime } from './wallTime'
@@ -26,7 +26,7 @@ export enum ISODayOfWeek {
26
26
  SUNDAY = 7,
27
27
  }
28
28
 
29
- export type LocalTimeInput = LocalTime | Date | IsoDateTimeString | UnixTimestampNumber
29
+ export type LocalTimeInput = LocalTime | Date | IsoDateTimeString | UnixTimestamp
30
30
  export type LocalTimeInputNullable = LocalTimeInput | null | undefined
31
31
  export type LocalTimeFormatter = (ld: LocalTime) => string
32
32
 
@@ -638,16 +638,16 @@ export class LocalTime {
638
638
  return new LocalTime(new Date(this.$date))
639
639
  }
640
640
 
641
- get unix(): UnixTimestampNumber {
642
- return Math.floor(this.$date.valueOf() / 1000)
641
+ get unix(): UnixTimestamp {
642
+ return Math.floor(this.$date.valueOf() / 1000) as UnixTimestamp
643
643
  }
644
644
 
645
- get unixMillis(): UnixTimestampMillisNumber {
646
- return this.$date.valueOf()
645
+ get unixMillis(): UnixTimestampMillis {
646
+ return this.$date.valueOf() as UnixTimestampMillis
647
647
  }
648
648
 
649
- valueOf(): UnixTimestampNumber {
650
- return Math.floor(this.$date.valueOf() / 1000)
649
+ valueOf(): UnixTimestamp {
650
+ return Math.floor(this.$date.valueOf() / 1000) as UnixTimestamp
651
651
  }
652
652
 
653
653
  toLocalDate(): LocalDate {
@@ -730,7 +730,7 @@ export class LocalTime {
730
730
  return this.toISODateTime()
731
731
  }
732
732
 
733
- toJSON(): UnixTimestampNumber {
733
+ toJSON(): UnixTimestamp {
734
734
  return this.unix
735
735
  }
736
736
 
@@ -772,8 +772,8 @@ class LocalTimeFactory {
772
772
  Convenience function to return current Unix timestamp in seconds.
773
773
  Like Date.now(), but in seconds.
774
774
  */
775
- nowUnix(): UnixTimestampNumber {
776
- return Math.floor(Date.now() / 1000)
775
+ nowUnix(): UnixTimestamp {
776
+ return Math.floor(Date.now() / 1000) as UnixTimestamp
777
777
  }
778
778
 
779
779
  /**
@@ -925,14 +925,14 @@ class LocalTimeFactory {
925
925
  return new LocalTime(date)
926
926
  }
927
927
 
928
- fromUnix(ts: UnixTimestampNumber): LocalTime {
928
+ fromUnix(ts: UnixTimestamp): LocalTime {
929
929
  return new LocalTime(new Date(ts * 1000))
930
930
  }
931
931
 
932
932
  /**
933
933
  * Create LocalTime from unixTimestamp in milliseconds (not in seconds).
934
934
  */
935
- fromMillis(millis: UnixTimestampMillisNumber): LocalTime {
935
+ fromMillis(millis: UnixTimestampMillis): LocalTime {
936
936
  return new LocalTime(new Date(millis))
937
937
  }
938
938
 
@@ -1,4 +1,4 @@
1
- import type { Inclusiveness, UnixTimestampNumber } from '../types'
1
+ import type { Inclusiveness, UnixTimestamp } from '../types'
2
2
  import { LocalTime, localTime, LocalTimeInput } from './localTime'
3
3
 
4
4
  export type TimeIntervalConfig = TimeInterval | TimeIntervalString
@@ -12,19 +12,19 @@ export type TimeIntervalString = string
12
12
  */
13
13
  export class TimeInterval {
14
14
  private constructor(
15
- private $start: UnixTimestampNumber,
16
- private $end: UnixTimestampNumber,
15
+ private $start: UnixTimestamp,
16
+ private $end: UnixTimestamp,
17
17
  ) {}
18
18
 
19
19
  static of(start: LocalTimeInput, end: LocalTimeInput): TimeInterval {
20
20
  return new TimeInterval(localTime.fromInput(start).unix, localTime.fromInput(end).unix)
21
21
  }
22
22
 
23
- get start(): UnixTimestampNumber {
23
+ get start(): UnixTimestamp {
24
24
  return this.$start
25
25
  }
26
26
 
27
- get end(): UnixTimestampNumber {
27
+ get end(): UnixTimestamp {
28
28
  return this.$end
29
29
  }
30
30
 
@@ -42,7 +42,7 @@ export class TimeInterval {
42
42
  static parse(d: TimeIntervalConfig): TimeInterval {
43
43
  if (d instanceof TimeInterval) return d
44
44
 
45
- const [start, end] = d.split('/').map(Number)
45
+ const [start, end] = d.split('/').map(Number) as UnixTimestamp[]
46
46
 
47
47
  if (!end || !start) {
48
48
  throw new Error(`Cannot parse "${d}" into TimeInterval`)
@@ -1,6 +1,6 @@
1
1
  import { _isPrimitive } from '../is.util'
2
2
  import { pDelay } from '../promise/pDelay'
3
- import type { UnixTimestampNumber } from '../types'
3
+ import type { UnixTimestamp } from '../types'
4
4
  import { MISS } from '../types'
5
5
 
6
6
  export type MemoSerializer = (args: any[]) => any
@@ -16,7 +16,7 @@ export interface MemoCacheOptions {
16
16
  * If set (and if it's implemented by the driver) - will set expiry TTL for each key of the batch.
17
17
  * E.g EXAT in Redis.
18
18
  */
19
- expireAt?: UnixTimestampNumber
19
+ expireAt?: UnixTimestamp
20
20
  }
21
21
 
22
22
  export interface MemoCache<KEY = any, VALUE = any> {
@@ -1,16 +1,16 @@
1
1
  import { localTime } from '../datetime/localTime'
2
- import type { UnixTimestampNumber } from '../types'
2
+ import type { UnixTimestamp } from '../types'
3
3
 
4
4
  export interface BuildInfo {
5
5
  /**
6
6
  * Unix timestamp of when the build was made.
7
7
  */
8
- ts: UnixTimestampNumber
8
+ ts: UnixTimestamp
9
9
 
10
10
  /**
11
11
  * Unix timestamp of commit ("committer date", not "author date")
12
12
  */
13
- tsCommit: UnixTimestampNumber
13
+ tsCommit: UnixTimestamp
14
14
 
15
15
  repoName: string
16
16
  branchName: string
@@ -1,6 +1,8 @@
1
1
  import { _deepEquals } from '../object/deepEquals'
2
2
  import { _stringify } from '../string/stringify'
3
3
  import type { Class } from '../typeFest'
4
+ import type { UnixTimestamp } from '../types'
5
+ import { TS_2000, TS_2500 } from '../zod/zod.shared.schemas'
4
6
  import type { BackendErrorResponseObject, ErrorData, ErrorObject } from './error.model'
5
7
  import { _isBackendErrorResponseObject, _isErrorObject, AssertionError } from './error.util'
6
8
 
@@ -141,3 +143,26 @@ export function _assertTypeOf<T>(v: any, expectedType: string, message?: string)
141
143
  throw new AssertionError(msg)
142
144
  }
143
145
  }
146
+
147
+ /**
148
+ * Casts an arbitrary number as UnixTimestamp.
149
+ * Right now does not perform any validation (unlike `asUnixTimestamp2000`),
150
+ * but only type casting.
151
+ */
152
+ export function asUnixTimestamp(n: number): UnixTimestamp {
153
+ return n as UnixTimestamp
154
+ }
155
+
156
+ /**
157
+ * Casts an arbitrary number as UnixTimestamp2000.
158
+ * Throws if the number is not inside 2000-01-01 and 2500-01-01 time interval,
159
+ * which would indicate a bug.
160
+ */
161
+ export function asUnixTimestamp2000(n: number): UnixTimestamp {
162
+ if (!n || n < TS_2000 || n > TS_2500) {
163
+ throw new AssertionError(`Number is not a valid UnixTimestamp2000: ${n}`, {
164
+ fingerprint: 'asUnixTimestamp2000',
165
+ })
166
+ }
167
+ return n as UnixTimestamp
168
+ }
@@ -1,4 +1,4 @@
1
- import type { CommonLogger } from '../index'
1
+ import type { CommonLogger, UnixTimestampMillis } from '../index'
2
2
  import { _anyToError, _since } from '../index'
3
3
  import type { AnyFunction } from '../types'
4
4
 
@@ -39,7 +39,7 @@ export function _tryCatch<T extends AnyFunction>(fn: T, opt: TryCatchOptions = {
39
39
  const fname = fn.name || 'anonymous'
40
40
 
41
41
  return async function (this: any, ...args: any[]) {
42
- const started = Date.now()
42
+ const started = Date.now() as UnixTimestampMillis
43
43
 
44
44
  try {
45
45
  const r = await fn.apply(this, args)
@@ -4,7 +4,7 @@
4
4
  import type { ErrorData } from '../error/error.model'
5
5
  import type { CommonLogger } from '../log/commonLogger'
6
6
  import type { Promisable } from '../typeFest'
7
- import type { AnyObject, NumberOfMilliseconds, Reviver, UnixTimestampMillisNumber } from '../types'
7
+ import type { AnyObject, NumberOfMilliseconds, Reviver, UnixTimestampMillis } from '../types'
8
8
  import type { HttpMethod, HttpStatusFamily } from './http.model'
9
9
 
10
10
  export interface FetcherNormalizedCfg
@@ -149,7 +149,7 @@ export interface FetcherRequest
149
149
  retry3xx: boolean
150
150
  retry4xx: boolean
151
151
  retry5xx: boolean
152
- started: UnixTimestampMillisNumber
152
+ started: UnixTimestampMillis
153
153
  }
154
154
 
155
155
  export interface FetcherOptions {
@@ -28,7 +28,7 @@ import { pTimeout } from '../promise/pTimeout'
28
28
  import { _jsonParse, _jsonParseIfPossible } from '../string/json.util'
29
29
  import { _stringify } from '../string/stringify'
30
30
  import { _ms, _since } from '../time/time.util'
31
- import { ErrorDataTuple, NumberOfMilliseconds } from '../types'
31
+ import { ErrorDataTuple, NumberOfMilliseconds, UnixTimestampMillis } from '../types'
32
32
  import type {
33
33
  FetcherAfterResponseHook,
34
34
  FetcherBeforeRequestHook,
@@ -262,7 +262,7 @@ export class Fetcher {
262
262
  } as FetcherResponse<any>
263
263
 
264
264
  while (!res.retryStatus.retryStopped) {
265
- req.started = Date.now()
265
+ req.started = Date.now() as UnixTimestampMillis
266
266
 
267
267
  // setup timeout
268
268
  let timeoutId: number | undefined
@@ -708,7 +708,7 @@ export class Fetcher {
708
708
  'throwHttpErrors',
709
709
  'errorData',
710
710
  ]),
711
- started: Date.now(),
711
+ started: Date.now() as UnixTimestampMillis,
712
712
  ..._omit(opt, ['method', 'headers', 'credentials']),
713
713
  inputUrl: opt.url || '',
714
714
  fullUrl: opt.url || '',
@@ -1,4 +1,4 @@
1
- import type { AnyFunction, CommonLogger, ErrorData } from '..'
1
+ import type { AnyFunction, CommonLogger, ErrorData, UnixTimestampMillis } from '..'
2
2
  import { _errorDataAppend, _since, pDelay, pTimeout } from '..'
3
3
 
4
4
  export interface PRetryOptions {
@@ -129,7 +129,7 @@ export async function pRetry<T>(
129
129
  let attempt = 0
130
130
 
131
131
  while (true) {
132
- const started = Date.now()
132
+ const started = Date.now() as UnixTimestampMillis
133
133
 
134
134
  try {
135
135
  attempt++
@@ -1,3 +1,5 @@
1
+ import type { NumberOfMilliseconds, UnixTimestampMillis } from '../types'
2
+
1
3
  /**
2
4
  * using _ = blockTimer()
3
5
  * // will log "took 1.234 sec" on dispose
@@ -8,7 +10,7 @@
8
10
  * @experimental
9
11
  */
10
12
  export function _blockTimer(name?: string): Disposable {
11
- const started = Date.now()
13
+ const started = Date.now() as UnixTimestampMillis
12
14
  return {
13
15
  [Symbol.dispose](): void {
14
16
  console.log(`${name ? name + ' ' : ''}took ${_since(started)}`)
@@ -19,7 +21,10 @@ export function _blockTimer(name?: string): Disposable {
19
21
  /**
20
22
  * Returns time passed since `from` until `until` (default to Date.now())
21
23
  */
22
- export function _since(from: number, until = Date.now()): string {
24
+ export function _since(
25
+ from: UnixTimestampMillis,
26
+ until: UnixTimestampMillis = Date.now() as UnixTimestampMillis,
27
+ ): string {
23
28
  return _ms(until - from)
24
29
  }
25
30
 
@@ -32,7 +37,7 @@ export function _since(from: number, until = Date.now()): string {
32
37
  * 59m2s
33
38
  * 1h3m12s
34
39
  */
35
- export function _ms(millis: number): string {
40
+ export function _ms(millis: NumberOfMilliseconds): string {
36
41
  // <1 sec
37
42
  if (millis < 1000) return `${Math.round(millis)} ms`
38
43
 
package/src/types.ts CHANGED
@@ -70,18 +70,18 @@ export type BaseDBEntity = {
70
70
  /**
71
71
  * unixTimestamp of when the entity was first created (in the DB).
72
72
  */
73
- created: UnixTimestampNumber
73
+ created: UnixTimestamp
74
74
 
75
75
  /**
76
76
  * unixTimestamp of when the entity was last updated (in the DB).
77
77
  */
78
- updated: UnixTimestampNumber
78
+ updated: UnixTimestamp
79
79
  }
80
80
 
81
81
  export type Saved<T> = T & {
82
82
  id: string
83
- created: UnixTimestampNumber
84
- updated: UnixTimestampNumber
83
+ created: UnixTimestamp
84
+ updated: UnixTimestamp
85
85
  }
86
86
 
87
87
  export type SavedId<T> = T & {
@@ -90,8 +90,8 @@ export type SavedId<T> = T & {
90
90
 
91
91
  export type Unsaved<T> = Omit<T, 'id' | 'created' | 'updated'> & {
92
92
  id?: string
93
- created?: UnixTimestampNumber
94
- updated?: UnixTimestampNumber
93
+ created?: UnixTimestamp
94
+ updated?: UnixTimestamp
95
95
  }
96
96
 
97
97
  export type UnsavedId<T> = Omit<T, 'id'> & {
@@ -249,18 +249,20 @@ export type IsoDateTimeString = string
249
249
  export type MonthId = string
250
250
 
251
251
  /**
252
- * Interface explicitly states that the value is a Unix timestamp (in seconds).
252
+ * Branded UnixTimestamp in seconds.
253
+ * Extends (compatible with) `number`.
253
254
  *
254
255
  * @example 1628945450
255
256
  */
256
- export type UnixTimestampNumber = number
257
+ export type UnixTimestamp = Branded<number, 'UnixTimestamp'>
257
258
 
258
259
  /**
259
- * Interface explicitly states that the value is a "Unix timestamp in **milleseconds**" (not seconds)
260
+ * Branded UnixTimestamp in milliseconds (not seconds).
261
+ * Extends (compatible with) `number`.
260
262
  *
261
263
  * @example 1628945450000
262
264
  */
263
- export type UnixTimestampMillisNumber = number
265
+ export type UnixTimestampMillis = Branded<number, 'UnixTimestampMillis'>
264
266
 
265
267
  export type NumberOfHours = number
266
268
  export type NumberOfMinutes = number