Skip to content

Commit

Permalink
feat(NODE-4867)!: adopt BSON v5 (#3490)
Browse files Browse the repository at this point in the history
  • Loading branch information
nbbeeken authored Jan 20, 2023
1 parent 410ef30 commit b850868
Show file tree
Hide file tree
Showing 20 changed files with 360 additions and 431 deletions.
2 changes: 1 addition & 1 deletion etc/notes/CHANGES_5.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ The following is a detailed collection of the changes in the major v5 release of

### Dot Notation Typescript Support Removed By Default

**NOTE** This is a **Typescript compile-time only** change. Dot notation in filters sent to MongoDB will still work the same.
**NOTE** This is a **Typescript compile-time only** change. Dot notation in filters sent to MongoDB will still work the same.

Version 4.3.0 introduced Typescript support for dot notation in filter predicates. For example:

Expand Down
55 changes: 39 additions & 16 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"email": "dbx-node@mongodb.com"
},
"dependencies": {
"bson": "^4.7.0",
"bson": "^5.0.0-alpha.3",
"mongodb-connection-string-url": "^2.6.0",
"socks": "^2.7.1"
},
Expand Down
11 changes: 3 additions & 8 deletions src/bson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import type { DeserializeOptions, SerializeOptions } from 'bson';

export {
Binary,
BSON,
BSONRegExp,
BSONSymbol,
BSONType,
calculateObjectSize,
Code,
DBRef,
Expand All @@ -13,21 +15,13 @@ export {
Double,
Int32,
Long,
Map,
MaxKey,
MinKey,
ObjectId,
serialize,
Timestamp
} from 'bson';

// TODO(NODE-4867): fix with bson v5
/** @internal */
// eslint-disable-next-line @typescript-eslint/no-var-requires
const BSON = require('bson');

export { BSON };

/**
* BSON Serialization options.
* @public
Expand All @@ -42,6 +36,7 @@ export interface BSONSerializeOptions
| 'allowObjectSmallerThanBufferSize'
| 'index'
| 'validation'
| 'useBigInt64'
> {
/**
* Enabling the raw option will return a [Node.js Buffer](https://nodejs.org/api/buffer.html)
Expand Down
7 changes: 4 additions & 3 deletions src/cmap/auth/mongodb_aws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
MongoMissingCredentialsError,
MongoRuntimeError
} from '../../error';
import { Callback, maxWireVersion, ns } from '../../utils';
import { ByteUtils, Callback, maxWireVersion, ns } from '../../utils';
import { AuthContext, AuthProvider } from './auth_provider';
import { MongoCredentials } from './mongo_credentials';
import { AuthMechanism } from './providers';
Expand Down Expand Up @@ -108,7 +108,8 @@ export class MongoDBAWS extends AuthProvider {
return;
}

if (serverNonce.compare(nonce, 0, nonce.length, 0, nonce.length) !== 0) {
// TODO(NODE-4990)
if (!ByteUtils.equals(serverNonce.subarray(0, nonce.byteLength), nonce)) {
// TODO(NODE-3483)
callback(new MongoRuntimeError('Server nonce does not begin with client nonce'));
return;
Expand All @@ -130,7 +131,7 @@ export class MongoDBAWS extends AuthProvider {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': body.length,
'X-MongoDB-Server-Nonce': serverNonce.toString('base64'),
'X-MongoDB-Server-Nonce': ByteUtils.toBase64(serverNonce),
'X-MongoDB-GS2-CB-Flag': 'n'
},
path: '/',
Expand Down
6 changes: 3 additions & 3 deletions src/cmap/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ export class Query {
}

// Uses a single allocated buffer for the process, avoiding multiple memory allocations
toBin(): Buffer[] {
toBin(): Uint8Array[] {
const buffers = [];
let projection = null;

Expand Down Expand Up @@ -550,7 +550,7 @@ export class Msg {
return buffers;
}

makeDocumentSegment(buffers: Buffer[], document: Document): number {
makeDocumentSegment(buffers: Uint8Array[], document: Document): number {
const payloadTypeBuffer = Buffer.alloc(1);
payloadTypeBuffer[0] = 0;

Expand All @@ -561,7 +561,7 @@ export class Msg {
return payloadTypeBuffer.length + documentBuffer.length;
}

serializeBson(document: Document): Buffer {
serializeBson(document: Document): Uint8Array {
return BSON.serialize(document, {
checkKeys: this.checkKeys,
serializeFunctions: this.serializeFunctions,
Expand Down
5 changes: 2 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@ import { MongoClient } from './mongo_client';
import { CancellationToken } from './mongo_types';
import { ClientSession } from './sessions';

/** @internal */
/** @public */
export { BSON } from './bson';
export {
Binary,
BSONRegExp,
BSONSymbol,
BSONType,
Code,
DBRef,
Decimal128,
Double,
Int32,
Long,
Map,
MaxKey,
MinKey,
ObjectId,
Expand Down Expand Up @@ -103,7 +103,6 @@ export { MongoErrorLabel } from './error';
export { ExplainVerbosity } from './explain';
export { LoggerLevel } from './logger';
export { ServerApiVersion } from './mongo_client';
export { BSONType } from './mongo_types';
export { ReturnDocument } from './operations/find_and_modify';
export { ProfilingLevel } from './operations/set_profiling_level';
export { ReadConcernLevel } from './read_concern';
Expand Down
29 changes: 1 addition & 28 deletions src/mongo_types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ObjectIdLike } from 'bson';
import type { BSONType, ObjectIdLike } from 'bson';
import { EventEmitter } from 'events';

import type {
Expand Down Expand Up @@ -158,33 +158,6 @@ export type BitwiseFilter =
| Binary /** BinData bit mask */
| ReadonlyArray<number>; /** `[ <position1>, <position2>, ... ]` */

/** @public */
export const BSONType = Object.freeze({
double: 1,
string: 2,
object: 3,
array: 4,
binData: 5,
undefined: 6,
objectId: 7,
bool: 8,
date: 9,
null: 10,
regex: 11,
dbPointer: 12,
javascript: 13,
symbol: 14,
javascriptWithScope: 15,
int: 16,
timestamp: 17,
long: 18,
decimal: 19,
minKey: -1,
maxKey: 127
} as const);

/** @public */
export type BSONType = typeof BSONType[keyof typeof BSONType];
/** @public */
export type BSONTypeAlias = keyof typeof BSONType;

Expand Down
3 changes: 2 additions & 1 deletion src/sessions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { ReadPreference } from './read_preference';
import { _advanceClusterTime, ClusterTime, TopologyType } from './sdam/common';
import { isTransactionCommand, Transaction, TransactionOptions, TxnState } from './transactions';
import {
ByteUtils,
calculateDurationInMs,
Callback,
commandSupportsReadConcern,
Expand Down Expand Up @@ -347,7 +348,7 @@ export class ClientSession extends TypedEventEmitter<ClientSessionEvents> {
return false;
}

return this.id.id.buffer.equals(session.id.id.buffer);
return ByteUtils.equals(this.id.id.buffer, session.id.id.buffer);
}

/**
Expand Down
24 changes: 21 additions & 3 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,28 @@ import { W, WriteConcern, WriteConcernOptions } from './write_concern';
*/
export type Callback<T = any> = (error?: AnyError, result?: T) => void;

export const MAX_JS_INT = Number.MAX_SAFE_INTEGER + 1;

export type AnyOptions = Document;

export const ByteUtils = {
toLocalBufferType(this: void, buffer: Buffer | Uint8Array): Buffer {
return Buffer.isBuffer(buffer)
? buffer
: Buffer.from(buffer.buffer, buffer.byteOffset, buffer.byteLength);
},

equals(this: void, seqA: Uint8Array, seqB: Uint8Array) {
return ByteUtils.toLocalBufferType(seqA).equals(seqB);
},

compare(this: void, seqA: Uint8Array, seqB: Uint8Array) {
return ByteUtils.toLocalBufferType(seqA).compare(seqB);
},

toBase64(this: void, uint8array: Uint8Array) {
return ByteUtils.toLocalBufferType(uint8array).toString('base64');
}
};

/**
* Throws if collectionName is not a valid mongodb collection namespace.
* @internal
Expand Down Expand Up @@ -1401,7 +1419,7 @@ export function compareObjectId(oid1?: ObjectId | null, oid2?: ObjectId | null):
return 1;
}

return oid1.id.compare(oid2.id);
return ByteUtils.compare(oid1.id, oid2.id);
}

export function parseInteger(value: unknown): number | null {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ describe('Change Stream prose tests', function () {

// Helpers
timestamp() {
return new Timestamp(this._timestampCounter++, Date.now());
return new Timestamp({ i: this._timestampCounter++, t: this._timestampCounter });
}

applyOpTime(obj) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,6 @@ const skippedAuthTests = [
'unset works with an encrypted field',
'updateOne with deterministic encryption',
'updateMany with deterministic encryption',
'type=date',
'type=regex',
'type=timestamp',
'type=javascript',
'type=binData',
'type=int',
'type=objectId',
'type=symbol',
'replaceOne with encryption',
'Insert with encryption on a missing key',
'A local schema should override',
Expand Down
Loading

0 comments on commit b850868

Please sign in to comment.