bson 5.0.0-alpha.1 → 5.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,10 +1,7 @@
1
1
  # BSON parser
2
2
 
3
- BSON is short for "Binary JSON," and is the binary-encoded serialization of JSON-like documents. You can learn more about it in [the specification](http://bsonspec.org).
4
-
5
- This browser version of the BSON parser is compiled using [rollup](https://rollupjs.org/) and the current version is pre-compiled in the `dist` directory.
6
-
7
- This is the default BSON parser, however, there is a C++ Node.js addon version as well that does not support the browser. It can be found at [mongod-js/bson-ext](https://github.com/mongodb-js/bson-ext).
3
+ BSON is short for "Binary JSON," and is the binary-encoded serialization of JSON-like documents.
4
+ You can learn more about it in [the specification](http://bsonspec.org).
8
5
 
9
6
  ### Table of Contents
10
7
  - [Usage](#usage)
@@ -32,106 +29,43 @@ npm install
32
29
  npm run build
33
30
  ```
34
31
 
35
- ### Node (no bundling)
36
- A simple example of how to use BSON in `Node.js`:
32
+ ### Node.js or Bundling Usage
37
33
 
38
- ```js
39
- const BSON = require('bson');
40
- const Long = BSON.Long;
34
+ When using a bundler or Node.js you can import bson using the package name:
41
35
 
42
- // Serialize a document
43
- const doc = { long: Long.fromNumber(100) };
44
- const data = BSON.serialize(doc);
45
- console.log('data:', data);
36
+ ```js
37
+ import { BSON, EJSON, ObjectId } from 'bson';
38
+ // or:
39
+ // const { BSON, EJSON, ObjectId } = require('bson');
46
40
 
47
- // Deserialize the resulting Buffer
48
- const doc_2 = BSON.deserialize(data);
49
- console.log('doc_2:', doc_2);
41
+ const bytes = BSON.serialize({ _id: new ObjectId() });
42
+ console.log(bytes);
43
+ const doc = BSON.deserialize(bytes);
44
+ console.log(EJSON.stringify(doc));
45
+ // {"_id":{"$oid":"..."}}
50
46
  ```
51
47
 
52
- ### Browser (no bundling)
48
+ ### Browser Usage
53
49
 
54
- If you are not using a bundler like webpack, you can include `dist/bson.bundle.js` using a script tag. It includes polyfills for built-in node types like `Buffer`.
50
+ If you are working directly in the browser without a bundler please use the `.mjs` bundle like so:
55
51
 
56
52
  ```html
57
- <script src="./dist/bson.bundle.js"></script>
58
-
59
- <script>
60
- function start() {
61
- // Get the Long type
62
- const Long = BSON.Long;
63
-
64
- // Serialize a document
65
- const doc = { long: Long.fromNumber(100) }
66
- const data = BSON.serialize(doc);
67
- console.log('data:', data);
68
-
69
- // De serialize it again
70
- const doc_2 = BSON.deserialize(data);
71
- console.log('doc_2:', doc_2);
72
- }
53
+ <script type="module">
54
+ import { BSON, EJSON, ObjectId } from './lib/bson.mjs';
55
+
56
+ const bytes = BSON.serialize({ _id: new ObjectId() });
57
+ console.log(bytes);
58
+ const doc = BSON.deserialize(bytes);
59
+ console.log(EJSON.stringify(doc));
60
+ // {"_id":{"$oid":"..."}}
73
61
  </script>
74
62
  ```
75
63
 
76
- ### Using webpack
77
-
78
- If using webpack, you can use your normal import/require syntax of your project to pull in the `bson` library.
79
-
80
- ES6 Example:
81
-
82
- ```js
83
- import { Long, serialize, deserialize } from 'bson';
84
-
85
- // Serialize a document
86
- const doc = { long: Long.fromNumber(100) };
87
- const data = serialize(doc);
88
- console.log('data:', data);
89
-
90
- // De serialize it again
91
- const doc_2 = deserialize(data);
92
- console.log('doc_2:', doc_2);
93
- ```
94
-
95
- ES5 Example:
96
-
97
- ```js
98
- const BSON = require('bson');
99
- const Long = BSON.Long;
100
-
101
- // Serialize a document
102
- const doc = { long: Long.fromNumber(100) };
103
- const data = BSON.serialize(doc);
104
- console.log('data:', data);
105
-
106
- // Deserialize the resulting Buffer
107
- const doc_2 = BSON.deserialize(data);
108
- console.log('doc_2:', doc_2);
109
- ```
110
-
111
- Depending on your settings, webpack will under the hood resolve to one of the following:
112
-
113
- - `dist/bson.browser.esm.js` If your project is in the browser and using ES6 modules (Default for `webworker` and `web` targets)
114
- - `dist/bson.browser.umd.js` If your project is in the browser and not using ES6 modules
115
- - `dist/bson.esm.js` If your project is in Node.js and using ES6 modules (Default for `node` targets)
116
- - `lib/bson.js` (the normal include path) If your project is in Node.js and not using ES6 modules
117
-
118
- For more information, see [this page on webpack's `resolve.mainFields`](https://webpack.js.org/configuration/resolve/#resolvemainfields) and [the `package.json` for this project](./package.json#L52)
119
-
120
- ### Usage with Angular
121
-
122
- Starting with Angular 6, Angular CLI removed the shim for `global` and other node built-in variables (original comment [here](https://github.com/angular/angular-cli/issues/9827#issuecomment-386154063)). If you are using BSON with Angular, you may need to add the following shim to your `polyfills.ts` file:
123
-
124
- ```js
125
- // In polyfills.ts
126
- (window as any).global = window;
127
- ```
128
-
129
- - [Original Comment by Angular CLI](https://github.com/angular/angular-cli/issues/9827#issuecomment-386154063)
130
- - [Original Source for Solution](https://stackoverflow.com/a/50488337/4930088)
131
-
132
64
  ## Installation
133
65
 
134
- `npm install bson`
66
+ ```sh
67
+ npm install bson
68
+ ```
135
69
 
136
70
  ## Documentation
137
71
 
@@ -304,12 +238,13 @@ Serialize a Javascript object using a predefined Buffer and index into the buffe
304
238
  | buffer | <code>Buffer</code> | | the buffer containing the serialized set of BSON documents. |
305
239
  | [options.evalFunctions] | <code>Object</code> | <code>false</code> | evaluate functions in the BSON document scoped to the object deserialized. |
306
240
  | [options.cacheFunctions] | <code>Object</code> | <code>false</code> | cache evaluated functions for reuse. |
241
+ | [options.useBigInt64] | <code>Object</code> | <code>false</code> | when deserializing a Long will return a BigInt. |
307
242
  | [options.promoteLongs] | <code>Object</code> | <code>true</code> | when deserializing a Long will fit it into a Number if it's smaller than 53 bits |
308
243
  | [options.promoteBuffers] | <code>Object</code> | <code>false</code> | when deserializing a Binary will return it as a node.js Buffer instance. |
309
244
  | [options.promoteValues] | <code>Object</code> | <code>false</code> | when deserializing will promote BSON values to their Node.js closest equivalent types. |
310
245
  | [options.fieldsAsRaw] | <code>Object</code> | <code></code> | allow to specify if there what fields we wish to return as unserialized raw buffer. |
311
246
  | [options.bsonRegExp] | <code>Object</code> | <code>false</code> | return BSON regular expressions as BSONRegExp instances. |
312
- | [options.allowObjectSmallerThanBufferSize] | <code>boolean</code> | <code>false</code> | allows the buffer to be larger than the parsed BSON object |
247
+ | [options.allowObjectSmallerThanBufferSize] | <code>boolean</code> | <code>false</code> | allows the buffer to be larger than the parsed BSON object. |
313
248
 
314
249
  Deserialize data as BSON.
315
250
 
@@ -351,6 +286,63 @@ Deserialize stream data as BSON documents.
351
286
 
352
287
  **Returns**: <code>Number</code> - returns the next index in the buffer after deserialization **x** numbers of documents.
353
288
 
289
+ ## Error Handling
290
+
291
+ It is our recommendation to use `BSONError.isBSONError()` checks on errors and to avoid relying on parsing `error.message` and `error.name` strings in your code. We guarantee `BSONError.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.
292
+
293
+ Any new errors we add to the driver will directly extend an existing error class and no existing error will be moved to a different parent class outside of a major release.
294
+ This means `BSONError.isBSONError()` will always be able to accurately capture the errors that our BSON library throws.
295
+
296
+ Hypothetical example: A collection in our Db has an issue with UTF-8 data:
297
+
298
+ ```ts
299
+ let documentCount = 0;
300
+ const cursor = collection.find({}, { utf8Validation: true });
301
+ try {
302
+ for await (const doc of cursor) documentCount += 1;
303
+ } catch (error) {
304
+ if (BSONError.isBSONError(error)) {
305
+ console.log(`Found the troublemaker UTF-8!: ${documentCount} ${error.message}`);
306
+ return documentCount;
307
+ }
308
+ throw error;
309
+ }
310
+ ```
311
+
312
+ ## React Native
313
+
314
+ BSON requires that `TextEncoder`, `TextDecoder`, `atob`, `btoa`, and `crypto.getRandomValues` are available globally. These are present in most Javascript runtimes but require polyfilling in React Native. Polyfills for the missing functionality can be installed with the following command:
315
+ ```sh
316
+ npm install --save react-native-get-random-values text-encoding-polyfill base-64
317
+ ```
318
+
319
+ The following snippet should be placed at the top of the entrypoint (by default this is the root `index.js` file) for React Native projects using the BSON library. These lines must be placed for any code that imports `BSON`.
320
+
321
+ ```typescript
322
+ // Required Polyfills For ReactNative
323
+ import {encode, decode} from 'base-64';
324
+ if (global.btoa == null) {
325
+ global.btoa = encode;
326
+ }
327
+ if (global.atob == null) {
328
+ global.atob = decode;
329
+ }
330
+ import 'text-encoding-polyfill';
331
+ import 'react-native-get-random-values';
332
+ ```
333
+
334
+ Finally, import the `BSON` library like so:
335
+
336
+ ```typescript
337
+ import { BSON, EJSON } from 'bson';
338
+ ```
339
+
340
+ This will cause React Native to import the `node_modules/bson/lib/bson.cjs` bundle (see the `"react-native"` setting we have in the `"exports"` section of our [package.json](./package.json).)
341
+
342
+ ### Technical Note about React Native module import
343
+
344
+ The `"exports"` definition in our `package.json` will result in BSON's CommonJS bundle being imported in a React Native project instead of the ES module bundle. Importing the CommonJS bundle is necessary because BSON's ES module bundle of BSON uses top-level await, which is not supported syntax in [React Native's runtime hermes](https://hermesengine.dev/).
345
+
354
346
  ## FAQ
355
347
 
356
348
  #### Why does `undefined` get converted to `null`?
package/bson.d.ts CHANGED
@@ -142,7 +142,6 @@ declare namespace BSON {
142
142
  BSONRegExp,
143
143
  Decimal128,
144
144
  BSONError,
145
- BSONTypeError,
146
145
  BSONType,
147
146
  EJSON,
148
147
  Document,
@@ -151,10 +150,24 @@ declare namespace BSON {
151
150
  }
152
151
  export { BSON }
153
152
 
154
- /** @public */
153
+ /**
154
+ * @public
155
+ * `BSONError` objects are thrown when runtime errors occur.
156
+ */
155
157
  export declare class BSONError extends Error {
156
- constructor(message: string);
158
+ /* Excluded from this release type: bsonError */
157
159
  get name(): string;
160
+ constructor(message: string);
161
+ /**
162
+ * @public
163
+ *
164
+ * All errors thrown from the BSON library inherit from `BSONError`.
165
+ * This method can assist with determining if an error originates from the BSON library
166
+ * even if it does not pass an `instanceof` check against this class' constructor.
167
+ *
168
+ * @param value - any javascript value that needs type checking
169
+ */
170
+ static isBSONError(value: unknown): value is BSONError;
158
171
  }
159
172
 
160
173
  /**
@@ -245,12 +258,6 @@ export declare const BSONType: Readonly<{
245
258
  /** @public */
246
259
  export declare type BSONType = typeof BSONType[keyof typeof BSONType];
247
260
 
248
- /** @public */
249
- export declare class BSONTypeError extends TypeError {
250
- constructor(message: string);
251
- get name(): string;
252
- }
253
-
254
261
  /**
255
262
  * Calculate the bson size for a passed in Javascript object.
256
263
  *
@@ -367,7 +374,9 @@ export declare function deserialize(buffer: Uint8Array, options?: DeserializeOpt
367
374
 
368
375
  /** @public */
369
376
  export declare interface DeserializeOptions {
370
- /** when deserializing a Long will fit it into a Number if it's smaller than 53 bits */
377
+ /** when deserializing a Long will return as a BigInt. */
378
+ useBigInt64?: boolean;
379
+ /** when deserializing a Long will fit it into a Number if it's smaller than 53 bits. */
371
380
  promoteLongs?: boolean;
372
381
  /** when deserializing a Binary will return it as a node.js Buffer instance. */
373
382
  promoteBuffers?: boolean;
@@ -377,7 +386,7 @@ export declare interface DeserializeOptions {
377
386
  fieldsAsRaw?: Document;
378
387
  /** return BSON regular expressions as BSONRegExp instances. */
379
388
  bsonRegExp?: boolean;
380
- /** allows the buffer to be larger than the parsed BSON object */
389
+ /** allows the buffer to be larger than the parsed BSON object. */
381
390
  allowObjectSmallerThanBufferSize?: boolean;
382
391
  /** Offset into buffer to begin reading document from */
383
392
  index?: number;