|
|
import { BSONError } from './error'; |
|
|
import type { Int32 } from './int_32'; |
|
|
import { Long } from './long'; |
|
|
|
|
|
|
|
|
export type TimestampOverrides = '_bsontype' | 'toExtendedJSON' | 'fromExtendedJSON' | 'inspect'; |
|
|
|
|
|
export type LongWithoutOverrides = new ( |
|
|
low: unknown, |
|
|
high?: number | boolean, |
|
|
unsigned?: boolean |
|
|
) => { |
|
|
[P in Exclude<keyof Long, TimestampOverrides>]: Long[P]; |
|
|
}; |
|
|
|
|
|
export const LongWithoutOverridesClass: LongWithoutOverrides = |
|
|
Long as unknown as LongWithoutOverrides; |
|
|
|
|
|
|
|
|
export interface TimestampExtended { |
|
|
$timestamp: { |
|
|
t: number; |
|
|
i: number; |
|
|
}; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export class Timestamp extends LongWithoutOverridesClass { |
|
|
get _bsontype(): 'Timestamp' { |
|
|
return 'Timestamp'; |
|
|
} |
|
|
|
|
|
static readonly MAX_VALUE = Long.MAX_UNSIGNED_VALUE; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
constructor(int: bigint); |
|
|
|
|
|
|
|
|
|
|
|
constructor(long: Long); |
|
|
|
|
|
|
|
|
|
|
|
constructor(value: { t: number; i: number }); |
|
|
constructor(low?: bigint | Long | { t: number | Int32; i: number | Int32 }) { |
|
|
if (low == null) { |
|
|
super(0, 0, true); |
|
|
} else if (typeof low === 'bigint') { |
|
|
super(low, true); |
|
|
} else if (Long.isLong(low)) { |
|
|
super(low.low, low.high, true); |
|
|
} else if (typeof low === 'object' && 't' in low && 'i' in low) { |
|
|
if (typeof low.t !== 'number' && (typeof low.t !== 'object' || low.t._bsontype !== 'Int32')) { |
|
|
throw new BSONError('Timestamp constructed from { t, i } must provide t as a number'); |
|
|
} |
|
|
if (typeof low.i !== 'number' && (typeof low.i !== 'object' || low.i._bsontype !== 'Int32')) { |
|
|
throw new BSONError('Timestamp constructed from { t, i } must provide i as a number'); |
|
|
} |
|
|
const t = Number(low.t); |
|
|
const i = Number(low.i); |
|
|
if (t < 0 || Number.isNaN(t)) { |
|
|
throw new BSONError('Timestamp constructed from { t, i } must provide a positive t'); |
|
|
} |
|
|
if (i < 0 || Number.isNaN(i)) { |
|
|
throw new BSONError('Timestamp constructed from { t, i } must provide a positive i'); |
|
|
} |
|
|
if (t > 0xffff_ffff) { |
|
|
throw new BSONError( |
|
|
'Timestamp constructed from { t, i } must provide t equal or less than uint32 max' |
|
|
); |
|
|
} |
|
|
if (i > 0xffff_ffff) { |
|
|
throw new BSONError( |
|
|
'Timestamp constructed from { t, i } must provide i equal or less than uint32 max' |
|
|
); |
|
|
} |
|
|
|
|
|
super(i, t, true); |
|
|
} else { |
|
|
throw new BSONError( |
|
|
'A Timestamp can only be constructed with: bigint, Long, or { t: number; i: number }' |
|
|
); |
|
|
} |
|
|
} |
|
|
|
|
|
toJSON(): { $timestamp: string } { |
|
|
return { |
|
|
$timestamp: this.toString() |
|
|
}; |
|
|
} |
|
|
|
|
|
|
|
|
static fromInt(value: number): Timestamp { |
|
|
return new Timestamp(Long.fromInt(value, true)); |
|
|
} |
|
|
|
|
|
|
|
|
static fromNumber(value: number): Timestamp { |
|
|
return new Timestamp(Long.fromNumber(value, true)); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static fromBits(lowBits: number, highBits: number): Timestamp { |
|
|
return new Timestamp({ i: lowBits, t: highBits }); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static fromString(str: string, optRadix: number): Timestamp { |
|
|
return new Timestamp(Long.fromString(str, true, optRadix)); |
|
|
} |
|
|
|
|
|
|
|
|
toExtendedJSON(): TimestampExtended { |
|
|
return { $timestamp: { t: this.high >>> 0, i: this.low >>> 0 } }; |
|
|
} |
|
|
|
|
|
|
|
|
static fromExtendedJSON(doc: TimestampExtended): Timestamp { |
|
|
|
|
|
const i = Long.isLong(doc.$timestamp.i) |
|
|
? doc.$timestamp.i.getLowBitsUnsigned() |
|
|
: doc.$timestamp.i; |
|
|
const t = Long.isLong(doc.$timestamp.t) |
|
|
? doc.$timestamp.t.getLowBitsUnsigned() |
|
|
: doc.$timestamp.t; |
|
|
return new Timestamp({ t, i }); |
|
|
} |
|
|
|
|
|
|
|
|
[Symbol.for('nodejs.util.inspect.custom')](): string { |
|
|
return this.inspect(); |
|
|
} |
|
|
|
|
|
inspect(): string { |
|
|
return `new Timestamp({ t: ${this.getHighBits()}, i: ${this.getLowBits()} })`; |
|
|
} |
|
|
} |
|
|
|