diff --git a/src/timestamp.ts b/src/timestamp.ts index 098420d4..e6eb470f 100644 --- a/src/timestamp.ts +++ b/src/timestamp.ts @@ -1,9 +1,10 @@ import { Long } from './long'; +import { isObjectLike } from './parser/utils'; /** @public */ export type TimestampOverrides = '_bsontype' | 'toExtendedJSON' | 'fromExtendedJSON' | 'inspect'; /** @public */ -export type LongWithoutOverrides = new (low: number | Long, high?: number, unsigned?: boolean) => { +export type LongWithoutOverrides = new (low: unknown, high?: number, unsigned?: boolean) => { [P in Exclude]: Long[P]; }; /** @public */ @@ -27,20 +28,26 @@ export class Timestamp extends LongWithoutOverridesClass { /** * @param low - A 64-bit Long representing the Timestamp. */ - constructor(low: Long); + constructor(long: Long); + /** + * @param value - A pair of two values indicating timestamp and increment. + */ + constructor(value: { t: number; i: number }); /** * @param low - the low (signed) 32 bits of the Timestamp. * @param high - the high (signed) 32 bits of the Timestamp. + * @deprecated Please use `Timestamp({ t: high, i: low })` or `Timestamp(Long(low, high))` instead. */ - constructor(low: Long); constructor(low: number, high: number); - constructor(low: number | Long, high?: number) { + constructor(low: number | Long | { t: number; i: number }, high?: number) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment ///@ts-expect-error if (!(this instanceof Timestamp)) return new Timestamp(low, high); if (Long.isLong(low)) { super(low.low, low.high, true); + } else if (isObjectLike(low) && typeof low.t !== 'undefined' && typeof low.i !== 'undefined') { + super(low.i, low.t, true); } else { super(low, high, true); } @@ -95,7 +102,7 @@ export class Timestamp extends LongWithoutOverridesClass { /** @internal */ static fromExtendedJSON(doc: TimestampExtended): Timestamp { - return new Timestamp(doc.$timestamp.i, doc.$timestamp.t); + return new Timestamp(doc.$timestamp); } /** @internal */ @@ -104,6 +111,6 @@ export class Timestamp extends LongWithoutOverridesClass { } inspect(): string { - return `new Timestamp(${this.getLowBits().toString()}, ${this.getHighBits().toString()})`; + return `new Timestamp({ t: ${this.getHighBits()}, i: ${this.getLowBits()} })`; } } diff --git a/test/node/bson_test.js b/test/node/bson_test.js index b5541da6..6059d6dc 100644 --- a/test/node/bson_test.js +++ b/test/node/bson_test.js @@ -2120,8 +2120,8 @@ describe('BSON', function () { * @ignore */ it('Timestamp', function () { - const timestamp = new Timestamp(1, 100); - expect(inspect(timestamp)).to.equal('new Timestamp(1, 100)'); + const timestamp = new Timestamp({ t: 100, i: 1 }); + expect(inspect(timestamp)).to.equal('new Timestamp({ t: 100, i: 1 })'); }); }); }); diff --git a/test/node/timestamp_tests.js b/test/node/timestamp_tests.js index 136cf06f..7abfc31b 100644 --- a/test/node/timestamp_tests.js +++ b/test/node/timestamp_tests.js @@ -15,7 +15,10 @@ describe('Timestamp', function () { new BSON.Timestamp(-1, -1), new BSON.Timestamp(new BSON.Timestamp(0xffffffff, 0xffffffff)), new BSON.Timestamp(new BSON.Long(0xffffffff, 0xfffffffff, false)), - new BSON.Timestamp(new BSON.Long(0xffffffff, 0xfffffffff, true)) + new BSON.Timestamp(new BSON.Long(0xffffffff, 0xfffffffff, true)), + new BSON.Timestamp({ t: 0xffffffff, i: 0xfffffffff }), + new BSON.Timestamp({ t: -1, i: -1 }), + new BSON.Timestamp({ t: new BSON.Int32(0xffffffff), i: new BSON.Int32(0xffffffff) }) ].forEach(timestamp => { expect(timestamp).to.have.property('unsigned', true); }); @@ -29,4 +32,16 @@ describe('Timestamp', function () { $timestamp: { t: 4294967295, i: 4294967295 } }); }); + + it('should accept a { t, i } object as constructor input', function () { + const input = { t: 89, i: 144 }; + const timestamp = new BSON.Timestamp(input); + expect(timestamp.toExtendedJSON()).to.deep.equal({ $timestamp: input }); + }); + + it('should accept a { t, i } object as constructor input and coerce to integer', function () { + const input = { t: new BSON.Int32(89), i: new BSON.Int32(144) }; + const timestamp = new BSON.Timestamp(input); + expect(timestamp.toExtendedJSON()).to.deep.equal({ $timestamp: { t: 89, i: 144 } }); + }); });