bson 4.1.0 → 4.2.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.
Files changed (90) hide show
  1. package/HISTORY.md +48 -1
  2. package/README.md +7 -9
  3. package/bower.json +1 -1
  4. package/bson.d.ts +986 -0
  5. package/dist/bson.browser.esm.js +7811 -5011
  6. package/dist/bson.browser.esm.js.map +1 -0
  7. package/dist/bson.browser.umd.js +7862 -5099
  8. package/dist/bson.browser.umd.js.map +1 -0
  9. package/dist/bson.bundle.js +8723 -9228
  10. package/dist/bson.bundle.js.map +1 -0
  11. package/dist/bson.esm.js +5728 -4951
  12. package/dist/bson.esm.js.map +1 -0
  13. package/etc/prepare.js +19 -0
  14. package/lib/binary.js +218 -398
  15. package/lib/binary.js.map +1 -0
  16. package/lib/bson.js +201 -240
  17. package/lib/bson.js.map +1 -0
  18. package/lib/code.js +41 -41
  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 +88 -81
  23. package/lib/db_ref.js.map +1 -0
  24. package/lib/decimal128.js +667 -777
  25. package/lib/decimal128.js.map +1 -0
  26. package/lib/double.js +68 -70
  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 +310 -321
  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 +50 -49
  35. package/lib/int_32.js.map +1 -0
  36. package/lib/long.js +881 -16
  37. package/lib/long.js.map +1 -0
  38. package/lib/map.js +130 -122
  39. package/lib/map.js.map +1 -0
  40. package/lib/max_key.js +28 -25
  41. package/lib/max_key.js.map +1 -0
  42. package/lib/min_key.js +28 -25
  43. package/lib/min_key.js.map +1 -0
  44. package/lib/objectid.js +300 -410
  45. package/lib/objectid.js.map +1 -0
  46. package/lib/parser/calculate_size.js +188 -224
  47. package/lib/parser/calculate_size.js.map +1 -0
  48. package/lib/parser/deserializer.js +545 -621
  49. package/lib/parser/deserializer.js.map +1 -0
  50. package/lib/parser/serializer.js +798 -923
  51. package/lib/parser/serializer.js.map +1 -0
  52. package/lib/parser/utils.js +92 -30
  53. package/lib/parser/utils.js.map +1 -0
  54. package/lib/regexp.js +61 -74
  55. package/lib/regexp.js.map +1 -0
  56. package/lib/symbol.js +45 -58
  57. package/lib/symbol.js.map +1 -0
  58. package/lib/timestamp.js +91 -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 +41 -42
  63. package/lib/validate_utf8.js.map +1 -0
  64. package/package.json +53 -31
  65. package/src/binary.ts +272 -0
  66. package/src/bson.ts +326 -0
  67. package/src/code.ts +61 -0
  68. package/src/constants.ts +104 -0
  69. package/src/db_ref.ts +119 -0
  70. package/src/decimal128.ts +803 -0
  71. package/src/double.ts +87 -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 +66 -0
  76. package/src/long.ts +1002 -0
  77. package/src/map.ts +139 -0
  78. package/src/max_key.ts +37 -0
  79. package/src/min_key.ts +37 -0
  80. package/src/objectid.ts +379 -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 +94 -0
  86. package/src/symbol.ts +59 -0
  87. package/src/timestamp.ts +108 -0
  88. package/src/uuid.ts +57 -0
  89. package/src/validate_utf8.ts +47 -0
  90. package/lib/fnv1a.js +0 -48
package/src/binary.ts ADDED
@@ -0,0 +1,272 @@
1
+ import { Buffer } from 'buffer';
2
+ import { ensureBuffer } from './ensure_buffer';
3
+ import type { EJSONOptions } from './extended_json';
4
+ import { parseUUID, UUIDExtended } from './uuid';
5
+
6
+ /** @public */
7
+ export type BinarySequence = Uint8Array | Buffer | number[];
8
+
9
+ /** @public */
10
+ export interface BinaryExtendedLegacy {
11
+ $type: string;
12
+ $binary: string;
13
+ }
14
+
15
+ /** @public */
16
+ export interface BinaryExtended {
17
+ $binary: {
18
+ subType: string;
19
+ base64: string;
20
+ };
21
+ }
22
+
23
+ /**
24
+ * A class representation of the BSON Binary type.
25
+ * @public
26
+ */
27
+ export class Binary {
28
+ _bsontype!: 'Binary';
29
+
30
+ /**
31
+ * Binary default subtype
32
+ * @internal
33
+ */
34
+ private static readonly BSON_BINARY_SUBTYPE_DEFAULT = 0;
35
+
36
+ /** Initial buffer default size */
37
+ static readonly BUFFER_SIZE = 256;
38
+ /** Default BSON type */
39
+ static readonly SUBTYPE_DEFAULT = 0;
40
+ /** Function BSON type */
41
+ static readonly SUBTYPE_FUNCTION = 1;
42
+ /** Byte Array BSON type */
43
+ static readonly SUBTYPE_BYTE_ARRAY = 2;
44
+ /** Deprecated UUID BSON type @deprecated Please use SUBTYPE_UUID */
45
+ static readonly SUBTYPE_UUID_OLD = 3;
46
+ /** UUID BSON type */
47
+ static readonly SUBTYPE_UUID = 4;
48
+ /** MD5 BSON type */
49
+ static readonly SUBTYPE_MD5 = 5;
50
+ /** User BSON type */
51
+ static readonly SUBTYPE_USER_DEFINED = 128;
52
+
53
+ buffer!: Buffer;
54
+ sub_type!: number;
55
+ position!: number;
56
+
57
+ /**
58
+ * @param buffer - a buffer object containing the binary data.
59
+ * @param subType - the option binary type.
60
+ */
61
+ constructor(buffer?: string | BinarySequence, subType?: number) {
62
+ if (!(this instanceof Binary)) return new Binary(buffer, subType);
63
+
64
+ if (
65
+ !(buffer == null) &&
66
+ !(typeof buffer === 'string') &&
67
+ !ArrayBuffer.isView(buffer) &&
68
+ !(buffer instanceof ArrayBuffer) &&
69
+ !Array.isArray(buffer)
70
+ ) {
71
+ throw new TypeError(
72
+ 'Binary can only be constructed from string, Buffer, TypedArray, or Array<number>'
73
+ );
74
+ }
75
+
76
+ this.sub_type = subType ?? Binary.BSON_BINARY_SUBTYPE_DEFAULT;
77
+
78
+ if (buffer == null) {
79
+ // create an empty binary buffer
80
+ this.buffer = Buffer.alloc(Binary.BUFFER_SIZE);
81
+ this.position = 0;
82
+ } else {
83
+ if (typeof buffer === 'string') {
84
+ // string
85
+ this.buffer = Buffer.from(buffer, 'binary');
86
+ } else if (Array.isArray(buffer)) {
87
+ // number[]
88
+ this.buffer = Buffer.from(buffer);
89
+ } else {
90
+ // Buffer | TypedArray | ArrayBuffer
91
+ this.buffer = ensureBuffer(buffer);
92
+ }
93
+
94
+ this.position = this.buffer.byteLength;
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Updates this binary with byte_value.
100
+ *
101
+ * @param byteValue - a single byte we wish to write.
102
+ */
103
+ put(byteValue: string | number | Uint8Array | Buffer | number[]): void {
104
+ // If it's a string and a has more than one character throw an error
105
+ if (typeof byteValue === 'string' && byteValue.length !== 1) {
106
+ throw new TypeError('only accepts single character String');
107
+ } else if (typeof byteValue !== 'number' && byteValue.length !== 1)
108
+ throw new TypeError('only accepts single character Uint8Array or Array');
109
+
110
+ // Decode the byte value once
111
+ let decodedByte: number;
112
+ if (typeof byteValue === 'string') {
113
+ decodedByte = byteValue.charCodeAt(0);
114
+ } else if (typeof byteValue === 'number') {
115
+ decodedByte = byteValue;
116
+ } else {
117
+ decodedByte = byteValue[0];
118
+ }
119
+
120
+ if (decodedByte < 0 || decodedByte > 255) {
121
+ throw new TypeError('only accepts number in a valid unsigned byte range 0-255');
122
+ }
123
+
124
+ if (this.buffer.length > this.position) {
125
+ this.buffer[this.position++] = decodedByte;
126
+ } else {
127
+ const buffer = Buffer.alloc(Binary.BUFFER_SIZE + this.buffer.length);
128
+ // Combine the two buffers together
129
+ this.buffer.copy(buffer, 0, 0, this.buffer.length);
130
+ this.buffer = buffer;
131
+ this.buffer[this.position++] = decodedByte;
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Writes a buffer or string to the binary.
137
+ *
138
+ * @param sequence - a string or buffer to be written to the Binary BSON object.
139
+ * @param offset - specify the binary of where to write the content.
140
+ */
141
+ write(sequence: string | BinarySequence, offset: number): void {
142
+ offset = typeof offset === 'number' ? offset : this.position;
143
+
144
+ // If the buffer is to small let's extend the buffer
145
+ if (this.buffer.length < offset + sequence.length) {
146
+ const buffer = Buffer.alloc(this.buffer.length + sequence.length);
147
+ this.buffer.copy(buffer, 0, 0, this.buffer.length);
148
+
149
+ // Assign the new buffer
150
+ this.buffer = buffer;
151
+ }
152
+
153
+ if (ArrayBuffer.isView(sequence)) {
154
+ this.buffer.set(ensureBuffer(sequence), offset);
155
+ this.position =
156
+ offset + sequence.byteLength > this.position ? offset + sequence.length : this.position;
157
+ } else if (typeof sequence === 'string') {
158
+ this.buffer.write(sequence, offset, sequence.length, 'binary');
159
+ this.position =
160
+ offset + sequence.length > this.position ? offset + sequence.length : this.position;
161
+ }
162
+ }
163
+
164
+ /**
165
+ * Reads **length** bytes starting at **position**.
166
+ *
167
+ * @param position - read from the given position in the Binary.
168
+ * @param length - the number of bytes to read.
169
+ */
170
+ read(position: number, length: number): BinarySequence {
171
+ length = length && length > 0 ? length : this.position;
172
+
173
+ // Let's return the data based on the type we have
174
+ return this.buffer.slice(position, position + length);
175
+ }
176
+
177
+ /**
178
+ * Returns the value of this binary as a string.
179
+ * @param asRaw - Will skip converting to a string
180
+ * @remarks
181
+ * This is handy when calling this function conditionally for some key value pairs and not others
182
+ */
183
+ value(asRaw?: boolean): string | BinarySequence {
184
+ asRaw = !!asRaw;
185
+
186
+ // Optimize to serialize for the situation where the data == size of buffer
187
+ if (asRaw && this.buffer.length === this.position) {
188
+ return this.buffer;
189
+ }
190
+
191
+ // If it's a node.js buffer object
192
+ if (asRaw) {
193
+ return this.buffer.slice(0, this.position);
194
+ }
195
+ return this.buffer.toString('binary', 0, this.position);
196
+ }
197
+
198
+ /** the length of the binary sequence */
199
+ length(): number {
200
+ return this.position;
201
+ }
202
+
203
+ /** @internal */
204
+ toJSON(): string {
205
+ return this.buffer.toString('base64');
206
+ }
207
+
208
+ /** @internal */
209
+ toString(format: string): string {
210
+ return this.buffer.toString(format);
211
+ }
212
+
213
+ /** @internal */
214
+ toExtendedJSON(options?: EJSONOptions): BinaryExtendedLegacy | BinaryExtended {
215
+ options = options || {};
216
+ const base64String = this.buffer.toString('base64');
217
+
218
+ const subType = Number(this.sub_type).toString(16);
219
+ if (options.legacy) {
220
+ return {
221
+ $binary: base64String,
222
+ $type: subType.length === 1 ? '0' + subType : subType
223
+ };
224
+ }
225
+ return {
226
+ $binary: {
227
+ base64: base64String,
228
+ subType: subType.length === 1 ? '0' + subType : subType
229
+ }
230
+ };
231
+ }
232
+
233
+ /** @internal */
234
+ static fromExtendedJSON(
235
+ doc: BinaryExtendedLegacy | BinaryExtended | UUIDExtended,
236
+ options?: EJSONOptions
237
+ ): Binary {
238
+ options = options || {};
239
+ let data: Buffer | undefined;
240
+ let type;
241
+ if ('$binary' in doc) {
242
+ if (options.legacy && typeof doc.$binary === 'string' && '$type' in doc) {
243
+ type = doc.$type ? parseInt(doc.$type, 16) : 0;
244
+ data = Buffer.from(doc.$binary, 'base64');
245
+ } else {
246
+ if (typeof doc.$binary !== 'string') {
247
+ type = doc.$binary.subType ? parseInt(doc.$binary.subType, 16) : 0;
248
+ data = Buffer.from(doc.$binary.base64, 'base64');
249
+ }
250
+ }
251
+ } else if ('$uuid' in doc) {
252
+ type = 4;
253
+ data = Buffer.from(parseUUID(doc.$uuid));
254
+ }
255
+ if (!data) {
256
+ throw new TypeError(`Unexpected Binary Extended JSON format ${JSON.stringify(doc)}`);
257
+ }
258
+ return new Binary(data, type);
259
+ }
260
+
261
+ /** @internal */
262
+ [Symbol.for('nodejs.util.inspect.custom')](): string {
263
+ return this.inspect();
264
+ }
265
+
266
+ inspect(): string {
267
+ const asBuffer = this.value(true);
268
+ return `new Binary(Buffer.from("${asBuffer.toString('hex')}", "hex"), ${this.sub_type})`;
269
+ }
270
+ }
271
+
272
+ Object.defineProperty(Binary.prototype, '_bsontype', { value: 'Binary' });
package/src/bson.ts ADDED
@@ -0,0 +1,326 @@
1
+ import { Buffer } from 'buffer';
2
+ import { Binary } from './binary';
3
+ import { Code } from './code';
4
+ import { DBRef } from './db_ref';
5
+ import { Decimal128 } from './decimal128';
6
+ import { Double } from './double';
7
+ import { ensureBuffer } from './ensure_buffer';
8
+ import { EJSON } from './extended_json';
9
+ import { Int32 } from './int_32';
10
+ import { Long } from './long';
11
+ import { Map } from './map';
12
+ import { MaxKey } from './max_key';
13
+ import { MinKey } from './min_key';
14
+ import { ObjectId } from './objectid';
15
+ import { calculateObjectSize as internalCalculateObjectSize } from './parser/calculate_size';
16
+ // Parts of the parser
17
+ import { deserialize as internalDeserialize, DeserializeOptions } from './parser/deserializer';
18
+ import { serializeInto as internalSerialize, SerializeOptions } from './parser/serializer';
19
+ import { BSONRegExp } from './regexp';
20
+ import { BSONSymbol } from './symbol';
21
+ import { Timestamp } from './timestamp';
22
+ export { BinaryExtended, BinaryExtendedLegacy, BinarySequence } from './binary';
23
+ export { CodeExtended } from './code';
24
+ export {
25
+ BSON_BINARY_SUBTYPE_BYTE_ARRAY,
26
+ BSON_BINARY_SUBTYPE_DEFAULT,
27
+ BSON_BINARY_SUBTYPE_FUNCTION,
28
+ BSON_BINARY_SUBTYPE_MD5,
29
+ BSON_BINARY_SUBTYPE_USER_DEFINED,
30
+ BSON_BINARY_SUBTYPE_UUID,
31
+ BSON_BINARY_SUBTYPE_UUID_NEW,
32
+ BSON_DATA_ARRAY,
33
+ BSON_DATA_BINARY,
34
+ BSON_DATA_BOOLEAN,
35
+ BSON_DATA_CODE,
36
+ BSON_DATA_CODE_W_SCOPE,
37
+ BSON_DATA_DATE,
38
+ BSON_DATA_DBPOINTER,
39
+ BSON_DATA_DECIMAL128,
40
+ BSON_DATA_INT,
41
+ BSON_DATA_LONG,
42
+ BSON_DATA_MAX_KEY,
43
+ BSON_DATA_MIN_KEY,
44
+ BSON_DATA_NULL,
45
+ BSON_DATA_NUMBER,
46
+ BSON_DATA_OBJECT,
47
+ BSON_DATA_OID,
48
+ BSON_DATA_REGEXP,
49
+ BSON_DATA_STRING,
50
+ BSON_DATA_SYMBOL,
51
+ BSON_DATA_TIMESTAMP,
52
+ BSON_DATA_UNDEFINED,
53
+ BSON_INT32_MAX,
54
+ BSON_INT32_MIN,
55
+ BSON_INT64_MAX,
56
+ BSON_INT64_MIN
57
+ } from './constants';
58
+ export { DBRefLike } from './db_ref';
59
+ export { Decimal128Extended } from './decimal128';
60
+ export { DoubleExtended } from './double';
61
+ export { EJSON, EJSONOptions } from './extended_json';
62
+ export { Int32Extended } from './int_32';
63
+ export { LongExtended } from './long';
64
+ export { MaxKeyExtended } from './max_key';
65
+ export { MinKeyExtended } from './min_key';
66
+ export { ObjectIdExtended, ObjectIdLike } from './objectid';
67
+ export { BSONRegExpExtended, BSONRegExpExtendedLegacy } from './regexp';
68
+ export { BSONSymbolExtended } from './symbol';
69
+ export {
70
+ LongWithoutOverrides,
71
+ LongWithoutOverridesClass,
72
+ TimestampExtended,
73
+ TimestampOverrides
74
+ } from './timestamp';
75
+ export { UUIDExtended } from './uuid';
76
+ export { SerializeOptions, DeserializeOptions };
77
+ export {
78
+ Code,
79
+ Map,
80
+ BSONSymbol,
81
+ DBRef,
82
+ Binary,
83
+ ObjectId,
84
+ Long,
85
+ Timestamp,
86
+ Double,
87
+ Int32,
88
+ MinKey,
89
+ MaxKey,
90
+ BSONRegExp,
91
+ Decimal128,
92
+ // In 4.0.0 and 4.0.1, this property name was changed to ObjectId to match the class name.
93
+ // This caused interoperability problems with previous versions of the library, so in
94
+ // later builds we changed it back to ObjectID (capital D) to match legacy implementations.
95
+ ObjectId as ObjectID
96
+ };
97
+
98
+ /** @public */
99
+ export interface Document {
100
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
101
+ [key: string]: any;
102
+ }
103
+
104
+ /** @internal */
105
+ // Default Max Size
106
+ const MAXSIZE = 1024 * 1024 * 17;
107
+
108
+ // Current Internal Temporary Serialization Buffer
109
+ let buffer = Buffer.alloc(MAXSIZE);
110
+
111
+ /**
112
+ * Sets the size of the internal serialization buffer.
113
+ *
114
+ * @param size - The desired size for the internal serialization buffer
115
+ * @public
116
+ */
117
+ export function setInternalBufferSize(size: number): void {
118
+ // Resize the internal serialization buffer if needed
119
+ if (buffer.length < size) {
120
+ buffer = Buffer.alloc(size);
121
+ }
122
+ }
123
+
124
+ /**
125
+ * Serialize a Javascript object.
126
+ *
127
+ * @param object - the Javascript object to serialize.
128
+ * @returns Buffer object containing the serialized object.
129
+ * @public
130
+ */
131
+ export function serialize(object: Document, options: SerializeOptions = {}): Buffer {
132
+ // Unpack the options
133
+ const checkKeys = typeof options.checkKeys === 'boolean' ? options.checkKeys : false;
134
+ const serializeFunctions =
135
+ typeof options.serializeFunctions === 'boolean' ? options.serializeFunctions : false;
136
+ const ignoreUndefined =
137
+ typeof options.ignoreUndefined === 'boolean' ? options.ignoreUndefined : true;
138
+ const minInternalBufferSize =
139
+ typeof options.minInternalBufferSize === 'number' ? options.minInternalBufferSize : MAXSIZE;
140
+
141
+ // Resize the internal serialization buffer if needed
142
+ if (buffer.length < minInternalBufferSize) {
143
+ buffer = Buffer.alloc(minInternalBufferSize);
144
+ }
145
+
146
+ // Attempt to serialize
147
+ const serializationIndex = internalSerialize(
148
+ buffer,
149
+ object,
150
+ checkKeys,
151
+ 0,
152
+ 0,
153
+ serializeFunctions,
154
+ ignoreUndefined,
155
+ []
156
+ );
157
+
158
+ // Create the final buffer
159
+ const finishedBuffer = Buffer.alloc(serializationIndex);
160
+
161
+ // Copy into the finished buffer
162
+ buffer.copy(finishedBuffer, 0, 0, finishedBuffer.length);
163
+
164
+ // Return the buffer
165
+ return finishedBuffer;
166
+ }
167
+
168
+ /**
169
+ * Serialize a Javascript object using a predefined Buffer and index into the buffer,
170
+ * useful when pre-allocating the space for serialization.
171
+ *
172
+ * @param object - the Javascript object to serialize.
173
+ * @param finalBuffer - the Buffer you pre-allocated to store the serialized BSON object.
174
+ * @returns the index pointing to the last written byte in the buffer.
175
+ * @public
176
+ */
177
+ export function serializeWithBufferAndIndex(
178
+ object: Document,
179
+ finalBuffer: Buffer,
180
+ options: SerializeOptions = {}
181
+ ): number {
182
+ // Unpack the options
183
+ const checkKeys = typeof options.checkKeys === 'boolean' ? options.checkKeys : false;
184
+ const serializeFunctions =
185
+ typeof options.serializeFunctions === 'boolean' ? options.serializeFunctions : false;
186
+ const ignoreUndefined =
187
+ typeof options.ignoreUndefined === 'boolean' ? options.ignoreUndefined : true;
188
+ const startIndex = typeof options.index === 'number' ? options.index : 0;
189
+
190
+ // Attempt to serialize
191
+ const serializationIndex = internalSerialize(
192
+ buffer,
193
+ object,
194
+ checkKeys,
195
+ 0,
196
+ 0,
197
+ serializeFunctions,
198
+ ignoreUndefined
199
+ );
200
+ buffer.copy(finalBuffer, startIndex, 0, serializationIndex);
201
+
202
+ // Return the index
203
+ return startIndex + serializationIndex - 1;
204
+ }
205
+
206
+ /**
207
+ * Deserialize data as BSON.
208
+ *
209
+ * @param buffer - the buffer containing the serialized set of BSON documents.
210
+ * @returns returns the deserialized Javascript Object.
211
+ * @public
212
+ */
213
+ export function deserialize(
214
+ buffer: Buffer | ArrayBufferView | ArrayBuffer,
215
+ options: DeserializeOptions = {}
216
+ ): Document {
217
+ return internalDeserialize(ensureBuffer(buffer), options);
218
+ }
219
+
220
+ /** @public */
221
+ export type CalculateObjectSizeOptions = Pick<
222
+ SerializeOptions,
223
+ 'serializeFunctions' | 'ignoreUndefined'
224
+ >;
225
+
226
+ /**
227
+ * Calculate the bson size for a passed in Javascript object.
228
+ *
229
+ * @param object - the Javascript object to calculate the BSON byte size for
230
+ * @returns size of BSON object in bytes
231
+ * @public
232
+ */
233
+ export function calculateObjectSize(
234
+ object: Document,
235
+ options: CalculateObjectSizeOptions = {}
236
+ ): number {
237
+ options = options || {};
238
+
239
+ const serializeFunctions =
240
+ typeof options.serializeFunctions === 'boolean' ? options.serializeFunctions : false;
241
+ const ignoreUndefined =
242
+ typeof options.ignoreUndefined === 'boolean' ? options.ignoreUndefined : true;
243
+
244
+ return internalCalculateObjectSize(object, serializeFunctions, ignoreUndefined);
245
+ }
246
+
247
+ /**
248
+ * Deserialize stream data as BSON documents.
249
+ *
250
+ * @param data - the buffer containing the serialized set of BSON documents.
251
+ * @param startIndex - the start index in the data Buffer where the deserialization is to start.
252
+ * @param numberOfDocuments - number of documents to deserialize.
253
+ * @param documents - an array where to store the deserialized documents.
254
+ * @param docStartIndex - the index in the documents array from where to start inserting documents.
255
+ * @param options - additional options used for the deserialization.
256
+ * @returns next index in the buffer after deserialization **x** numbers of documents.
257
+ * @public
258
+ */
259
+ export function deserializeStream(
260
+ data: Buffer | ArrayBufferView | ArrayBuffer,
261
+ startIndex: number,
262
+ numberOfDocuments: number,
263
+ documents: Document[],
264
+ docStartIndex: number,
265
+ options: DeserializeOptions
266
+ ): number {
267
+ const internalOptions = Object.assign(
268
+ { allowObjectSmallerThanBufferSize: true, index: 0 },
269
+ options
270
+ );
271
+ const bufferData = ensureBuffer(data);
272
+
273
+ let index = startIndex;
274
+ // Loop over all documents
275
+ for (let i = 0; i < numberOfDocuments; i++) {
276
+ // Find size of the document
277
+ const size =
278
+ bufferData[index] |
279
+ (bufferData[index + 1] << 8) |
280
+ (bufferData[index + 2] << 16) |
281
+ (bufferData[index + 3] << 24);
282
+ // Update options with index
283
+ internalOptions.index = index;
284
+ // Parse the document at this point
285
+ documents[docStartIndex + i] = internalDeserialize(bufferData, internalOptions);
286
+ // Adjust index by the document size
287
+ index = index + size;
288
+ }
289
+
290
+ // Return object containing end index of parsing and list of documents
291
+ return index;
292
+ }
293
+
294
+ /**
295
+ * BSON default export
296
+ * @deprecated Please use named exports
297
+ * @privateRemarks
298
+ * We want to someday deprecate the default export,
299
+ * so none of the new TS types are being exported on the default
300
+ * @public
301
+ */
302
+ const BSON = {
303
+ Binary,
304
+ Code,
305
+ DBRef,
306
+ Decimal128,
307
+ Double,
308
+ Int32,
309
+ Long,
310
+ Map,
311
+ MaxKey,
312
+ MinKey,
313
+ ObjectId,
314
+ ObjectID: ObjectId,
315
+ BSONRegExp,
316
+ BSONSymbol,
317
+ Timestamp,
318
+ EJSON,
319
+ setInternalBufferSize,
320
+ serialize,
321
+ serializeWithBufferAndIndex,
322
+ deserialize,
323
+ calculateObjectSize,
324
+ deserializeStream
325
+ };
326
+ export default BSON;
package/src/code.ts ADDED
@@ -0,0 +1,61 @@
1
+ import type { Document } from './bson';
2
+
3
+ /** @public */
4
+ export interface CodeExtended {
5
+ $code: string | Function;
6
+ $scope?: Document;
7
+ }
8
+
9
+ /**
10
+ * A class representation of the BSON Code type.
11
+ * @public
12
+ */
13
+ export class Code {
14
+ _bsontype!: 'Code';
15
+
16
+ code!: string | Function;
17
+ scope?: Document;
18
+ /**
19
+ * @param code - a string or function.
20
+ * @param scope - an optional scope for the function.
21
+ */
22
+ constructor(code: string | Function, scope?: Document) {
23
+ if (!(this instanceof Code)) return new Code(code, scope);
24
+
25
+ this.code = code;
26
+ this.scope = scope;
27
+ }
28
+
29
+ /** @internal */
30
+ toJSON(): { code: string | Function; scope?: Document } {
31
+ return { code: this.code, scope: this.scope };
32
+ }
33
+
34
+ /** @internal */
35
+ toExtendedJSON(): CodeExtended {
36
+ if (this.scope) {
37
+ return { $code: this.code, $scope: this.scope };
38
+ }
39
+
40
+ return { $code: this.code };
41
+ }
42
+
43
+ /** @internal */
44
+ static fromExtendedJSON(doc: CodeExtended): Code {
45
+ return new Code(doc.$code, doc.$scope);
46
+ }
47
+
48
+ /** @internal */
49
+ [Symbol.for('nodejs.util.inspect.custom')](): string {
50
+ return this.inspect();
51
+ }
52
+
53
+ inspect(): string {
54
+ const codeJson = this.toJSON();
55
+ return `new Code("${codeJson.code}"${
56
+ codeJson.scope ? `, ${JSON.stringify(codeJson.scope)}` : ''
57
+ })`;
58
+ }
59
+ }
60
+
61
+ Object.defineProperty(Code.prototype, '_bsontype', { value: 'Code' });