Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!(NODE-4704): remove deprecated ObjectId methods #525

Merged
merged 5 commits into from
Nov 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions docs/upgrade-to-v5.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,16 @@ This library no longer polyfills [ES Map](https://developer.mozilla.org/en-US/do
### `Decimal128` `toObject()` mapper support removed

`Decimal128` can no longer have a `toObject()` method added on to its prototype for mapping to a custom value. This feature was undocumented and inconsistent with the rest of our BSON types. At this time there is no direct migration: cursors in the driver support transformations via `.map`, otherwise the `Decimal128` instances will require manual transformation. There is a plan to provide a better mechanism for consistently transforming BSON values tracked in [NODE-4680](https://jira.mongodb.org/browse/NODE-4680), please feel free to add a vote or comment with a use case to help us land the feature in the most useful form.

### Remove deprecated ObjectId methods

The following deprecated methods have been removed:

- `ObjectId.prototype.generate`
- Instead, generate a new ObjectId with the constructor: `new ObjectId()` or using the `static generate(time?: number)` method.
- `ObjectId.prototype.generationTime`
- Instead, use `static createFromTime()` and `getTimestamp()` to set and inspect these values on an `ObjectId()`
- `ObjectId.prototype.getInc`
- `ObjectId.prototype.get_inc`
- `ObjectId.get_inc`
- The `static getInc()` is private since invoking it increments the next `ObjectId` index, so invoking would impact the creation of subsequent ObjectIds.
41 changes: 3 additions & 38 deletions src/objectid.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BSONTypeError } from './error';
import { deprecate, isUint8Array, randomBytes } from './parser/utils';
import { isUint8Array, randomBytes } from './parser/utils';
import { BSONDataView, ByteUtils } from './utils/byte_utils';

// Regular expression that checks for hex value
Expand Down Expand Up @@ -33,7 +33,7 @@ export class ObjectId {
}

/** @internal */
static index = Math.floor(Math.random() * 0xffffff);
private static index = Math.floor(Math.random() * 0xffffff);
baileympearson marked this conversation as resolved.
Show resolved Hide resolved

static cacheHexString: boolean;

Expand Down Expand Up @@ -113,19 +113,6 @@ export class ObjectId {
}
}

/**
* The generation time of this ObjectId instance
* @deprecated Please use getTimestamp / createFromTime which returns an int32 epoch
*/
get generationTime(): number {
return BSONDataView.fromUint8Array(this.id).getUint32(0, false);
}

set generationTime(value: number) {
// Encode time into first 4 bytes
BSONDataView.fromUint8Array(this.id).setUint32(0, value, false);
}

/** Returns the ObjectId id as a 24 character hex string representation */
toHexString(): string {
if (ObjectId.cacheHexString && this.__id) {
Expand All @@ -143,11 +130,9 @@ export class ObjectId {

/**
* Update the ObjectId index
* @privateRemarks
* Used in generating new ObjectId's on the driver
* @internal
*/
static getInc(): number {
private static getInc(): number {
return (ObjectId.index = (ObjectId.index + 1) % 0xffffff);
}

Expand Down Expand Up @@ -330,23 +315,3 @@ export class ObjectId {
return `new ObjectId("${this.toHexString()}")`;
}
}

// Deprecated methods
Object.defineProperty(ObjectId.prototype, 'generate', {
value: deprecate(
(time: number) => ObjectId.generate(time),
'Please use the static `ObjectId.generate(time)` instead'
)
});

Object.defineProperty(ObjectId.prototype, 'getInc', {
value: deprecate(() => ObjectId.getInc(), 'Please use the static `ObjectId.getInc()` instead')
});

Object.defineProperty(ObjectId.prototype, 'get_inc', {
value: deprecate(() => ObjectId.getInc(), 'Please use the static `ObjectId.getInc()` instead')
});

Object.defineProperty(ObjectId, 'get_inc', {
value: deprecate(() => ObjectId.getInc(), 'Please use the static `ObjectId.getInc()` instead')
});
14 changes: 1 addition & 13 deletions src/parser/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ByteUtils } from '../utils/byte_utils';
import { getGlobal } from '../utils/global';

type RandomBytesFunction = (size: number) => Uint8Array;
declare let console: { warn(...message: unknown[]): void };

/**
* Normalizes our expected stringified form of a function across versions of node
Expand Down Expand Up @@ -107,16 +108,3 @@ export function isDate(d: unknown): d is Date {
export function isObjectLike(candidate: unknown): candidate is Record<string, unknown> {
return typeof candidate === 'object' && candidate !== null;
}

declare let console: { warn(...message: unknown[]): void };
export function deprecate<T extends Function>(fn: T, message: string): T {
let warned = false;
function deprecated(this: unknown, ...args: unknown[]) {
if (!warned) {
console.warn(message);
warned = true;
}
return fn.apply(this, args);
}
return deprecated as unknown as T;
}
32 changes: 22 additions & 10 deletions test/node/object_id_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,30 @@ const getSymbolFrom = require('./tools/utils').getSymbolFrom;
const isBufferOrUint8Array = require('./tools/utils').isBufferOrUint8Array;

describe('ObjectId', function () {
it('should correctly handle objectId timestamps', function (done) {
const a = ObjectId.createFromTime(1);
expect(Buffer.from([0, 0, 0, 1])).to.deep.equal(a.id.slice(0, 4));
expect(1000).to.equal(a.getTimestamp().getTime());
describe('static createFromTime()', () => {
it('creates an objectId with user defined value in the timestamp field', function () {
const a = ObjectId.createFromTime(1);
expect(a.id.slice(0, 4)).to.deep.equal(Buffer.from([0, 0, 0, 1]));
expect(a.getTimestamp()).to.deep.equal(new Date(1 * 1000));
expect(a.getTimestamp().getTime()).to.equal(1000);
});
});

const b = new ObjectId();
b.generationTime = 1;
expect(Buffer.from([0, 0, 0, 1])).to.deep.equal(b.id.slice(0, 4));
expect(1).to.equal(b.generationTime);
expect(1000).to.equal(b.getTimestamp().getTime());
describe('getTimestamp()', () => {
it('fetches the big endian int32 leading the Oid and create a Date instance', function () {
const a = new ObjectId('00000002' + '00'.repeat(8));
expect(a.id.slice(0, 4)).to.deep.equal(Buffer.from([0, 0, 0, 2]));
expect(Object.prototype.toString.call(a.getTimestamp())).to.equal('[object Date]');
expect(a.getTimestamp()).to.deep.equal(new Date(2 * 1000));
expect(a.getTimestamp().getTime()).to.equal(2000);
});
});

done();
it('creates an objectId with user defined value in the timestamp field', function () {
const a = ObjectId.createFromTime(1);
expect(a.id.slice(0, 4)).to.deep.equal(Buffer.from([0, 0, 0, 1]));
expect(a.getTimestamp()).to.deep.equal(new Date(1 * 1000));
expect(a.getTimestamp().getTime()).to.equal(1000);
});

it('should correctly create ObjectId from ObjectId', function () {
Expand Down