@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,924 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CursorTimeoutContext = exports.AbstractCursor = exports.CursorTimeoutMode = exports.CURSOR_FLAGS = void 0;
4
+ const stream_1 = require("stream");
5
+ const bson_1 = require("../bson");
6
+ const error_1 = require("../error");
7
+ const mongo_types_1 = require("../mongo_types");
8
+ const execute_operation_1 = require("../operations/execute_operation");
9
+ const get_more_1 = require("../operations/get_more");
10
+ const kill_cursors_1 = require("../operations/kill_cursors");
11
+ const read_concern_1 = require("../read_concern");
12
+ const read_preference_1 = require("../read_preference");
13
+ const sessions_1 = require("../sessions");
14
+ const timeout_1 = require("../timeout");
15
+ const utils_1 = require("../utils");
16
+ /** @public */
17
+ exports.CURSOR_FLAGS = [
18
+ 'tailable',
19
+ 'oplogReplay',
20
+ 'noCursorTimeout',
21
+ 'awaitData',
22
+ 'exhaust',
23
+ 'partial'
24
+ ];
25
+ function removeActiveCursor() {
26
+ this.client.s.activeCursors.delete(this);
27
+ }
28
+ /**
29
+ * @public
30
+ * @experimental
31
+ * Specifies how `timeoutMS` is applied to the cursor. Can be either `'cursorLifeTime'` or `'iteration'`
32
+ * When set to `'iteration'`, the deadline specified by `timeoutMS` applies to each call of
33
+ * `cursor.next()`.
34
+ * When set to `'cursorLifetime'`, the deadline applies to the life of the entire cursor.
35
+ *
36
+ * Depending on the type of cursor being used, this option has different default values.
37
+ * For non-tailable cursors, this value defaults to `'cursorLifetime'`
38
+ * For tailable cursors, this value defaults to `'iteration'` since tailable cursors, by
39
+ * definition can have an arbitrarily long lifetime.
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * const cursor = collection.find({}, {timeoutMS: 100, timeoutMode: 'iteration'});
44
+ * for await (const doc of cursor) {
45
+ * // process doc
46
+ * // This will throw a timeout error if any of the iterator's `next()` calls takes more than 100ms, but
47
+ * // will continue to iterate successfully otherwise, regardless of the number of batches.
48
+ * }
49
+ * ```
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * const cursor = collection.find({}, { timeoutMS: 1000, timeoutMode: 'cursorLifetime' });
54
+ * const docs = await cursor.toArray(); // This entire line will throw a timeout error if all batches are not fetched and returned within 1000ms.
55
+ * ```
56
+ */
57
+ exports.CursorTimeoutMode = Object.freeze({
58
+ ITERATION: 'iteration',
59
+ LIFETIME: 'cursorLifetime'
60
+ });
61
+ /** @public */
62
+ class AbstractCursor extends mongo_types_1.TypedEventEmitter {
63
+ /** @event */
64
+ static { this.CLOSE = 'close'; }
65
+ /** @internal */
66
+ constructor(client, namespace, options = {}) {
67
+ super();
68
+ /** @internal */
69
+ this.documents = null;
70
+ /** @internal */
71
+ this.hasEmittedClose = false;
72
+ this.on('error', utils_1.noop);
73
+ if (!client.s.isMongoClient) {
74
+ throw new error_1.MongoRuntimeError('Cursor must be constructed with MongoClient');
75
+ }
76
+ this.cursorClient = client;
77
+ this.cursorNamespace = namespace;
78
+ this.cursorId = null;
79
+ this.initialized = false;
80
+ this.isClosed = false;
81
+ this.isKilled = false;
82
+ this.cursorOptions = {
83
+ readPreference: options.readPreference && options.readPreference instanceof read_preference_1.ReadPreference
84
+ ? options.readPreference
85
+ : read_preference_1.ReadPreference.primary,
86
+ ...(0, bson_1.pluckBSONSerializeOptions)(options),
87
+ timeoutMS: options?.timeoutContext?.csotEnabled()
88
+ ? options.timeoutContext.timeoutMS
89
+ : options.timeoutMS,
90
+ tailable: options.tailable,
91
+ awaitData: options.awaitData
92
+ };
93
+ if (this.cursorOptions.timeoutMS != null) {
94
+ if (options.timeoutMode == null) {
95
+ if (options.tailable) {
96
+ if (options.awaitData) {
97
+ if (options.maxAwaitTimeMS != null &&
98
+ options.maxAwaitTimeMS >= this.cursorOptions.timeoutMS)
99
+ throw new error_1.MongoInvalidArgumentError('Cannot specify maxAwaitTimeMS >= timeoutMS for a tailable awaitData cursor');
100
+ }
101
+ this.cursorOptions.timeoutMode = exports.CursorTimeoutMode.ITERATION;
102
+ }
103
+ else {
104
+ this.cursorOptions.timeoutMode = exports.CursorTimeoutMode.LIFETIME;
105
+ }
106
+ }
107
+ else {
108
+ if (options.tailable && options.timeoutMode === exports.CursorTimeoutMode.LIFETIME) {
109
+ throw new error_1.MongoInvalidArgumentError("Cannot set tailable cursor's timeoutMode to LIFETIME");
110
+ }
111
+ this.cursorOptions.timeoutMode = options.timeoutMode;
112
+ }
113
+ }
114
+ else {
115
+ if (options.timeoutMode != null)
116
+ throw new error_1.MongoInvalidArgumentError('Cannot set timeoutMode without setting timeoutMS');
117
+ }
118
+ // Set for initial command
119
+ this.cursorOptions.omitMaxTimeMS =
120
+ this.cursorOptions.timeoutMS != null &&
121
+ ((this.cursorOptions.timeoutMode === exports.CursorTimeoutMode.ITERATION &&
122
+ !this.cursorOptions.tailable) ||
123
+ (this.cursorOptions.tailable && !this.cursorOptions.awaitData));
124
+ const readConcern = read_concern_1.ReadConcern.fromOptions(options);
125
+ if (readConcern) {
126
+ this.cursorOptions.readConcern = readConcern;
127
+ }
128
+ if (typeof options.batchSize === 'number') {
129
+ this.cursorOptions.batchSize = options.batchSize;
130
+ }
131
+ // we check for undefined specifically here to allow falsy values
132
+ // eslint-disable-next-line no-restricted-syntax
133
+ if (options.comment !== undefined) {
134
+ this.cursorOptions.comment = options.comment;
135
+ }
136
+ if (typeof options.maxTimeMS === 'number') {
137
+ this.cursorOptions.maxTimeMS = options.maxTimeMS;
138
+ }
139
+ if (typeof options.maxAwaitTimeMS === 'number') {
140
+ this.cursorOptions.maxAwaitTimeMS = options.maxAwaitTimeMS;
141
+ }
142
+ this.cursorSession = options.session ?? null;
143
+ this.deserializationOptions = {
144
+ ...this.cursorOptions,
145
+ validation: {
146
+ utf8: options?.enableUtf8Validation === false ? false : true
147
+ }
148
+ };
149
+ this.timeoutContext = options.timeoutContext;
150
+ this.signal = options.signal;
151
+ this.abortListener = (0, utils_1.addAbortListener)(this.signal, () => void this.close().then(undefined, utils_1.squashError));
152
+ this.trackCursor();
153
+ }
154
+ /**
155
+ * The cursor has no id until it receives a response from the initial cursor creating command.
156
+ *
157
+ * It is non-zero for as long as the database has an open cursor.
158
+ *
159
+ * The initiating command may receive a zero id if the entire result is in the `firstBatch`.
160
+ */
161
+ get id() {
162
+ return this.cursorId ?? undefined;
163
+ }
164
+ /** @internal */
165
+ get isDead() {
166
+ return (this.cursorId?.isZero() ?? false) || this.isClosed || this.isKilled;
167
+ }
168
+ /** @internal */
169
+ get client() {
170
+ return this.cursorClient;
171
+ }
172
+ /** @internal */
173
+ get server() {
174
+ return this.selectedServer;
175
+ }
176
+ get namespace() {
177
+ return this.cursorNamespace;
178
+ }
179
+ get readPreference() {
180
+ return this.cursorOptions.readPreference;
181
+ }
182
+ get readConcern() {
183
+ return this.cursorOptions.readConcern;
184
+ }
185
+ /** @internal */
186
+ get session() {
187
+ return this.cursorSession;
188
+ }
189
+ set session(clientSession) {
190
+ this.cursorSession = clientSession;
191
+ }
192
+ /**
193
+ * The cursor is closed and all remaining locally buffered documents have been iterated.
194
+ */
195
+ get closed() {
196
+ return this.isClosed && (this.documents?.length ?? 0) === 0;
197
+ }
198
+ /**
199
+ * A `killCursors` command was attempted on this cursor.
200
+ * This is performed if the cursor id is non zero.
201
+ */
202
+ get killed() {
203
+ return this.isKilled;
204
+ }
205
+ get loadBalanced() {
206
+ return !!this.cursorClient.topology?.loadBalanced;
207
+ }
208
+ /**
209
+ * @experimental
210
+ * An alias for {@link AbstractCursor.close|AbstractCursor.close()}.
211
+ */
212
+ async [Symbol.asyncDispose]() {
213
+ await this.close();
214
+ }
215
+ /** Adds cursor to client's tracking so it will be closed by MongoClient.close() */
216
+ trackCursor() {
217
+ this.cursorClient.s.activeCursors.add(this);
218
+ if (!this.listeners('close').includes(removeActiveCursor)) {
219
+ this.once('close', removeActiveCursor);
220
+ }
221
+ }
222
+ /** Returns current buffered documents length */
223
+ bufferedCount() {
224
+ return this.documents?.length ?? 0;
225
+ }
226
+ /** Returns current buffered documents */
227
+ readBufferedDocuments(number) {
228
+ const bufferedDocs = [];
229
+ const documentsToRead = Math.min(number ?? this.documents?.length ?? 0, this.documents?.length ?? 0);
230
+ for (let count = 0; count < documentsToRead; count++) {
231
+ const document = this.documents?.shift(this.deserializationOptions);
232
+ if (document != null) {
233
+ bufferedDocs.push(document);
234
+ }
235
+ }
236
+ return bufferedDocs;
237
+ }
238
+ async *[Symbol.asyncIterator]() {
239
+ this.signal?.throwIfAborted();
240
+ if (this.closed) {
241
+ return;
242
+ }
243
+ try {
244
+ while (true) {
245
+ if (this.isKilled) {
246
+ return;
247
+ }
248
+ if (this.closed) {
249
+ return;
250
+ }
251
+ if (this.cursorId != null && this.isDead && (this.documents?.length ?? 0) === 0) {
252
+ return;
253
+ }
254
+ const document = await this.next();
255
+ // eslint-disable-next-line no-restricted-syntax
256
+ if (document === null) {
257
+ return;
258
+ }
259
+ yield document;
260
+ this.signal?.throwIfAborted();
261
+ }
262
+ }
263
+ finally {
264
+ // Only close the cursor if it has not already been closed. This finally clause handles
265
+ // the case when a user would break out of a for await of loop early.
266
+ if (!this.isClosed) {
267
+ try {
268
+ await this.close();
269
+ }
270
+ catch (error) {
271
+ (0, utils_1.squashError)(error);
272
+ }
273
+ }
274
+ }
275
+ }
276
+ stream() {
277
+ const readable = new ReadableCursorStream(this);
278
+ const abortListener = (0, utils_1.addAbortListener)(this.signal, function () {
279
+ readable.destroy(this.reason);
280
+ });
281
+ readable.once('end', () => {
282
+ abortListener?.[utils_1.kDispose]();
283
+ });
284
+ return readable;
285
+ }
286
+ async hasNext() {
287
+ this.signal?.throwIfAborted();
288
+ if (this.cursorId === bson_1.Long.ZERO) {
289
+ return false;
290
+ }
291
+ if (this.cursorOptions.timeoutMode === exports.CursorTimeoutMode.ITERATION && this.cursorId != null) {
292
+ this.timeoutContext?.refresh();
293
+ }
294
+ try {
295
+ do {
296
+ if ((this.documents?.length ?? 0) !== 0) {
297
+ return true;
298
+ }
299
+ await this.fetchBatch();
300
+ } while (!this.isDead || (this.documents?.length ?? 0) !== 0);
301
+ }
302
+ finally {
303
+ if (this.cursorOptions.timeoutMode === exports.CursorTimeoutMode.ITERATION) {
304
+ this.timeoutContext?.clear();
305
+ }
306
+ }
307
+ return false;
308
+ }
309
+ /** Get the next available document from the cursor, returns null if no more documents are available. */
310
+ async next() {
311
+ this.signal?.throwIfAborted();
312
+ if (this.cursorId === bson_1.Long.ZERO) {
313
+ throw new error_1.MongoCursorExhaustedError();
314
+ }
315
+ if (this.cursorOptions.timeoutMode === exports.CursorTimeoutMode.ITERATION && this.cursorId != null) {
316
+ this.timeoutContext?.refresh();
317
+ }
318
+ try {
319
+ do {
320
+ const doc = this.documents?.shift(this.deserializationOptions);
321
+ if (doc != null) {
322
+ if (this.transform != null)
323
+ return await this.transformDocument(doc);
324
+ return doc;
325
+ }
326
+ await this.fetchBatch();
327
+ } while (!this.isDead || (this.documents?.length ?? 0) !== 0);
328
+ }
329
+ finally {
330
+ if (this.cursorOptions.timeoutMode === exports.CursorTimeoutMode.ITERATION) {
331
+ this.timeoutContext?.clear();
332
+ }
333
+ }
334
+ return null;
335
+ }
336
+ /**
337
+ * Try to get the next available document from the cursor or `null` if an empty batch is returned
338
+ */
339
+ async tryNext() {
340
+ this.signal?.throwIfAborted();
341
+ if (this.cursorId === bson_1.Long.ZERO) {
342
+ throw new error_1.MongoCursorExhaustedError();
343
+ }
344
+ if (this.cursorOptions.timeoutMode === exports.CursorTimeoutMode.ITERATION && this.cursorId != null) {
345
+ this.timeoutContext?.refresh();
346
+ }
347
+ try {
348
+ let doc = this.documents?.shift(this.deserializationOptions);
349
+ if (doc != null) {
350
+ if (this.transform != null)
351
+ return await this.transformDocument(doc);
352
+ return doc;
353
+ }
354
+ await this.fetchBatch();
355
+ doc = this.documents?.shift(this.deserializationOptions);
356
+ if (doc != null) {
357
+ if (this.transform != null)
358
+ return await this.transformDocument(doc);
359
+ return doc;
360
+ }
361
+ }
362
+ finally {
363
+ if (this.cursorOptions.timeoutMode === exports.CursorTimeoutMode.ITERATION) {
364
+ this.timeoutContext?.clear();
365
+ }
366
+ }
367
+ return null;
368
+ }
369
+ /**
370
+ * Iterates over all the documents for this cursor using the iterator, callback pattern.
371
+ *
372
+ * If the iterator returns `false`, iteration will stop.
373
+ *
374
+ * @param iterator - The iteration callback.
375
+ * @deprecated - Will be removed in a future release. Use for await...of instead.
376
+ */
377
+ async forEach(iterator) {
378
+ this.signal?.throwIfAborted();
379
+ if (typeof iterator !== 'function') {
380
+ throw new error_1.MongoInvalidArgumentError('Argument "iterator" must be a function');
381
+ }
382
+ for await (const document of this) {
383
+ const result = iterator(document);
384
+ if (result === false) {
385
+ break;
386
+ }
387
+ }
388
+ }
389
+ /**
390
+ * Frees any client-side resources used by the cursor.
391
+ */
392
+ async close(options) {
393
+ await this.cleanup(options?.timeoutMS);
394
+ }
395
+ /**
396
+ * Returns an array of documents. The caller is responsible for making sure that there
397
+ * is enough memory to store the results. Note that the array only contains partial
398
+ * results when this cursor had been previously accessed. In that case,
399
+ * cursor.rewind() can be used to reset the cursor.
400
+ */
401
+ async toArray() {
402
+ this.signal?.throwIfAborted();
403
+ const array = [];
404
+ // at the end of the loop (since readBufferedDocuments is called) the buffer will be empty
405
+ // then, the 'await of' syntax will run a getMore call
406
+ for await (const document of this) {
407
+ array.push(document);
408
+ const docs = this.readBufferedDocuments();
409
+ if (this.transform != null) {
410
+ for (const doc of docs) {
411
+ array.push(await this.transformDocument(doc));
412
+ }
413
+ }
414
+ else {
415
+ // Note: previous versions of this logic used `array.push(...)`, which adds each item
416
+ // to the callstack. For large arrays, this can exceed the maximum call size.
417
+ for (const doc of docs) {
418
+ array.push(doc);
419
+ }
420
+ }
421
+ }
422
+ return array;
423
+ }
424
+ /**
425
+ * Add a cursor flag to the cursor
426
+ *
427
+ * @param flag - The flag to set, must be one of following ['tailable', 'oplogReplay', 'noCursorTimeout', 'awaitData', 'partial' -.
428
+ * @param value - The flag boolean value.
429
+ */
430
+ addCursorFlag(flag, value) {
431
+ this.throwIfInitialized();
432
+ if (!exports.CURSOR_FLAGS.includes(flag)) {
433
+ throw new error_1.MongoInvalidArgumentError(`Flag ${flag} is not one of ${exports.CURSOR_FLAGS}`);
434
+ }
435
+ if (typeof value !== 'boolean') {
436
+ throw new error_1.MongoInvalidArgumentError(`Flag ${flag} must be a boolean value`);
437
+ }
438
+ this.cursorOptions[flag] = value;
439
+ return this;
440
+ }
441
+ /**
442
+ * Map all documents using the provided function
443
+ * If there is a transform set on the cursor, that will be called first and the result passed to
444
+ * this function's transform.
445
+ *
446
+ * @remarks
447
+ *
448
+ * **Note** Cursors use `null` internally to indicate that there are no more documents in the cursor. Providing a mapping
449
+ * function that maps values to `null` will result in the cursor closing itself before it has finished iterating
450
+ * all documents. This will **not** result in a memory leak, just surprising behavior. For example:
451
+ *
452
+ * ```typescript
453
+ * const cursor = collection.find({});
454
+ * cursor.map(() => null);
455
+ *
456
+ * const documents = await cursor.toArray();
457
+ * // documents is always [], regardless of how many documents are in the collection.
458
+ * ```
459
+ *
460
+ * Other falsey values are allowed:
461
+ *
462
+ * ```typescript
463
+ * const cursor = collection.find({});
464
+ * cursor.map(() => '');
465
+ *
466
+ * const documents = await cursor.toArray();
467
+ * // documents is now an array of empty strings
468
+ * ```
469
+ *
470
+ * **Note for Typescript Users:** adding a transform changes the return type of the iteration of this cursor,
471
+ * it **does not** return a new instance of a cursor. This means when calling map,
472
+ * you should always assign the result to a new variable in order to get a correctly typed cursor variable.
473
+ * Take note of the following example:
474
+ *
475
+ * @example
476
+ * ```typescript
477
+ * const cursor: FindCursor<Document> = coll.find();
478
+ * const mappedCursor: FindCursor<number> = cursor.map(doc => Object.keys(doc).length);
479
+ * const keyCounts: number[] = await mappedCursor.toArray(); // cursor.toArray() still returns Document[]
480
+ * ```
481
+ * @param transform - The mapping transformation method.
482
+ */
483
+ map(transform) {
484
+ this.throwIfInitialized();
485
+ const oldTransform = this.transform;
486
+ if (oldTransform) {
487
+ this.transform = doc => {
488
+ return transform(oldTransform(doc));
489
+ };
490
+ }
491
+ else {
492
+ this.transform = transform;
493
+ }
494
+ return this;
495
+ }
496
+ /**
497
+ * Set the ReadPreference for the cursor.
498
+ *
499
+ * @param readPreference - The new read preference for the cursor.
500
+ */
501
+ withReadPreference(readPreference) {
502
+ this.throwIfInitialized();
503
+ if (readPreference instanceof read_preference_1.ReadPreference) {
504
+ this.cursorOptions.readPreference = readPreference;
505
+ }
506
+ else if (typeof readPreference === 'string') {
507
+ this.cursorOptions.readPreference = read_preference_1.ReadPreference.fromString(readPreference);
508
+ }
509
+ else {
510
+ throw new error_1.MongoInvalidArgumentError(`Invalid read preference: ${readPreference}`);
511
+ }
512
+ return this;
513
+ }
514
+ /**
515
+ * Set the ReadPreference for the cursor.
516
+ *
517
+ * @param readPreference - The new read preference for the cursor.
518
+ */
519
+ withReadConcern(readConcern) {
520
+ this.throwIfInitialized();
521
+ const resolvedReadConcern = read_concern_1.ReadConcern.fromOptions({ readConcern });
522
+ if (resolvedReadConcern) {
523
+ this.cursorOptions.readConcern = resolvedReadConcern;
524
+ }
525
+ return this;
526
+ }
527
+ /**
528
+ * Set a maxTimeMS on the cursor query, allowing for hard timeout limits on queries (Only supported on MongoDB 2.6 or higher)
529
+ *
530
+ * @param value - Number of milliseconds to wait before aborting the query.
531
+ */
532
+ maxTimeMS(value) {
533
+ this.throwIfInitialized();
534
+ if (typeof value !== 'number') {
535
+ throw new error_1.MongoInvalidArgumentError('Argument for maxTimeMS must be a number');
536
+ }
537
+ this.cursorOptions.maxTimeMS = value;
538
+ return this;
539
+ }
540
+ /**
541
+ * Set the batch size for the cursor.
542
+ *
543
+ * @param value - The number of documents to return per batch. See {@link https://www.mongodb.com/docs/manual/reference/command/find/|find command documentation}.
544
+ */
545
+ batchSize(value) {
546
+ this.throwIfInitialized();
547
+ if (this.cursorOptions.tailable) {
548
+ throw new error_1.MongoTailableCursorError('Tailable cursor does not support batchSize');
549
+ }
550
+ if (typeof value !== 'number') {
551
+ throw new error_1.MongoInvalidArgumentError('Operation "batchSize" requires an integer');
552
+ }
553
+ this.cursorOptions.batchSize = value;
554
+ return this;
555
+ }
556
+ /**
557
+ * Rewind this cursor to its uninitialized state. Any options that are present on the cursor will
558
+ * remain in effect. Iterating this cursor will cause new queries to be sent to the server, even
559
+ * if the resultant data has already been retrieved by this cursor.
560
+ */
561
+ rewind() {
562
+ if (this.timeoutContext && this.timeoutContext.owner !== this) {
563
+ throw new error_1.MongoAPIError(`Cannot rewind cursor that does not own its timeout context.`);
564
+ }
565
+ if (!this.initialized) {
566
+ return;
567
+ }
568
+ this.cursorId = null;
569
+ this.documents?.clear();
570
+ this.timeoutContext?.clear();
571
+ this.timeoutContext = undefined;
572
+ this.isClosed = false;
573
+ this.isKilled = false;
574
+ this.initialized = false;
575
+ this.hasEmittedClose = false;
576
+ this.trackCursor();
577
+ // We only want to end this session if we created it, and it hasn't ended yet
578
+ if (this.cursorSession?.explicit === false) {
579
+ if (!this.cursorSession.hasEnded) {
580
+ this.cursorSession.endSession().then(undefined, utils_1.squashError);
581
+ }
582
+ this.cursorSession = null;
583
+ }
584
+ }
585
+ /** @internal */
586
+ async getMore() {
587
+ if (this.cursorId == null) {
588
+ throw new error_1.MongoRuntimeError('Unexpected null cursor id. A cursor creating command should have set this');
589
+ }
590
+ if (this.selectedServer == null) {
591
+ throw new error_1.MongoRuntimeError('Unexpected null selectedServer. A cursor creating command should have set this');
592
+ }
593
+ if (this.cursorSession == null) {
594
+ throw new error_1.MongoRuntimeError('Unexpected null session. A cursor creating command should have set this');
595
+ }
596
+ const getMoreOptions = {
597
+ ...this.cursorOptions,
598
+ session: this.cursorSession,
599
+ batchSize: this.cursorOptions.batchSize
600
+ };
601
+ const getMoreOperation = new get_more_1.GetMoreOperation(this.cursorNamespace, this.cursorId, this.selectedServer, getMoreOptions);
602
+ return await (0, execute_operation_1.executeOperation)(this.cursorClient, getMoreOperation, this.timeoutContext);
603
+ }
604
+ /**
605
+ * @internal
606
+ *
607
+ * This function is exposed for the unified test runner's createChangeStream
608
+ * operation. We cannot refactor to use the abstract _initialize method without
609
+ * a significant refactor.
610
+ */
611
+ async cursorInit() {
612
+ if (this.cursorOptions.timeoutMS != null) {
613
+ this.timeoutContext ??= new CursorTimeoutContext(timeout_1.TimeoutContext.create({
614
+ serverSelectionTimeoutMS: this.client.s.options.serverSelectionTimeoutMS,
615
+ timeoutMS: this.cursorOptions.timeoutMS
616
+ }), this);
617
+ }
618
+ try {
619
+ this.cursorSession ??= this.cursorClient.startSession({ owner: this, explicit: false });
620
+ const state = await this._initialize(this.cursorSession);
621
+ // Set omitMaxTimeMS to the value needed for subsequent getMore calls
622
+ this.cursorOptions.omitMaxTimeMS = this.cursorOptions.timeoutMS != null;
623
+ const response = state.response;
624
+ this.selectedServer = state.server;
625
+ this.cursorId = response.id;
626
+ this.cursorNamespace = response.ns ?? this.namespace;
627
+ this.documents = response;
628
+ this.initialized = true; // the cursor is now initialized, even if it is dead
629
+ }
630
+ catch (error) {
631
+ // the cursor is now initialized, even if an error occurred
632
+ this.initialized = true;
633
+ await this.cleanup(undefined, error);
634
+ throw error;
635
+ }
636
+ if (this.isDead) {
637
+ await this.cleanup();
638
+ }
639
+ return;
640
+ }
641
+ /** @internal Attempt to obtain more documents */
642
+ async fetchBatch() {
643
+ if (this.isClosed) {
644
+ return;
645
+ }
646
+ if (this.isDead) {
647
+ // if the cursor is dead, we clean it up
648
+ // cleanupCursor should never throw, but if it does it indicates a bug in the driver
649
+ // and we should surface the error
650
+ await this.cleanup();
651
+ return;
652
+ }
653
+ if (this.cursorId == null) {
654
+ await this.cursorInit();
655
+ // If the cursor died or returned documents, return
656
+ if ((this.documents?.length ?? 0) !== 0 || this.isDead)
657
+ return;
658
+ }
659
+ // Otherwise, run a getMore
660
+ try {
661
+ const response = await this.getMore();
662
+ this.cursorId = response.id;
663
+ this.documents = response;
664
+ }
665
+ catch (error) {
666
+ try {
667
+ await this.cleanup(undefined, error);
668
+ }
669
+ catch (cleanupError) {
670
+ // `cleanupCursor` should never throw, squash and throw the original error
671
+ (0, utils_1.squashError)(cleanupError);
672
+ }
673
+ throw error;
674
+ }
675
+ if (this.isDead) {
676
+ // If we successfully received a response from a cursor BUT the cursor indicates that it is exhausted,
677
+ // we intentionally clean up the cursor to release its session back into the pool before the cursor
678
+ // is iterated. This prevents a cursor that is exhausted on the server from holding
679
+ // onto a session indefinitely until the AbstractCursor is iterated.
680
+ //
681
+ // cleanupCursorAsync should never throw, but if it does it indicates a bug in the driver
682
+ // and we should surface the error
683
+ await this.cleanup();
684
+ }
685
+ }
686
+ /** @internal */
687
+ async cleanup(timeoutMS, error) {
688
+ this.abortListener?.[utils_1.kDispose]();
689
+ this.isClosed = true;
690
+ const timeoutContextForKillCursors = () => {
691
+ if (timeoutMS != null) {
692
+ this.timeoutContext?.clear();
693
+ return new CursorTimeoutContext(timeout_1.TimeoutContext.create({
694
+ serverSelectionTimeoutMS: this.client.s.options.serverSelectionTimeoutMS,
695
+ timeoutMS
696
+ }), this);
697
+ }
698
+ else {
699
+ return this.timeoutContext?.refreshed();
700
+ }
701
+ };
702
+ const withEmitClose = async (fn) => {
703
+ try {
704
+ await fn();
705
+ }
706
+ finally {
707
+ this.emitClose();
708
+ }
709
+ };
710
+ const close = async () => {
711
+ // if no session has been defined on the cursor, the cursor was never initialized
712
+ // or the cursor was re-wound and never re-iterated. In either case, we
713
+ // 1. do not need to end the session (there is no session after all)
714
+ // 2. do not need to kill the cursor server-side
715
+ const session = this.cursorSession;
716
+ if (!session)
717
+ return;
718
+ try {
719
+ if (!this.isKilled &&
720
+ this.cursorId &&
721
+ !this.cursorId.isZero() &&
722
+ this.cursorNamespace &&
723
+ this.selectedServer &&
724
+ !session.hasEnded) {
725
+ this.isKilled = true;
726
+ const cursorId = this.cursorId;
727
+ this.cursorId = bson_1.Long.ZERO;
728
+ await (0, execute_operation_1.executeOperation)(this.cursorClient, new kill_cursors_1.KillCursorsOperation(cursorId, this.cursorNamespace, this.selectedServer, {
729
+ session
730
+ }), timeoutContextForKillCursors());
731
+ }
732
+ }
733
+ catch (error) {
734
+ (0, utils_1.squashError)(error);
735
+ }
736
+ finally {
737
+ if (session.owner === this) {
738
+ await session.endSession({ error });
739
+ }
740
+ if (!session.inTransaction()) {
741
+ (0, sessions_1.maybeClearPinnedConnection)(session, { error });
742
+ }
743
+ }
744
+ };
745
+ await withEmitClose(close);
746
+ }
747
+ /** @internal */
748
+ emitClose() {
749
+ try {
750
+ if (!this.hasEmittedClose && ((this.documents?.length ?? 0) === 0 || this.isClosed)) {
751
+ // @ts-expect-error: CursorEvents is generic so Parameters<CursorEvents["close"]> may not be assignable to `[]`. Not sure how to require extenders do not add parameters.
752
+ this.emit('close');
753
+ }
754
+ }
755
+ finally {
756
+ this.hasEmittedClose = true;
757
+ }
758
+ }
759
+ /** @internal */
760
+ async transformDocument(document) {
761
+ if (this.transform == null)
762
+ return document;
763
+ try {
764
+ const transformedDocument = this.transform(document);
765
+ // eslint-disable-next-line no-restricted-syntax
766
+ if (transformedDocument === null) {
767
+ const TRANSFORM_TO_NULL_ERROR = 'Cursor returned a `null` document, but the cursor is not exhausted. Mapping documents to `null` is not supported in the cursor transform.';
768
+ throw new error_1.MongoAPIError(TRANSFORM_TO_NULL_ERROR);
769
+ }
770
+ return transformedDocument;
771
+ }
772
+ catch (transformError) {
773
+ try {
774
+ await this.close();
775
+ }
776
+ catch (closeError) {
777
+ (0, utils_1.squashError)(closeError);
778
+ }
779
+ throw transformError;
780
+ }
781
+ }
782
+ /** @internal */
783
+ throwIfInitialized() {
784
+ if (this.initialized)
785
+ throw new error_1.MongoCursorInUseError();
786
+ }
787
+ }
788
+ exports.AbstractCursor = AbstractCursor;
789
+ class ReadableCursorStream extends stream_1.Readable {
790
+ constructor(cursor) {
791
+ super({
792
+ objectMode: true,
793
+ autoDestroy: false,
794
+ highWaterMark: 1
795
+ });
796
+ this._readInProgress = false;
797
+ this._cursor = cursor;
798
+ }
799
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
800
+ _read(size) {
801
+ if (!this._readInProgress) {
802
+ this._readInProgress = true;
803
+ this._readNext();
804
+ }
805
+ }
806
+ _destroy(error, callback) {
807
+ this._cursor.close().then(() => callback(error), closeError => callback(closeError));
808
+ }
809
+ _readNext() {
810
+ if (this._cursor.id === bson_1.Long.ZERO) {
811
+ this.push(null);
812
+ return;
813
+ }
814
+ this._cursor
815
+ .next()
816
+ .then(
817
+ // result from next()
818
+ result => {
819
+ if (result == null) {
820
+ this.push(null);
821
+ }
822
+ else if (this.destroyed) {
823
+ this._cursor.close().then(undefined, utils_1.squashError);
824
+ }
825
+ else {
826
+ if (this.push(result)) {
827
+ return this._readNext();
828
+ }
829
+ this._readInProgress = false;
830
+ }
831
+ },
832
+ // error from next()
833
+ err => {
834
+ // NOTE: This is questionable, but we have a test backing the behavior. It seems the
835
+ // desired behavior is that a stream ends cleanly when a user explicitly closes
836
+ // a client during iteration. Alternatively, we could do the "right" thing and
837
+ // propagate the error message by removing this special case.
838
+ if (err.message.match(/server is closed/)) {
839
+ this._cursor.close().then(undefined, utils_1.squashError);
840
+ return this.push(null);
841
+ }
842
+ // NOTE: This is also perhaps questionable. The rationale here is that these errors tend
843
+ // to be "operation was interrupted", where a cursor has been closed but there is an
844
+ // active getMore in-flight. This used to check if the cursor was killed but once
845
+ // that changed to happen in cleanup legitimate errors would not destroy the
846
+ // stream. There are change streams test specifically test these cases.
847
+ if (err.message.match(/operation was interrupted/)) {
848
+ return this.push(null);
849
+ }
850
+ // NOTE: The two above checks on the message of the error will cause a null to be pushed
851
+ // to the stream, thus closing the stream before the destroy call happens. This means
852
+ // that either of those error messages on a change stream will not get a proper
853
+ // 'error' event to be emitted (the error passed to destroy). Change stream resumability
854
+ // relies on that error event to be emitted to create its new cursor and thus was not
855
+ // working on 4.4 servers because the error emitted on failover was "interrupted at
856
+ // shutdown" while on 5.0+ it is "The server is in quiesce mode and will shut down".
857
+ // See NODE-4475.
858
+ return this.destroy(err);
859
+ })
860
+ // if either of the above handlers throw
861
+ .catch(error => {
862
+ this._readInProgress = false;
863
+ this.destroy(error);
864
+ });
865
+ }
866
+ }
867
+ /**
868
+ * @internal
869
+ * The cursor timeout context is a wrapper around a timeout context
870
+ * that keeps track of the "owner" of the cursor. For timeout contexts
871
+ * instantiated inside a cursor, the owner will be the cursor.
872
+ *
873
+ * All timeout behavior is exactly the same as the wrapped timeout context's.
874
+ */
875
+ class CursorTimeoutContext extends timeout_1.TimeoutContext {
876
+ constructor(timeoutContext, owner) {
877
+ super();
878
+ this.timeoutContext = timeoutContext;
879
+ this.owner = owner;
880
+ }
881
+ get serverSelectionTimeout() {
882
+ return this.timeoutContext.serverSelectionTimeout;
883
+ }
884
+ get connectionCheckoutTimeout() {
885
+ return this.timeoutContext.connectionCheckoutTimeout;
886
+ }
887
+ get clearServerSelectionTimeout() {
888
+ return this.timeoutContext.clearServerSelectionTimeout;
889
+ }
890
+ get timeoutForSocketWrite() {
891
+ return this.timeoutContext.timeoutForSocketWrite;
892
+ }
893
+ get timeoutForSocketRead() {
894
+ return this.timeoutContext.timeoutForSocketRead;
895
+ }
896
+ csotEnabled() {
897
+ return this.timeoutContext.csotEnabled();
898
+ }
899
+ refresh() {
900
+ if (typeof this.owner !== 'symbol')
901
+ return this.timeoutContext.refresh();
902
+ }
903
+ clear() {
904
+ if (typeof this.owner !== 'symbol')
905
+ return this.timeoutContext.clear();
906
+ }
907
+ get maxTimeMS() {
908
+ return this.timeoutContext.maxTimeMS;
909
+ }
910
+ get timeoutMS() {
911
+ return this.timeoutContext.csotEnabled() ? this.timeoutContext.timeoutMS : null;
912
+ }
913
+ refreshed() {
914
+ return new CursorTimeoutContext(this.timeoutContext.refreshed(), this.owner);
915
+ }
916
+ addMaxTimeMSToCommand(command, options) {
917
+ this.timeoutContext.addMaxTimeMSToCommand(command, options);
918
+ }
919
+ getSocketTimeoutMS() {
920
+ return this.timeoutContext.getSocketTimeoutMS();
921
+ }
922
+ }
923
+ exports.CursorTimeoutContext = CursorTimeoutContext;
924
+ //# sourceMappingURL=abstract_cursor.js.map