@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,1297 @@
1
+ import * as dns from 'dns';
2
+ import ConnectionString from 'mongodb-connection-string-url';
3
+ import * as process from 'process';
4
+ import { URLSearchParams } from 'url';
5
+
6
+ import type { Document } from './bson';
7
+ import { MongoCredentials } from './cmap/auth/mongo_credentials';
8
+ import { AUTH_MECHS_AUTH_SRC_EXTERNAL, AuthMechanism } from './cmap/auth/providers';
9
+ import { Compressor, type CompressorName } from './cmap/wire_protocol/compression';
10
+ import { Encrypter } from './encrypter';
11
+ import { MongoAPIError, MongoInvalidArgumentError, MongoParseError } from './error';
12
+ import {
13
+ MongoClient,
14
+ type MongoClientOptions,
15
+ type MongoOptions,
16
+ type PkFactory,
17
+ type ServerApi,
18
+ ServerApiVersion
19
+ } from './mongo_client';
20
+ import { MongoLoggableComponent, MongoLogger, SeverityLevel } from './mongo_logger';
21
+ import { ReadConcern, type ReadConcernLevel } from './read_concern';
22
+ import { ReadPreference, type ReadPreferenceMode } from './read_preference';
23
+ import { ServerMonitoringMode } from './sdam/monitor';
24
+ import type { TagSet } from './sdam/server_description';
25
+ import {
26
+ checkParentDomainMatch,
27
+ DEFAULT_PK_FACTORY,
28
+ emitWarning,
29
+ HostAddress,
30
+ isRecord,
31
+ parseInteger,
32
+ setDifference,
33
+ squashError
34
+ } from './utils';
35
+ import { type W, WriteConcern } from './write_concern';
36
+
37
+ const VALID_TXT_RECORDS = ['authSource', 'replicaSet', 'loadBalanced'];
38
+
39
+ const LB_SINGLE_HOST_ERROR = 'loadBalanced option only supported with a single host in the URI';
40
+ const LB_REPLICA_SET_ERROR = 'loadBalanced option not supported with a replicaSet option';
41
+ const LB_DIRECT_CONNECTION_ERROR =
42
+ 'loadBalanced option not supported when directConnection is provided';
43
+
44
+ function retryDNSTimeoutFor(api: 'resolveSrv'): (a: string) => Promise<dns.SrvRecord[]>;
45
+ function retryDNSTimeoutFor(api: 'resolveTxt'): (a: string) => Promise<string[][]>;
46
+ function retryDNSTimeoutFor(
47
+ api: 'resolveSrv' | 'resolveTxt'
48
+ ): (a: string) => Promise<dns.SrvRecord[] | string[][]> {
49
+ return async function dnsReqRetryTimeout(lookupAddress: string) {
50
+ try {
51
+ return await dns.promises[api](lookupAddress);
52
+ } catch (firstDNSError) {
53
+ if (firstDNSError.code === dns.TIMEOUT) {
54
+ return await dns.promises[api](lookupAddress);
55
+ } else {
56
+ throw firstDNSError;
57
+ }
58
+ }
59
+ };
60
+ }
61
+
62
+ const resolveSrv = retryDNSTimeoutFor('resolveSrv');
63
+ const resolveTxt = retryDNSTimeoutFor('resolveTxt');
64
+
65
+ /**
66
+ * Lookup a `mongodb+srv` connection string, combine the parts and reparse it as a normal
67
+ * connection string.
68
+ *
69
+ * @param uri - The connection string to parse
70
+ * @param options - Optional user provided connection string options
71
+ */
72
+ export async function resolveSRVRecord(options: MongoOptions): Promise<HostAddress[]> {
73
+ if (typeof options.srvHost !== 'string') {
74
+ throw new MongoAPIError('Option "srvHost" must not be empty');
75
+ }
76
+
77
+ // Asynchronously start TXT resolution so that we do not have to wait until
78
+ // the SRV record is resolved before starting a second DNS query.
79
+ const lookupAddress = options.srvHost;
80
+ const txtResolutionPromise = resolveTxt(lookupAddress);
81
+
82
+ txtResolutionPromise.then(undefined, squashError); // rejections will be handled later
83
+
84
+ const hostname = `_${options.srvServiceName}._tcp.${lookupAddress}`;
85
+ // Resolve the SRV record and use the result as the list of hosts to connect to.
86
+ const addresses = await resolveSrv(hostname);
87
+
88
+ if (addresses.length === 0) {
89
+ throw new MongoAPIError('No addresses found at host');
90
+ }
91
+
92
+ for (const { name } of addresses) {
93
+ checkParentDomainMatch(name, lookupAddress);
94
+ }
95
+
96
+ const hostAddresses = addresses.map(r => HostAddress.fromString(`${r.name}:${r.port ?? 27017}`));
97
+
98
+ validateLoadBalancedOptions(hostAddresses, options, true);
99
+
100
+ // Use the result of resolving the TXT record and add options from there if they exist.
101
+ let record;
102
+ try {
103
+ record = await txtResolutionPromise;
104
+ } catch (error) {
105
+ if (error.code !== 'ENODATA' && error.code !== 'ENOTFOUND') {
106
+ throw error;
107
+ }
108
+ return hostAddresses;
109
+ }
110
+
111
+ if (record.length > 1) {
112
+ throw new MongoParseError('Multiple text records not allowed');
113
+ }
114
+
115
+ const txtRecordOptions = new URLSearchParams(record[0].join(''));
116
+ const txtRecordOptionKeys = [...txtRecordOptions.keys()];
117
+ if (txtRecordOptionKeys.some(key => !VALID_TXT_RECORDS.includes(key))) {
118
+ throw new MongoParseError(`Text record may only set any of: ${VALID_TXT_RECORDS.join(', ')}`);
119
+ }
120
+
121
+ if (VALID_TXT_RECORDS.some(option => txtRecordOptions.get(option) === '')) {
122
+ throw new MongoParseError('Cannot have empty URI params in DNS TXT Record');
123
+ }
124
+
125
+ const source = txtRecordOptions.get('authSource') ?? undefined;
126
+ const replicaSet = txtRecordOptions.get('replicaSet') ?? undefined;
127
+ const loadBalanced = txtRecordOptions.get('loadBalanced') ?? undefined;
128
+
129
+ if (
130
+ !options.userSpecifiedAuthSource &&
131
+ source &&
132
+ options.credentials &&
133
+ !AUTH_MECHS_AUTH_SRC_EXTERNAL.has(options.credentials.mechanism)
134
+ ) {
135
+ options.credentials = MongoCredentials.merge(options.credentials, { source });
136
+ }
137
+
138
+ if (!options.userSpecifiedReplicaSet && replicaSet) {
139
+ options.replicaSet = replicaSet;
140
+ }
141
+
142
+ if (loadBalanced === 'true') {
143
+ options.loadBalanced = true;
144
+ }
145
+
146
+ if (options.replicaSet && options.srvMaxHosts > 0) {
147
+ throw new MongoParseError('Cannot combine replicaSet option with srvMaxHosts');
148
+ }
149
+
150
+ validateLoadBalancedOptions(hostAddresses, options, true);
151
+
152
+ return hostAddresses;
153
+ }
154
+
155
+ /**
156
+ * Checks if TLS options are valid
157
+ *
158
+ * @param allOptions - All options provided by user or included in default options map
159
+ * @throws MongoAPIError if TLS options are invalid
160
+ */
161
+ function checkTLSOptions(allOptions: CaseInsensitiveMap): void {
162
+ if (!allOptions) return;
163
+ const check = (a: string, b: string) => {
164
+ if (allOptions.has(a) && allOptions.has(b)) {
165
+ throw new MongoAPIError(`The '${a}' option cannot be used with the '${b}' option`);
166
+ }
167
+ };
168
+ check('tlsInsecure', 'tlsAllowInvalidCertificates');
169
+ check('tlsInsecure', 'tlsAllowInvalidHostnames');
170
+ }
171
+ function getBoolean(name: string, value: unknown): boolean {
172
+ if (typeof value === 'boolean') return value;
173
+ switch (value) {
174
+ case 'true':
175
+ return true;
176
+ case 'false':
177
+ return false;
178
+ default:
179
+ throw new MongoParseError(`${name} must be either "true" or "false"`);
180
+ }
181
+ }
182
+
183
+ function getIntFromOptions(name: string, value: unknown): number {
184
+ const parsedInt = parseInteger(value);
185
+ if (parsedInt != null) {
186
+ return parsedInt;
187
+ }
188
+ throw new MongoParseError(`Expected ${name} to be stringified int value, got: ${value}`);
189
+ }
190
+
191
+ function getUIntFromOptions(name: string, value: unknown): number {
192
+ const parsedValue = getIntFromOptions(name, value);
193
+ if (parsedValue < 0) {
194
+ throw new MongoParseError(`${name} can only be a positive int value, got: ${value}`);
195
+ }
196
+ return parsedValue;
197
+ }
198
+
199
+ function* entriesFromString(value: string): Generator<[string, string]> {
200
+ if (value === '') {
201
+ return;
202
+ }
203
+ const keyValuePairs = value.split(',');
204
+ for (const keyValue of keyValuePairs) {
205
+ const [key, value] = keyValue.split(/:(.*)/);
206
+ if (value == null) {
207
+ throw new MongoParseError('Cannot have undefined values in key value pairs');
208
+ }
209
+
210
+ yield [key, value];
211
+ }
212
+ }
213
+
214
+ class CaseInsensitiveMap<Value = any> extends Map<string, Value> {
215
+ constructor(entries: Array<[string, any]> = []) {
216
+ super(entries.map(([k, v]) => [k.toLowerCase(), v]));
217
+ }
218
+ override has(k: string) {
219
+ return super.has(k.toLowerCase());
220
+ }
221
+ override get(k: string) {
222
+ return super.get(k.toLowerCase());
223
+ }
224
+ override set(k: string, v: any) {
225
+ return super.set(k.toLowerCase(), v);
226
+ }
227
+ override delete(k: string): boolean {
228
+ return super.delete(k.toLowerCase());
229
+ }
230
+ }
231
+
232
+ export function parseOptions(
233
+ uri: string,
234
+ mongoClient: MongoClient | MongoClientOptions | undefined = undefined,
235
+ options: MongoClientOptions = {}
236
+ ): MongoOptions {
237
+ if (mongoClient != null && !(mongoClient instanceof MongoClient)) {
238
+ options = mongoClient;
239
+ mongoClient = undefined;
240
+ }
241
+
242
+ // validate BSONOptions
243
+ if (options.useBigInt64 && typeof options.promoteLongs === 'boolean' && !options.promoteLongs) {
244
+ throw new MongoAPIError('Must request either bigint or Long for int64 deserialization');
245
+ }
246
+
247
+ if (options.useBigInt64 && typeof options.promoteValues === 'boolean' && !options.promoteValues) {
248
+ throw new MongoAPIError('Must request either bigint or Long for int64 deserialization');
249
+ }
250
+
251
+ const url = new ConnectionString(uri);
252
+ const { hosts, isSRV } = url;
253
+
254
+ const mongoOptions = Object.create(null);
255
+
256
+ mongoOptions.hosts = isSRV ? [] : hosts.map(HostAddress.fromString);
257
+
258
+ const urlOptions = new CaseInsensitiveMap<unknown[]>();
259
+
260
+ if (url.pathname !== '/' && url.pathname !== '') {
261
+ const dbName = decodeURIComponent(
262
+ url.pathname[0] === '/' ? url.pathname.slice(1) : url.pathname
263
+ );
264
+ if (dbName) {
265
+ urlOptions.set('dbName', [dbName]);
266
+ }
267
+ }
268
+
269
+ if (url.username !== '') {
270
+ const auth: Document = {
271
+ username: decodeURIComponent(url.username)
272
+ };
273
+
274
+ if (typeof url.password === 'string') {
275
+ auth.password = decodeURIComponent(url.password);
276
+ }
277
+
278
+ urlOptions.set('auth', [auth]);
279
+ }
280
+
281
+ for (const key of url.searchParams.keys()) {
282
+ const values = url.searchParams.getAll(key);
283
+
284
+ const isReadPreferenceTags = /readPreferenceTags/i.test(key);
285
+
286
+ if (!isReadPreferenceTags && values.length > 1) {
287
+ throw new MongoInvalidArgumentError(
288
+ `URI option "${key}" cannot appear more than once in the connection string`
289
+ );
290
+ }
291
+
292
+ if (!isReadPreferenceTags && values.includes('')) {
293
+ throw new MongoAPIError(`URI option "${key}" cannot be specified with no value`);
294
+ }
295
+
296
+ if (!urlOptions.has(key)) {
297
+ urlOptions.set(key, values);
298
+ }
299
+ }
300
+
301
+ const objectOptions = new CaseInsensitiveMap<unknown>(
302
+ Object.entries(options).filter(([, v]) => v != null)
303
+ );
304
+
305
+ // Validate options that can only be provided by one of uri or object
306
+
307
+ if (urlOptions.has('serverApi')) {
308
+ throw new MongoParseError(
309
+ 'URI cannot contain `serverApi`, it can only be passed to the client'
310
+ );
311
+ }
312
+
313
+ const uriMechanismProperties = urlOptions.get('authMechanismProperties');
314
+ if (uriMechanismProperties) {
315
+ for (const property of uriMechanismProperties) {
316
+ if (/(^|,)ALLOWED_HOSTS:/.test(property as string)) {
317
+ throw new MongoParseError(
318
+ 'Auth mechanism property ALLOWED_HOSTS is not allowed in the connection string.'
319
+ );
320
+ }
321
+ }
322
+ }
323
+
324
+ if (objectOptions.has('loadBalanced')) {
325
+ throw new MongoParseError('loadBalanced is only a valid option in the URI');
326
+ }
327
+
328
+ // All option collection
329
+
330
+ const allProvidedOptions = new CaseInsensitiveMap<unknown[]>();
331
+
332
+ const allProvidedKeys = new Set<string>([...urlOptions.keys(), ...objectOptions.keys()]);
333
+
334
+ for (const key of allProvidedKeys) {
335
+ const values = [];
336
+ const objectOptionValue = objectOptions.get(key);
337
+ if (objectOptionValue != null) {
338
+ values.push(objectOptionValue);
339
+ }
340
+
341
+ const urlValues = urlOptions.get(key) ?? [];
342
+ values.push(...urlValues);
343
+ allProvidedOptions.set(key, values);
344
+ }
345
+
346
+ if (allProvidedOptions.has('tls') || allProvidedOptions.has('ssl')) {
347
+ const tlsAndSslOpts = (allProvidedOptions.get('tls') || [])
348
+ .concat(allProvidedOptions.get('ssl') || [])
349
+ .map(getBoolean.bind(null, 'tls/ssl'));
350
+ if (new Set(tlsAndSslOpts).size !== 1) {
351
+ throw new MongoParseError('All values of tls/ssl must be the same.');
352
+ }
353
+ }
354
+
355
+ checkTLSOptions(allProvidedOptions);
356
+
357
+ const unsupportedOptions = setDifference(
358
+ allProvidedKeys,
359
+ Array.from(Object.keys(OPTIONS)).map(s => s.toLowerCase())
360
+ );
361
+ if (unsupportedOptions.size !== 0) {
362
+ const optionWord = unsupportedOptions.size > 1 ? 'options' : 'option';
363
+ const isOrAre = unsupportedOptions.size > 1 ? 'are' : 'is';
364
+ throw new MongoParseError(
365
+ `${optionWord} ${Array.from(unsupportedOptions).join(', ')} ${isOrAre} not supported`
366
+ );
367
+ }
368
+
369
+ // Option parsing and setting
370
+
371
+ for (const [key, descriptor] of Object.entries(OPTIONS)) {
372
+ const values = allProvidedOptions.get(key);
373
+ if (!values || values.length === 0) {
374
+ if (DEFAULT_OPTIONS.has(key)) {
375
+ setOption(mongoOptions, key, descriptor, [DEFAULT_OPTIONS.get(key)]);
376
+ }
377
+ } else {
378
+ const { deprecated } = descriptor;
379
+ if (deprecated) {
380
+ const deprecatedMsg = typeof deprecated === 'string' ? `: ${deprecated}` : '';
381
+ emitWarning(`${key} is a deprecated option${deprecatedMsg}`);
382
+ }
383
+
384
+ setOption(mongoOptions, key, descriptor, values);
385
+ }
386
+ }
387
+
388
+ if (mongoOptions.credentials) {
389
+ const isGssapi = mongoOptions.credentials.mechanism === AuthMechanism.MONGODB_GSSAPI;
390
+ const isX509 = mongoOptions.credentials.mechanism === AuthMechanism.MONGODB_X509;
391
+ const isAws = mongoOptions.credentials.mechanism === AuthMechanism.MONGODB_AWS;
392
+ const isOidc = mongoOptions.credentials.mechanism === AuthMechanism.MONGODB_OIDC;
393
+ if (
394
+ (isGssapi || isX509) &&
395
+ allProvidedOptions.has('authSource') &&
396
+ mongoOptions.credentials.source !== '$external'
397
+ ) {
398
+ // If authSource was explicitly given and its incorrect, we error
399
+ throw new MongoParseError(
400
+ `authMechanism ${mongoOptions.credentials.mechanism} requires an authSource of '$external'`
401
+ );
402
+ }
403
+
404
+ if (
405
+ !(isGssapi || isX509 || isAws || isOidc) &&
406
+ mongoOptions.dbName &&
407
+ !allProvidedOptions.has('authSource')
408
+ ) {
409
+ // inherit the dbName unless GSSAPI or X509, then silently ignore dbName
410
+ // and there was no specific authSource given
411
+ mongoOptions.credentials = MongoCredentials.merge(mongoOptions.credentials, {
412
+ source: mongoOptions.dbName
413
+ });
414
+ }
415
+
416
+ if (isAws) {
417
+ const { username, password } = mongoOptions.credentials;
418
+ if (username || password) {
419
+ throw new MongoAPIError(
420
+ 'username and password cannot be provided when using MONGODB-AWS. Credentials must be provided in a manner that can be read by the AWS SDK.'
421
+ );
422
+ }
423
+ if (mongoOptions.credentials.mechanismProperties.AWS_SESSION_TOKEN) {
424
+ throw new MongoAPIError(
425
+ 'AWS_SESSION_TOKEN cannot be provided when using MONGODB-AWS. Credentials must be provided in a manner that can be read by the AWS SDK.'
426
+ );
427
+ }
428
+ }
429
+
430
+ mongoOptions.credentials.validate();
431
+
432
+ // Check if the only auth related option provided was authSource, if so we can remove credentials
433
+ if (
434
+ mongoOptions.credentials.password === '' &&
435
+ mongoOptions.credentials.username === '' &&
436
+ mongoOptions.credentials.mechanism === AuthMechanism.MONGODB_DEFAULT &&
437
+ Object.keys(mongoOptions.credentials.mechanismProperties).length === 0
438
+ ) {
439
+ delete mongoOptions.credentials;
440
+ }
441
+ }
442
+
443
+ if (!mongoOptions.dbName) {
444
+ // dbName default is applied here because of the credential validation above
445
+ mongoOptions.dbName = 'test';
446
+ }
447
+
448
+ validateLoadBalancedOptions(hosts, mongoOptions, isSRV);
449
+
450
+ if (mongoClient && mongoOptions.autoEncryption) {
451
+ Encrypter.checkForMongoCrypt();
452
+ mongoOptions.encrypter = new Encrypter(mongoClient, uri, options);
453
+ mongoOptions.autoEncrypter = mongoOptions.encrypter.autoEncrypter;
454
+ }
455
+
456
+ // Potential SRV Overrides and SRV connection string validations
457
+
458
+ mongoOptions.userSpecifiedAuthSource =
459
+ objectOptions.has('authSource') || urlOptions.has('authSource');
460
+ mongoOptions.userSpecifiedReplicaSet =
461
+ objectOptions.has('replicaSet') || urlOptions.has('replicaSet');
462
+
463
+ if (isSRV) {
464
+ // SRV Record is resolved upon connecting
465
+ mongoOptions.srvHost = hosts[0];
466
+
467
+ if (mongoOptions.directConnection) {
468
+ throw new MongoAPIError('SRV URI does not support directConnection');
469
+ }
470
+
471
+ if (mongoOptions.srvMaxHosts > 0 && typeof mongoOptions.replicaSet === 'string') {
472
+ throw new MongoParseError('Cannot use srvMaxHosts option with replicaSet');
473
+ }
474
+
475
+ // SRV turns on TLS by default, but users can override and turn it off
476
+ const noUserSpecifiedTLS = !objectOptions.has('tls') && !urlOptions.has('tls');
477
+ const noUserSpecifiedSSL = !objectOptions.has('ssl') && !urlOptions.has('ssl');
478
+ if (noUserSpecifiedTLS && noUserSpecifiedSSL) {
479
+ mongoOptions.tls = true;
480
+ }
481
+ } else {
482
+ const userSpecifiedSrvOptions =
483
+ urlOptions.has('srvMaxHosts') ||
484
+ objectOptions.has('srvMaxHosts') ||
485
+ urlOptions.has('srvServiceName') ||
486
+ objectOptions.has('srvServiceName');
487
+
488
+ if (userSpecifiedSrvOptions) {
489
+ throw new MongoParseError(
490
+ 'Cannot use srvMaxHosts or srvServiceName with a non-srv connection string'
491
+ );
492
+ }
493
+ }
494
+
495
+ if (mongoOptions.directConnection && mongoOptions.hosts.length !== 1) {
496
+ throw new MongoParseError('directConnection option requires exactly one host');
497
+ }
498
+
499
+ if (
500
+ !mongoOptions.proxyHost &&
501
+ (mongoOptions.proxyPort || mongoOptions.proxyUsername || mongoOptions.proxyPassword)
502
+ ) {
503
+ throw new MongoParseError('Must specify proxyHost if other proxy options are passed');
504
+ }
505
+
506
+ if (
507
+ (mongoOptions.proxyUsername && !mongoOptions.proxyPassword) ||
508
+ (!mongoOptions.proxyUsername && mongoOptions.proxyPassword)
509
+ ) {
510
+ throw new MongoParseError('Can only specify both of proxy username/password or neither');
511
+ }
512
+
513
+ const proxyOptions = ['proxyHost', 'proxyPort', 'proxyUsername', 'proxyPassword'].map(
514
+ key => urlOptions.get(key) ?? []
515
+ );
516
+
517
+ if (proxyOptions.some(options => options.length > 1)) {
518
+ throw new MongoParseError(
519
+ 'Proxy options cannot be specified multiple times in the connection string'
520
+ );
521
+ }
522
+
523
+ mongoOptions.mongoLoggerOptions = MongoLogger.resolveOptions(
524
+ {
525
+ MONGODB_LOG_COMMAND: process.env.MONGODB_LOG_COMMAND,
526
+ MONGODB_LOG_TOPOLOGY: process.env.MONGODB_LOG_TOPOLOGY,
527
+ MONGODB_LOG_SERVER_SELECTION: process.env.MONGODB_LOG_SERVER_SELECTION,
528
+ MONGODB_LOG_CONNECTION: process.env.MONGODB_LOG_CONNECTION,
529
+ MONGODB_LOG_CLIENT: process.env.MONGODB_LOG_CLIENT,
530
+ MONGODB_LOG_ALL: process.env.MONGODB_LOG_ALL,
531
+ MONGODB_LOG_MAX_DOCUMENT_LENGTH: process.env.MONGODB_LOG_MAX_DOCUMENT_LENGTH,
532
+ MONGODB_LOG_PATH: process.env.MONGODB_LOG_PATH
533
+ },
534
+ {
535
+ mongodbLogPath: mongoOptions.mongodbLogPath,
536
+ mongodbLogComponentSeverities: mongoOptions.mongodbLogComponentSeverities,
537
+ mongodbLogMaxDocumentLength: mongoOptions.mongodbLogMaxDocumentLength
538
+ }
539
+ );
540
+
541
+ return mongoOptions;
542
+ }
543
+
544
+ /**
545
+ * #### Throws if LB mode is true:
546
+ * - hosts contains more than one host
547
+ * - there is a replicaSet name set
548
+ * - directConnection is set
549
+ * - if srvMaxHosts is used when an srv connection string is passed in
550
+ *
551
+ * @throws MongoParseError
552
+ */
553
+ function validateLoadBalancedOptions(
554
+ hosts: HostAddress[] | string[],
555
+ mongoOptions: MongoOptions,
556
+ isSrv: boolean
557
+ ): void {
558
+ if (mongoOptions.loadBalanced) {
559
+ if (hosts.length > 1) {
560
+ throw new MongoParseError(LB_SINGLE_HOST_ERROR);
561
+ }
562
+ if (mongoOptions.replicaSet) {
563
+ throw new MongoParseError(LB_REPLICA_SET_ERROR);
564
+ }
565
+ if (mongoOptions.directConnection) {
566
+ throw new MongoParseError(LB_DIRECT_CONNECTION_ERROR);
567
+ }
568
+
569
+ if (isSrv && mongoOptions.srvMaxHosts > 0) {
570
+ throw new MongoParseError('Cannot limit srv hosts with loadBalanced enabled');
571
+ }
572
+ }
573
+ return;
574
+ }
575
+
576
+ function setOption(
577
+ mongoOptions: any,
578
+ key: string,
579
+ descriptor: OptionDescriptor,
580
+ values: unknown[]
581
+ ) {
582
+ const { target, type, transform } = descriptor;
583
+ const name = target ?? key;
584
+
585
+ switch (type) {
586
+ case 'boolean':
587
+ mongoOptions[name] = getBoolean(name, values[0]);
588
+ break;
589
+ case 'int':
590
+ mongoOptions[name] = getIntFromOptions(name, values[0]);
591
+ break;
592
+ case 'uint':
593
+ mongoOptions[name] = getUIntFromOptions(name, values[0]);
594
+ break;
595
+ case 'string':
596
+ if (values[0] == null) {
597
+ break;
598
+ }
599
+ // The value should always be a string here, but since the array is typed as unknown
600
+ // there still needs to be an explicit cast.
601
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
602
+ mongoOptions[name] = String(values[0]);
603
+ break;
604
+ case 'record':
605
+ if (!isRecord(values[0])) {
606
+ throw new MongoParseError(`${name} must be an object`);
607
+ }
608
+ mongoOptions[name] = values[0];
609
+ break;
610
+ case 'any':
611
+ mongoOptions[name] = values[0];
612
+ break;
613
+ default: {
614
+ if (!transform) {
615
+ throw new MongoParseError('Descriptors missing a type must define a transform');
616
+ }
617
+ const transformValue = transform({ name, options: mongoOptions, values });
618
+ mongoOptions[name] = transformValue;
619
+ break;
620
+ }
621
+ }
622
+ }
623
+
624
+ interface OptionDescriptor {
625
+ target?: string;
626
+ type?: 'boolean' | 'int' | 'uint' | 'record' | 'string' | 'any';
627
+ default?: any;
628
+
629
+ deprecated?: boolean | string;
630
+ /**
631
+ * @param name - the original option name
632
+ * @param options - the options so far for resolution
633
+ * @param values - the possible values in precedence order
634
+ */
635
+ transform?: (args: { name: string; options: MongoOptions; values: unknown[] }) => unknown;
636
+ }
637
+
638
+ export const OPTIONS = {
639
+ appName: {
640
+ type: 'string'
641
+ },
642
+ auth: {
643
+ target: 'credentials',
644
+ transform({ name, options, values: [value] }): MongoCredentials {
645
+ if (!isRecord(value, ['username', 'password'] as const)) {
646
+ throw new MongoParseError(
647
+ `${name} must be an object with 'username' and 'password' properties`
648
+ );
649
+ }
650
+ return MongoCredentials.merge(options.credentials, {
651
+ username: value.username,
652
+ password: value.password
653
+ });
654
+ }
655
+ },
656
+ authMechanism: {
657
+ target: 'credentials',
658
+ transform({ options, values: [value] }): MongoCredentials {
659
+ const mechanisms = Object.values(AuthMechanism);
660
+ const [mechanism] = mechanisms.filter(m => m.match(RegExp(String.raw`\b${value}\b`, 'i')));
661
+ if (!mechanism) {
662
+ throw new MongoParseError(`authMechanism one of ${mechanisms}, got ${value}`);
663
+ }
664
+ let source = options.credentials?.source;
665
+ if (
666
+ mechanism === AuthMechanism.MONGODB_PLAIN ||
667
+ AUTH_MECHS_AUTH_SRC_EXTERNAL.has(mechanism)
668
+ ) {
669
+ // some mechanisms have '$external' as the Auth Source
670
+ source = '$external';
671
+ }
672
+
673
+ let password = options.credentials?.password;
674
+ if (mechanism === AuthMechanism.MONGODB_X509 && password === '') {
675
+ password = undefined;
676
+ }
677
+ return MongoCredentials.merge(options.credentials, {
678
+ mechanism,
679
+ source,
680
+ password
681
+ });
682
+ }
683
+ },
684
+ // Note that if the authMechanismProperties contain a TOKEN_RESOURCE that has a
685
+ // comma in it, it MUST be supplied as a MongoClient option instead of in the
686
+ // connection string.
687
+ authMechanismProperties: {
688
+ target: 'credentials',
689
+ transform({ options, values }): MongoCredentials {
690
+ // We can have a combination of options passed in the URI and options passed
691
+ // as an object to the MongoClient. So we must transform the string options
692
+ // as well as merge them together with a potentially provided object.
693
+ let mechanismProperties = Object.create(null);
694
+
695
+ for (const optionValue of values) {
696
+ if (typeof optionValue === 'string') {
697
+ for (const [key, value] of entriesFromString(optionValue)) {
698
+ try {
699
+ mechanismProperties[key] = getBoolean(key, value);
700
+ } catch {
701
+ mechanismProperties[key] = value;
702
+ }
703
+ }
704
+ } else {
705
+ if (!isRecord(optionValue)) {
706
+ throw new MongoParseError('AuthMechanismProperties must be an object');
707
+ }
708
+ mechanismProperties = { ...optionValue };
709
+ }
710
+ }
711
+ return MongoCredentials.merge(options.credentials, {
712
+ mechanismProperties
713
+ });
714
+ }
715
+ },
716
+ authSource: {
717
+ target: 'credentials',
718
+ transform({ options, values: [value] }): MongoCredentials {
719
+ const source = String(value);
720
+ return MongoCredentials.merge(options.credentials, { source });
721
+ }
722
+ },
723
+ autoEncryption: {
724
+ type: 'record'
725
+ },
726
+ autoSelectFamily: {
727
+ type: 'boolean',
728
+ default: true
729
+ },
730
+ autoSelectFamilyAttemptTimeout: {
731
+ type: 'uint'
732
+ },
733
+ bsonRegExp: {
734
+ type: 'boolean'
735
+ },
736
+ serverApi: {
737
+ target: 'serverApi',
738
+ transform({ values: [version] }): ServerApi {
739
+ const serverApiToValidate =
740
+ typeof version === 'string' ? ({ version } as ServerApi) : (version as ServerApi);
741
+ const versionToValidate = serverApiToValidate && serverApiToValidate.version;
742
+ if (!versionToValidate) {
743
+ throw new MongoParseError(
744
+ `Invalid \`serverApi\` property; must specify a version from the following enum: ["${Object.values(
745
+ ServerApiVersion
746
+ ).join('", "')}"]`
747
+ );
748
+ }
749
+ if (!Object.values(ServerApiVersion).some(v => v === versionToValidate)) {
750
+ throw new MongoParseError(
751
+ `Invalid server API version=${versionToValidate}; must be in the following enum: ["${Object.values(
752
+ ServerApiVersion
753
+ ).join('", "')}"]`
754
+ );
755
+ }
756
+ return serverApiToValidate;
757
+ }
758
+ },
759
+ checkKeys: {
760
+ type: 'boolean'
761
+ },
762
+ compressors: {
763
+ default: 'none',
764
+ target: 'compressors',
765
+ transform({ values }) {
766
+ const compressionList = new Set();
767
+ for (const compVal of values as (CompressorName[] | string)[]) {
768
+ const compValArray = typeof compVal === 'string' ? compVal.split(',') : compVal;
769
+ if (!Array.isArray(compValArray)) {
770
+ throw new MongoInvalidArgumentError(
771
+ 'compressors must be an array or a comma-delimited list of strings'
772
+ );
773
+ }
774
+ for (const c of compValArray) {
775
+ if (Object.keys(Compressor).includes(String(c))) {
776
+ compressionList.add(String(c));
777
+ } else {
778
+ throw new MongoInvalidArgumentError(
779
+ `${c} is not a valid compression mechanism. Must be one of: ${Object.keys(
780
+ Compressor
781
+ )}.`
782
+ );
783
+ }
784
+ }
785
+ }
786
+ return [...compressionList];
787
+ }
788
+ },
789
+ connectTimeoutMS: {
790
+ default: 30000,
791
+ type: 'uint'
792
+ },
793
+ dbName: {
794
+ type: 'string'
795
+ },
796
+ directConnection: {
797
+ default: false,
798
+ type: 'boolean'
799
+ },
800
+ driverInfo: {
801
+ default: {},
802
+ type: 'record'
803
+ },
804
+ enableUtf8Validation: { type: 'boolean', default: true },
805
+ family: {
806
+ transform({ name, values: [value] }): 4 | 6 {
807
+ const transformValue = getIntFromOptions(name, value);
808
+ if (transformValue === 4 || transformValue === 6) {
809
+ return transformValue;
810
+ }
811
+ throw new MongoParseError(`Option 'family' must be 4 or 6 got ${transformValue}.`);
812
+ }
813
+ },
814
+ fieldsAsRaw: {
815
+ type: 'record'
816
+ },
817
+ forceServerObjectId: {
818
+ default: false,
819
+ type: 'boolean'
820
+ },
821
+ fsync: {
822
+ deprecated: 'Please use journal instead',
823
+ target: 'writeConcern',
824
+ transform({ name, options, values: [value] }): WriteConcern {
825
+ const wc = WriteConcern.fromOptions({
826
+ writeConcern: {
827
+ ...options.writeConcern,
828
+ fsync: getBoolean(name, value)
829
+ }
830
+ });
831
+ if (!wc) throw new MongoParseError(`Unable to make a writeConcern from fsync=${value}`);
832
+ return wc;
833
+ }
834
+ } as OptionDescriptor,
835
+ heartbeatFrequencyMS: {
836
+ default: 10000,
837
+ type: 'uint'
838
+ },
839
+ ignoreUndefined: {
840
+ type: 'boolean'
841
+ },
842
+ j: {
843
+ deprecated: 'Please use journal instead',
844
+ target: 'writeConcern',
845
+ transform({ name, options, values: [value] }): WriteConcern {
846
+ const wc = WriteConcern.fromOptions({
847
+ writeConcern: {
848
+ ...options.writeConcern,
849
+ journal: getBoolean(name, value)
850
+ }
851
+ });
852
+ if (!wc) throw new MongoParseError(`Unable to make a writeConcern from journal=${value}`);
853
+ return wc;
854
+ }
855
+ } as OptionDescriptor,
856
+ journal: {
857
+ target: 'writeConcern',
858
+ transform({ name, options, values: [value] }): WriteConcern {
859
+ const wc = WriteConcern.fromOptions({
860
+ writeConcern: {
861
+ ...options.writeConcern,
862
+ journal: getBoolean(name, value)
863
+ }
864
+ });
865
+ if (!wc) throw new MongoParseError(`Unable to make a writeConcern from journal=${value}`);
866
+ return wc;
867
+ }
868
+ },
869
+ loadBalanced: {
870
+ default: false,
871
+ type: 'boolean'
872
+ },
873
+ localThresholdMS: {
874
+ default: 15,
875
+ type: 'uint'
876
+ },
877
+ maxConnecting: {
878
+ default: 2,
879
+ transform({ name, values: [value] }): number {
880
+ const maxConnecting = getUIntFromOptions(name, value);
881
+ if (maxConnecting === 0) {
882
+ throw new MongoInvalidArgumentError('maxConnecting must be > 0 if specified');
883
+ }
884
+ return maxConnecting;
885
+ }
886
+ },
887
+ maxIdleTimeMS: {
888
+ default: 0,
889
+ type: 'uint'
890
+ },
891
+ maxPoolSize: {
892
+ default: 100,
893
+ type: 'uint'
894
+ },
895
+ maxStalenessSeconds: {
896
+ target: 'readPreference',
897
+ transform({ name, options, values: [value] }) {
898
+ const maxStalenessSeconds = getUIntFromOptions(name, value);
899
+ if (options.readPreference) {
900
+ return ReadPreference.fromOptions({
901
+ readPreference: { ...options.readPreference, maxStalenessSeconds }
902
+ });
903
+ } else {
904
+ return new ReadPreference('secondary', undefined, { maxStalenessSeconds });
905
+ }
906
+ }
907
+ },
908
+ minInternalBufferSize: {
909
+ type: 'uint'
910
+ },
911
+ minPoolSize: {
912
+ default: 0,
913
+ type: 'uint'
914
+ },
915
+ minHeartbeatFrequencyMS: {
916
+ default: 500,
917
+ type: 'uint'
918
+ },
919
+ monitorCommands: {
920
+ default: false,
921
+ type: 'boolean'
922
+ },
923
+ name: {
924
+ target: 'driverInfo',
925
+ transform({ values: [value], options }) {
926
+ return { ...options.driverInfo, name: String(value) };
927
+ }
928
+ } as OptionDescriptor,
929
+ noDelay: {
930
+ default: true,
931
+ type: 'boolean'
932
+ },
933
+ pkFactory: {
934
+ default: DEFAULT_PK_FACTORY,
935
+ transform({ values: [value] }): PkFactory {
936
+ if (isRecord(value, ['createPk'] as const) && typeof value.createPk === 'function') {
937
+ return value as PkFactory;
938
+ }
939
+ throw new MongoParseError(
940
+ `Option pkFactory must be an object with a createPk function, got ${value}`
941
+ );
942
+ }
943
+ },
944
+ promoteBuffers: {
945
+ type: 'boolean'
946
+ },
947
+ promoteLongs: {
948
+ type: 'boolean'
949
+ },
950
+ promoteValues: {
951
+ type: 'boolean'
952
+ },
953
+ useBigInt64: {
954
+ type: 'boolean'
955
+ },
956
+ proxyHost: {
957
+ type: 'string'
958
+ },
959
+ proxyPassword: {
960
+ type: 'string'
961
+ },
962
+ proxyPort: {
963
+ type: 'uint'
964
+ },
965
+ proxyUsername: {
966
+ type: 'string'
967
+ },
968
+ raw: {
969
+ default: false,
970
+ type: 'boolean'
971
+ },
972
+ readConcern: {
973
+ transform({ values: [value], options }) {
974
+ if (value instanceof ReadConcern || isRecord(value, ['level'] as const)) {
975
+ return ReadConcern.fromOptions({ ...options.readConcern, ...value } as any);
976
+ }
977
+ throw new MongoParseError(`ReadConcern must be an object, got ${JSON.stringify(value)}`);
978
+ }
979
+ },
980
+ readConcernLevel: {
981
+ target: 'readConcern',
982
+ transform({ values: [level], options }) {
983
+ return ReadConcern.fromOptions({
984
+ ...options.readConcern,
985
+ level: level as ReadConcernLevel
986
+ });
987
+ }
988
+ },
989
+ readPreference: {
990
+ default: ReadPreference.primary,
991
+ transform({ values: [value], options }) {
992
+ if (value instanceof ReadPreference) {
993
+ return ReadPreference.fromOptions({
994
+ readPreference: { ...options.readPreference, ...value },
995
+ ...value
996
+ } as any);
997
+ }
998
+ if (isRecord(value, ['mode'] as const)) {
999
+ const rp = ReadPreference.fromOptions({
1000
+ readPreference: { ...options.readPreference, ...value },
1001
+ ...value
1002
+ } as any);
1003
+ if (rp) return rp;
1004
+ else throw new MongoParseError(`Cannot make read preference from ${JSON.stringify(value)}`);
1005
+ }
1006
+ if (typeof value === 'string') {
1007
+ const rpOpts = {
1008
+ hedge: options.readPreference?.hedge,
1009
+ maxStalenessSeconds: options.readPreference?.maxStalenessSeconds
1010
+ };
1011
+ return new ReadPreference(
1012
+ value as ReadPreferenceMode,
1013
+ options.readPreference?.tags,
1014
+ rpOpts
1015
+ );
1016
+ }
1017
+ throw new MongoParseError(`Unknown ReadPreference value: ${value}`);
1018
+ }
1019
+ },
1020
+ readPreferenceTags: {
1021
+ target: 'readPreference',
1022
+ transform({
1023
+ values,
1024
+ options
1025
+ }: {
1026
+ values: Array<string | Record<string, string>[]>;
1027
+ options: MongoClientOptions;
1028
+ }) {
1029
+ const tags: Array<string | Record<string, string>> = Array.isArray(values[0])
1030
+ ? values[0]
1031
+ : (values as Array<string>);
1032
+ const readPreferenceTags = [];
1033
+ for (const tag of tags) {
1034
+ const readPreferenceTag: TagSet = Object.create(null);
1035
+ if (typeof tag === 'string') {
1036
+ for (const [k, v] of entriesFromString(tag)) {
1037
+ readPreferenceTag[k] = v;
1038
+ }
1039
+ }
1040
+ if (isRecord(tag)) {
1041
+ for (const [k, v] of Object.entries(tag)) {
1042
+ readPreferenceTag[k] = v;
1043
+ }
1044
+ }
1045
+ readPreferenceTags.push(readPreferenceTag);
1046
+ }
1047
+ return ReadPreference.fromOptions({
1048
+ readPreference: options.readPreference,
1049
+ readPreferenceTags
1050
+ });
1051
+ }
1052
+ },
1053
+ replicaSet: {
1054
+ type: 'string'
1055
+ },
1056
+ retryReads: {
1057
+ default: true,
1058
+ type: 'boolean'
1059
+ },
1060
+ retryWrites: {
1061
+ default: true,
1062
+ type: 'boolean'
1063
+ },
1064
+ serializeFunctions: {
1065
+ type: 'boolean'
1066
+ },
1067
+ serverMonitoringMode: {
1068
+ default: 'auto',
1069
+ transform({ values: [value] }) {
1070
+ if (!Object.values(ServerMonitoringMode).includes(value as any)) {
1071
+ throw new MongoParseError(
1072
+ 'serverMonitoringMode must be one of `auto`, `poll`, or `stream`'
1073
+ );
1074
+ }
1075
+ return value;
1076
+ }
1077
+ },
1078
+ serverSelectionTimeoutMS: {
1079
+ default: 30000,
1080
+ type: 'uint'
1081
+ },
1082
+ servername: {
1083
+ type: 'string'
1084
+ },
1085
+ socketTimeoutMS: {
1086
+ // TODO(NODE-6491): deprecated: 'Please use timeoutMS instead',
1087
+ default: 0,
1088
+ type: 'uint'
1089
+ },
1090
+ srvMaxHosts: {
1091
+ type: 'uint',
1092
+ default: 0
1093
+ },
1094
+ srvServiceName: {
1095
+ type: 'string',
1096
+ default: 'mongodb'
1097
+ },
1098
+ ssl: {
1099
+ target: 'tls',
1100
+ type: 'boolean'
1101
+ },
1102
+ timeoutMS: {
1103
+ type: 'uint'
1104
+ },
1105
+ tls: {
1106
+ type: 'boolean'
1107
+ },
1108
+ tlsAllowInvalidCertificates: {
1109
+ target: 'rejectUnauthorized',
1110
+ transform({ name, values: [value] }) {
1111
+ // allowInvalidCertificates is the inverse of rejectUnauthorized
1112
+ return !getBoolean(name, value);
1113
+ }
1114
+ },
1115
+ tlsAllowInvalidHostnames: {
1116
+ target: 'checkServerIdentity',
1117
+ transform({ name, values: [value] }) {
1118
+ // tlsAllowInvalidHostnames means setting the checkServerIdentity function to a noop
1119
+ return getBoolean(name, value) ? () => undefined : undefined;
1120
+ }
1121
+ },
1122
+ tlsCAFile: {
1123
+ type: 'string'
1124
+ },
1125
+ tlsCRLFile: {
1126
+ type: 'string'
1127
+ },
1128
+ tlsCertificateKeyFile: {
1129
+ type: 'string'
1130
+ },
1131
+ tlsCertificateKeyFilePassword: {
1132
+ target: 'passphrase',
1133
+ type: 'any'
1134
+ },
1135
+ tlsInsecure: {
1136
+ transform({ name, options, values: [value] }) {
1137
+ const tlsInsecure = getBoolean(name, value);
1138
+ if (tlsInsecure) {
1139
+ options.checkServerIdentity = () => undefined;
1140
+ options.rejectUnauthorized = false;
1141
+ } else {
1142
+ options.checkServerIdentity = options.tlsAllowInvalidHostnames
1143
+ ? () => undefined
1144
+ : undefined;
1145
+ options.rejectUnauthorized = options.tlsAllowInvalidCertificates ? false : true;
1146
+ }
1147
+ return tlsInsecure;
1148
+ }
1149
+ },
1150
+ w: {
1151
+ target: 'writeConcern',
1152
+ transform({ values: [value], options }) {
1153
+ return WriteConcern.fromOptions({ writeConcern: { ...options.writeConcern, w: value as W } });
1154
+ }
1155
+ },
1156
+ waitQueueTimeoutMS: {
1157
+ // TODO(NODE-6491): deprecated: 'Please use timeoutMS instead',
1158
+ default: 0,
1159
+ type: 'uint'
1160
+ },
1161
+ writeConcern: {
1162
+ target: 'writeConcern',
1163
+ transform({ values: [value], options }) {
1164
+ if (isRecord(value) || value instanceof WriteConcern) {
1165
+ return WriteConcern.fromOptions({
1166
+ writeConcern: {
1167
+ ...options.writeConcern,
1168
+ ...value
1169
+ }
1170
+ });
1171
+ } else if (value === 'majority' || typeof value === 'number') {
1172
+ return WriteConcern.fromOptions({
1173
+ writeConcern: {
1174
+ ...options.writeConcern,
1175
+ w: value
1176
+ }
1177
+ });
1178
+ }
1179
+
1180
+ throw new MongoParseError(`Invalid WriteConcern cannot parse: ${JSON.stringify(value)}`);
1181
+ }
1182
+ },
1183
+ wtimeout: {
1184
+ deprecated: 'Please use wtimeoutMS instead',
1185
+ target: 'writeConcern',
1186
+ transform({ values: [value], options }) {
1187
+ const wc = WriteConcern.fromOptions({
1188
+ writeConcern: {
1189
+ ...options.writeConcern,
1190
+ wtimeout: getUIntFromOptions('wtimeout', value)
1191
+ }
1192
+ });
1193
+ if (wc) return wc;
1194
+ throw new MongoParseError(`Cannot make WriteConcern from wtimeout`);
1195
+ }
1196
+ } as OptionDescriptor,
1197
+ wtimeoutMS: {
1198
+ target: 'writeConcern',
1199
+ transform({ values: [value], options }) {
1200
+ const wc = WriteConcern.fromOptions({
1201
+ writeConcern: {
1202
+ ...options.writeConcern,
1203
+ wtimeoutMS: getUIntFromOptions('wtimeoutMS', value)
1204
+ }
1205
+ });
1206
+ if (wc) return wc;
1207
+ throw new MongoParseError(`Cannot make WriteConcern from wtimeout`);
1208
+ }
1209
+ },
1210
+ zlibCompressionLevel: {
1211
+ default: 0,
1212
+ type: 'int'
1213
+ },
1214
+ mongodbLogPath: {
1215
+ transform({ values: [value] }) {
1216
+ if (
1217
+ !(
1218
+ (typeof value === 'string' && ['stderr', 'stdout'].includes(value)) ||
1219
+ (value &&
1220
+ typeof value === 'object' &&
1221
+ 'write' in value &&
1222
+ typeof value.write === 'function')
1223
+ )
1224
+ ) {
1225
+ throw new MongoAPIError(
1226
+ `Option 'mongodbLogPath' must be of type 'stderr' | 'stdout' | MongoDBLogWritable`
1227
+ );
1228
+ }
1229
+ return value;
1230
+ }
1231
+ },
1232
+ mongodbLogComponentSeverities: {
1233
+ transform({ values: [value] }) {
1234
+ if (typeof value !== 'object' || !value) {
1235
+ throw new MongoAPIError(`Option 'mongodbLogComponentSeverities' must be a non-null object`);
1236
+ }
1237
+ for (const [k, v] of Object.entries(value)) {
1238
+ if (typeof v !== 'string' || typeof k !== 'string') {
1239
+ throw new MongoAPIError(
1240
+ `User input for option 'mongodbLogComponentSeverities' object cannot include a non-string key or value`
1241
+ );
1242
+ }
1243
+ if (!Object.values(MongoLoggableComponent).some(val => val === k) && k !== 'default') {
1244
+ throw new MongoAPIError(
1245
+ `User input for option 'mongodbLogComponentSeverities' contains invalid key: ${k}`
1246
+ );
1247
+ }
1248
+ if (!Object.values(SeverityLevel).some(val => val === v)) {
1249
+ throw new MongoAPIError(
1250
+ `Option 'mongodbLogComponentSeverities' does not support ${v} as a value for ${k}`
1251
+ );
1252
+ }
1253
+ }
1254
+ return value;
1255
+ }
1256
+ },
1257
+ mongodbLogMaxDocumentLength: { type: 'uint' },
1258
+ // Custom types for modifying core behavior
1259
+ connectionType: { type: 'any' },
1260
+ srvPoller: { type: 'any' },
1261
+ // Accepted Node.js Options
1262
+ allowPartialTrustChain: { type: 'any' },
1263
+ minDHSize: { type: 'any' },
1264
+ pskCallback: { type: 'any' },
1265
+ secureContext: { type: 'any' },
1266
+ enableTrace: { type: 'any' },
1267
+ requestCert: { type: 'any' },
1268
+ rejectUnauthorized: { type: 'any' },
1269
+ checkServerIdentity: { type: 'any' },
1270
+ keepAliveInitialDelay: { type: 'any' },
1271
+ ALPNProtocols: { type: 'any' },
1272
+ SNICallback: { type: 'any' },
1273
+ session: { type: 'any' },
1274
+ requestOCSP: { type: 'any' },
1275
+ localAddress: { type: 'any' },
1276
+ localPort: { type: 'any' },
1277
+ hints: { type: 'any' },
1278
+ lookup: { type: 'any' },
1279
+ ca: { type: 'any' },
1280
+ cert: { type: 'any' },
1281
+ ciphers: { type: 'any' },
1282
+ crl: { type: 'any' },
1283
+ ecdhCurve: { type: 'any' },
1284
+ key: { type: 'any' },
1285
+ passphrase: { type: 'any' },
1286
+ pfx: { type: 'any' },
1287
+ secureProtocol: { type: 'any' },
1288
+ index: { type: 'any' },
1289
+ // Legacy options from v3 era
1290
+ __skipPingOnConnect: { type: 'boolean' }
1291
+ } as Record<keyof MongoClientOptions, OptionDescriptor>;
1292
+
1293
+ export const DEFAULT_OPTIONS = new CaseInsensitiveMap(
1294
+ Object.entries(OPTIONS)
1295
+ .filter(([, descriptor]) => descriptor.default != null)
1296
+ .map(([k, d]) => [k, d.default])
1297
+ );