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 +85 -93
- package/bson.d.ts +20 -11
- package/lib/bson.bundle.js +101 -79
- package/lib/bson.bundle.js.map +1 -1
- package/lib/bson.cjs +101 -79
- package/lib/bson.cjs.map +1 -1
- package/lib/bson.mjs +102 -79
- package/lib/bson.mjs.map +1 -1
- package/package.json +4 -4
- package/src/binary.ts +7 -7
- package/src/bson.ts +1 -1
- package/src/decimal128.ts +7 -7
- package/src/double.ts +6 -14
- package/src/error.ts +33 -9
- package/src/extended_json.ts +11 -5
- package/src/long.ts +6 -5
- package/src/objectid.ts +6 -8
- package/src/parser/calculate_size.ts +12 -1
- package/src/parser/deserializer.ts +24 -9
- package/src/parser/serializer.ts +50 -31
- package/src/regexp.ts +2 -2
- package/src/uuid_utils.ts +2 -2
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.
|
|
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
|
|
36
|
-
A simple example of how to use BSON in `Node.js`:
|
|
32
|
+
### Node.js or Bundling Usage
|
|
37
33
|
|
|
38
|
-
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
36
|
+
```js
|
|
37
|
+
import { BSON, EJSON, ObjectId } from 'bson';
|
|
38
|
+
// or:
|
|
39
|
+
// const { BSON, EJSON, ObjectId } = require('bson');
|
|
46
40
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
|
48
|
+
### Browser Usage
|
|
53
49
|
|
|
54
|
-
If you are
|
|
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
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
|
|
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
|
-
/**
|
|
153
|
+
/**
|
|
154
|
+
* @public
|
|
155
|
+
* `BSONError` objects are thrown when runtime errors occur.
|
|
156
|
+
*/
|
|
155
157
|
export declare class BSONError extends Error {
|
|
156
|
-
|
|
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
|
|
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;
|