bson 4.0.4 → 4.2.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.
Files changed (90) hide show
  1. package/HISTORY.md +56 -1
  2. package/README.md +7 -9
  3. package/bower.json +1 -1
  4. package/bson.d.ts +983 -0
  5. package/dist/bson.browser.esm.js +7261 -5004
  6. package/dist/bson.browser.esm.js.map +1 -0
  7. package/dist/bson.browser.umd.js +7319 -5099
  8. package/dist/bson.browser.umd.js.map +1 -0
  9. package/dist/bson.bundle.js +8168 -9216
  10. package/dist/bson.bundle.js.map +1 -0
  11. package/dist/bson.esm.js +5643 -5409
  12. package/dist/bson.esm.js.map +1 -0
  13. package/etc/prepare.js +19 -0
  14. package/lib/binary.js +194 -377
  15. package/lib/binary.js.map +1 -0
  16. package/lib/bson.js +200 -243
  17. package/lib/bson.js.map +1 -0
  18. package/lib/code.js +36 -39
  19. package/lib/code.js.map +1 -0
  20. package/lib/constants.js +78 -203
  21. package/lib/constants.js.map +1 -0
  22. package/lib/db_ref.js +79 -79
  23. package/lib/db_ref.js.map +1 -0
  24. package/lib/decimal128.js +647 -760
  25. package/lib/decimal128.js.map +1 -0
  26. package/lib/double.js +61 -58
  27. package/lib/double.js.map +1 -0
  28. package/lib/ensure_buffer.js +22 -18
  29. package/lib/ensure_buffer.js.map +1 -0
  30. package/lib/extended_json.js +305 -322
  31. package/lib/extended_json.js.map +1 -0
  32. package/lib/float_parser.js +98 -104
  33. package/lib/float_parser.js.map +1 -0
  34. package/lib/int_32.js +45 -47
  35. package/lib/int_32.js.map +1 -0
  36. package/lib/long.js +876 -16
  37. package/lib/long.js.map +1 -0
  38. package/lib/map.js +123 -124
  39. package/lib/map.js.map +1 -0
  40. package/lib/max_key.js +21 -23
  41. package/lib/max_key.js.map +1 -0
  42. package/lib/min_key.js +21 -23
  43. package/lib/min_key.js.map +1 -0
  44. package/lib/objectid.js +264 -382
  45. package/lib/objectid.js.map +1 -0
  46. package/lib/parser/calculate_size.js +185 -224
  47. package/lib/parser/calculate_size.js.map +1 -0
  48. package/lib/parser/deserializer.js +543 -620
  49. package/lib/parser/deserializer.js.map +1 -0
  50. package/lib/parser/serializer.js +774 -918
  51. package/lib/parser/serializer.js.map +1 -0
  52. package/lib/parser/utils.js +81 -30
  53. package/lib/parser/utils.js.map +1 -0
  54. package/lib/regexp.js +54 -70
  55. package/lib/regexp.js.map +1 -0
  56. package/lib/symbol.js +40 -56
  57. package/lib/symbol.js.map +1 -0
  58. package/lib/timestamp.js +70 -95
  59. package/lib/timestamp.js.map +1 -0
  60. package/lib/uuid.js +48 -0
  61. package/lib/uuid.js.map +1 -0
  62. package/lib/validate_utf8.js +32 -33
  63. package/lib/validate_utf8.js.map +1 -0
  64. package/package.json +53 -31
  65. package/src/binary.ts +270 -0
  66. package/src/bson.ts +326 -0
  67. package/src/code.ts +57 -0
  68. package/src/constants.ts +104 -0
  69. package/src/db_ref.ts +115 -0
  70. package/src/decimal128.ts +801 -0
  71. package/src/double.ts +85 -0
  72. package/src/ensure_buffer.ts +26 -0
  73. package/src/extended_json.ts +395 -0
  74. package/src/float_parser.ts +152 -0
  75. package/src/int_32.ts +64 -0
  76. package/src/long.ts +1000 -0
  77. package/src/map.ts +139 -0
  78. package/src/max_key.ts +33 -0
  79. package/src/min_key.ts +33 -0
  80. package/src/objectid.ts +377 -0
  81. package/src/parser/calculate_size.ts +230 -0
  82. package/src/parser/deserializer.ts +655 -0
  83. package/src/parser/serializer.ts +1069 -0
  84. package/src/parser/utils.ts +93 -0
  85. package/src/regexp.ts +92 -0
  86. package/src/symbol.ts +57 -0
  87. package/src/timestamp.ts +103 -0
  88. package/src/uuid.ts +57 -0
  89. package/src/validate_utf8.ts +47 -0
  90. package/lib/fnv1a.js +0 -48
@@ -1,347 +1,330 @@
1
- 'use strict';
2
-
3
- // const Buffer = require('buffer').Buffer;
4
- // const Map = require('./map');
5
- const Long = require('./long');
6
- const Double = require('./double');
7
- const Timestamp = require('./timestamp');
8
- const ObjectId = require('./objectid');
9
- const BSONRegExp = require('./regexp');
10
- const Symbol = require('./symbol');
11
- const Int32 = require('./int_32');
12
- const Code = require('./code');
13
- const Decimal128 = require('./decimal128');
14
- const MinKey = require('./min_key');
15
- const MaxKey = require('./max_key');
16
- const DBRef = require('./db_ref');
17
- const Binary = require('./binary');
18
-
19
- /**
20
- * @namespace EJSON
21
- */
22
-
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EJSON = exports.isBSONType = void 0;
4
+ const binary_1 = require("./binary");
5
+ const code_1 = require("./code");
6
+ const db_ref_1 = require("./db_ref");
7
+ const decimal128_1 = require("./decimal128");
8
+ const double_1 = require("./double");
9
+ const int_32_1 = require("./int_32");
10
+ const long_1 = require("./long");
11
+ const max_key_1 = require("./max_key");
12
+ const min_key_1 = require("./min_key");
13
+ const objectid_1 = require("./objectid");
14
+ const utils_1 = require("./parser/utils");
15
+ const regexp_1 = require("./regexp");
16
+ const symbol_1 = require("./symbol");
17
+ const timestamp_1 = require("./timestamp");
18
+ function isBSONType(value) {
19
+ return (utils_1.isObjectLike(value) && Reflect.has(value, '_bsontype') && typeof value._bsontype === 'string');
20
+ }
21
+ exports.isBSONType = isBSONType;
22
+ // INT32 boundaries
23
+ const BSON_INT32_MAX = 0x7fffffff;
24
+ const BSON_INT32_MIN = -0x80000000;
25
+ // INT64 boundaries
26
+ const BSON_INT64_MAX = 0x7fffffffffffffff;
27
+ const BSON_INT64_MIN = -0x8000000000000000;
23
28
  // all the types where we don't need to do any special processing and can just pass the EJSON
24
29
  //straight to type.fromExtendedJSON
25
30
  const keysToCodecs = {
26
- $oid: ObjectId,
27
- $binary: Binary,
28
- $symbol: Symbol,
29
- $numberInt: Int32,
30
- $numberDecimal: Decimal128,
31
- $numberDouble: Double,
32
- $numberLong: Long,
33
- $minKey: MinKey,
34
- $maxKey: MaxKey,
35
- $regex: BSONRegExp,
36
- $regularExpression: BSONRegExp,
37
- $timestamp: Timestamp
31
+ $oid: objectid_1.ObjectId,
32
+ $binary: binary_1.Binary,
33
+ $uuid: binary_1.Binary,
34
+ $symbol: symbol_1.BSONSymbol,
35
+ $numberInt: int_32_1.Int32,
36
+ $numberDecimal: decimal128_1.Decimal128,
37
+ $numberDouble: double_1.Double,
38
+ $numberLong: long_1.Long,
39
+ $minKey: min_key_1.MinKey,
40
+ $maxKey: max_key_1.MaxKey,
41
+ $regex: regexp_1.BSONRegExp,
42
+ $regularExpression: regexp_1.BSONRegExp,
43
+ $timestamp: timestamp_1.Timestamp
38
44
  };
39
-
40
- function deserializeValue(self, key, value, options) {
41
- if (typeof value === 'number') {
42
- if (options.relaxed || options.legacy) {
43
- return value;
45
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
46
+ function deserializeValue(value, options = {}) {
47
+ if (typeof value === 'number') {
48
+ if (options.relaxed || options.legacy) {
49
+ return value;
50
+ }
51
+ // if it's an integer, should interpret as smallest BSON integer
52
+ // that can represent it exactly. (if out of range, interpret as double.)
53
+ if (Math.floor(value) === value) {
54
+ if (value >= BSON_INT32_MIN && value <= BSON_INT32_MAX)
55
+ return new int_32_1.Int32(value);
56
+ if (value >= BSON_INT64_MIN && value <= BSON_INT64_MAX)
57
+ return long_1.Long.fromNumber(value);
58
+ }
59
+ // If the number is a non-integer or out of integer range, should interpret as BSON Double.
60
+ return new double_1.Double(value);
44
61
  }
45
-
46
- // if it's an integer, should interpret as smallest BSON integer
47
- // that can represent it exactly. (if out of range, interpret as double.)
48
- if (Math.floor(value) === value) {
49
- if (value >= BSON_INT32_MIN && value <= BSON_INT32_MAX) return new Int32(value);
50
- if (value >= BSON_INT64_MIN && value <= BSON_INT64_MAX) return new Long.fromNumber(value);
62
+ // from here on out we're looking for bson types, so bail if its not an object
63
+ if (value == null || typeof value !== 'object')
64
+ return value;
65
+ // upgrade deprecated undefined to null
66
+ if (value.$undefined)
67
+ return null;
68
+ const keys = Object.keys(value).filter(k => k.startsWith('$') && value[k] != null);
69
+ for (let i = 0; i < keys.length; i++) {
70
+ const c = keysToCodecs[keys[i]];
71
+ if (c)
72
+ return c.fromExtendedJSON(value, options);
51
73
  }
52
-
53
- // If the number is a non-integer or out of integer range, should interpret as BSON Double.
54
- return new Double(value);
55
- }
56
-
57
- // from here on out we're looking for bson types, so bail if its not an object
58
- if (value == null || typeof value !== 'object') return value;
59
-
60
- // upgrade deprecated undefined to null
61
- if (value.$undefined) return null;
62
-
63
- const keys = Object.keys(value).filter(k => k.startsWith('$') && value[k] != null);
64
- for (let i = 0; i < keys.length; i++) {
65
- let c = keysToCodecs[keys[i]];
66
- if (c) return c.fromExtendedJSON(value, options);
67
- }
68
-
69
- if (value.$date != null) {
70
- const d = value.$date;
71
- const date = new Date();
72
-
73
- if (options.legacy) {
74
- if (typeof d === 'number') date.setTime(d);
75
- else if (typeof d === 'string') date.setTime(Date.parse(d));
76
- } else {
77
- if (typeof d === 'string') date.setTime(Date.parse(d));
78
- else if (Long.isLong(d)) date.setTime(d.toNumber());
79
- else if (typeof d === 'number' && options.relaxed) date.setTime(d);
74
+ if (value.$date != null) {
75
+ const d = value.$date;
76
+ const date = new Date();
77
+ if (options.legacy) {
78
+ if (typeof d === 'number')
79
+ date.setTime(d);
80
+ else if (typeof d === 'string')
81
+ date.setTime(Date.parse(d));
82
+ }
83
+ else {
84
+ if (typeof d === 'string')
85
+ date.setTime(Date.parse(d));
86
+ else if (long_1.Long.isLong(d))
87
+ date.setTime(d.toNumber());
88
+ else if (typeof d === 'number' && options.relaxed)
89
+ date.setTime(d);
90
+ }
91
+ return date;
80
92
  }
81
- return date;
82
- }
83
-
84
- if (value.$code != null) {
85
- let copy = Object.assign({}, value);
86
- if (value.$scope) {
87
- copy.$scope = deserializeValue(self, null, value.$scope);
93
+ if (value.$code != null) {
94
+ const copy = Object.assign({}, value);
95
+ if (value.$scope) {
96
+ copy.$scope = deserializeValue(value.$scope);
97
+ }
98
+ return code_1.Code.fromExtendedJSON(value);
88
99
  }
89
-
90
- return Code.fromExtendedJSON(value);
91
- }
92
-
93
- if (value.$ref != null || value.$dbPointer != null) {
94
- let v = value.$ref ? value : value.$dbPointer;
95
-
96
- // we run into this in a "degenerate EJSON" case (with $id and $ref order flipped)
97
- // because of the order JSON.parse goes through the document
98
- if (v instanceof DBRef) return v;
99
-
100
- const dollarKeys = Object.keys(v).filter(k => k.startsWith('$'));
101
- let valid = true;
102
- dollarKeys.forEach(k => {
103
- if (['$ref', '$id', '$db'].indexOf(k) === -1) valid = false;
104
- });
105
-
106
- // only make DBRef if $ keys are all valid
107
- if (valid) return DBRef.fromExtendedJSON(v);
108
- }
109
-
110
- return value;
111
- }
112
-
113
- /**
114
- * Parse an Extended JSON string, constructing the JavaScript value or object described by that
115
- * string.
116
- *
117
- * @memberof EJSON
118
- * @param {string} text
119
- * @param {object} [options] Optional settings
120
- * @param {boolean} [options.relaxed=true] Attempt to return native JS types where possible, rather than BSON types (if true)
121
- * @return {object}
122
- *
123
- * @example
124
- * const { EJSON } = require('bson');
125
- * const text = '{ "int32": { "$numberInt": "10" } }';
126
- *
127
- * // prints { int32: { [String: '10'] _bsontype: 'Int32', value: '10' } }
128
- * console.log(EJSON.parse(text, { relaxed: false }));
129
- *
130
- * // prints { int32: 10 }
131
- * console.log(EJSON.parse(text));
132
- */
133
- function parse(text, options) {
134
- options = Object.assign({}, { relaxed: true, legacy: false }, options);
135
-
136
- // relaxed implies not strict
137
- if (typeof options.relaxed === 'boolean') options.strict = !options.relaxed;
138
- if (typeof options.strict === 'boolean') options.relaxed = !options.strict;
139
-
140
- return JSON.parse(text, (key, value) => deserializeValue(this, key, value, options));
141
- }
142
-
143
- //
144
- // Serializer
145
- //
146
-
147
- // MAX INT32 boundaries
148
- const BSON_INT32_MAX = 0x7fffffff,
149
- BSON_INT32_MIN = -0x80000000,
150
- BSON_INT64_MAX = 0x7fffffffffffffff,
151
- BSON_INT64_MIN = -0x8000000000000000;
152
-
153
- /**
154
- * Converts a BSON document to an Extended JSON string, optionally replacing values if a replacer
155
- * function is specified or optionally including only the specified properties if a replacer array
156
- * is specified.
157
- *
158
- * @memberof EJSON
159
- * @param {object} value The value to convert to extended JSON
160
- * @param {function|array} [replacer] A function that alters the behavior of the stringification process, or an array of String and Number objects that serve as a whitelist for selecting/filtering the properties of the value object to be included in the JSON string. If this value is null or not provided, all properties of the object are included in the resulting JSON string
161
- * @param {string|number} [space] A String or Number object that's used to insert white space into the output JSON string for readability purposes.
162
- * @param {object} [options] Optional settings
163
- * @param {boolean} [options.relaxed=true] Enabled Extended JSON's `relaxed` mode
164
- * @param {boolean} [options.legacy=false] Output using the Extended JSON v1 spec
165
- * @returns {string}
166
- *
167
- * @example
168
- * const { EJSON } = require('bson');
169
- * const Int32 = require('mongodb').Int32;
170
- * const doc = { int32: new Int32(10) };
171
- *
172
- * // prints '{"int32":{"$numberInt":"10"}}'
173
- * console.log(EJSON.stringify(doc, { relaxed: false }));
174
- *
175
- * // prints '{"int32":10}'
176
- * console.log(EJSON.stringify(doc));
177
- */
178
- function stringify(value, replacer, space, options) {
179
- if (space != null && typeof space === 'object') {
180
- options = space;
181
- space = 0;
182
- }
183
- if (replacer != null && typeof replacer === 'object' && !Array.isArray(replacer)) {
184
- options = replacer;
185
- replacer = null;
186
- space = 0;
187
- }
188
- options = Object.assign({}, { relaxed: true, legacy: false }, options);
189
-
190
- const doc = Array.isArray(value)
191
- ? serializeArray(value, options)
192
- : serializeDocument(value, options);
193
-
194
- return JSON.stringify(doc, replacer, space);
195
- }
196
-
197
- /**
198
- * Serializes an object to an Extended JSON string, and reparse it as a JavaScript object.
199
- *
200
- * @memberof EJSON
201
- * @param {object} bson The object to serialize
202
- * @param {object} [options] Optional settings passed to the `stringify` function
203
- * @return {object}
204
- */
205
- function serialize(bson, options) {
206
- options = options || {};
207
- return JSON.parse(stringify(bson, options));
208
- }
209
-
210
- /**
211
- * Deserializes an Extended JSON object into a plain JavaScript object with native/BSON types
212
- *
213
- * @memberof EJSON
214
- * @param {object} ejson The Extended JSON object to deserialize
215
- * @param {object} [options] Optional settings passed to the parse method
216
- * @return {object}
217
- */
218
- function deserialize(ejson, options) {
219
- options = options || {};
220
- return parse(JSON.stringify(ejson), options);
100
+ if (value.$ref != null || value.$dbPointer != null) {
101
+ const v = value.$ref ? value : value.$dbPointer;
102
+ // we run into this in a "degenerate EJSON" case (with $id and $ref order flipped)
103
+ // because of the order JSON.parse goes through the document
104
+ if (v instanceof db_ref_1.DBRef)
105
+ return v;
106
+ const dollarKeys = Object.keys(v).filter(k => k.startsWith('$'));
107
+ let valid = true;
108
+ dollarKeys.forEach(k => {
109
+ if (['$ref', '$id', '$db'].indexOf(k) === -1)
110
+ valid = false;
111
+ });
112
+ // only make DBRef if $ keys are all valid
113
+ if (valid)
114
+ return db_ref_1.DBRef.fromExtendedJSON(v);
115
+ }
116
+ return value;
221
117
  }
222
-
118
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
223
119
  function serializeArray(array, options) {
224
- return array.map(v => serializeValue(v, options));
120
+ return array.map((v) => serializeValue(v, options));
225
121
  }
226
-
227
122
  function getISOString(date) {
228
- const isoStr = date.toISOString();
229
- // we should only show milliseconds in timestamp if they're non-zero
230
- return date.getUTCMilliseconds() !== 0 ? isoStr : isoStr.slice(0, -5) + 'Z';
123
+ const isoStr = date.toISOString();
124
+ // we should only show milliseconds in timestamp if they're non-zero
125
+ return date.getUTCMilliseconds() !== 0 ? isoStr : isoStr.slice(0, -5) + 'Z';
231
126
  }
232
-
127
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
233
128
  function serializeValue(value, options) {
234
- if (Array.isArray(value)) return serializeArray(value, options);
235
-
236
- if (value === undefined) return null;
237
-
238
- if (value instanceof Date) {
239
- let dateNum = value.getTime(),
240
- // is it in year range 1970-9999?
241
- inRange = dateNum > -1 && dateNum < 253402318800000;
242
-
243
- if (options.legacy) {
244
- return options.relaxed && inRange
245
- ? { $date: value.getTime() }
246
- : { $date: getISOString(value) };
129
+ if (Array.isArray(value))
130
+ return serializeArray(value, options);
131
+ if (value === undefined)
132
+ return null;
133
+ if (value instanceof Date) {
134
+ const dateNum = value.getTime(),
135
+ // is it in year range 1970-9999?
136
+ inRange = dateNum > -1 && dateNum < 253402318800000;
137
+ if (options.legacy) {
138
+ return options.relaxed && inRange
139
+ ? { $date: value.getTime() }
140
+ : { $date: getISOString(value) };
141
+ }
142
+ return options.relaxed && inRange
143
+ ? { $date: getISOString(value) }
144
+ : { $date: { $numberLong: value.getTime().toString() } };
247
145
  }
248
- return options.relaxed && inRange
249
- ? { $date: getISOString(value) }
250
- : { $date: { $numberLong: value.getTime().toString() } };
251
- }
252
-
253
- if (typeof value === 'number' && !options.relaxed) {
254
- // it's an integer
255
- if (Math.floor(value) === value) {
256
- let int32Range = value >= BSON_INT32_MIN && value <= BSON_INT32_MAX,
257
- int64Range = value >= BSON_INT64_MIN && value <= BSON_INT64_MAX;
258
-
259
- // interpret as being of the smallest BSON integer type that can represent the number exactly
260
- if (int32Range) return { $numberInt: value.toString() };
261
- if (int64Range) return { $numberLong: value.toString() };
146
+ if (typeof value === 'number' && !options.relaxed) {
147
+ // it's an integer
148
+ if (Math.floor(value) === value) {
149
+ const int32Range = value >= BSON_INT32_MIN && value <= BSON_INT32_MAX, int64Range = value >= BSON_INT64_MIN && value <= BSON_INT64_MAX;
150
+ // interpret as being of the smallest BSON integer type that can represent the number exactly
151
+ if (int32Range)
152
+ return { $numberInt: value.toString() };
153
+ if (int64Range)
154
+ return { $numberLong: value.toString() };
155
+ }
156
+ return { $numberDouble: value.toString() };
262
157
  }
263
- return { $numberDouble: value.toString() };
264
- }
265
-
266
- if (value instanceof RegExp) {
267
- let flags = value.flags;
268
- if (flags === undefined) {
269
- flags = value.toString().match(/[gimuy]*$/)[0];
158
+ if (value instanceof RegExp) {
159
+ let flags = value.flags;
160
+ if (flags === undefined) {
161
+ const match = value.toString().match(/[gimuy]*$/);
162
+ if (match) {
163
+ flags = match[0];
164
+ }
165
+ }
166
+ const rx = new regexp_1.BSONRegExp(value.source, flags);
167
+ return rx.toExtendedJSON(options);
270
168
  }
271
-
272
- const rx = new BSONRegExp(value.source, flags);
273
- return rx.toExtendedJSON(options);
274
- }
275
-
276
- if (value != null && typeof value === 'object') return serializeDocument(value, options);
277
- return value;
169
+ if (value != null && typeof value === 'object')
170
+ return serializeDocument(value, options);
171
+ return value;
278
172
  }
279
-
280
173
  const BSON_TYPE_MAPPINGS = {
281
- Binary: o => new Binary(o.value(), o.subtype),
282
- Code: o => new Code(o.code, o.scope),
283
- DBRef: o => new DBRef(o.collection || o.namespace, o.oid, o.db, o.fields), // "namespace" for 1.x library backwards compat
284
- Decimal128: o => new Decimal128(o.bytes),
285
- Double: o => new Double(o.value),
286
- Int32: o => new Int32(o.value),
287
- Long: o =>
288
- Long.fromBits(
289
- // underscore variants for 1.x backwards compatibility
290
- o.low != null ? o.low : o.low_,
291
- o.low != null ? o.high : o.high_,
292
- o.low != null ? o.unsigned : o.unsigned_
293
- ),
294
- MaxKey: () => new MaxKey(),
295
- MinKey: () => new MinKey(),
296
- ObjectID: o => new ObjectId(o),
297
- ObjectId: o => new ObjectId(o), // support 4.0.0/4.0.1 before _bsontype was reverted back to ObjectID
298
- BSONRegExp: o => new BSONRegExp(o.pattern, o.options),
299
- Symbol: o => new Symbol(o.value),
300
- Timestamp: o => Timestamp.fromBits(o.low, o.high)
174
+ Binary: (o) => new binary_1.Binary(o.value(), o.sub_type),
175
+ Code: (o) => new code_1.Code(o.code, o.scope),
176
+ DBRef: (o) => new db_ref_1.DBRef(o.collection || o.namespace, o.oid, o.db, o.fields),
177
+ Decimal128: (o) => new decimal128_1.Decimal128(o.bytes),
178
+ Double: (o) => new double_1.Double(o.value),
179
+ Int32: (o) => new int_32_1.Int32(o.value),
180
+ Long: (o) => long_1.Long.fromBits(
181
+ // underscore variants for 1.x backwards compatibility
182
+ o.low != null ? o.low : o.low_, o.low != null ? o.high : o.high_, o.low != null ? o.unsigned : o.unsigned_),
183
+ MaxKey: () => new max_key_1.MaxKey(),
184
+ MinKey: () => new min_key_1.MinKey(),
185
+ ObjectID: (o) => new objectid_1.ObjectId(o),
186
+ ObjectId: (o) => new objectid_1.ObjectId(o),
187
+ BSONRegExp: (o) => new regexp_1.BSONRegExp(o.pattern, o.options),
188
+ Symbol: (o) => new symbol_1.BSONSymbol(o.value),
189
+ Timestamp: (o) => timestamp_1.Timestamp.fromBits(o.low, o.high)
301
190
  };
302
-
191
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
303
192
  function serializeDocument(doc, options) {
304
- if (doc == null || typeof doc !== 'object') throw new Error('not an object instance');
305
-
306
- const bsontype = doc._bsontype;
307
- if (typeof bsontype === 'undefined') {
308
- // It's a regular object. Recursively serialize its property values.
309
- const _doc = {};
310
- for (let name in doc) {
311
- _doc[name] = serializeValue(doc[name], options);
193
+ if (doc == null || typeof doc !== 'object')
194
+ throw new Error('not an object instance');
195
+ const bsontype = doc._bsontype;
196
+ if (typeof bsontype === 'undefined') {
197
+ // It's a regular object. Recursively serialize its property values.
198
+ const _doc = {};
199
+ for (const name in doc) {
200
+ _doc[name] = serializeValue(doc[name], options);
201
+ }
202
+ return _doc;
312
203
  }
313
- return _doc;
314
- } else if (typeof bsontype === 'string') {
315
- // the "document" is really just a BSON type object
316
- let _doc = doc;
317
- if (typeof _doc.toExtendedJSON !== 'function') {
318
- // There's no EJSON serialization function on the object. It's probably an
319
- // object created by a previous version of this library (or another library)
320
- // that's duck-typing objects to look like they were generated by this library).
321
- // Copy the object into this library's version of that type.
322
- const mapper = BSON_TYPE_MAPPINGS[bsontype];
323
- if (!mapper) {
324
- throw new TypeError('Unrecognized or invalid _bsontype: ' + bsontype);
325
- }
326
- _doc = mapper(_doc);
204
+ else if (isBSONType(doc)) {
205
+ // the "document" is really just a BSON type object
206
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
207
+ let outDoc = doc;
208
+ if (typeof outDoc.toExtendedJSON !== 'function') {
209
+ // There's no EJSON serialization function on the object. It's probably an
210
+ // object created by a previous version of this library (or another library)
211
+ // that's duck-typing objects to look like they were generated by this library).
212
+ // Copy the object into this library's version of that type.
213
+ const mapper = BSON_TYPE_MAPPINGS[doc._bsontype];
214
+ if (!mapper) {
215
+ throw new TypeError('Unrecognized or invalid _bsontype: ' + doc._bsontype);
216
+ }
217
+ outDoc = mapper(outDoc);
218
+ }
219
+ // Two BSON types may have nested objects that may need to be serialized too
220
+ if (bsontype === 'Code' && outDoc.scope) {
221
+ outDoc = new code_1.Code(outDoc.code, serializeValue(outDoc.scope, options));
222
+ }
223
+ else if (bsontype === 'DBRef' && outDoc.oid) {
224
+ outDoc = new db_ref_1.DBRef(outDoc.collection, serializeValue(outDoc.oid, options), outDoc.db, outDoc.fields);
225
+ }
226
+ return outDoc.toExtendedJSON(options);
327
227
  }
328
-
329
- // Two BSON types may have nested objects that may need to be serialized too
330
- if (bsontype === 'Code' && _doc.scope) {
331
- _doc = new Code(_doc.code, serializeValue(_doc.scope, options));
332
- } else if (bsontype === 'DBRef' && _doc.oid) {
333
- _doc = new DBRef(_doc.collection, serializeValue(_doc.oid, options), _doc.db, _doc.fields);
228
+ else {
229
+ throw new Error('_bsontype must be a string, but was: ' + typeof bsontype);
334
230
  }
335
-
336
- return _doc.toExtendedJSON(options);
337
- } else {
338
- throw new Error('_bsontype must be a string, but was: ' + typeof bsontype);
339
- }
340
231
  }
341
-
342
- module.exports = {
343
- parse,
344
- deserialize,
345
- serialize,
346
- stringify
347
- };
232
+ /**
233
+ * EJSON parse / stringify API
234
+ * @public
235
+ */
236
+ // the namespace here is used to emulate `export * as EJSON from '...'`
237
+ // which as of now (sept 2020) api-extractor does not support
238
+ // eslint-disable-next-line @typescript-eslint/no-namespace
239
+ var EJSON;
240
+ (function (EJSON) {
241
+ /**
242
+ * Parse an Extended JSON string, constructing the JavaScript value or object described by that
243
+ * string.
244
+ *
245
+ * @example
246
+ * ```js
247
+ * const { EJSON } = require('bson');
248
+ * const text = '{ "int32": { "$numberInt": "10" } }';
249
+ *
250
+ * // prints { int32: { [String: '10'] _bsontype: 'Int32', value: '10' } }
251
+ * console.log(EJSON.parse(text, { relaxed: false }));
252
+ *
253
+ * // prints { int32: 10 }
254
+ * console.log(EJSON.parse(text));
255
+ * ```
256
+ */
257
+ function parse(text, options) {
258
+ const finalOptions = Object.assign({}, { relaxed: true, legacy: false }, options);
259
+ // relaxed implies not strict
260
+ if (typeof finalOptions.relaxed === 'boolean')
261
+ finalOptions.strict = !finalOptions.relaxed;
262
+ if (typeof finalOptions.strict === 'boolean')
263
+ finalOptions.relaxed = !finalOptions.strict;
264
+ return JSON.parse(text, (_key, value) => deserializeValue(value, finalOptions));
265
+ }
266
+ EJSON.parse = parse;
267
+ /**
268
+ * Converts a BSON document to an Extended JSON string, optionally replacing values if a replacer
269
+ * function is specified or optionally including only the specified properties if a replacer array
270
+ * is specified.
271
+ *
272
+ * @param value - The value to convert to extended JSON
273
+ * @param replacer - A function that alters the behavior of the stringification process, or an array of String and Number objects that serve as a whitelist for selecting/filtering the properties of the value object to be included in the JSON string. If this value is null or not provided, all properties of the object are included in the resulting JSON string
274
+ * @param space - A String or Number object that's used to insert white space into the output JSON string for readability purposes.
275
+ * @param options - Optional settings
276
+ *
277
+ * @example
278
+ * ```js
279
+ * const { EJSON } = require('bson');
280
+ * const Int32 = require('mongodb').Int32;
281
+ * const doc = { int32: new Int32(10) };
282
+ *
283
+ * // prints '{"int32":{"$numberInt":"10"}}'
284
+ * console.log(EJSON.stringify(doc, { relaxed: false }));
285
+ *
286
+ * // prints '{"int32":10}'
287
+ * console.log(EJSON.stringify(doc));
288
+ * ```
289
+ */
290
+ function stringify(value,
291
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
292
+ replacer, space, options) {
293
+ if (space != null && typeof space === 'object') {
294
+ options = space;
295
+ space = 0;
296
+ }
297
+ if (replacer != null && typeof replacer === 'object' && !Array.isArray(replacer)) {
298
+ options = replacer;
299
+ replacer = undefined;
300
+ space = 0;
301
+ }
302
+ options = Object.assign({}, { relaxed: true, legacy: false }, options);
303
+ const doc = serializeValue(value, options);
304
+ return JSON.stringify(doc, replacer, space);
305
+ }
306
+ EJSON.stringify = stringify;
307
+ /**
308
+ * Serializes an object to an Extended JSON string, and reparse it as a JavaScript object.
309
+ *
310
+ * @param value - The object to serialize
311
+ * @param options - Optional settings passed to the `stringify` function
312
+ */
313
+ function serialize(value, options) {
314
+ options = options || {};
315
+ return JSON.parse(stringify(value, options));
316
+ }
317
+ EJSON.serialize = serialize;
318
+ /**
319
+ * Deserializes an Extended JSON object into a plain JavaScript object with native/BSON types
320
+ *
321
+ * @param ejson - The Extended JSON object to deserialize
322
+ * @param options - Optional settings passed to the parse method
323
+ */
324
+ function deserialize(ejson, options) {
325
+ options = options || {};
326
+ return parse(JSON.stringify(ejson), options);
327
+ }
328
+ EJSON.deserialize = deserialize;
329
+ })(EJSON = exports.EJSON || (exports.EJSON = {}));
330
+ //# sourceMappingURL=extended_json.js.map