Skip to content

Commit 1c6be19

Browse files
authored
docs(NODE-4794): Clean up migration guide for BSON v5 (#557)
1 parent f5d9b69 commit 1c6be19

File tree

1 file changed

+42
-37
lines changed

1 file changed

+42
-37
lines changed

docs/upgrade-to-v5.md

Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,17 @@
33
## TOC
44

55
- [Changes to Support Cross-platform JS API Compatibility](#changes-to-support-cross-platform-js-api-compatibility)
6-
- [Remove reliance on Node.js Buffer](#remove-reliance-on-nodejs-buffer)
7-
- [Impacted APIs now return Uint8Array in web environments; Node.js environments unaffected](#apis-impacted)
6+
- [Remove reliance on Node.js `Buffer`](#remove-reliance-on-nodejs-buffer)
7+
- [Impacted APIs now return `Uint8Array` in web environments; Node.js environments are unaffected](#apis-impacted)
88
- [Restrict supported encodings in `ObjectId.toString` / `UUID.toString` / `Binary.toString`](#restrict-supported-encodings-in-objectidtostring--uuidtostring--binarytostring)
99
- [Migration available if types beyond `'hex' | 'base64' | 'utf8'` are desired](#migration-example)
1010
- [Other Changes](#other-changes)
11-
- [serializeFunctions bug fix](#serializefunctions-bug-fix)
11+
- [`serializeFunctions` bug fix](#serializefunctions-bug-fix)
1212
- [TS "target" set to es2020](#ts-target-set-to-es2020)
1313

1414
## About
1515

16-
The following is a detailed collection of the changes in the major v5 release of the bson package
17-
for Node.js and web platforms.
16+
The following is a detailed collection of the changes in the major v5 release of the BSON package for Node.js and web platforms.
1817

1918
<!--
2019
1. a brief statement of what is breaking (brief as in "x will now return y instead of z", or "x is no longer supported, use y instead", etc
@@ -26,15 +25,15 @@ for Node.js and web platforms.
2625

2726
### Remove reliance on Node.js Buffer
2827

29-
> **TL;DR**: Impacted APIs now return Uint8Array in web environments; Node.js environments unaffected
28+
> **TL;DR**: Impacted APIs now return `Uint8Array` in web environments; Node.js environments are unaffected
3029
31-
For those that use the BSON library on Node.js, there is no change - the BSON APIs will still return and accept instances of Node.js Buffer. Since we no longer depend on the Buffer web shim for compatibility with browsers, in non-Node.js environments a Uint8Array will be returned instead.
30+
For those that use the BSON library on Node.js, there is no change - the BSON APIs will still return and accept instances of Node.js `Buffer`. Since we no longer depend on the `Buffer` web shim for compatibility with browsers, in non-Node.js environments a `Uint8Array` will be returned instead.
3231

33-
This allows the BSON library to be better at platform independence while keeping its behavior consistent cross platform. The Buffer shim served the library well but brought in more than was necessary for the concerns of the code here.
32+
This allows the BSON library to be more platform independent while keeping its behavior consistent cross platform.
3433

3534
#### APIs impacted
3635

37-
The following APIs now return Uint8Arrays when the library is loaded in an environment that does not define a global Node.js Buffer.
36+
The following APIs now return `Uint8Arrays` when the library is loaded in an environment that does not define a global Node.js `Buffer`.
3837

3938
- `Binary.prototype.buffer`
4039
- `Binary.prototype.read()`
@@ -50,7 +49,7 @@ The following APIs now return Uint8Arrays when the library is loaded in an envir
5049

5150
> **TL;DR**: The only supported encodings are: `'hex' | 'base64' | 'utf8'`
5251
53-
The methods: `ObjectId.toString`, `UUID.toString`, and `Binary.toString` took encodings that were passed through to the Node.js Buffer API. As a result of no longer relying on the presence of `Buffer` we can no longer support [every encoding that Node.js does](https://nodejs.org/dist/latest-v16.x/docs/api/buffer.html#buffers-and-character-encodings). We continue to support `'hex'` and `'base64'` on all three methods and additionally `'utf-8' | 'utf8'` on `Binary.toString`. If any of the other encodings are desired the underlying buffer for all these classes are publicly accessible and while in Node.js will be stored as a Node.js buffer:
52+
The methods: `ObjectId.toString`, `UUID.toString`, and `Binary.toString` took encodings that were passed through to the Node.js `Buffer` API. As a result of no longer relying on the presence of `Buffer` we can no longer support [every encoding that Node.js does](https://nodejs.org/dist/latest-v16.x/docs/api/buffer.html#buffers-and-character-encodings). We continue to support `'hex'` and `'base64'` on all three methods and additionally `'utf-8' | 'utf8'` on `Binary.toString`. If any of the other encodings are desired the underlying buffer for all these classes are publicly accessible and while in Node.js will be stored as a Node.js buffer:
5453

5554
#### Migration Example
5655

@@ -70,34 +69,36 @@ new TextDecoder('utf-16le').decode(bin.value(true));
7069

7170
### TS "target" set to es2020
7271

73-
We have set our typescript compilation target to `es2020` which aligns with our minimum supported Node.js version 14+. The following is from the typescript release notes on es2020 support, so it's some of the syntax that can be expected to be preserved after compilation:
72+
We have set our TypeScript compilation target to `es2020` which aligns with our minimum supported Node.js version 14+. The following is from the [TypeScript release notes on `es2020` support](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#es2020-for-target-and-module), so it's some of the syntax that can be expected to be preserved after compilation:
7473

7574
> This will preserve newer ECMAScript 2020 features like optional chaining, nullish coalescing, export \* as ns, and dynamic import(...) syntax. It also means bigint literals now have a stable target below esnext.
7675
77-
### serializeFunctions bug fix
76+
### `serializeFunctions` bug fix
7877

79-
If serializeFunctions was enabled and the functions being serialized had a name that is outside of [Controls and Basic Latin](https://en.wikibooks.org/wiki/Unicode/Character_reference/0000-0FFF) character ranges (a.k.a utf8 bytes: 0x00-0x7F) they would be incorrectly serialized.
78+
If `serializeFunctions` was enabled and the functions being serialized had a name that is outside of [Controls and Basic Latin](https://en.wikibooks.org/wiki/Unicode/Character_reference/0000-0FFF) character ranges (a.k.a utf8 bytes: `0x00-0x7F`) they would be incorrectly serialized.
8079

8180
### Remove `Map` export
8281

83-
This library no longer polyfills [ES Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) and the export "Map" was removed. Users should migrate to using the global Map constructor available in all supported JS environments.
82+
This library no longer polyfills [ES Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) and the export "`Map`" was removed. Users should migrate to using the global `Map` constructor available in all supported JS environments.
8483

8584
### `Decimal128` `toObject()` mapper support removed
8685

87-
`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.
86+
`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.
8887

89-
### Remove deprecated ObjectId methods
88+
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.
89+
90+
### Remove deprecated `ObjectId` methods
9091

9192
The following deprecated methods have been removed:
9293

9394
- `ObjectId.prototype.generate`
94-
- Instead, generate a new ObjectId with the constructor: `new ObjectId()` or using the `static generate(time?: number)` method.
95+
- Instead, generate a new `ObjectId` with the constructor: `new ObjectId()` or using the `static generate(time?: number)` method.
9596
- `ObjectId.prototype.generationTime`
9697
- Instead, use `static createFromTime()` and `getTimestamp()` to set and inspect these values on an `ObjectId()`
9798
- `ObjectId.prototype.getInc`
9899
- `ObjectId.prototype.get_inc`
99100
- `ObjectId.get_inc`
100-
- The `static getInc()` is private since invoking it increments the next `ObjectId` index, so invoking would impact the creation of subsequent ObjectIds.
101+
- The `static getInc()` is private since invoking it increments the next `ObjectId` index, so invoking would impact the creation of subsequent `ObjectId`s.
101102

102103
### BSON Element names are now fetched only from object's own properties
103104

@@ -129,13 +130,13 @@ BSON.deserialize(BSON.serialize({ d: -0 }))
129130
// type preservation, returns { d: -0 }
130131
```
131132

132-
### Capital "D" ObjectID export removed
133+
### Capital "D" `ObjectID` export removed
133134

134135
For clarity the deprecated and duplicate export `ObjectID` has been removed. `ObjectId` matches the class name and is equal in every way to the capital "D" export.
135136

136137
### Timestamp constructor validation
137138

138-
The `Timestamp` type no longer accepts two number arguments for the low and high bits of the int64 value.
139+
The `Timestamp` type no longer accepts two number arguments for the low and high bits of the `int64` value.
139140

140141
Supported constructors are as follows:
141142

@@ -147,7 +148,7 @@ class Timestamp {
147148
}
148149
```
149150

150-
Any code that use the two number argument style of constructing a Timestamp will need to be migrated to one of the supported constructors. We recommend using the `{ t: number; i: number }` style input, representing the timestamp and increment respectively.
151+
Any code that uses the two number argument style of constructing a `Timestamp` will need to be migrated to one of the supported constructors. We recommend using the `{ t: number; i: number }` style input, representing the timestamp and increment respectively.
151152

152153
```typescript
153154
// in 4.x BSON
@@ -156,7 +157,7 @@ new Timestamp(1, 2); // as an int64: 8589934593
156157
new Timestamp({ t: 2, i: 1 }); // as an int64: 8589934593
157158
```
158159

159-
Additionally, the `t` and `i` fields of `{ t: number; i: number }` are now validated more strictly to ensure your Timestamps are being constructed as expected.
160+
Additionally, the `t` and `i` fields of `{ t: number; i: number }` are now validated more strictly to ensure your timestamps are being constructed as expected.
160161

161162
For example:
162163
```typescript
@@ -183,8 +184,8 @@ EJSON.stringify({}, { strict: false }); /* migrate to */ EJSON.stringify({}, { r
183184

184185
### The BSON default export has been removed.
185186

186-
* If you import BSON commonjs style `const BSON = require('bson')` then the `BSON.default` property is no longer present.
187-
* If you import BSON esmodule style `import BSON from 'bson'` then this code will crash upon loading. **TODO: This is not the case right now but it will be after NODE-4713.**
187+
* If you import BSON `commonjs` style `const BSON = require('bson')` then the `BSON.default` property is no longer present.
188+
* If you import BSON `esmodule` style `import BSON from 'bson'` then this code will crash upon loading.
188189
* This error will throw: `SyntaxError: The requested module 'bson' does not provide an export named 'default'`.
189190

190191
### `class Code` always converts `.code` to string
@@ -201,9 +202,10 @@ const myCode = new Code(function iLoveJavascript() { console.log('I love javascr
201202
### `BSON.deserialize()` only returns `Code` instances
202203

203204
The deserialize options: `evalFunctions`, `cacheFunctions`, and `cacheFunctionsCrc32` have been removed.
204-
The `evalFunctions` option, when enabled, would return BSON Code typed values as eval-ed javascript functions, now it will always return Code instances.
205+
The `evalFunctions` option, when enabled, would return BSON `Code` typed values as eval-ed JavaScript functions, now it will always return `Code` instances.
205206

206207
See the following snippet for how to migrate:
208+
207209
```typescript
208210
const bsonBytes = BSON.serialize(
209211
{ iLoveJavascript: function () { console.log('I love javascript') } },
@@ -221,7 +223,7 @@ iLoveJavascript();
221223
### `BSON.serialize()` validation
222224

223225
The BSON format does not support encoding arrays as the **root** object.
224-
However, in javascript arrays are just objects where the keys are numeric (and a magic `length` property), so round tripping an array (ex. `[1, 2]`) though BSON would return `{ '0': 1, '1': 2 }`.
226+
However, in JavaScript arrays are just objects where the keys are numeric (and a magic `length` property), so round tripping an array (ex. `[1, 2]`) though BSON would return `{ '0': 1, '1': 2 }`.
225227

226228
`BSON.serialize()` now validates input types, the input to serialize must be an object or a `Map`, arrays will now cause an error.
227229

@@ -230,7 +232,7 @@ BSON.serialize([1, 2, 3])
230232
// BSONError: serialize does not support an array as the root input
231233
```
232234

233-
if the functionality of turning arrays into an object with numeric keys is useful see the following example:
235+
If the functionality of turning arrays into an object with numeric keys is useful, see the following example:
234236

235237
```typescript
236238
// Migration example:
@@ -242,20 +244,21 @@ BSON.deserialize(result)
242244
### Exports and available bundles
243245

244246
Most users should be unaffected by these changes, Node.js `require()` / Node.js `import` will fetch the corresponding BSON library as expected.
245-
And for folks using bundlers like, webpack or rollup a tree shakable es module bundle will be pulled in because of the settings in our package.json.
247+
And for folks using bundlers like webpack or rollup, a tree shakable ES module bundle will be pulled in because of the settings in our `package.json`.
246248

247-
Our package.json defines the following `"exports"` settings.
249+
Our `package.json` defines the following `"exports"` settings.
248250
```json
249251
{
250252
"main": "./lib/bson.cjs",
251253
"module": "./lib/bson.mjs",
252-
"browser": "./lib/bson.mjs",
253254
"exports": {
254-
"browser": "./lib/bson.mjs",
255255
"import": "./lib/bson.mjs",
256-
"require": "./lib/bson.cjs"
257-
}
256+
"require": "./lib/bson.cjs",
257+
"react-native": "./lib/bson.cjs",
258+
"browser": "./lib/bson.mjs"
259+
},
258260
}
261+
259262
```
260263

261264
You can now find compiled bundles of the BSON library in 3 common formats in the `lib` directory.
@@ -267,14 +270,16 @@ You can now find compiled bundles of the BSON library in 3 common formats in the
267270

268271
### `BSONTypeError` removed and `BSONError` offers filtering functionality with `static isBSONError()`
269272

270-
`BSONTypeError` has been removed because it was not a subclass of BSONError so would not return true for an `instanceof` check against `BSONError`. To learn more about our expectations of error handling see [this section of the mongodb driver's readme](https://github.com/mongodb/node-mongodb-native/tree/main#error-handling).
273+
`BSONTypeError` has been removed because it was not a subclass of BSONError so would not return true for an `instanceof` check against `BSONError`. To learn more about our expectations of error handling see [this section of the MongoDB Node.js Driver's README](https://github.com/mongodb/node-mongodb-native/tree/main#error-handling).
271274

272275

273276
A `BSONError` can be thrown from deep within a library that relies on BSON, having one error super class for the library helps with programmatic filtering of an error's origin.
277+
274278
Since BSON can be used in environments where instances may originate from across realms, `BSONError` has a static `isBSONError()` method that helps with determining if an object is a `BSONError` instance (much like [Array.isArray](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray)).
279+
275280
It is our recommendation to use `isBSONError()` checks on errors and to avoid relying on parsing `error.message` and `error.name` strings in your code. We guarantee `isBSONError()` checks will pass according to semver guidelines, but errors may be sub-classed or their messages may change at any time, even patch releases, as we see fit to increase the helpfulness of the errors.
276281

277-
Hypothetical example: A collection in our Db has an issue with UTF-8 data:
282+
Hypothetical example: A collection in our database contains invalid UTF-8 data:
278283
```ts
279284
let documentCount = 0;
280285
const cursor = collection.find({}, { utf8Validation: true });
@@ -291,8 +296,8 @@ try {
291296

292297
### Explicit cross version incompatibility
293298

294-
Starting with v5.0.0 of the BSON library instances of types from previous versions will throw an error when passed to the serializer.
295-
This is to ensure that types are always serialized correctly and that there is no unexpected silent BSON serialization mistakes that could occur when mixing versions.
299+
Starting with v5.0.0 of the BSON library instances of types from previous versions will throw an error when passed to the serializer. This is to ensure that types are always serialized correctly and that there is no unexpected silent BSON serialization mistakes that could occur when mixing versions.
300+
296301
It's unexpected for any applications to have more than one version of the BSON library but with nested dependencies and re-exporting, this new error will illuminate those incorrect combinations.
297302

298303
```ts

0 commit comments

Comments
 (0)