serializer.js 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.serializeInto = void 0;
  4. var binary_1 = require("../binary");
  5. var constants = require("../constants");
  6. var ensure_buffer_1 = require("../ensure_buffer");
  7. var error_1 = require("../error");
  8. var extended_json_1 = require("../extended_json");
  9. var long_1 = require("../long");
  10. var map_1 = require("../map");
  11. var utils_1 = require("./utils");
  12. var regexp = /\x00/; // eslint-disable-line no-control-regex
  13. var ignoreKeys = new Set(['$db', '$ref', '$id', '$clusterTime']);
  14. /*
  15. * isArray indicates if we are writing to a BSON array (type 0x04)
  16. * which forces the "key" which really an array index as a string to be written as ascii
  17. * This will catch any errors in index as a string generation
  18. */
  19. function serializeString(buffer, key, value, index, isArray) {
  20. // Encode String type
  21. buffer[index++] = constants.BSON_DATA_STRING;
  22. // Number of written bytes
  23. var numberOfWrittenBytes = !isArray
  24. ? buffer.write(key, index, undefined, 'utf8')
  25. : buffer.write(key, index, undefined, 'ascii');
  26. // Encode the name
  27. index = index + numberOfWrittenBytes + 1;
  28. buffer[index - 1] = 0;
  29. // Write the string
  30. var size = buffer.write(value, index + 4, undefined, 'utf8');
  31. // Write the size of the string to buffer
  32. buffer[index + 3] = ((size + 1) >> 24) & 0xff;
  33. buffer[index + 2] = ((size + 1) >> 16) & 0xff;
  34. buffer[index + 1] = ((size + 1) >> 8) & 0xff;
  35. buffer[index] = (size + 1) & 0xff;
  36. // Update index
  37. index = index + 4 + size;
  38. // Write zero
  39. buffer[index++] = 0;
  40. return index;
  41. }
  42. var SPACE_FOR_FLOAT64 = new Uint8Array(8);
  43. var DV_FOR_FLOAT64 = new DataView(SPACE_FOR_FLOAT64.buffer, SPACE_FOR_FLOAT64.byteOffset, SPACE_FOR_FLOAT64.byteLength);
  44. function serializeNumber(buffer, key, value, index, isArray) {
  45. // We have an integer value
  46. // TODO(NODE-2529): Add support for big int
  47. if (Number.isInteger(value) &&
  48. value >= constants.BSON_INT32_MIN &&
  49. value <= constants.BSON_INT32_MAX) {
  50. // If the value fits in 32 bits encode as int32
  51. // Set int type 32 bits or less
  52. buffer[index++] = constants.BSON_DATA_INT;
  53. // Number of written bytes
  54. var numberOfWrittenBytes = !isArray
  55. ? buffer.write(key, index, undefined, 'utf8')
  56. : buffer.write(key, index, undefined, 'ascii');
  57. // Encode the name
  58. index = index + numberOfWrittenBytes;
  59. buffer[index++] = 0;
  60. // Write the int value
  61. buffer[index++] = value & 0xff;
  62. buffer[index++] = (value >> 8) & 0xff;
  63. buffer[index++] = (value >> 16) & 0xff;
  64. buffer[index++] = (value >> 24) & 0xff;
  65. }
  66. else {
  67. // Encode as double
  68. buffer[index++] = constants.BSON_DATA_NUMBER;
  69. // Number of written bytes
  70. var numberOfWrittenBytes = !isArray
  71. ? buffer.write(key, index, undefined, 'utf8')
  72. : buffer.write(key, index, undefined, 'ascii');
  73. // Encode the name
  74. index = index + numberOfWrittenBytes;
  75. buffer[index++] = 0;
  76. // Write float
  77. DV_FOR_FLOAT64.setFloat64(0, value, true);
  78. buffer.set(SPACE_FOR_FLOAT64, index);
  79. // Adjust index
  80. index = index + 8;
  81. }
  82. return index;
  83. }
  84. function serializeNull(buffer, key, _, index, isArray) {
  85. // Set long type
  86. buffer[index++] = constants.BSON_DATA_NULL;
  87. // Number of written bytes
  88. var numberOfWrittenBytes = !isArray
  89. ? buffer.write(key, index, undefined, 'utf8')
  90. : buffer.write(key, index, undefined, 'ascii');
  91. // Encode the name
  92. index = index + numberOfWrittenBytes;
  93. buffer[index++] = 0;
  94. return index;
  95. }
  96. function serializeBoolean(buffer, key, value, index, isArray) {
  97. // Write the type
  98. buffer[index++] = constants.BSON_DATA_BOOLEAN;
  99. // Number of written bytes
  100. var numberOfWrittenBytes = !isArray
  101. ? buffer.write(key, index, undefined, 'utf8')
  102. : buffer.write(key, index, undefined, 'ascii');
  103. // Encode the name
  104. index = index + numberOfWrittenBytes;
  105. buffer[index++] = 0;
  106. // Encode the boolean value
  107. buffer[index++] = value ? 1 : 0;
  108. return index;
  109. }
  110. function serializeDate(buffer, key, value, index, isArray) {
  111. // Write the type
  112. buffer[index++] = constants.BSON_DATA_DATE;
  113. // Number of written bytes
  114. var numberOfWrittenBytes = !isArray
  115. ? buffer.write(key, index, undefined, 'utf8')
  116. : buffer.write(key, index, undefined, 'ascii');
  117. // Encode the name
  118. index = index + numberOfWrittenBytes;
  119. buffer[index++] = 0;
  120. // Write the date
  121. var dateInMilis = long_1.Long.fromNumber(value.getTime());
  122. var lowBits = dateInMilis.getLowBits();
  123. var highBits = dateInMilis.getHighBits();
  124. // Encode low bits
  125. buffer[index++] = lowBits & 0xff;
  126. buffer[index++] = (lowBits >> 8) & 0xff;
  127. buffer[index++] = (lowBits >> 16) & 0xff;
  128. buffer[index++] = (lowBits >> 24) & 0xff;
  129. // Encode high bits
  130. buffer[index++] = highBits & 0xff;
  131. buffer[index++] = (highBits >> 8) & 0xff;
  132. buffer[index++] = (highBits >> 16) & 0xff;
  133. buffer[index++] = (highBits >> 24) & 0xff;
  134. return index;
  135. }
  136. function serializeRegExp(buffer, key, value, index, isArray) {
  137. // Write the type
  138. buffer[index++] = constants.BSON_DATA_REGEXP;
  139. // Number of written bytes
  140. var numberOfWrittenBytes = !isArray
  141. ? buffer.write(key, index, undefined, 'utf8')
  142. : buffer.write(key, index, undefined, 'ascii');
  143. // Encode the name
  144. index = index + numberOfWrittenBytes;
  145. buffer[index++] = 0;
  146. if (value.source && value.source.match(regexp) != null) {
  147. throw Error('value ' + value.source + ' must not contain null bytes');
  148. }
  149. // Adjust the index
  150. index = index + buffer.write(value.source, index, undefined, 'utf8');
  151. // Write zero
  152. buffer[index++] = 0x00;
  153. // Write the parameters
  154. if (value.ignoreCase)
  155. buffer[index++] = 0x69; // i
  156. if (value.global)
  157. buffer[index++] = 0x73; // s
  158. if (value.multiline)
  159. buffer[index++] = 0x6d; // m
  160. // Add ending zero
  161. buffer[index++] = 0x00;
  162. return index;
  163. }
  164. function serializeBSONRegExp(buffer, key, value, index, isArray) {
  165. // Write the type
  166. buffer[index++] = constants.BSON_DATA_REGEXP;
  167. // Number of written bytes
  168. var numberOfWrittenBytes = !isArray
  169. ? buffer.write(key, index, undefined, 'utf8')
  170. : buffer.write(key, index, undefined, 'ascii');
  171. // Encode the name
  172. index = index + numberOfWrittenBytes;
  173. buffer[index++] = 0;
  174. // Check the pattern for 0 bytes
  175. if (value.pattern.match(regexp) != null) {
  176. // The BSON spec doesn't allow keys with null bytes because keys are
  177. // null-terminated.
  178. throw Error('pattern ' + value.pattern + ' must not contain null bytes');
  179. }
  180. // Adjust the index
  181. index = index + buffer.write(value.pattern, index, undefined, 'utf8');
  182. // Write zero
  183. buffer[index++] = 0x00;
  184. // Write the options
  185. index = index + buffer.write(value.options.split('').sort().join(''), index, undefined, 'utf8');
  186. // Add ending zero
  187. buffer[index++] = 0x00;
  188. return index;
  189. }
  190. function serializeMinMax(buffer, key, value, index, isArray) {
  191. // Write the type of either min or max key
  192. if (value === null) {
  193. buffer[index++] = constants.BSON_DATA_NULL;
  194. }
  195. else if (value._bsontype === 'MinKey') {
  196. buffer[index++] = constants.BSON_DATA_MIN_KEY;
  197. }
  198. else {
  199. buffer[index++] = constants.BSON_DATA_MAX_KEY;
  200. }
  201. // Number of written bytes
  202. var numberOfWrittenBytes = !isArray
  203. ? buffer.write(key, index, undefined, 'utf8')
  204. : buffer.write(key, index, undefined, 'ascii');
  205. // Encode the name
  206. index = index + numberOfWrittenBytes;
  207. buffer[index++] = 0;
  208. return index;
  209. }
  210. function serializeObjectId(buffer, key, value, index, isArray) {
  211. // Write the type
  212. buffer[index++] = constants.BSON_DATA_OID;
  213. // Number of written bytes
  214. var numberOfWrittenBytes = !isArray
  215. ? buffer.write(key, index, undefined, 'utf8')
  216. : buffer.write(key, index, undefined, 'ascii');
  217. // Encode the name
  218. index = index + numberOfWrittenBytes;
  219. buffer[index++] = 0;
  220. // Write the objectId into the shared buffer
  221. if (typeof value.id === 'string') {
  222. buffer.write(value.id, index, undefined, 'binary');
  223. }
  224. else if ((0, utils_1.isUint8Array)(value.id)) {
  225. // Use the standard JS methods here because buffer.copy() is buggy with the
  226. // browser polyfill
  227. buffer.set(value.id.subarray(0, 12), index);
  228. }
  229. else {
  230. throw new error_1.BSONTypeError('object [' + JSON.stringify(value) + '] is not a valid ObjectId');
  231. }
  232. // Adjust index
  233. return index + 12;
  234. }
  235. function serializeBuffer(buffer, key, value, index, isArray) {
  236. // Write the type
  237. buffer[index++] = constants.BSON_DATA_BINARY;
  238. // Number of written bytes
  239. var numberOfWrittenBytes = !isArray
  240. ? buffer.write(key, index, undefined, 'utf8')
  241. : buffer.write(key, index, undefined, 'ascii');
  242. // Encode the name
  243. index = index + numberOfWrittenBytes;
  244. buffer[index++] = 0;
  245. // Get size of the buffer (current write point)
  246. var size = value.length;
  247. // Write the size of the string to buffer
  248. buffer[index++] = size & 0xff;
  249. buffer[index++] = (size >> 8) & 0xff;
  250. buffer[index++] = (size >> 16) & 0xff;
  251. buffer[index++] = (size >> 24) & 0xff;
  252. // Write the default subtype
  253. buffer[index++] = constants.BSON_BINARY_SUBTYPE_DEFAULT;
  254. // Copy the content form the binary field to the buffer
  255. buffer.set((0, ensure_buffer_1.ensureBuffer)(value), index);
  256. // Adjust the index
  257. index = index + size;
  258. return index;
  259. }
  260. function serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, isArray, path) {
  261. if (checkKeys === void 0) { checkKeys = false; }
  262. if (depth === void 0) { depth = 0; }
  263. if (serializeFunctions === void 0) { serializeFunctions = false; }
  264. if (ignoreUndefined === void 0) { ignoreUndefined = true; }
  265. if (isArray === void 0) { isArray = false; }
  266. if (path === void 0) { path = []; }
  267. for (var i = 0; i < path.length; i++) {
  268. if (path[i] === value)
  269. throw new error_1.BSONError('cyclic dependency detected');
  270. }
  271. // Push value to stack
  272. path.push(value);
  273. // Write the type
  274. buffer[index++] = Array.isArray(value) ? constants.BSON_DATA_ARRAY : constants.BSON_DATA_OBJECT;
  275. // Number of written bytes
  276. var numberOfWrittenBytes = !isArray
  277. ? buffer.write(key, index, undefined, 'utf8')
  278. : buffer.write(key, index, undefined, 'ascii');
  279. // Encode the name
  280. index = index + numberOfWrittenBytes;
  281. buffer[index++] = 0;
  282. var endIndex = serializeInto(buffer, value, checkKeys, index, depth + 1, serializeFunctions, ignoreUndefined, path);
  283. // Pop stack
  284. path.pop();
  285. return endIndex;
  286. }
  287. function serializeDecimal128(buffer, key, value, index, isArray) {
  288. buffer[index++] = constants.BSON_DATA_DECIMAL128;
  289. // Number of written bytes
  290. var numberOfWrittenBytes = !isArray
  291. ? buffer.write(key, index, undefined, 'utf8')
  292. : buffer.write(key, index, undefined, 'ascii');
  293. // Encode the name
  294. index = index + numberOfWrittenBytes;
  295. buffer[index++] = 0;
  296. // Write the data from the value
  297. // Prefer the standard JS methods because their typechecking is not buggy,
  298. // unlike the `buffer` polyfill's.
  299. buffer.set(value.bytes.subarray(0, 16), index);
  300. return index + 16;
  301. }
  302. function serializeLong(buffer, key, value, index, isArray) {
  303. // Write the type
  304. buffer[index++] =
  305. value._bsontype === 'Long' ? constants.BSON_DATA_LONG : constants.BSON_DATA_TIMESTAMP;
  306. // Number of written bytes
  307. var numberOfWrittenBytes = !isArray
  308. ? buffer.write(key, index, undefined, 'utf8')
  309. : buffer.write(key, index, undefined, 'ascii');
  310. // Encode the name
  311. index = index + numberOfWrittenBytes;
  312. buffer[index++] = 0;
  313. // Write the date
  314. var lowBits = value.getLowBits();
  315. var highBits = value.getHighBits();
  316. // Encode low bits
  317. buffer[index++] = lowBits & 0xff;
  318. buffer[index++] = (lowBits >> 8) & 0xff;
  319. buffer[index++] = (lowBits >> 16) & 0xff;
  320. buffer[index++] = (lowBits >> 24) & 0xff;
  321. // Encode high bits
  322. buffer[index++] = highBits & 0xff;
  323. buffer[index++] = (highBits >> 8) & 0xff;
  324. buffer[index++] = (highBits >> 16) & 0xff;
  325. buffer[index++] = (highBits >> 24) & 0xff;
  326. return index;
  327. }
  328. function serializeInt32(buffer, key, value, index, isArray) {
  329. value = value.valueOf();
  330. // Set int type 32 bits or less
  331. buffer[index++] = constants.BSON_DATA_INT;
  332. // Number of written bytes
  333. var numberOfWrittenBytes = !isArray
  334. ? buffer.write(key, index, undefined, 'utf8')
  335. : buffer.write(key, index, undefined, 'ascii');
  336. // Encode the name
  337. index = index + numberOfWrittenBytes;
  338. buffer[index++] = 0;
  339. // Write the int value
  340. buffer[index++] = value & 0xff;
  341. buffer[index++] = (value >> 8) & 0xff;
  342. buffer[index++] = (value >> 16) & 0xff;
  343. buffer[index++] = (value >> 24) & 0xff;
  344. return index;
  345. }
  346. function serializeDouble(buffer, key, value, index, isArray) {
  347. // Encode as double
  348. buffer[index++] = constants.BSON_DATA_NUMBER;
  349. // Number of written bytes
  350. var numberOfWrittenBytes = !isArray
  351. ? buffer.write(key, index, undefined, 'utf8')
  352. : buffer.write(key, index, undefined, 'ascii');
  353. // Encode the name
  354. index = index + numberOfWrittenBytes;
  355. buffer[index++] = 0;
  356. // Write float
  357. DV_FOR_FLOAT64.setFloat64(0, value.value, true);
  358. buffer.set(SPACE_FOR_FLOAT64, index);
  359. // Adjust index
  360. index = index + 8;
  361. return index;
  362. }
  363. function serializeFunction(buffer, key, value, index, _checkKeys, _depth, isArray) {
  364. if (_checkKeys === void 0) { _checkKeys = false; }
  365. if (_depth === void 0) { _depth = 0; }
  366. buffer[index++] = constants.BSON_DATA_CODE;
  367. // Number of written bytes
  368. var numberOfWrittenBytes = !isArray
  369. ? buffer.write(key, index, undefined, 'utf8')
  370. : buffer.write(key, index, undefined, 'ascii');
  371. // Encode the name
  372. index = index + numberOfWrittenBytes;
  373. buffer[index++] = 0;
  374. // Function string
  375. var functionString = (0, utils_1.normalizedFunctionString)(value);
  376. // Write the string
  377. var size = buffer.write(functionString, index + 4, undefined, 'utf8') + 1;
  378. // Write the size of the string to buffer
  379. buffer[index] = size & 0xff;
  380. buffer[index + 1] = (size >> 8) & 0xff;
  381. buffer[index + 2] = (size >> 16) & 0xff;
  382. buffer[index + 3] = (size >> 24) & 0xff;
  383. // Update index
  384. index = index + 4 + size - 1;
  385. // Write zero
  386. buffer[index++] = 0;
  387. return index;
  388. }
  389. function serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, isArray) {
  390. if (checkKeys === void 0) { checkKeys = false; }
  391. if (depth === void 0) { depth = 0; }
  392. if (serializeFunctions === void 0) { serializeFunctions = false; }
  393. if (ignoreUndefined === void 0) { ignoreUndefined = true; }
  394. if (isArray === void 0) { isArray = false; }
  395. if (value.scope && typeof value.scope === 'object') {
  396. // Write the type
  397. buffer[index++] = constants.BSON_DATA_CODE_W_SCOPE;
  398. // Number of written bytes
  399. var numberOfWrittenBytes = !isArray
  400. ? buffer.write(key, index, undefined, 'utf8')
  401. : buffer.write(key, index, undefined, 'ascii');
  402. // Encode the name
  403. index = index + numberOfWrittenBytes;
  404. buffer[index++] = 0;
  405. // Starting index
  406. var startIndex = index;
  407. // Serialize the function
  408. // Get the function string
  409. var functionString = typeof value.code === 'string' ? value.code : value.code.toString();
  410. // Index adjustment
  411. index = index + 4;
  412. // Write string into buffer
  413. var codeSize = buffer.write(functionString, index + 4, undefined, 'utf8') + 1;
  414. // Write the size of the string to buffer
  415. buffer[index] = codeSize & 0xff;
  416. buffer[index + 1] = (codeSize >> 8) & 0xff;
  417. buffer[index + 2] = (codeSize >> 16) & 0xff;
  418. buffer[index + 3] = (codeSize >> 24) & 0xff;
  419. // Write end 0
  420. buffer[index + 4 + codeSize - 1] = 0;
  421. // Write the
  422. index = index + codeSize + 4;
  423. //
  424. // Serialize the scope value
  425. var endIndex = serializeInto(buffer, value.scope, checkKeys, index, depth + 1, serializeFunctions, ignoreUndefined);
  426. index = endIndex - 1;
  427. // Writ the total
  428. var totalSize = endIndex - startIndex;
  429. // Write the total size of the object
  430. buffer[startIndex++] = totalSize & 0xff;
  431. buffer[startIndex++] = (totalSize >> 8) & 0xff;
  432. buffer[startIndex++] = (totalSize >> 16) & 0xff;
  433. buffer[startIndex++] = (totalSize >> 24) & 0xff;
  434. // Write trailing zero
  435. buffer[index++] = 0;
  436. }
  437. else {
  438. buffer[index++] = constants.BSON_DATA_CODE;
  439. // Number of written bytes
  440. var numberOfWrittenBytes = !isArray
  441. ? buffer.write(key, index, undefined, 'utf8')
  442. : buffer.write(key, index, undefined, 'ascii');
  443. // Encode the name
  444. index = index + numberOfWrittenBytes;
  445. buffer[index++] = 0;
  446. // Function string
  447. var functionString = value.code.toString();
  448. // Write the string
  449. var size = buffer.write(functionString, index + 4, undefined, 'utf8') + 1;
  450. // Write the size of the string to buffer
  451. buffer[index] = size & 0xff;
  452. buffer[index + 1] = (size >> 8) & 0xff;
  453. buffer[index + 2] = (size >> 16) & 0xff;
  454. buffer[index + 3] = (size >> 24) & 0xff;
  455. // Update index
  456. index = index + 4 + size - 1;
  457. // Write zero
  458. buffer[index++] = 0;
  459. }
  460. return index;
  461. }
  462. function serializeBinary(buffer, key, value, index, isArray) {
  463. // Write the type
  464. buffer[index++] = constants.BSON_DATA_BINARY;
  465. // Number of written bytes
  466. var numberOfWrittenBytes = !isArray
  467. ? buffer.write(key, index, undefined, 'utf8')
  468. : buffer.write(key, index, undefined, 'ascii');
  469. // Encode the name
  470. index = index + numberOfWrittenBytes;
  471. buffer[index++] = 0;
  472. // Extract the buffer
  473. var data = value.value(true);
  474. // Calculate size
  475. var size = value.position;
  476. // Add the deprecated 02 type 4 bytes of size to total
  477. if (value.sub_type === binary_1.Binary.SUBTYPE_BYTE_ARRAY)
  478. size = size + 4;
  479. // Write the size of the string to buffer
  480. buffer[index++] = size & 0xff;
  481. buffer[index++] = (size >> 8) & 0xff;
  482. buffer[index++] = (size >> 16) & 0xff;
  483. buffer[index++] = (size >> 24) & 0xff;
  484. // Write the subtype to the buffer
  485. buffer[index++] = value.sub_type;
  486. // If we have binary type 2 the 4 first bytes are the size
  487. if (value.sub_type === binary_1.Binary.SUBTYPE_BYTE_ARRAY) {
  488. size = size - 4;
  489. buffer[index++] = size & 0xff;
  490. buffer[index++] = (size >> 8) & 0xff;
  491. buffer[index++] = (size >> 16) & 0xff;
  492. buffer[index++] = (size >> 24) & 0xff;
  493. }
  494. // Write the data to the object
  495. buffer.set(data, index);
  496. // Adjust the index
  497. index = index + value.position;
  498. return index;
  499. }
  500. function serializeSymbol(buffer, key, value, index, isArray) {
  501. // Write the type
  502. buffer[index++] = constants.BSON_DATA_SYMBOL;
  503. // Number of written bytes
  504. var numberOfWrittenBytes = !isArray
  505. ? buffer.write(key, index, undefined, 'utf8')
  506. : buffer.write(key, index, undefined, 'ascii');
  507. // Encode the name
  508. index = index + numberOfWrittenBytes;
  509. buffer[index++] = 0;
  510. // Write the string
  511. var size = buffer.write(value.value, index + 4, undefined, 'utf8') + 1;
  512. // Write the size of the string to buffer
  513. buffer[index] = size & 0xff;
  514. buffer[index + 1] = (size >> 8) & 0xff;
  515. buffer[index + 2] = (size >> 16) & 0xff;
  516. buffer[index + 3] = (size >> 24) & 0xff;
  517. // Update index
  518. index = index + 4 + size - 1;
  519. // Write zero
  520. buffer[index++] = 0x00;
  521. return index;
  522. }
  523. function serializeDBRef(buffer, key, value, index, depth, serializeFunctions, isArray) {
  524. // Write the type
  525. buffer[index++] = constants.BSON_DATA_OBJECT;
  526. // Number of written bytes
  527. var numberOfWrittenBytes = !isArray
  528. ? buffer.write(key, index, undefined, 'utf8')
  529. : buffer.write(key, index, undefined, 'ascii');
  530. // Encode the name
  531. index = index + numberOfWrittenBytes;
  532. buffer[index++] = 0;
  533. var startIndex = index;
  534. var output = {
  535. $ref: value.collection || value.namespace,
  536. $id: value.oid
  537. };
  538. if (value.db != null) {
  539. output.$db = value.db;
  540. }
  541. output = Object.assign(output, value.fields);
  542. var endIndex = serializeInto(buffer, output, false, index, depth + 1, serializeFunctions);
  543. // Calculate object size
  544. var size = endIndex - startIndex;
  545. // Write the size
  546. buffer[startIndex++] = size & 0xff;
  547. buffer[startIndex++] = (size >> 8) & 0xff;
  548. buffer[startIndex++] = (size >> 16) & 0xff;
  549. buffer[startIndex++] = (size >> 24) & 0xff;
  550. // Set index
  551. return endIndex;
  552. }
  553. function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializeFunctions, ignoreUndefined, path) {
  554. if (checkKeys === void 0) { checkKeys = false; }
  555. if (startingIndex === void 0) { startingIndex = 0; }
  556. if (depth === void 0) { depth = 0; }
  557. if (serializeFunctions === void 0) { serializeFunctions = false; }
  558. if (ignoreUndefined === void 0) { ignoreUndefined = true; }
  559. if (path === void 0) { path = []; }
  560. startingIndex = startingIndex || 0;
  561. path = path || [];
  562. // Push the object to the path
  563. path.push(object);
  564. // Start place to serialize into
  565. var index = startingIndex + 4;
  566. // Special case isArray
  567. if (Array.isArray(object)) {
  568. // Get object keys
  569. for (var i = 0; i < object.length; i++) {
  570. var key = "".concat(i);
  571. var value = object[i];
  572. // Is there an override value
  573. if (typeof (value === null || value === void 0 ? void 0 : value.toBSON) === 'function') {
  574. value = value.toBSON();
  575. }
  576. if (typeof value === 'string') {
  577. index = serializeString(buffer, key, value, index, true);
  578. }
  579. else if (typeof value === 'number') {
  580. index = serializeNumber(buffer, key, value, index, true);
  581. }
  582. else if (typeof value === 'bigint') {
  583. throw new error_1.BSONTypeError('Unsupported type BigInt, please use Decimal128');
  584. }
  585. else if (typeof value === 'boolean') {
  586. index = serializeBoolean(buffer, key, value, index, true);
  587. }
  588. else if (value instanceof Date || (0, utils_1.isDate)(value)) {
  589. index = serializeDate(buffer, key, value, index, true);
  590. }
  591. else if (value === undefined) {
  592. index = serializeNull(buffer, key, value, index, true);
  593. }
  594. else if (value === null) {
  595. index = serializeNull(buffer, key, value, index, true);
  596. }
  597. else if (value['_bsontype'] === 'ObjectId' || value['_bsontype'] === 'ObjectID') {
  598. index = serializeObjectId(buffer, key, value, index, true);
  599. }
  600. else if ((0, utils_1.isUint8Array)(value)) {
  601. index = serializeBuffer(buffer, key, value, index, true);
  602. }
  603. else if (value instanceof RegExp || (0, utils_1.isRegExp)(value)) {
  604. index = serializeRegExp(buffer, key, value, index, true);
  605. }
  606. else if (typeof value === 'object' && value['_bsontype'] == null) {
  607. index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, true, path);
  608. }
  609. else if (typeof value === 'object' &&
  610. (0, extended_json_1.isBSONType)(value) &&
  611. value._bsontype === 'Decimal128') {
  612. index = serializeDecimal128(buffer, key, value, index, true);
  613. }
  614. else if (value['_bsontype'] === 'Long' || value['_bsontype'] === 'Timestamp') {
  615. index = serializeLong(buffer, key, value, index, true);
  616. }
  617. else if (value['_bsontype'] === 'Double') {
  618. index = serializeDouble(buffer, key, value, index, true);
  619. }
  620. else if (typeof value === 'function' && serializeFunctions) {
  621. index = serializeFunction(buffer, key, value, index, checkKeys, depth, true);
  622. }
  623. else if (value['_bsontype'] === 'Code') {
  624. index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, true);
  625. }
  626. else if (value['_bsontype'] === 'Binary') {
  627. index = serializeBinary(buffer, key, value, index, true);
  628. }
  629. else if (value['_bsontype'] === 'Symbol') {
  630. index = serializeSymbol(buffer, key, value, index, true);
  631. }
  632. else if (value['_bsontype'] === 'DBRef') {
  633. index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, true);
  634. }
  635. else if (value['_bsontype'] === 'BSONRegExp') {
  636. index = serializeBSONRegExp(buffer, key, value, index, true);
  637. }
  638. else if (value['_bsontype'] === 'Int32') {
  639. index = serializeInt32(buffer, key, value, index, true);
  640. }
  641. else if (value['_bsontype'] === 'MinKey' || value['_bsontype'] === 'MaxKey') {
  642. index = serializeMinMax(buffer, key, value, index, true);
  643. }
  644. else if (typeof value['_bsontype'] !== 'undefined') {
  645. throw new error_1.BSONTypeError("Unrecognized or invalid _bsontype: ".concat(String(value['_bsontype'])));
  646. }
  647. }
  648. }
  649. else if (object instanceof map_1.Map || (0, utils_1.isMap)(object)) {
  650. var iterator = object.entries();
  651. var done = false;
  652. while (!done) {
  653. // Unpack the next entry
  654. var entry = iterator.next();
  655. done = !!entry.done;
  656. // Are we done, then skip and terminate
  657. if (done)
  658. continue;
  659. // Get the entry values
  660. var key = entry.value[0];
  661. var value = entry.value[1];
  662. // Check the type of the value
  663. var type = typeof value;
  664. // Check the key and throw error if it's illegal
  665. if (typeof key === 'string' && !ignoreKeys.has(key)) {
  666. if (key.match(regexp) != null) {
  667. // The BSON spec doesn't allow keys with null bytes because keys are
  668. // null-terminated.
  669. throw Error('key ' + key + ' must not contain null bytes');
  670. }
  671. if (checkKeys) {
  672. if ('$' === key[0]) {
  673. throw Error('key ' + key + " must not start with '$'");
  674. }
  675. else if (~key.indexOf('.')) {
  676. throw Error('key ' + key + " must not contain '.'");
  677. }
  678. }
  679. }
  680. if (type === 'string') {
  681. index = serializeString(buffer, key, value, index);
  682. }
  683. else if (type === 'number') {
  684. index = serializeNumber(buffer, key, value, index);
  685. }
  686. else if (type === 'bigint' || (0, utils_1.isBigInt64Array)(value) || (0, utils_1.isBigUInt64Array)(value)) {
  687. throw new error_1.BSONTypeError('Unsupported type BigInt, please use Decimal128');
  688. }
  689. else if (type === 'boolean') {
  690. index = serializeBoolean(buffer, key, value, index);
  691. }
  692. else if (value instanceof Date || (0, utils_1.isDate)(value)) {
  693. index = serializeDate(buffer, key, value, index);
  694. }
  695. else if (value === null || (value === undefined && ignoreUndefined === false)) {
  696. index = serializeNull(buffer, key, value, index);
  697. }
  698. else if (value['_bsontype'] === 'ObjectId' || value['_bsontype'] === 'ObjectID') {
  699. index = serializeObjectId(buffer, key, value, index);
  700. }
  701. else if ((0, utils_1.isUint8Array)(value)) {
  702. index = serializeBuffer(buffer, key, value, index);
  703. }
  704. else if (value instanceof RegExp || (0, utils_1.isRegExp)(value)) {
  705. index = serializeRegExp(buffer, key, value, index);
  706. }
  707. else if (type === 'object' && value['_bsontype'] == null) {
  708. index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, false, path);
  709. }
  710. else if (type === 'object' && value['_bsontype'] === 'Decimal128') {
  711. index = serializeDecimal128(buffer, key, value, index);
  712. }
  713. else if (value['_bsontype'] === 'Long' || value['_bsontype'] === 'Timestamp') {
  714. index = serializeLong(buffer, key, value, index);
  715. }
  716. else if (value['_bsontype'] === 'Double') {
  717. index = serializeDouble(buffer, key, value, index);
  718. }
  719. else if (value['_bsontype'] === 'Code') {
  720. index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined);
  721. }
  722. else if (typeof value === 'function' && serializeFunctions) {
  723. index = serializeFunction(buffer, key, value, index, checkKeys, depth, serializeFunctions);
  724. }
  725. else if (value['_bsontype'] === 'Binary') {
  726. index = serializeBinary(buffer, key, value, index);
  727. }
  728. else if (value['_bsontype'] === 'Symbol') {
  729. index = serializeSymbol(buffer, key, value, index);
  730. }
  731. else if (value['_bsontype'] === 'DBRef') {
  732. index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions);
  733. }
  734. else if (value['_bsontype'] === 'BSONRegExp') {
  735. index = serializeBSONRegExp(buffer, key, value, index);
  736. }
  737. else if (value['_bsontype'] === 'Int32') {
  738. index = serializeInt32(buffer, key, value, index);
  739. }
  740. else if (value['_bsontype'] === 'MinKey' || value['_bsontype'] === 'MaxKey') {
  741. index = serializeMinMax(buffer, key, value, index);
  742. }
  743. else if (typeof value['_bsontype'] !== 'undefined') {
  744. throw new error_1.BSONTypeError("Unrecognized or invalid _bsontype: ".concat(String(value['_bsontype'])));
  745. }
  746. }
  747. }
  748. else {
  749. if (typeof (object === null || object === void 0 ? void 0 : object.toBSON) === 'function') {
  750. // Provided a custom serialization method
  751. object = object.toBSON();
  752. if (object != null && typeof object !== 'object') {
  753. throw new error_1.BSONTypeError('toBSON function did not return an object');
  754. }
  755. }
  756. // Iterate over all the keys
  757. for (var key in object) {
  758. var value = object[key];
  759. // Is there an override value
  760. if (typeof (value === null || value === void 0 ? void 0 : value.toBSON) === 'function') {
  761. value = value.toBSON();
  762. }
  763. // Check the type of the value
  764. var type = typeof value;
  765. // Check the key and throw error if it's illegal
  766. if (typeof key === 'string' && !ignoreKeys.has(key)) {
  767. if (key.match(regexp) != null) {
  768. // The BSON spec doesn't allow keys with null bytes because keys are
  769. // null-terminated.
  770. throw Error('key ' + key + ' must not contain null bytes');
  771. }
  772. if (checkKeys) {
  773. if ('$' === key[0]) {
  774. throw Error('key ' + key + " must not start with '$'");
  775. }
  776. else if (~key.indexOf('.')) {
  777. throw Error('key ' + key + " must not contain '.'");
  778. }
  779. }
  780. }
  781. if (type === 'string') {
  782. index = serializeString(buffer, key, value, index);
  783. }
  784. else if (type === 'number') {
  785. index = serializeNumber(buffer, key, value, index);
  786. }
  787. else if (type === 'bigint') {
  788. throw new error_1.BSONTypeError('Unsupported type BigInt, please use Decimal128');
  789. }
  790. else if (type === 'boolean') {
  791. index = serializeBoolean(buffer, key, value, index);
  792. }
  793. else if (value instanceof Date || (0, utils_1.isDate)(value)) {
  794. index = serializeDate(buffer, key, value, index);
  795. }
  796. else if (value === undefined) {
  797. if (ignoreUndefined === false)
  798. index = serializeNull(buffer, key, value, index);
  799. }
  800. else if (value === null) {
  801. index = serializeNull(buffer, key, value, index);
  802. }
  803. else if (value['_bsontype'] === 'ObjectId' || value['_bsontype'] === 'ObjectID') {
  804. index = serializeObjectId(buffer, key, value, index);
  805. }
  806. else if ((0, utils_1.isUint8Array)(value)) {
  807. index = serializeBuffer(buffer, key, value, index);
  808. }
  809. else if (value instanceof RegExp || (0, utils_1.isRegExp)(value)) {
  810. index = serializeRegExp(buffer, key, value, index);
  811. }
  812. else if (type === 'object' && value['_bsontype'] == null) {
  813. index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, false, path);
  814. }
  815. else if (type === 'object' && value['_bsontype'] === 'Decimal128') {
  816. index = serializeDecimal128(buffer, key, value, index);
  817. }
  818. else if (value['_bsontype'] === 'Long' || value['_bsontype'] === 'Timestamp') {
  819. index = serializeLong(buffer, key, value, index);
  820. }
  821. else if (value['_bsontype'] === 'Double') {
  822. index = serializeDouble(buffer, key, value, index);
  823. }
  824. else if (value['_bsontype'] === 'Code') {
  825. index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined);
  826. }
  827. else if (typeof value === 'function' && serializeFunctions) {
  828. index = serializeFunction(buffer, key, value, index, checkKeys, depth, serializeFunctions);
  829. }
  830. else if (value['_bsontype'] === 'Binary') {
  831. index = serializeBinary(buffer, key, value, index);
  832. }
  833. else if (value['_bsontype'] === 'Symbol') {
  834. index = serializeSymbol(buffer, key, value, index);
  835. }
  836. else if (value['_bsontype'] === 'DBRef') {
  837. index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions);
  838. }
  839. else if (value['_bsontype'] === 'BSONRegExp') {
  840. index = serializeBSONRegExp(buffer, key, value, index);
  841. }
  842. else if (value['_bsontype'] === 'Int32') {
  843. index = serializeInt32(buffer, key, value, index);
  844. }
  845. else if (value['_bsontype'] === 'MinKey' || value['_bsontype'] === 'MaxKey') {
  846. index = serializeMinMax(buffer, key, value, index);
  847. }
  848. else if (typeof value['_bsontype'] !== 'undefined') {
  849. throw new error_1.BSONTypeError("Unrecognized or invalid _bsontype: ".concat(String(value['_bsontype'])));
  850. }
  851. }
  852. }
  853. // Remove the path
  854. path.pop();
  855. // Final padding byte for object
  856. buffer[index++] = 0x00;
  857. // Final size
  858. var size = index - startingIndex;
  859. // Write the size of the object
  860. buffer[startingIndex++] = size & 0xff;
  861. buffer[startingIndex++] = (size >> 8) & 0xff;
  862. buffer[startingIndex++] = (size >> 16) & 0xff;
  863. buffer[startingIndex++] = (size >> 24) & 0xff;
  864. return index;
  865. }
  866. exports.serializeInto = serializeInto;
  867. //# sourceMappingURL=serializer.js.map