bson 5.0.0-alpha.1 → 5.0.0-alpha.3

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
@@ -3,7 +3,7 @@
3
3
  * @public
4
4
  * @category BSONType
5
5
  */
6
- export declare class Binary {
6
+ export declare class Binary extends BSONValue {
7
7
  get _bsontype(): 'Binary';
8
8
  /* Excluded from this release type: BSON_BINARY_SUBTYPE_DEFAULT */
9
9
  /** Initial buffer default size */
@@ -141,8 +141,9 @@ declare namespace BSON {
141
141
  MaxKey,
142
142
  BSONRegExp,
143
143
  Decimal128,
144
+ BSONValue,
144
145
  BSONError,
145
- BSONTypeError,
146
+ BSONVersionError,
146
147
  BSONType,
147
148
  EJSON,
148
149
  Document,
@@ -151,10 +152,24 @@ declare namespace BSON {
151
152
  }
152
153
  export { BSON }
153
154
 
154
- /** @public */
155
+ /**
156
+ * @public
157
+ * `BSONError` objects are thrown when runtime errors occur.
158
+ */
155
159
  export declare class BSONError extends Error {
156
- constructor(message: string);
160
+ /* Excluded from this release type: bsonError */
157
161
  get name(): string;
162
+ constructor(message: string);
163
+ /**
164
+ * @public
165
+ *
166
+ * All errors thrown from the BSON library inherit from `BSONError`.
167
+ * This method can assist with determining if an error originates from the BSON library
168
+ * even if it does not pass an `instanceof` check against this class' constructor.
169
+ *
170
+ * @param value - any javascript value that needs type checking
171
+ */
172
+ static isBSONError(value: unknown): value is BSONError;
158
173
  }
159
174
 
160
175
  /**
@@ -162,7 +177,7 @@ export declare class BSONError extends Error {
162
177
  * @public
163
178
  * @category BSONType
164
179
  */
165
- export declare class BSONRegExp {
180
+ export declare class BSONRegExp extends BSONValue {
166
181
  get _bsontype(): 'BSONRegExp';
167
182
  pattern: string;
168
183
  options: string;
@@ -196,7 +211,7 @@ export declare interface BSONRegExpExtendedLegacy {
196
211
  * @public
197
212
  * @category BSONType
198
213
  */
199
- export declare class BSONSymbol {
214
+ export declare class BSONSymbol extends BSONValue {
200
215
  get _bsontype(): 'BSONSymbol';
201
216
  value: string;
202
217
  /**
@@ -206,7 +221,7 @@ export declare class BSONSymbol {
206
221
  /** Access the wrapped string value. */
207
222
  valueOf(): string;
208
223
  toString(): string;
209
- /* Excluded from this release type: inspect */
224
+ inspect(): string;
210
225
  toJSON(): string;
211
226
  /* Excluded from this release type: toExtendedJSON */
212
227
  /* Excluded from this release type: fromExtendedJSON */
@@ -246,9 +261,18 @@ export declare const BSONType: Readonly<{
246
261
  export declare type BSONType = typeof BSONType[keyof typeof BSONType];
247
262
 
248
263
  /** @public */
249
- export declare class BSONTypeError extends TypeError {
250
- constructor(message: string);
251
- get name(): string;
264
+ export declare abstract class BSONValue {
265
+ /** @public */
266
+ abstract get _bsontype(): string;
267
+ /** @public */
268
+ abstract inspect(): string;
269
+ /* Excluded from this release type: toExtendedJSON */
270
+ }
271
+
272
+ /** @public */
273
+ export declare class BSONVersionError extends BSONError {
274
+ get name(): 'BSONVersionError';
275
+ constructor();
252
276
  }
253
277
 
254
278
  /**
@@ -268,7 +292,7 @@ export declare type CalculateObjectSizeOptions = Pick<SerializeOptions, 'seriali
268
292
  * @public
269
293
  * @category BSONType
270
294
  */
271
- export declare class Code {
295
+ export declare class Code extends BSONValue {
272
296
  get _bsontype(): 'Code';
273
297
  code: string;
274
298
  scope: Document | null;
@@ -297,7 +321,7 @@ export declare interface CodeExtended {
297
321
  * @public
298
322
  * @category BSONType
299
323
  */
300
- export declare class DBRef {
324
+ export declare class DBRef extends BSONValue {
301
325
  get _bsontype(): 'DBRef';
302
326
  collection: string;
303
327
  oid: ObjectId;
@@ -329,7 +353,7 @@ export declare interface DBRefLike {
329
353
  * @public
330
354
  * @category BSONType
331
355
  */
332
- export declare class Decimal128 {
356
+ export declare class Decimal128 extends BSONValue {
333
357
  get _bsontype(): 'Decimal128';
334
358
  readonly bytes: Uint8Array;
335
359
  /**
@@ -367,7 +391,9 @@ export declare function deserialize(buffer: Uint8Array, options?: DeserializeOpt
367
391
 
368
392
  /** @public */
369
393
  export declare interface DeserializeOptions {
370
- /** when deserializing a Long will fit it into a Number if it's smaller than 53 bits */
394
+ /** when deserializing a Long will return as a BigInt. */
395
+ useBigInt64?: boolean;
396
+ /** when deserializing a Long will fit it into a Number if it's smaller than 53 bits. */
371
397
  promoteLongs?: boolean;
372
398
  /** when deserializing a Binary will return it as a node.js Buffer instance. */
373
399
  promoteBuffers?: boolean;
@@ -377,7 +403,7 @@ export declare interface DeserializeOptions {
377
403
  fieldsAsRaw?: Document;
378
404
  /** return BSON regular expressions as BSONRegExp instances. */
379
405
  bsonRegExp?: boolean;
380
- /** allows the buffer to be larger than the parsed BSON object */
406
+ /** allows the buffer to be larger than the parsed BSON object. */
381
407
  allowObjectSmallerThanBufferSize?: boolean;
382
408
  /** Offset into buffer to begin reading document from */
383
409
  index?: number;
@@ -426,7 +452,7 @@ export declare interface Document {
426
452
  * @public
427
453
  * @category BSONType
428
454
  */
429
- export declare class Double {
455
+ export declare class Double extends BSONValue {
430
456
  get _bsontype(): 'Double';
431
457
  value: number;
432
458
  /**
@@ -475,6 +501,8 @@ export declare type EJSONOptions = {
475
501
  legacy?: boolean;
476
502
  /** Enable Extended JSON's `relaxed` mode, which attempts to return native JS types where possible, rather than BSON types */
477
503
  relaxed?: boolean;
504
+ /** Enable native bigint support */
505
+ useBigInt64?: boolean;
478
506
  };
479
507
 
480
508
  /**
@@ -490,7 +518,7 @@ declare function EJSONserialize(value: any, options?: EJSONOptions): Document;
490
518
  * @public
491
519
  * @category BSONType
492
520
  */
493
- export declare class Int32 {
521
+ export declare class Int32 extends BSONValue {
494
522
  get _bsontype(): 'Int32';
495
523
  value: number;
496
524
  /**
@@ -538,7 +566,7 @@ declare const kId: unique symbol;
538
566
  * case would often result in infinite recursion.
539
567
  * Common constant values ZERO, ONE, NEG_ONE, etc. are found as static properties on this class.
540
568
  */
541
- export declare class Long {
569
+ export declare class Long extends BSONValue {
542
570
  get _bsontype(): 'Long';
543
571
  /** An indicator used to reliably determine if an object is a Long or not. */
544
572
  get __isLong__(): boolean;
@@ -831,7 +859,7 @@ export declare class Long {
831
859
  toExtendedJSON(options?: EJSONOptions): number | LongExtended;
832
860
  static fromExtendedJSON(doc: {
833
861
  $numberLong: string;
834
- }, options?: EJSONOptions): number | Long;
862
+ }, options?: EJSONOptions): number | Long | bigint;
835
863
  inspect(): string;
836
864
  }
837
865
 
@@ -853,7 +881,7 @@ export declare const LongWithoutOverridesClass: LongWithoutOverrides;
853
881
  * @public
854
882
  * @category BSONType
855
883
  */
856
- export declare class MaxKey {
884
+ export declare class MaxKey extends BSONValue {
857
885
  get _bsontype(): 'MaxKey';
858
886
  /* Excluded from this release type: toExtendedJSON */
859
887
  /* Excluded from this release type: fromExtendedJSON */
@@ -870,7 +898,7 @@ export declare interface MaxKeyExtended {
870
898
  * @public
871
899
  * @category BSONType
872
900
  */
873
- export declare class MinKey {
901
+ export declare class MinKey extends BSONValue {
874
902
  get _bsontype(): 'MinKey';
875
903
  /* Excluded from this release type: toExtendedJSON */
876
904
  /* Excluded from this release type: fromExtendedJSON */
@@ -887,7 +915,7 @@ export declare interface MinKeyExtended {
887
915
  * @public
888
916
  * @category BSONType
889
917
  */
890
- export declare class ObjectId {
918
+ export declare class ObjectId extends BSONValue {
891
919
  get _bsontype(): 'ObjectId';
892
920
  /* Excluded from this release type: index */
893
921
  static cacheHexString: boolean;