@depup/mongodb 7.1.0-depup.0

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 (396) hide show
  1. package/LICENSE.md +201 -0
  2. package/README.md +33 -0
  3. package/etc/prepare.js +12 -0
  4. package/lib/admin.js +136 -0
  5. package/lib/admin.js.map +1 -0
  6. package/lib/bson.js +85 -0
  7. package/lib/bson.js.map +1 -0
  8. package/lib/bulk/common.js +835 -0
  9. package/lib/bulk/common.js.map +1 -0
  10. package/lib/bulk/ordered.js +67 -0
  11. package/lib/bulk/ordered.js.map +1 -0
  12. package/lib/bulk/unordered.js +92 -0
  13. package/lib/bulk/unordered.js.map +1 -0
  14. package/lib/change_stream.js +513 -0
  15. package/lib/change_stream.js.map +1 -0
  16. package/lib/client-side-encryption/auto_encrypter.js +272 -0
  17. package/lib/client-side-encryption/auto_encrypter.js.map +1 -0
  18. package/lib/client-side-encryption/client_encryption.js +609 -0
  19. package/lib/client-side-encryption/client_encryption.js.map +1 -0
  20. package/lib/client-side-encryption/errors.js +138 -0
  21. package/lib/client-side-encryption/errors.js.map +1 -0
  22. package/lib/client-side-encryption/mongocryptd_manager.js +85 -0
  23. package/lib/client-side-encryption/mongocryptd_manager.js.map +1 -0
  24. package/lib/client-side-encryption/providers/aws.js +23 -0
  25. package/lib/client-side-encryption/providers/aws.js.map +1 -0
  26. package/lib/client-side-encryption/providers/azure.js +132 -0
  27. package/lib/client-side-encryption/providers/azure.js.map +1 -0
  28. package/lib/client-side-encryption/providers/gcp.js +16 -0
  29. package/lib/client-side-encryption/providers/gcp.js.map +1 -0
  30. package/lib/client-side-encryption/providers/index.js +43 -0
  31. package/lib/client-side-encryption/providers/index.js.map +1 -0
  32. package/lib/client-side-encryption/state_machine.js +427 -0
  33. package/lib/client-side-encryption/state_machine.js.map +1 -0
  34. package/lib/cmap/auth/auth_provider.js +51 -0
  35. package/lib/cmap/auth/auth_provider.js.map +1 -0
  36. package/lib/cmap/auth/aws4.js +161 -0
  37. package/lib/cmap/auth/aws4.js.map +1 -0
  38. package/lib/cmap/auth/aws_temporary_credentials.js +103 -0
  39. package/lib/cmap/auth/aws_temporary_credentials.js.map +1 -0
  40. package/lib/cmap/auth/gssapi.js +155 -0
  41. package/lib/cmap/auth/gssapi.js.map +1 -0
  42. package/lib/cmap/auth/mongo_credentials.js +169 -0
  43. package/lib/cmap/auth/mongo_credentials.js.map +1 -0
  44. package/lib/cmap/auth/mongodb_aws.js +128 -0
  45. package/lib/cmap/auth/mongodb_aws.js.map +1 -0
  46. package/lib/cmap/auth/mongodb_oidc/automated_callback_workflow.js +84 -0
  47. package/lib/cmap/auth/mongodb_oidc/automated_callback_workflow.js.map +1 -0
  48. package/lib/cmap/auth/mongodb_oidc/azure_machine_workflow.js +62 -0
  49. package/lib/cmap/auth/mongodb_oidc/azure_machine_workflow.js.map +1 -0
  50. package/lib/cmap/auth/mongodb_oidc/callback_workflow.js +141 -0
  51. package/lib/cmap/auth/mongodb_oidc/callback_workflow.js.map +1 -0
  52. package/lib/cmap/auth/mongodb_oidc/command_builders.js +44 -0
  53. package/lib/cmap/auth/mongodb_oidc/command_builders.js.map +1 -0
  54. package/lib/cmap/auth/mongodb_oidc/gcp_machine_workflow.js +39 -0
  55. package/lib/cmap/auth/mongodb_oidc/gcp_machine_workflow.js.map +1 -0
  56. package/lib/cmap/auth/mongodb_oidc/human_callback_workflow.js +122 -0
  57. package/lib/cmap/auth/mongodb_oidc/human_callback_workflow.js.map +1 -0
  58. package/lib/cmap/auth/mongodb_oidc/k8s_machine_workflow.js +32 -0
  59. package/lib/cmap/auth/mongodb_oidc/k8s_machine_workflow.js.map +1 -0
  60. package/lib/cmap/auth/mongodb_oidc/token_cache.js +52 -0
  61. package/lib/cmap/auth/mongodb_oidc/token_cache.js.map +1 -0
  62. package/lib/cmap/auth/mongodb_oidc/token_machine_workflow.js +23 -0
  63. package/lib/cmap/auth/mongodb_oidc/token_machine_workflow.js.map +1 -0
  64. package/lib/cmap/auth/mongodb_oidc.js +73 -0
  65. package/lib/cmap/auth/mongodb_oidc.js.map +1 -0
  66. package/lib/cmap/auth/plain.js +26 -0
  67. package/lib/cmap/auth/plain.js.map +1 -0
  68. package/lib/cmap/auth/providers.js +22 -0
  69. package/lib/cmap/auth/providers.js.map +1 -0
  70. package/lib/cmap/auth/scram.js +254 -0
  71. package/lib/cmap/auth/scram.js.map +1 -0
  72. package/lib/cmap/auth/x509.js +36 -0
  73. package/lib/cmap/auth/x509.js.map +1 -0
  74. package/lib/cmap/command_monitoring_events.js +223 -0
  75. package/lib/cmap/command_monitoring_events.js.map +1 -0
  76. package/lib/cmap/commands.js +535 -0
  77. package/lib/cmap/commands.js.map +1 -0
  78. package/lib/cmap/connect.js +381 -0
  79. package/lib/cmap/connect.js.map +1 -0
  80. package/lib/cmap/connection.js +571 -0
  81. package/lib/cmap/connection.js.map +1 -0
  82. package/lib/cmap/connection_pool.js +558 -0
  83. package/lib/cmap/connection_pool.js.map +1 -0
  84. package/lib/cmap/connection_pool_events.js +190 -0
  85. package/lib/cmap/connection_pool_events.js.map +1 -0
  86. package/lib/cmap/errors.js +108 -0
  87. package/lib/cmap/errors.js.map +1 -0
  88. package/lib/cmap/handshake/client_metadata.js +242 -0
  89. package/lib/cmap/handshake/client_metadata.js.map +1 -0
  90. package/lib/cmap/metrics.js +62 -0
  91. package/lib/cmap/metrics.js.map +1 -0
  92. package/lib/cmap/stream_description.js +70 -0
  93. package/lib/cmap/stream_description.js.map +1 -0
  94. package/lib/cmap/wire_protocol/compression.js +178 -0
  95. package/lib/cmap/wire_protocol/compression.js.map +1 -0
  96. package/lib/cmap/wire_protocol/constants.js +21 -0
  97. package/lib/cmap/wire_protocol/constants.js.map +1 -0
  98. package/lib/cmap/wire_protocol/on_data.js +111 -0
  99. package/lib/cmap/wire_protocol/on_data.js.map +1 -0
  100. package/lib/cmap/wire_protocol/on_demand/document.js +222 -0
  101. package/lib/cmap/wire_protocol/on_demand/document.js.map +1 -0
  102. package/lib/cmap/wire_protocol/responses.js +315 -0
  103. package/lib/cmap/wire_protocol/responses.js.map +1 -0
  104. package/lib/cmap/wire_protocol/shared.js +35 -0
  105. package/lib/cmap/wire_protocol/shared.js.map +1 -0
  106. package/lib/collection.js +751 -0
  107. package/lib/collection.js.map +1 -0
  108. package/lib/connection_string.js +1090 -0
  109. package/lib/connection_string.js.map +1 -0
  110. package/lib/constants.js +170 -0
  111. package/lib/constants.js.map +1 -0
  112. package/lib/cursor/abstract_cursor.js +924 -0
  113. package/lib/cursor/abstract_cursor.js.map +1 -0
  114. package/lib/cursor/aggregation_cursor.js +164 -0
  115. package/lib/cursor/aggregation_cursor.js.map +1 -0
  116. package/lib/cursor/change_stream_cursor.js +104 -0
  117. package/lib/cursor/change_stream_cursor.js.map +1 -0
  118. package/lib/cursor/client_bulk_write_cursor.js +52 -0
  119. package/lib/cursor/client_bulk_write_cursor.js.map +1 -0
  120. package/lib/cursor/explainable_cursor.js +36 -0
  121. package/lib/cursor/explainable_cursor.js.map +1 -0
  122. package/lib/cursor/find_cursor.js +399 -0
  123. package/lib/cursor/find_cursor.js.map +1 -0
  124. package/lib/cursor/list_collections_cursor.js +34 -0
  125. package/lib/cursor/list_collections_cursor.js.map +1 -0
  126. package/lib/cursor/list_indexes_cursor.js +32 -0
  127. package/lib/cursor/list_indexes_cursor.js.map +1 -0
  128. package/lib/cursor/list_search_indexes_cursor.js +14 -0
  129. package/lib/cursor/list_search_indexes_cursor.js.map +1 -0
  130. package/lib/cursor/run_command_cursor.js +94 -0
  131. package/lib/cursor/run_command_cursor.js.map +1 -0
  132. package/lib/db.js +419 -0
  133. package/lib/db.js.map +1 -0
  134. package/lib/deps.js +112 -0
  135. package/lib/deps.js.map +1 -0
  136. package/lib/encrypter.js +106 -0
  137. package/lib/encrypter.js.map +1 -0
  138. package/lib/error.js +1380 -0
  139. package/lib/error.js.map +1 -0
  140. package/lib/explain.js +59 -0
  141. package/lib/explain.js.map +1 -0
  142. package/lib/gridfs/download.js +305 -0
  143. package/lib/gridfs/download.js.map +1 -0
  144. package/lib/gridfs/index.js +164 -0
  145. package/lib/gridfs/index.js.map +1 -0
  146. package/lib/gridfs/upload.js +358 -0
  147. package/lib/gridfs/upload.js.map +1 -0
  148. package/lib/index.js +193 -0
  149. package/lib/index.js.map +1 -0
  150. package/lib/mongo_client.js +557 -0
  151. package/lib/mongo_client.js.map +1 -0
  152. package/lib/mongo_client_auth_providers.js +80 -0
  153. package/lib/mongo_client_auth_providers.js.map +1 -0
  154. package/lib/mongo_logger.js +655 -0
  155. package/lib/mongo_logger.js.map +1 -0
  156. package/lib/mongo_types.js +56 -0
  157. package/lib/mongo_types.js.map +1 -0
  158. package/lib/operations/aggregate.js +90 -0
  159. package/lib/operations/aggregate.js.map +1 -0
  160. package/lib/operations/client_bulk_write/client_bulk_write.js +51 -0
  161. package/lib/operations/client_bulk_write/client_bulk_write.js.map +1 -0
  162. package/lib/operations/client_bulk_write/command_builder.js +340 -0
  163. package/lib/operations/client_bulk_write/command_builder.js.map +1 -0
  164. package/lib/operations/client_bulk_write/common.js +3 -0
  165. package/lib/operations/client_bulk_write/common.js.map +1 -0
  166. package/lib/operations/client_bulk_write/executor.js +120 -0
  167. package/lib/operations/client_bulk_write/executor.js.map +1 -0
  168. package/lib/operations/client_bulk_write/results_merger.js +204 -0
  169. package/lib/operations/client_bulk_write/results_merger.js.map +1 -0
  170. package/lib/operations/command.js +83 -0
  171. package/lib/operations/command.js.map +1 -0
  172. package/lib/operations/count.js +45 -0
  173. package/lib/operations/count.js.map +1 -0
  174. package/lib/operations/create_collection.js +109 -0
  175. package/lib/operations/create_collection.js.map +1 -0
  176. package/lib/operations/delete.js +125 -0
  177. package/lib/operations/delete.js.map +1 -0
  178. package/lib/operations/distinct.js +61 -0
  179. package/lib/operations/distinct.js.map +1 -0
  180. package/lib/operations/drop.js +93 -0
  181. package/lib/operations/drop.js.map +1 -0
  182. package/lib/operations/end_sessions.js +34 -0
  183. package/lib/operations/end_sessions.js.map +1 -0
  184. package/lib/operations/estimated_document_count.js +41 -0
  185. package/lib/operations/estimated_document_count.js.map +1 -0
  186. package/lib/operations/execute_operation.js +239 -0
  187. package/lib/operations/execute_operation.js.map +1 -0
  188. package/lib/operations/find.js +148 -0
  189. package/lib/operations/find.js.map +1 -0
  190. package/lib/operations/find_and_modify.js +158 -0
  191. package/lib/operations/find_and_modify.js.map +1 -0
  192. package/lib/operations/get_more.js +62 -0
  193. package/lib/operations/get_more.js.map +1 -0
  194. package/lib/operations/indexes.js +186 -0
  195. package/lib/operations/indexes.js.map +1 -0
  196. package/lib/operations/insert.js +70 -0
  197. package/lib/operations/insert.js.map +1 -0
  198. package/lib/operations/kill_cursors.js +43 -0
  199. package/lib/operations/kill_cursors.js.map +1 -0
  200. package/lib/operations/list_collections.js +53 -0
  201. package/lib/operations/list_collections.js.map +1 -0
  202. package/lib/operations/list_databases.js +40 -0
  203. package/lib/operations/list_databases.js.map +1 -0
  204. package/lib/operations/operation.js +102 -0
  205. package/lib/operations/operation.js.map +1 -0
  206. package/lib/operations/profiling_level.js +43 -0
  207. package/lib/operations/profiling_level.js.map +1 -0
  208. package/lib/operations/remove_user.js +27 -0
  209. package/lib/operations/remove_user.js.map +1 -0
  210. package/lib/operations/rename.js +38 -0
  211. package/lib/operations/rename.js.map +1 -0
  212. package/lib/operations/run_command.js +47 -0
  213. package/lib/operations/run_command.js.map +1 -0
  214. package/lib/operations/search_indexes/create.js +33 -0
  215. package/lib/operations/search_indexes/create.js.map +1 -0
  216. package/lib/operations/search_indexes/drop.js +43 -0
  217. package/lib/operations/search_indexes/drop.js.map +1 -0
  218. package/lib/operations/search_indexes/update.js +35 -0
  219. package/lib/operations/search_indexes/update.js.map +1 -0
  220. package/lib/operations/set_profiling_level.js +53 -0
  221. package/lib/operations/set_profiling_level.js.map +1 -0
  222. package/lib/operations/stats.js +27 -0
  223. package/lib/operations/stats.js.map +1 -0
  224. package/lib/operations/update.js +188 -0
  225. package/lib/operations/update.js.map +1 -0
  226. package/lib/operations/validate_collection.js +37 -0
  227. package/lib/operations/validate_collection.js.map +1 -0
  228. package/lib/read_concern.js +73 -0
  229. package/lib/read_concern.js.map +1 -0
  230. package/lib/read_preference.js +191 -0
  231. package/lib/read_preference.js.map +1 -0
  232. package/lib/sdam/common.js +49 -0
  233. package/lib/sdam/common.js.map +1 -0
  234. package/lib/sdam/events.js +146 -0
  235. package/lib/sdam/events.js.map +1 -0
  236. package/lib/sdam/monitor.js +544 -0
  237. package/lib/sdam/monitor.js.map +1 -0
  238. package/lib/sdam/server.js +404 -0
  239. package/lib/sdam/server.js.map +1 -0
  240. package/lib/sdam/server_description.js +204 -0
  241. package/lib/sdam/server_description.js.map +1 -0
  242. package/lib/sdam/server_selection.js +294 -0
  243. package/lib/sdam/server_selection.js.map +1 -0
  244. package/lib/sdam/server_selection_events.js +85 -0
  245. package/lib/sdam/server_selection_events.js.map +1 -0
  246. package/lib/sdam/srv_polling.js +108 -0
  247. package/lib/sdam/srv_polling.js.map +1 -0
  248. package/lib/sdam/topology.js +652 -0
  249. package/lib/sdam/topology.js.map +1 -0
  250. package/lib/sdam/topology_description.js +383 -0
  251. package/lib/sdam/topology_description.js.map +1 -0
  252. package/lib/sessions.js +892 -0
  253. package/lib/sessions.js.map +1 -0
  254. package/lib/sort.js +103 -0
  255. package/lib/sort.js.map +1 -0
  256. package/lib/timeout.js +296 -0
  257. package/lib/timeout.js.map +1 -0
  258. package/lib/transactions.js +135 -0
  259. package/lib/transactions.js.map +1 -0
  260. package/lib/utils.js +1163 -0
  261. package/lib/utils.js.map +1 -0
  262. package/lib/write_concern.js +100 -0
  263. package/lib/write_concern.js.map +1 -0
  264. package/mongodb.d.ts +9018 -0
  265. package/package.json +197 -0
  266. package/src/admin.ts +173 -0
  267. package/src/bson.ts +149 -0
  268. package/src/bulk/common.ts +1251 -0
  269. package/src/bulk/ordered.ts +83 -0
  270. package/src/bulk/unordered.ts +115 -0
  271. package/src/change_stream.ts +1160 -0
  272. package/src/client-side-encryption/auto_encrypter.ts +469 -0
  273. package/src/client-side-encryption/client_encryption.ts +1150 -0
  274. package/src/client-side-encryption/errors.ts +144 -0
  275. package/src/client-side-encryption/mongocryptd_manager.ts +100 -0
  276. package/src/client-side-encryption/providers/aws.ts +33 -0
  277. package/src/client-side-encryption/providers/azure.ts +181 -0
  278. package/src/client-side-encryption/providers/gcp.ts +16 -0
  279. package/src/client-side-encryption/providers/index.ts +207 -0
  280. package/src/client-side-encryption/state_machine.ts +651 -0
  281. package/src/cmap/auth/auth_provider.ts +77 -0
  282. package/src/cmap/auth/aws4.ts +207 -0
  283. package/src/cmap/auth/aws_temporary_credentials.ts +129 -0
  284. package/src/cmap/auth/gssapi.ts +203 -0
  285. package/src/cmap/auth/mongo_credentials.ts +292 -0
  286. package/src/cmap/auth/mongodb_aws.ts +179 -0
  287. package/src/cmap/auth/mongodb_oidc/automated_callback_workflow.ts +88 -0
  288. package/src/cmap/auth/mongodb_oidc/azure_machine_workflow.ts +73 -0
  289. package/src/cmap/auth/mongodb_oidc/callback_workflow.ts +188 -0
  290. package/src/cmap/auth/mongodb_oidc/command_builders.ts +53 -0
  291. package/src/cmap/auth/mongodb_oidc/gcp_machine_workflow.ts +46 -0
  292. package/src/cmap/auth/mongodb_oidc/human_callback_workflow.ts +141 -0
  293. package/src/cmap/auth/mongodb_oidc/k8s_machine_workflow.ts +31 -0
  294. package/src/cmap/auth/mongodb_oidc/token_cache.ts +62 -0
  295. package/src/cmap/auth/mongodb_oidc/token_machine_workflow.ts +22 -0
  296. package/src/cmap/auth/mongodb_oidc.ts +185 -0
  297. package/src/cmap/auth/plain.ts +25 -0
  298. package/src/cmap/auth/providers.ts +22 -0
  299. package/src/cmap/auth/scram.ts +344 -0
  300. package/src/cmap/auth/x509.ts +43 -0
  301. package/src/cmap/command_monitoring_events.ts +316 -0
  302. package/src/cmap/commands.ts +788 -0
  303. package/src/cmap/connect.ts +518 -0
  304. package/src/cmap/connection.ts +931 -0
  305. package/src/cmap/connection_pool.ts +831 -0
  306. package/src/cmap/connection_pool_events.ts +300 -0
  307. package/src/cmap/errors.ts +119 -0
  308. package/src/cmap/handshake/client_metadata.ts +353 -0
  309. package/src/cmap/metrics.ts +58 -0
  310. package/src/cmap/stream_description.ts +96 -0
  311. package/src/cmap/wire_protocol/compression.ts +211 -0
  312. package/src/cmap/wire_protocol/constants.ts +17 -0
  313. package/src/cmap/wire_protocol/on_data.ts +139 -0
  314. package/src/cmap/wire_protocol/on_demand/document.ts +358 -0
  315. package/src/cmap/wire_protocol/responses.ts +393 -0
  316. package/src/cmap/wire_protocol/shared.ts +48 -0
  317. package/src/collection.ts +1314 -0
  318. package/src/connection_string.ts +1297 -0
  319. package/src/constants.ts +176 -0
  320. package/src/cursor/abstract_cursor.ts +1247 -0
  321. package/src/cursor/aggregation_cursor.ts +245 -0
  322. package/src/cursor/change_stream_cursor.ts +171 -0
  323. package/src/cursor/client_bulk_write_cursor.ts +83 -0
  324. package/src/cursor/explainable_cursor.ts +51 -0
  325. package/src/cursor/find_cursor.ts +497 -0
  326. package/src/cursor/list_collections_cursor.ts +50 -0
  327. package/src/cursor/list_indexes_cursor.ts +37 -0
  328. package/src/cursor/list_search_indexes_cursor.ts +20 -0
  329. package/src/cursor/run_command_cursor.ts +178 -0
  330. package/src/db.ts +621 -0
  331. package/src/deps.ts +227 -0
  332. package/src/encrypter.ts +127 -0
  333. package/src/error.ts +1567 -0
  334. package/src/explain.ts +124 -0
  335. package/src/gridfs/download.ts +483 -0
  336. package/src/gridfs/index.ts +264 -0
  337. package/src/gridfs/upload.ts +537 -0
  338. package/src/index.ts +633 -0
  339. package/src/mongo_client.ts +1155 -0
  340. package/src/mongo_client_auth_providers.ts +87 -0
  341. package/src/mongo_logger.ts +1081 -0
  342. package/src/mongo_types.ts +678 -0
  343. package/src/operations/aggregate.ts +153 -0
  344. package/src/operations/client_bulk_write/client_bulk_write.ts +72 -0
  345. package/src/operations/client_bulk_write/command_builder.ts +487 -0
  346. package/src/operations/client_bulk_write/common.ts +276 -0
  347. package/src/operations/client_bulk_write/executor.ts +149 -0
  348. package/src/operations/client_bulk_write/results_merger.ts +260 -0
  349. package/src/operations/command.ts +171 -0
  350. package/src/operations/count.ts +74 -0
  351. package/src/operations/create_collection.ts +218 -0
  352. package/src/operations/delete.ts +183 -0
  353. package/src/operations/distinct.ts +92 -0
  354. package/src/operations/drop.ts +130 -0
  355. package/src/operations/end_sessions.ts +44 -0
  356. package/src/operations/estimated_document_count.ts +61 -0
  357. package/src/operations/execute_operation.ts +319 -0
  358. package/src/operations/find.ts +254 -0
  359. package/src/operations/find_and_modify.ts +319 -0
  360. package/src/operations/get_more.ts +108 -0
  361. package/src/operations/indexes.ts +418 -0
  362. package/src/operations/insert.ts +108 -0
  363. package/src/operations/kill_cursors.ts +64 -0
  364. package/src/operations/list_collections.ts +108 -0
  365. package/src/operations/list_databases.ts +68 -0
  366. package/src/operations/operation.ts +181 -0
  367. package/src/operations/profiling_level.ts +46 -0
  368. package/src/operations/remove_user.ts +36 -0
  369. package/src/operations/rename.ts +60 -0
  370. package/src/operations/run_command.ts +79 -0
  371. package/src/operations/search_indexes/create.ts +56 -0
  372. package/src/operations/search_indexes/drop.ts +58 -0
  373. package/src/operations/search_indexes/update.ts +45 -0
  374. package/src/operations/set_profiling_level.ts +74 -0
  375. package/src/operations/stats.ts +37 -0
  376. package/src/operations/update.ts +318 -0
  377. package/src/operations/validate_collection.ts +50 -0
  378. package/src/read_concern.ts +88 -0
  379. package/src/read_preference.ts +256 -0
  380. package/src/sdam/common.ts +74 -0
  381. package/src/sdam/events.ts +219 -0
  382. package/src/sdam/monitor.ts +771 -0
  383. package/src/sdam/server.ts +595 -0
  384. package/src/sdam/server_description.ts +297 -0
  385. package/src/sdam/server_selection.ts +415 -0
  386. package/src/sdam/server_selection_events.ts +142 -0
  387. package/src/sdam/srv_polling.ts +146 -0
  388. package/src/sdam/topology.ts +1100 -0
  389. package/src/sdam/topology_description.ts +548 -0
  390. package/src/sessions.ts +1244 -0
  391. package/src/sort.ts +141 -0
  392. package/src/timeout.ts +405 -0
  393. package/src/transactions.ts +181 -0
  394. package/src/utils.ts +1434 -0
  395. package/src/write_concern.ts +183 -0
  396. package/tsconfig.json +46 -0
@@ -0,0 +1,1081 @@
1
+ import * as process from 'process';
2
+ import { inspect } from 'util';
3
+
4
+ import {
5
+ type Binary,
6
+ type BSONRegExp,
7
+ type BSONSymbol,
8
+ type Code,
9
+ type DBRef,
10
+ type Decimal128,
11
+ type Document,
12
+ type Double,
13
+ EJSON,
14
+ type EJSONOptions,
15
+ type Int32,
16
+ type Long,
17
+ type MaxKey,
18
+ type MinKey,
19
+ type ObjectId,
20
+ type Timestamp
21
+ } from './bson';
22
+ import type { CommandStartedEvent } from './cmap/command_monitoring_events';
23
+ import type {
24
+ ConnectionCheckedInEvent,
25
+ ConnectionCheckedOutEvent,
26
+ ConnectionCheckOutFailedEvent,
27
+ ConnectionCheckOutStartedEvent,
28
+ ConnectionClosedEvent,
29
+ ConnectionCreatedEvent,
30
+ ConnectionPoolClearedEvent,
31
+ ConnectionPoolClosedEvent,
32
+ ConnectionPoolCreatedEvent,
33
+ ConnectionPoolReadyEvent,
34
+ ConnectionReadyEvent
35
+ } from './cmap/connection_pool_events';
36
+ import {
37
+ COMMAND_FAILED,
38
+ COMMAND_STARTED,
39
+ COMMAND_SUCCEEDED,
40
+ CONNECTION_CHECK_OUT_FAILED,
41
+ CONNECTION_CHECK_OUT_STARTED,
42
+ CONNECTION_CHECKED_IN,
43
+ CONNECTION_CHECKED_OUT,
44
+ CONNECTION_CLOSED,
45
+ CONNECTION_CREATED,
46
+ CONNECTION_POOL_CLEARED,
47
+ CONNECTION_POOL_CLOSED,
48
+ CONNECTION_POOL_CREATED,
49
+ CONNECTION_POOL_READY,
50
+ CONNECTION_READY,
51
+ SERVER_CLOSED,
52
+ SERVER_HEARTBEAT_FAILED,
53
+ SERVER_HEARTBEAT_STARTED,
54
+ SERVER_HEARTBEAT_SUCCEEDED,
55
+ SERVER_OPENING,
56
+ SERVER_SELECTION_FAILED,
57
+ SERVER_SELECTION_STARTED,
58
+ SERVER_SELECTION_SUCCEEDED,
59
+ TOPOLOGY_CLOSED,
60
+ TOPOLOGY_DESCRIPTION_CHANGED,
61
+ TOPOLOGY_OPENING,
62
+ WAITING_FOR_SUITABLE_SERVER
63
+ } from './constants';
64
+ import type {
65
+ ServerClosedEvent,
66
+ ServerOpeningEvent,
67
+ TopologyClosedEvent,
68
+ TopologyDescriptionChangedEvent,
69
+ TopologyOpeningEvent
70
+ } from './sdam/events';
71
+ import type {
72
+ ServerSelectionEvent,
73
+ ServerSelectionFailedEvent,
74
+ ServerSelectionStartedEvent,
75
+ ServerSelectionSucceededEvent,
76
+ WaitingForSuitableServerEvent
77
+ } from './sdam/server_selection_events';
78
+ import { HostAddress, isPromiseLike, isUint8Array, parseUnsignedInteger } from './utils';
79
+
80
+ /**
81
+ * @public
82
+ * Severity levels align with unix syslog.
83
+ * Most typical driver functions will log to debug.
84
+ */
85
+ export const SeverityLevel = Object.freeze({
86
+ EMERGENCY: 'emergency',
87
+ ALERT: 'alert',
88
+ CRITICAL: 'critical',
89
+ ERROR: 'error',
90
+ WARNING: 'warn',
91
+ NOTICE: 'notice',
92
+ INFORMATIONAL: 'info',
93
+ DEBUG: 'debug',
94
+ TRACE: 'trace',
95
+ OFF: 'off'
96
+ } as const);
97
+
98
+ /** @internal */
99
+ export const DEFAULT_MAX_DOCUMENT_LENGTH = 1000;
100
+ /** @public */
101
+ export type SeverityLevel = (typeof SeverityLevel)[keyof typeof SeverityLevel];
102
+
103
+ /** @internal */
104
+ class SeverityLevelMap extends Map<SeverityLevel | number, SeverityLevel | number> {
105
+ constructor(entries: [SeverityLevel | number, SeverityLevel | number][]) {
106
+ const newEntries: [number | SeverityLevel, SeverityLevel | number][] = [];
107
+ for (const [level, value] of entries) {
108
+ newEntries.push([value, level]);
109
+ }
110
+
111
+ newEntries.push(...entries);
112
+ super(newEntries);
113
+ }
114
+
115
+ getNumericSeverityLevel(severity: SeverityLevel): number {
116
+ return this.get(severity) as number;
117
+ }
118
+
119
+ getSeverityLevelName(level: number): SeverityLevel | undefined {
120
+ return this.get(level) as SeverityLevel | undefined;
121
+ }
122
+ }
123
+
124
+ /** @internal */
125
+ export const SEVERITY_LEVEL_MAP = new SeverityLevelMap([
126
+ [SeverityLevel.OFF, -Infinity],
127
+ [SeverityLevel.EMERGENCY, 0],
128
+ [SeverityLevel.ALERT, 1],
129
+ [SeverityLevel.CRITICAL, 2],
130
+ [SeverityLevel.ERROR, 3],
131
+ [SeverityLevel.WARNING, 4],
132
+ [SeverityLevel.NOTICE, 5],
133
+ [SeverityLevel.INFORMATIONAL, 6],
134
+ [SeverityLevel.DEBUG, 7],
135
+ [SeverityLevel.TRACE, 8]
136
+ ]);
137
+
138
+ /** @public */
139
+ export const MongoLoggableComponent = Object.freeze({
140
+ COMMAND: 'command',
141
+ TOPOLOGY: 'topology',
142
+ SERVER_SELECTION: 'serverSelection',
143
+ CONNECTION: 'connection',
144
+ CLIENT: 'client'
145
+ } as const);
146
+
147
+ /** @public */
148
+ export type MongoLoggableComponent =
149
+ (typeof MongoLoggableComponent)[keyof typeof MongoLoggableComponent];
150
+
151
+ /** @internal */
152
+ export interface MongoLoggerEnvOptions {
153
+ /** Severity level for command component */
154
+ MONGODB_LOG_COMMAND?: string;
155
+ /** Severity level for topology component */
156
+ MONGODB_LOG_TOPOLOGY?: string;
157
+ /** Severity level for server selection component */
158
+ MONGODB_LOG_SERVER_SELECTION?: string;
159
+ /** Severity level for CMAP */
160
+ MONGODB_LOG_CONNECTION?: string;
161
+ /** Severity level for client */
162
+ MONGODB_LOG_CLIENT?: string;
163
+ /** Default severity level to be if any of the above are unset */
164
+ MONGODB_LOG_ALL?: string;
165
+ /** Max length of embedded EJSON docs. Setting to 0 disables truncation. Defaults to 1000. */
166
+ MONGODB_LOG_MAX_DOCUMENT_LENGTH?: string;
167
+ /** Destination for log messages. Must be 'stderr', 'stdout'. Defaults to 'stderr'. */
168
+ MONGODB_LOG_PATH?: string;
169
+ }
170
+
171
+ /** @public */
172
+ export interface LogComponentSeveritiesClientOptions {
173
+ /** Optional severity level for command component */
174
+ command?: SeverityLevel;
175
+ /** Optional severity level for topology component */
176
+ topology?: SeverityLevel;
177
+ /** Optional severity level for server selection component */
178
+ serverSelection?: SeverityLevel;
179
+ /** Optional severity level for connection component */
180
+ connection?: SeverityLevel;
181
+ /** Optional severity level for client component */
182
+ client?: SeverityLevel;
183
+ /** Optional default severity level to be used if any of the above are unset */
184
+ default?: SeverityLevel;
185
+ }
186
+
187
+ /** @internal */
188
+ export interface MongoLoggerMongoClientOptions {
189
+ /** Destination for log messages */
190
+ mongodbLogPath?: 'stdout' | 'stderr' | MongoDBLogWritable;
191
+ /** Severity levels for logger components */
192
+ mongodbLogComponentSeverities?: LogComponentSeveritiesClientOptions;
193
+ /** Max length of embedded EJSON docs. Setting to 0 disables truncation. Defaults to 1000. */
194
+ mongodbLogMaxDocumentLength?: number;
195
+ }
196
+
197
+ /** @internal */
198
+ export interface MongoLoggerOptions {
199
+ componentSeverities: {
200
+ /** Severity level for command component */
201
+ command: SeverityLevel;
202
+ /** Severity level for topology component */
203
+ topology: SeverityLevel;
204
+ /** Severity level for server selection component */
205
+ serverSelection: SeverityLevel;
206
+ /** Severity level for connection component */
207
+ connection: SeverityLevel;
208
+ /** Severity level for client component */
209
+ client: SeverityLevel;
210
+ /** Default severity level to be used if any of the above are unset */
211
+ default: SeverityLevel;
212
+ };
213
+ /** Max length of embedded EJSON docs. Setting to 0 disables truncation. Defaults to 1000. */
214
+ maxDocumentLength: number;
215
+ /** Destination for log messages. */
216
+ logDestination: MongoDBLogWritable;
217
+ /** For internal check to see if error should stop logging. */
218
+ logDestinationIsStdErr: boolean;
219
+ }
220
+
221
+ /**
222
+ * Parses a string as one of SeverityLevel
223
+ * @internal
224
+ *
225
+ * @param s - the value to be parsed
226
+ * @returns one of SeverityLevel if value can be parsed as such, otherwise null
227
+ */
228
+ export function parseSeverityFromString(s?: string): SeverityLevel | null {
229
+ const validSeverities: string[] = Object.values(SeverityLevel);
230
+ const lowerSeverity = s?.toLowerCase();
231
+
232
+ if (lowerSeverity != null && validSeverities.includes(lowerSeverity)) {
233
+ return lowerSeverity as SeverityLevel;
234
+ }
235
+
236
+ return null;
237
+ }
238
+
239
+ /** @internal */
240
+ export function createStdioLogger(stream: {
241
+ write: NodeJS.WriteStream['write'];
242
+ }): MongoDBLogWritable {
243
+ return {
244
+ write: (log: Log): Promise<unknown> => {
245
+ return new Promise((resolve, reject) => {
246
+ const logLine = inspect(log, { compact: true, breakLength: Infinity });
247
+ stream.write(`${logLine}\n`, 'utf-8', error => {
248
+ if (error) return reject(error);
249
+ resolve(true);
250
+ });
251
+ });
252
+ }
253
+ };
254
+ }
255
+
256
+ /**
257
+ * resolves the MONGODB_LOG_PATH and mongodbLogPath options from the environment and the
258
+ * mongo client options respectively. The mongodbLogPath can be either 'stdout', 'stderr', a NodeJS
259
+ * Writable or an object which has a `write` method with the signature:
260
+ * ```ts
261
+ * write(log: Log): void
262
+ * ```
263
+ *
264
+ * @returns the MongoDBLogWritable object to write logs to
265
+ */
266
+ function resolveLogPath(
267
+ { MONGODB_LOG_PATH }: MongoLoggerEnvOptions,
268
+ { mongodbLogPath }: MongoLoggerMongoClientOptions
269
+ ): { mongodbLogPath: MongoDBLogWritable; mongodbLogPathIsStdErr: boolean } {
270
+ if (typeof mongodbLogPath === 'string' && /^stderr$/i.test(mongodbLogPath)) {
271
+ return { mongodbLogPath: createStdioLogger(process.stderr), mongodbLogPathIsStdErr: true };
272
+ }
273
+ if (typeof mongodbLogPath === 'string' && /^stdout$/i.test(mongodbLogPath)) {
274
+ return { mongodbLogPath: createStdioLogger(process.stdout), mongodbLogPathIsStdErr: false };
275
+ }
276
+
277
+ if (typeof mongodbLogPath === 'object' && typeof mongodbLogPath?.write === 'function') {
278
+ return { mongodbLogPath: mongodbLogPath, mongodbLogPathIsStdErr: false };
279
+ }
280
+
281
+ if (MONGODB_LOG_PATH && /^stderr$/i.test(MONGODB_LOG_PATH)) {
282
+ return { mongodbLogPath: createStdioLogger(process.stderr), mongodbLogPathIsStdErr: true };
283
+ }
284
+ if (MONGODB_LOG_PATH && /^stdout$/i.test(MONGODB_LOG_PATH)) {
285
+ return { mongodbLogPath: createStdioLogger(process.stdout), mongodbLogPathIsStdErr: false };
286
+ }
287
+
288
+ return { mongodbLogPath: createStdioLogger(process.stderr), mongodbLogPathIsStdErr: true };
289
+ }
290
+
291
+ function resolveSeverityConfiguration(
292
+ clientOption: string | undefined,
293
+ environmentOption: string | undefined,
294
+ defaultSeverity: SeverityLevel
295
+ ): SeverityLevel {
296
+ return (
297
+ parseSeverityFromString(clientOption) ??
298
+ parseSeverityFromString(environmentOption) ??
299
+ defaultSeverity
300
+ );
301
+ }
302
+
303
+ /** @public */
304
+ export interface Log extends Record<string, any> {
305
+ t: Date;
306
+ c: MongoLoggableComponent;
307
+ s: SeverityLevel;
308
+ message?: string;
309
+ }
310
+
311
+ /**
312
+ * @public
313
+ *
314
+ * A custom destination for structured logging messages.
315
+ */
316
+ export interface MongoDBLogWritable {
317
+ /**
318
+ * This function will be called for every enabled log message.
319
+ *
320
+ * It can be sync or async:
321
+ * - If it is synchronous it will block the driver from proceeding until this method returns.
322
+ * - If it is asynchronous the driver will not await the returned promise. It will attach fulfillment handling (`.then`).
323
+ * If the promise rejects the logger will write an error message to stderr and stop functioning.
324
+ * If the promise resolves the driver proceeds to the next log message (or waits for new ones to occur).
325
+ *
326
+ * Tips:
327
+ * - We recommend writing an async `write` function that _never_ rejects.
328
+ * Instead handle logging errors as necessary to your use case and make the write function a noop, until it can be recovered.
329
+ * - The Log messages are structured but **subject to change** since the intended purpose is informational.
330
+ * Program against this defensively and err on the side of stringifying whatever is passed in to write in some form or another.
331
+ *
332
+ */
333
+ write(log: Log): PromiseLike<unknown> | unknown;
334
+ }
335
+
336
+ function compareSeverity(s0: SeverityLevel, s1: SeverityLevel): 1 | 0 | -1 {
337
+ const s0Num = SEVERITY_LEVEL_MAP.getNumericSeverityLevel(s0);
338
+ const s1Num = SEVERITY_LEVEL_MAP.getNumericSeverityLevel(s1);
339
+
340
+ return s0Num < s1Num ? -1 : s0Num > s1Num ? 1 : 0;
341
+ }
342
+
343
+ /**
344
+ * @internal
345
+ * Must be separate from Events API due to differences in spec requirements for logging a command success
346
+ */
347
+ export type LoggableCommandSucceededEvent = {
348
+ address: string;
349
+ connectionId?: string | number;
350
+ requestId: number;
351
+ duration: number;
352
+ commandName: string;
353
+ reply: Document | undefined;
354
+ serviceId?: ObjectId;
355
+ name: typeof COMMAND_SUCCEEDED;
356
+ serverConnectionId: bigint | null;
357
+ databaseName: string;
358
+ };
359
+
360
+ /**
361
+ * @internal
362
+ * Must be separate from Events API due to differences in spec requirements for logging a command failure
363
+ */
364
+ export type LoggableCommandFailedEvent = {
365
+ address: string;
366
+ connectionId?: string | number;
367
+ requestId: number;
368
+ duration: number;
369
+ commandName: string;
370
+ failure: Error;
371
+ serviceId?: ObjectId;
372
+ name: typeof COMMAND_FAILED;
373
+ serverConnectionId: bigint | null;
374
+ databaseName: string;
375
+ };
376
+
377
+ /**
378
+ * @internal
379
+ * Must be separate from Events API due to differences in spec requirements for logging server heartbeat beginning
380
+ */
381
+ export type LoggableServerHeartbeatStartedEvent = {
382
+ topologyId: number;
383
+ awaited: boolean;
384
+ connectionId: string;
385
+ name: typeof SERVER_HEARTBEAT_STARTED;
386
+ };
387
+
388
+ /**
389
+ * @internal
390
+ * Must be separate from Events API due to differences in spec requirements for logging server heartbeat success
391
+ */
392
+ export type LoggableServerHeartbeatSucceededEvent = {
393
+ topologyId: number;
394
+ awaited: boolean;
395
+ connectionId: string;
396
+ reply: Document;
397
+ serverConnectionId: number | '<monitor>';
398
+ duration: number;
399
+ name: typeof SERVER_HEARTBEAT_SUCCEEDED;
400
+ };
401
+
402
+ /**
403
+ * @internal
404
+ * Must be separate from Events API due to differences in spec requirements for logging server heartbeat failure
405
+ */
406
+ export type LoggableServerHeartbeatFailedEvent = {
407
+ topologyId: number;
408
+ awaited: boolean;
409
+ connectionId: string;
410
+ failure: Error;
411
+ duration: number;
412
+ name: typeof SERVER_HEARTBEAT_FAILED;
413
+ };
414
+
415
+ type SDAMLoggableEvent =
416
+ | ServerClosedEvent
417
+ | LoggableServerHeartbeatFailedEvent
418
+ | LoggableServerHeartbeatStartedEvent
419
+ | LoggableServerHeartbeatSucceededEvent
420
+ | ServerOpeningEvent
421
+ | TopologyClosedEvent
422
+ | TopologyDescriptionChangedEvent
423
+ | TopologyOpeningEvent;
424
+
425
+ /** @internal */
426
+ export type LoggableEvent =
427
+ | ServerSelectionStartedEvent
428
+ | ServerSelectionFailedEvent
429
+ | ServerSelectionSucceededEvent
430
+ | WaitingForSuitableServerEvent
431
+ | CommandStartedEvent
432
+ | LoggableCommandSucceededEvent
433
+ | LoggableCommandFailedEvent
434
+ | ConnectionPoolCreatedEvent
435
+ | ConnectionPoolReadyEvent
436
+ | ConnectionPoolClosedEvent
437
+ | ConnectionPoolClearedEvent
438
+ | ConnectionCreatedEvent
439
+ | ConnectionReadyEvent
440
+ | ConnectionClosedEvent
441
+ | ConnectionCheckedInEvent
442
+ | ConnectionCheckedOutEvent
443
+ | ConnectionCheckOutStartedEvent
444
+ | ConnectionCheckOutFailedEvent
445
+ | ServerClosedEvent
446
+ | LoggableServerHeartbeatFailedEvent
447
+ | LoggableServerHeartbeatStartedEvent
448
+ | LoggableServerHeartbeatSucceededEvent
449
+ | ServerOpeningEvent
450
+ | TopologyClosedEvent
451
+ | TopologyDescriptionChangedEvent
452
+ | TopologyOpeningEvent;
453
+
454
+ /** @internal */
455
+ export interface LogConvertible extends Record<string, any> {
456
+ toLog(): Record<string, any>;
457
+ }
458
+
459
+ type BSONObject =
460
+ | BSONRegExp
461
+ | BSONSymbol
462
+ | Code
463
+ | DBRef
464
+ | Decimal128
465
+ | Double
466
+ | Int32
467
+ | Long
468
+ | MaxKey
469
+ | MinKey
470
+ | ObjectId
471
+ | Timestamp
472
+ | Binary;
473
+ /** @internal */
474
+ export function stringifyWithMaxLen(
475
+ value: any,
476
+ maxDocumentLength: number,
477
+ options: EJSONOptions = {}
478
+ ): string {
479
+ let strToTruncate = '';
480
+
481
+ let currentLength = 0;
482
+ const maxDocumentLengthEnsurer = function maxDocumentLengthEnsurer(key: string, value: any) {
483
+ if (currentLength >= maxDocumentLength) {
484
+ return undefined;
485
+ }
486
+ // Account for root document
487
+ if (key === '') {
488
+ // Account for starting brace
489
+ currentLength += 1;
490
+ return value;
491
+ }
492
+
493
+ // +4 accounts for 2 quotation marks, colon and comma after value
494
+ // Note that this potentially undercounts since it does not account for escape sequences which
495
+ // will have an additional backslash added to them once passed through JSON.stringify.
496
+ currentLength += key.length + 4;
497
+
498
+ if (value == null) return value;
499
+
500
+ switch (typeof value) {
501
+ case 'string':
502
+ // +2 accounts for quotes
503
+ // Note that this potentially undercounts similarly to the key length calculation
504
+ currentLength += value.length + 2;
505
+ break;
506
+ case 'number':
507
+ case 'bigint':
508
+ currentLength += String(value).length;
509
+ break;
510
+ case 'boolean':
511
+ currentLength += value ? 4 : 5;
512
+ break;
513
+ case 'object':
514
+ if (isUint8Array(value)) {
515
+ // '{"$binary":{"base64":"<base64 string>","subType":"XX"}}'
516
+ // This is an estimate based on the fact that the base64 is approximately 1.33x the length of
517
+ // the actual binary sequence https://en.wikipedia.org/wiki/Base64
518
+ currentLength += (22 + value.byteLength + value.byteLength * 0.33 + 18) | 0;
519
+ } else if ('_bsontype' in value) {
520
+ const v = value as BSONObject;
521
+ switch (v._bsontype) {
522
+ case 'Int32':
523
+ currentLength += String(v.value).length;
524
+ break;
525
+ case 'Double':
526
+ // Account for representing integers as <value>.0
527
+ currentLength +=
528
+ (v.value | 0) === v.value ? String(v.value).length + 2 : String(v.value).length;
529
+ break;
530
+ case 'Long':
531
+ currentLength += v.toString().length;
532
+ break;
533
+ case 'ObjectId':
534
+ // '{"$oid":"XXXXXXXXXXXXXXXXXXXXXXXX"}'
535
+ currentLength += 35;
536
+ break;
537
+ case 'MaxKey':
538
+ case 'MinKey':
539
+ // '{"$maxKey":1}' or '{"$minKey":1}'
540
+ currentLength += 13;
541
+ break;
542
+ case 'Binary':
543
+ // '{"$binary":{"base64":"<base64 string>","subType":"XX"}}'
544
+ // This is an estimate based on the fact that the base64 is approximately 1.33x the length of
545
+ // the actual binary sequence https://en.wikipedia.org/wiki/Base64
546
+ currentLength += (22 + value.position + value.position * 0.33 + 18) | 0;
547
+ break;
548
+ case 'Timestamp':
549
+ // '{"$timestamp":{"t":<t>,"i":<i>}}'
550
+ currentLength += 19 + String(v.t).length + 5 + String(v.i).length + 2;
551
+ break;
552
+ case 'Code':
553
+ // '{"$code":"<code>"}' or '{"$code":"<code>","$scope":<scope>}'
554
+ if (v.scope == null) {
555
+ currentLength += v.code.length + 10 + 2;
556
+ } else {
557
+ // Ignoring actual scope object, so this undercounts by a significant amount
558
+ currentLength += v.code.length + 10 + 11;
559
+ }
560
+ break;
561
+ case 'BSONRegExp':
562
+ // '{"$regularExpression":{"pattern":"<pattern>","options":"<options>"}}'
563
+ currentLength += 34 + v.pattern.length + 13 + v.options.length + 3;
564
+ break;
565
+ }
566
+ }
567
+ }
568
+ return value;
569
+ };
570
+
571
+ if (typeof value === 'string') {
572
+ strToTruncate = value;
573
+ } else if (typeof value === 'function') {
574
+ strToTruncate = value.name;
575
+ } else {
576
+ try {
577
+ if (maxDocumentLength !== 0) {
578
+ strToTruncate = EJSON.stringify(value, maxDocumentLengthEnsurer, 0, options);
579
+ } else {
580
+ strToTruncate = EJSON.stringify(value, options);
581
+ }
582
+ } catch (e) {
583
+ strToTruncate = `Extended JSON serialization failed with: ${e.message}`;
584
+ }
585
+ }
586
+
587
+ // handle truncation that occurs in the middle of multi-byte codepoints
588
+ if (
589
+ maxDocumentLength !== 0 &&
590
+ strToTruncate.length > maxDocumentLength &&
591
+ strToTruncate.charCodeAt(maxDocumentLength - 1) !==
592
+ strToTruncate.codePointAt(maxDocumentLength - 1)
593
+ ) {
594
+ maxDocumentLength--;
595
+ if (maxDocumentLength === 0) {
596
+ return '';
597
+ }
598
+ }
599
+
600
+ return maxDocumentLength !== 0 && strToTruncate.length > maxDocumentLength
601
+ ? `${strToTruncate.slice(0, maxDocumentLength)}...`
602
+ : strToTruncate;
603
+ }
604
+
605
+ /** @internal */
606
+ export type Loggable = LoggableEvent | LogConvertible;
607
+
608
+ function isLogConvertible(obj: Loggable): obj is LogConvertible {
609
+ const objAsLogConvertible = obj as LogConvertible;
610
+ // eslint-disable-next-line no-restricted-syntax
611
+ return objAsLogConvertible.toLog !== undefined && typeof objAsLogConvertible.toLog === 'function';
612
+ }
613
+
614
+ function attachServerSelectionFields(
615
+ log: Record<string, any>,
616
+ serverSelectionEvent: ServerSelectionEvent,
617
+ maxDocumentLength: number = DEFAULT_MAX_DOCUMENT_LENGTH
618
+ ) {
619
+ const { selector, operation, topologyDescription, message } = serverSelectionEvent;
620
+ log.selector = stringifyWithMaxLen(selector, maxDocumentLength);
621
+ log.operation = operation;
622
+ log.topologyDescription = stringifyWithMaxLen(topologyDescription, maxDocumentLength);
623
+ log.message = message;
624
+
625
+ return log;
626
+ }
627
+
628
+ function attachCommandFields(
629
+ log: Record<string, any>,
630
+ commandEvent: CommandStartedEvent | LoggableCommandSucceededEvent | LoggableCommandFailedEvent
631
+ ) {
632
+ log.commandName = commandEvent.commandName;
633
+ log.requestId = commandEvent.requestId;
634
+ log.driverConnectionId = commandEvent.connectionId;
635
+ const { host, port } = HostAddress.fromString(commandEvent.address).toHostPort();
636
+ log.serverHost = host;
637
+ log.serverPort = port;
638
+ if (commandEvent?.serviceId) {
639
+ log.serviceId = commandEvent.serviceId.toHexString();
640
+ }
641
+ log.databaseName = commandEvent.databaseName;
642
+ log.serverConnectionId = commandEvent.serverConnectionId;
643
+
644
+ return log;
645
+ }
646
+
647
+ function attachConnectionFields(log: Record<string, any>, event: any) {
648
+ const { host, port } = HostAddress.fromString(event.address).toHostPort();
649
+ log.serverHost = host;
650
+ log.serverPort = port;
651
+
652
+ return log;
653
+ }
654
+
655
+ function attachSDAMFields(log: Record<string, any>, sdamEvent: SDAMLoggableEvent) {
656
+ log.topologyId = sdamEvent.topologyId;
657
+ return log;
658
+ }
659
+
660
+ function attachServerHeartbeatFields(
661
+ log: Record<string, any>,
662
+ serverHeartbeatEvent:
663
+ | LoggableServerHeartbeatFailedEvent
664
+ | LoggableServerHeartbeatStartedEvent
665
+ | LoggableServerHeartbeatSucceededEvent
666
+ ) {
667
+ const { awaited, connectionId } = serverHeartbeatEvent;
668
+ log.awaited = awaited;
669
+ log.driverConnectionId = serverHeartbeatEvent.connectionId;
670
+ const { host, port } = HostAddress.fromString(connectionId).toHostPort();
671
+ log.serverHost = host;
672
+ log.serverPort = port;
673
+ return log;
674
+ }
675
+
676
+ /** @internal */
677
+ export function defaultLogTransform(
678
+ logObject: LoggableEvent | Record<string, any>,
679
+ maxDocumentLength: number = DEFAULT_MAX_DOCUMENT_LENGTH
680
+ ): Omit<Log, 's' | 't' | 'c'> {
681
+ let log: Omit<Log, 's' | 't' | 'c'> = Object.create(null);
682
+
683
+ switch (logObject.name) {
684
+ case SERVER_SELECTION_STARTED:
685
+ log = attachServerSelectionFields(log, logObject, maxDocumentLength);
686
+ return log;
687
+ case SERVER_SELECTION_FAILED:
688
+ log = attachServerSelectionFields(log, logObject, maxDocumentLength);
689
+ log.failure = logObject.failure?.message;
690
+ return log;
691
+ case SERVER_SELECTION_SUCCEEDED:
692
+ log = attachServerSelectionFields(log, logObject, maxDocumentLength);
693
+ log.serverHost = logObject.serverHost;
694
+ log.serverPort = logObject.serverPort;
695
+ return log;
696
+ case WAITING_FOR_SUITABLE_SERVER:
697
+ log = attachServerSelectionFields(log, logObject, maxDocumentLength);
698
+ log.remainingTimeMS = logObject.remainingTimeMS;
699
+ return log;
700
+ case COMMAND_STARTED:
701
+ log = attachCommandFields(log, logObject);
702
+ log.message = 'Command started';
703
+ log.command = stringifyWithMaxLen(logObject.command, maxDocumentLength, { relaxed: true });
704
+ log.databaseName = logObject.databaseName;
705
+ return log;
706
+ case COMMAND_SUCCEEDED:
707
+ log = attachCommandFields(log, logObject);
708
+ log.message = 'Command succeeded';
709
+ log.durationMS = logObject.duration;
710
+ log.reply = stringifyWithMaxLen(logObject.reply, maxDocumentLength, { relaxed: true });
711
+ return log;
712
+ case COMMAND_FAILED:
713
+ log = attachCommandFields(log, logObject);
714
+ log.message = 'Command failed';
715
+ log.durationMS = logObject.duration;
716
+ log.failure = logObject.failure?.message ?? '(redacted)';
717
+ return log;
718
+ case CONNECTION_POOL_CREATED:
719
+ log = attachConnectionFields(log, logObject);
720
+ log.message = 'Connection pool created';
721
+ if (logObject.options) {
722
+ const { maxIdleTimeMS, minPoolSize, maxPoolSize, maxConnecting, waitQueueTimeoutMS } =
723
+ logObject.options;
724
+ log = {
725
+ ...log,
726
+ maxIdleTimeMS,
727
+ minPoolSize,
728
+ maxPoolSize,
729
+ maxConnecting,
730
+ waitQueueTimeoutMS
731
+ };
732
+ }
733
+ return log;
734
+ case CONNECTION_POOL_READY:
735
+ log = attachConnectionFields(log, logObject);
736
+ log.message = 'Connection pool ready';
737
+ return log;
738
+ case CONNECTION_POOL_CLEARED:
739
+ log = attachConnectionFields(log, logObject);
740
+ log.message = 'Connection pool cleared';
741
+ if (logObject.serviceId?._bsontype === 'ObjectId') {
742
+ log.serviceId = logObject.serviceId?.toHexString();
743
+ }
744
+ return log;
745
+ case CONNECTION_POOL_CLOSED:
746
+ log = attachConnectionFields(log, logObject);
747
+ log.message = 'Connection pool closed';
748
+ return log;
749
+ case CONNECTION_CREATED:
750
+ log = attachConnectionFields(log, logObject);
751
+ log.message = 'Connection created';
752
+ log.driverConnectionId = logObject.connectionId;
753
+ return log;
754
+ case CONNECTION_READY:
755
+ log = attachConnectionFields(log, logObject);
756
+ log.message = 'Connection ready';
757
+ log.driverConnectionId = logObject.connectionId;
758
+ log.durationMS = logObject.durationMS;
759
+ return log;
760
+ case CONNECTION_CLOSED:
761
+ log = attachConnectionFields(log, logObject);
762
+ log.message = 'Connection closed';
763
+ log.driverConnectionId = logObject.connectionId;
764
+ switch (logObject.reason) {
765
+ case 'stale':
766
+ log.reason = 'Connection became stale because the pool was cleared';
767
+ break;
768
+ case 'idle':
769
+ log.reason =
770
+ 'Connection has been available but unused for longer than the configured max idle time';
771
+ break;
772
+ case 'error':
773
+ log.reason = 'An error occurred while using the connection';
774
+ if (logObject.error) {
775
+ log.error = logObject.error;
776
+ }
777
+ break;
778
+ case 'poolClosed':
779
+ log.reason = 'Connection pool was closed';
780
+ break;
781
+ default:
782
+ log.reason = `Unknown close reason: ${logObject.reason}`;
783
+ }
784
+ return log;
785
+ case CONNECTION_CHECK_OUT_STARTED:
786
+ log = attachConnectionFields(log, logObject);
787
+ log.message = 'Connection checkout started';
788
+ return log;
789
+ case CONNECTION_CHECK_OUT_FAILED:
790
+ log = attachConnectionFields(log, logObject);
791
+ log.message = 'Connection checkout failed';
792
+ switch (logObject.reason) {
793
+ case 'poolClosed':
794
+ log.reason = 'Connection pool was closed';
795
+ break;
796
+ case 'timeout':
797
+ log.reason = 'Wait queue timeout elapsed without a connection becoming available';
798
+ break;
799
+ case 'connectionError':
800
+ log.reason = 'An error occurred while trying to establish a new connection';
801
+ if (logObject.error) {
802
+ log.error = logObject.error;
803
+ }
804
+ break;
805
+ default:
806
+ log.reason = `Unknown close reason: ${logObject.reason}`;
807
+ }
808
+ log.durationMS = logObject.durationMS;
809
+ return log;
810
+ case CONNECTION_CHECKED_OUT:
811
+ log = attachConnectionFields(log, logObject);
812
+ log.message = 'Connection checked out';
813
+ log.driverConnectionId = logObject.connectionId;
814
+ log.durationMS = logObject.durationMS;
815
+ return log;
816
+ case CONNECTION_CHECKED_IN:
817
+ log = attachConnectionFields(log, logObject);
818
+ log.message = 'Connection checked in';
819
+ log.driverConnectionId = logObject.connectionId;
820
+ return log;
821
+ case SERVER_OPENING:
822
+ log = attachSDAMFields(log, logObject);
823
+ log = attachConnectionFields(log, logObject);
824
+ log.message = 'Starting server monitoring';
825
+ return log;
826
+ case SERVER_CLOSED:
827
+ log = attachSDAMFields(log, logObject);
828
+ log = attachConnectionFields(log, logObject);
829
+ log.message = 'Stopped server monitoring';
830
+ return log;
831
+ case SERVER_HEARTBEAT_STARTED:
832
+ log = attachSDAMFields(log, logObject);
833
+ log = attachServerHeartbeatFields(log, logObject);
834
+ log.message = 'Server heartbeat started';
835
+ return log;
836
+ case SERVER_HEARTBEAT_SUCCEEDED:
837
+ log = attachSDAMFields(log, logObject);
838
+ log = attachServerHeartbeatFields(log, logObject);
839
+ log.message = 'Server heartbeat succeeded';
840
+ log.durationMS = logObject.duration;
841
+ log.serverConnectionId = logObject.serverConnectionId;
842
+ log.reply = stringifyWithMaxLen(logObject.reply, maxDocumentLength, { relaxed: true });
843
+ return log;
844
+ case SERVER_HEARTBEAT_FAILED:
845
+ log = attachSDAMFields(log, logObject);
846
+ log = attachServerHeartbeatFields(log, logObject);
847
+ log.message = 'Server heartbeat failed';
848
+ log.durationMS = logObject.duration;
849
+ log.failure = logObject.failure?.message;
850
+ return log;
851
+ case TOPOLOGY_OPENING:
852
+ log = attachSDAMFields(log, logObject);
853
+ log.message = 'Starting topology monitoring';
854
+ return log;
855
+ case TOPOLOGY_CLOSED:
856
+ log = attachSDAMFields(log, logObject);
857
+ log.message = 'Stopped topology monitoring';
858
+ return log;
859
+ case TOPOLOGY_DESCRIPTION_CHANGED:
860
+ log = attachSDAMFields(log, logObject);
861
+ log.message = 'Topology description changed';
862
+ log.previousDescription = log.reply = stringifyWithMaxLen(
863
+ logObject.previousDescription,
864
+ maxDocumentLength
865
+ );
866
+ log.newDescription = log.reply = stringifyWithMaxLen(
867
+ logObject.newDescription,
868
+ maxDocumentLength
869
+ );
870
+ return log;
871
+ default:
872
+ for (const [key, value] of Object.entries(logObject)) {
873
+ if (value != null) log[key] = value;
874
+ }
875
+ }
876
+ return log;
877
+ }
878
+
879
+ /** @internal */
880
+ export class MongoLogger {
881
+ componentSeverities: Record<MongoLoggableComponent, SeverityLevel>;
882
+ maxDocumentLength: number;
883
+ logDestination: MongoDBLogWritable;
884
+ logDestinationIsStdErr: boolean;
885
+ pendingLog: PromiseLike<unknown> | unknown = null;
886
+ private severities: Record<MongoLoggableComponent, Record<SeverityLevel, boolean>>;
887
+
888
+ /**
889
+ * This method should be used when logging errors that do not have a public driver API for
890
+ * reporting errors.
891
+ */
892
+ error = this.log.bind(this, 'error');
893
+ /**
894
+ * This method should be used to log situations where undesirable application behaviour might
895
+ * occur. For example, failing to end sessions on `MongoClient.close`.
896
+ */
897
+ warn = this.log.bind(this, 'warn');
898
+ /**
899
+ * This method should be used to report high-level information about normal driver behaviour.
900
+ * For example, the creation of a `MongoClient`.
901
+ */
902
+ info = this.log.bind(this, 'info');
903
+ /**
904
+ * This method should be used to report information that would be helpful when debugging an
905
+ * application. For example, a command starting, succeeding or failing.
906
+ */
907
+ debug = this.log.bind(this, 'debug');
908
+ /**
909
+ * This method should be used to report fine-grained details related to logic flow. For example,
910
+ * entering and exiting a function body.
911
+ */
912
+ trace = this.log.bind(this, 'trace');
913
+
914
+ constructor(options: MongoLoggerOptions) {
915
+ this.componentSeverities = options.componentSeverities;
916
+ this.maxDocumentLength = options.maxDocumentLength;
917
+ this.logDestination = options.logDestination;
918
+ this.logDestinationIsStdErr = options.logDestinationIsStdErr;
919
+ this.severities = this.createLoggingSeverities();
920
+ }
921
+
922
+ createLoggingSeverities(): Record<MongoLoggableComponent, Record<SeverityLevel, boolean>> {
923
+ const severities = Object();
924
+ for (const component of Object.values(MongoLoggableComponent)) {
925
+ severities[component] = {};
926
+ for (const severityLevel of Object.values(SeverityLevel)) {
927
+ severities[component][severityLevel] =
928
+ compareSeverity(severityLevel, this.componentSeverities[component]) <= 0;
929
+ }
930
+ }
931
+ return severities;
932
+ }
933
+
934
+ turnOffSeverities() {
935
+ for (const component of Object.values(MongoLoggableComponent)) {
936
+ this.componentSeverities[component] = SeverityLevel.OFF;
937
+ for (const severityLevel of Object.values(SeverityLevel)) {
938
+ this.severities[component][severityLevel] = false;
939
+ }
940
+ }
941
+ }
942
+
943
+ private logWriteFailureHandler(error: Error) {
944
+ if (this.logDestinationIsStdErr) {
945
+ this.turnOffSeverities();
946
+ this.clearPendingLog();
947
+ return;
948
+ }
949
+ this.logDestination = createStdioLogger(process.stderr);
950
+ this.logDestinationIsStdErr = true;
951
+ this.clearPendingLog();
952
+ this.error(MongoLoggableComponent.CLIENT, {
953
+ toLog: function () {
954
+ return {
955
+ message: 'User input for mongodbLogPath is now invalid. Logging is halted.',
956
+ error: error.message
957
+ };
958
+ }
959
+ });
960
+ this.turnOffSeverities();
961
+ this.clearPendingLog();
962
+ }
963
+
964
+ private clearPendingLog() {
965
+ this.pendingLog = null;
966
+ }
967
+
968
+ willLog(component: MongoLoggableComponent, severity: SeverityLevel): boolean {
969
+ if (severity === SeverityLevel.OFF) return false;
970
+ return this.severities[component][severity];
971
+ }
972
+
973
+ private log(
974
+ severity: SeverityLevel,
975
+ component: MongoLoggableComponent,
976
+ message: Loggable | string
977
+ ): void {
978
+ if (!this.willLog(component, severity)) return;
979
+
980
+ let logMessage: Log = { t: new Date(), c: component, s: severity };
981
+ if (typeof message === 'string') {
982
+ logMessage.message = message;
983
+ } else if (typeof message === 'object') {
984
+ if (isLogConvertible(message)) {
985
+ logMessage = { ...logMessage, ...message.toLog() };
986
+ } else {
987
+ logMessage = { ...logMessage, ...defaultLogTransform(message, this.maxDocumentLength) };
988
+ }
989
+ }
990
+
991
+ if (isPromiseLike(this.pendingLog)) {
992
+ this.pendingLog = this.pendingLog
993
+
994
+ .then(() => this.logDestination.write(logMessage))
995
+
996
+ .then(this.clearPendingLog.bind(this), this.logWriteFailureHandler.bind(this));
997
+ return;
998
+ }
999
+
1000
+ try {
1001
+ const logResult = this.logDestination.write(logMessage);
1002
+ if (isPromiseLike(logResult)) {
1003
+ this.pendingLog = logResult.then(
1004
+ this.clearPendingLog.bind(this),
1005
+ this.logWriteFailureHandler.bind(this)
1006
+ );
1007
+ }
1008
+ } catch (error) {
1009
+ this.logWriteFailureHandler(error);
1010
+ }
1011
+ }
1012
+
1013
+ /**
1014
+ * Merges options set through environment variables and the MongoClient, preferring environment
1015
+ * variables when both are set, and substituting defaults for values not set. Options set in
1016
+ * constructor take precedence over both environment variables and MongoClient options.
1017
+ *
1018
+ * @remarks
1019
+ * When parsing component severity levels, invalid values are treated as unset and replaced with
1020
+ * the default severity.
1021
+ *
1022
+ * @param envOptions - options set for the logger from the environment
1023
+ * @param clientOptions - options set for the logger in the MongoClient options
1024
+ * @returns a MongoLoggerOptions object to be used when instantiating a new MongoLogger
1025
+ */
1026
+ static resolveOptions(
1027
+ envOptions: MongoLoggerEnvOptions,
1028
+ clientOptions: MongoLoggerMongoClientOptions
1029
+ ): MongoLoggerOptions {
1030
+ // client options take precedence over env options
1031
+ const resolvedLogPath = resolveLogPath(envOptions, clientOptions);
1032
+ const combinedOptions = {
1033
+ ...envOptions,
1034
+ ...clientOptions,
1035
+ mongodbLogPath: resolvedLogPath.mongodbLogPath,
1036
+ mongodbLogPathIsStdErr: resolvedLogPath.mongodbLogPathIsStdErr
1037
+ };
1038
+ const defaultSeverity = resolveSeverityConfiguration(
1039
+ combinedOptions.mongodbLogComponentSeverities?.default,
1040
+ combinedOptions.MONGODB_LOG_ALL,
1041
+ SeverityLevel.OFF
1042
+ );
1043
+
1044
+ return {
1045
+ componentSeverities: {
1046
+ command: resolveSeverityConfiguration(
1047
+ combinedOptions.mongodbLogComponentSeverities?.command,
1048
+ combinedOptions.MONGODB_LOG_COMMAND,
1049
+ defaultSeverity
1050
+ ),
1051
+ topology: resolveSeverityConfiguration(
1052
+ combinedOptions.mongodbLogComponentSeverities?.topology,
1053
+ combinedOptions.MONGODB_LOG_TOPOLOGY,
1054
+ defaultSeverity
1055
+ ),
1056
+ serverSelection: resolveSeverityConfiguration(
1057
+ combinedOptions.mongodbLogComponentSeverities?.serverSelection,
1058
+ combinedOptions.MONGODB_LOG_SERVER_SELECTION,
1059
+ defaultSeverity
1060
+ ),
1061
+ connection: resolveSeverityConfiguration(
1062
+ combinedOptions.mongodbLogComponentSeverities?.connection,
1063
+ combinedOptions.MONGODB_LOG_CONNECTION,
1064
+ defaultSeverity
1065
+ ),
1066
+ client: resolveSeverityConfiguration(
1067
+ combinedOptions.mongodbLogComponentSeverities?.client,
1068
+ combinedOptions.MONGODB_LOG_CLIENT,
1069
+ defaultSeverity
1070
+ ),
1071
+ default: defaultSeverity
1072
+ },
1073
+ maxDocumentLength:
1074
+ combinedOptions.mongodbLogMaxDocumentLength ??
1075
+ parseUnsignedInteger(combinedOptions.MONGODB_LOG_MAX_DOCUMENT_LENGTH) ??
1076
+ 1000,
1077
+ logDestination: combinedOptions.mongodbLogPath,
1078
+ logDestinationIsStdErr: combinedOptions.mongodbLogPathIsStdErr
1079
+ };
1080
+ }
1081
+ }