Skip to content

Commit 0298dd8

Browse files
authored
feat(NODE-3504): add unambiguous Timestamp() constructor overload (#449)
1 parent d1d8566 commit 0298dd8

File tree

3 files changed

+31
-9
lines changed

3 files changed

+31
-9
lines changed

src/timestamp.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { Long } from './long';
2+
import { isObjectLike } from './parser/utils';
23

34
/** @public */
45
export type TimestampOverrides = '_bsontype' | 'toExtendedJSON' | 'fromExtendedJSON' | 'inspect';
56
/** @public */
6-
export type LongWithoutOverrides = new (low: number | Long, high?: number, unsigned?: boolean) => {
7+
export type LongWithoutOverrides = new (low: unknown, high?: number, unsigned?: boolean) => {
78
[P in Exclude<keyof Long, TimestampOverrides>]: Long[P];
89
};
910
/** @public */
@@ -27,20 +28,26 @@ export class Timestamp extends LongWithoutOverridesClass {
2728
/**
2829
* @param low - A 64-bit Long representing the Timestamp.
2930
*/
30-
constructor(low: Long);
31+
constructor(long: Long);
32+
/**
33+
* @param value - A pair of two values indicating timestamp and increment.
34+
*/
35+
constructor(value: { t: number; i: number });
3136
/**
3237
* @param low - the low (signed) 32 bits of the Timestamp.
3338
* @param high - the high (signed) 32 bits of the Timestamp.
39+
* @deprecated Please use `Timestamp({ t: high, i: low })` or `Timestamp(Long(low, high))` instead.
3440
*/
35-
constructor(low: Long);
3641
constructor(low: number, high: number);
37-
constructor(low: number | Long, high?: number) {
42+
constructor(low: number | Long | { t: number; i: number }, high?: number) {
3843
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
3944
///@ts-expect-error
4045
if (!(this instanceof Timestamp)) return new Timestamp(low, high);
4146

4247
if (Long.isLong(low)) {
4348
super(low.low, low.high, true);
49+
} else if (isObjectLike(low) && typeof low.t !== 'undefined' && typeof low.i !== 'undefined') {
50+
super(low.i, low.t, true);
4451
} else {
4552
super(low, high, true);
4653
}
@@ -95,7 +102,7 @@ export class Timestamp extends LongWithoutOverridesClass {
95102

96103
/** @internal */
97104
static fromExtendedJSON(doc: TimestampExtended): Timestamp {
98-
return new Timestamp(doc.$timestamp.i, doc.$timestamp.t);
105+
return new Timestamp(doc.$timestamp);
99106
}
100107

101108
/** @internal */
@@ -104,6 +111,6 @@ export class Timestamp extends LongWithoutOverridesClass {
104111
}
105112

106113
inspect(): string {
107-
return `new Timestamp(${this.getLowBits().toString()}, ${this.getHighBits().toString()})`;
114+
return `new Timestamp({ t: ${this.getHighBits()}, i: ${this.getLowBits()} })`;
108115
}
109116
}

test/node/bson_test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2120,8 +2120,8 @@ describe('BSON', function () {
21202120
* @ignore
21212121
*/
21222122
it('Timestamp', function () {
2123-
const timestamp = new Timestamp(1, 100);
2124-
expect(inspect(timestamp)).to.equal('new Timestamp(1, 100)');
2123+
const timestamp = new Timestamp({ t: 100, i: 1 });
2124+
expect(inspect(timestamp)).to.equal('new Timestamp({ t: 100, i: 1 })');
21252125
});
21262126
});
21272127
});

test/node/timestamp_tests.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ describe('Timestamp', function () {
1515
new BSON.Timestamp(-1, -1),
1616
new BSON.Timestamp(new BSON.Timestamp(0xffffffff, 0xffffffff)),
1717
new BSON.Timestamp(new BSON.Long(0xffffffff, 0xfffffffff, false)),
18-
new BSON.Timestamp(new BSON.Long(0xffffffff, 0xfffffffff, true))
18+
new BSON.Timestamp(new BSON.Long(0xffffffff, 0xfffffffff, true)),
19+
new BSON.Timestamp({ t: 0xffffffff, i: 0xfffffffff }),
20+
new BSON.Timestamp({ t: -1, i: -1 }),
21+
new BSON.Timestamp({ t: new BSON.Int32(0xffffffff), i: new BSON.Int32(0xffffffff) })
1922
].forEach(timestamp => {
2023
expect(timestamp).to.have.property('unsigned', true);
2124
});
@@ -29,4 +32,16 @@ describe('Timestamp', function () {
2932
$timestamp: { t: 4294967295, i: 4294967295 }
3033
});
3134
});
35+
36+
it('should accept a { t, i } object as constructor input', function () {
37+
const input = { t: 89, i: 144 };
38+
const timestamp = new BSON.Timestamp(input);
39+
expect(timestamp.toExtendedJSON()).to.deep.equal({ $timestamp: input });
40+
});
41+
42+
it('should accept a { t, i } object as constructor input and coerce to integer', function () {
43+
const input = { t: new BSON.Int32(89), i: new BSON.Int32(144) };
44+
const timestamp = new BSON.Timestamp(input);
45+
expect(timestamp.toExtendedJSON()).to.deep.equal({ $timestamp: { t: 89, i: 144 } });
46+
});
3247
});

0 commit comments

Comments
 (0)