@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,185 @@
1
+ import type { Document } from '../../bson';
2
+ import { MongoInvalidArgumentError, MongoMissingCredentialsError } from '../../error';
3
+ import type { HandshakeDocument } from '../connect';
4
+ import type { Connection } from '../connection';
5
+ import { type AuthContext, AuthProvider } from './auth_provider';
6
+ import type { MongoCredentials } from './mongo_credentials';
7
+ import { AutomatedCallbackWorkflow } from './mongodb_oidc/automated_callback_workflow';
8
+ import { callback as azureCallback } from './mongodb_oidc/azure_machine_workflow';
9
+ import { callback as gcpCallback } from './mongodb_oidc/gcp_machine_workflow';
10
+ import { callback as k8sCallback } from './mongodb_oidc/k8s_machine_workflow';
11
+ import { TokenCache } from './mongodb_oidc/token_cache';
12
+ import { callback as testCallback } from './mongodb_oidc/token_machine_workflow';
13
+
14
+ /** Error when credentials are missing. */
15
+ const MISSING_CREDENTIALS_ERROR = 'AuthContext must provide credentials.';
16
+
17
+ /**
18
+ * The information returned by the server on the IDP server.
19
+ * @public
20
+ */
21
+ export interface IdPInfo {
22
+ /**
23
+ * A URL which describes the Authentication Server. This identifier should
24
+ * be the iss of provided access tokens, and be viable for RFC8414 metadata
25
+ * discovery and RFC9207 identification.
26
+ */
27
+ issuer: string;
28
+ /** A unique client ID for this OIDC client. */
29
+ clientId: string;
30
+ /** A list of additional scopes to request from IdP. */
31
+ requestScopes?: string[];
32
+ }
33
+
34
+ /**
35
+ * The response from the IdP server with the access token and
36
+ * optional expiration time and refresh token.
37
+ * @public
38
+ */
39
+ export interface IdPServerResponse {
40
+ /** The OIDC access token. */
41
+ accessToken: string;
42
+ /** The time when the access token expires. For future use. */
43
+ expiresInSeconds?: number;
44
+ /** The refresh token, if applicable, to be used by the callback to request a new token from the issuer. */
45
+ refreshToken?: string;
46
+ }
47
+
48
+ /**
49
+ * The response required to be returned from the machine or
50
+ * human callback workflows' callback.
51
+ * @public
52
+ */
53
+ export interface OIDCResponse {
54
+ /** The OIDC access token. */
55
+ accessToken: string;
56
+ /** The time when the access token expires. For future use. */
57
+ expiresInSeconds?: number;
58
+ /** The refresh token, if applicable, to be used by the callback to request a new token from the issuer. */
59
+ refreshToken?: string;
60
+ }
61
+
62
+ /**
63
+ * The parameters that the driver provides to the user supplied
64
+ * human or machine callback.
65
+ *
66
+ * The version number is used to communicate callback API changes that are not breaking but that
67
+ * users may want to know about and review their implementation. Users may wish to check the version
68
+ * number and throw an error if their expected version number and the one provided do not match.
69
+ * @public
70
+ */
71
+ export interface OIDCCallbackParams {
72
+ /** Optional username. */
73
+ username?: string;
74
+ /** The context in which to timeout the OIDC callback. */
75
+ timeoutContext: AbortSignal;
76
+ /** The current OIDC API version. */
77
+ version: 1;
78
+ /** The IdP information returned from the server. */
79
+ idpInfo?: IdPInfo;
80
+ /** The refresh token, if applicable, to be used by the callback to request a new token from the issuer. */
81
+ refreshToken?: string;
82
+ /** The token audience for GCP and Azure. */
83
+ tokenAudience?: string;
84
+ }
85
+
86
+ /**
87
+ * The signature of the human or machine callback functions.
88
+ * @public
89
+ */
90
+ export type OIDCCallbackFunction = (params: OIDCCallbackParams) => Promise<OIDCResponse>;
91
+
92
+ /** The current version of OIDC implementation. */
93
+ export const OIDC_VERSION = 1;
94
+
95
+ type EnvironmentName = 'test' | 'azure' | 'gcp' | 'k8s' | undefined;
96
+
97
+ /** @internal */
98
+ export interface Workflow {
99
+ cache: TokenCache;
100
+
101
+ /**
102
+ * All device workflows must implement this method in order to get the access
103
+ * token and then call authenticate with it.
104
+ */
105
+ execute(
106
+ connection: Connection,
107
+ credentials: MongoCredentials,
108
+ response?: Document
109
+ ): Promise<void>;
110
+
111
+ /**
112
+ * Each workflow should specify the correct custom behaviour for reauthentication.
113
+ */
114
+ reauthenticate(connection: Connection, credentials: MongoCredentials): Promise<void>;
115
+
116
+ /**
117
+ * Get the document to add for speculative authentication.
118
+ */
119
+ speculativeAuth(connection: Connection, credentials: MongoCredentials): Promise<Document>;
120
+ }
121
+
122
+ /** @internal */
123
+ export const OIDC_WORKFLOWS: Map<EnvironmentName, () => Workflow> = new Map();
124
+ OIDC_WORKFLOWS.set('test', () => new AutomatedCallbackWorkflow(new TokenCache(), testCallback));
125
+ OIDC_WORKFLOWS.set('azure', () => new AutomatedCallbackWorkflow(new TokenCache(), azureCallback));
126
+ OIDC_WORKFLOWS.set('gcp', () => new AutomatedCallbackWorkflow(new TokenCache(), gcpCallback));
127
+ OIDC_WORKFLOWS.set('k8s', () => new AutomatedCallbackWorkflow(new TokenCache(), k8sCallback));
128
+
129
+ /**
130
+ * OIDC auth provider.
131
+ */
132
+ export class MongoDBOIDC extends AuthProvider {
133
+ workflow: Workflow;
134
+
135
+ /**
136
+ * Instantiate the auth provider.
137
+ */
138
+ constructor(workflow?: Workflow) {
139
+ super();
140
+ if (!workflow) {
141
+ throw new MongoInvalidArgumentError('No workflow provided to the OIDC auth provider.');
142
+ }
143
+ this.workflow = workflow;
144
+ }
145
+
146
+ /**
147
+ * Authenticate using OIDC
148
+ */
149
+ override async auth(authContext: AuthContext): Promise<void> {
150
+ const { connection, reauthenticating, response } = authContext;
151
+ if (response?.speculativeAuthenticate?.done && !reauthenticating) {
152
+ return;
153
+ }
154
+ const credentials = getCredentials(authContext);
155
+ if (reauthenticating) {
156
+ await this.workflow.reauthenticate(connection, credentials);
157
+ } else {
158
+ await this.workflow.execute(connection, credentials, response);
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Add the speculative auth for the initial handshake.
164
+ */
165
+ override async prepare(
166
+ handshakeDoc: HandshakeDocument,
167
+ authContext: AuthContext
168
+ ): Promise<HandshakeDocument> {
169
+ const { connection } = authContext;
170
+ const credentials = getCredentials(authContext);
171
+ const result = await this.workflow.speculativeAuth(connection, credentials);
172
+ return { ...handshakeDoc, ...result };
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Get credentials from the auth context, throwing if they do not exist.
178
+ */
179
+ function getCredentials(authContext: AuthContext): MongoCredentials {
180
+ const { credentials } = authContext;
181
+ if (!credentials) {
182
+ throw new MongoMissingCredentialsError(MISSING_CREDENTIALS_ERROR);
183
+ }
184
+ return credentials;
185
+ }
@@ -0,0 +1,25 @@
1
+ import { Binary } from '../../bson';
2
+ import { MongoMissingCredentialsError } from '../../error';
3
+ import { ns } from '../../utils';
4
+ import { type AuthContext, AuthProvider } from './auth_provider';
5
+
6
+ export class Plain extends AuthProvider {
7
+ override async auth(authContext: AuthContext): Promise<void> {
8
+ const { connection, credentials } = authContext;
9
+ if (!credentials) {
10
+ throw new MongoMissingCredentialsError('AuthContext must provide credentials.');
11
+ }
12
+
13
+ const { username, password } = credentials;
14
+
15
+ const payload = new Binary(Buffer.from(`\x00${username}\x00${password}`));
16
+ const command = {
17
+ saslStart: 1,
18
+ mechanism: 'PLAIN',
19
+ payload: payload,
20
+ autoAuthorize: 1
21
+ };
22
+
23
+ await connection.command(ns('$external.$cmd'), command, undefined);
24
+ }
25
+ }
@@ -0,0 +1,22 @@
1
+ /** @public */
2
+ export const AuthMechanism = Object.freeze({
3
+ MONGODB_AWS: 'MONGODB-AWS',
4
+ MONGODB_DEFAULT: 'DEFAULT',
5
+ MONGODB_GSSAPI: 'GSSAPI',
6
+ MONGODB_PLAIN: 'PLAIN',
7
+ MONGODB_SCRAM_SHA1: 'SCRAM-SHA-1',
8
+ MONGODB_SCRAM_SHA256: 'SCRAM-SHA-256',
9
+ MONGODB_X509: 'MONGODB-X509',
10
+ MONGODB_OIDC: 'MONGODB-OIDC'
11
+ } as const);
12
+
13
+ /** @public */
14
+ export type AuthMechanism = (typeof AuthMechanism)[keyof typeof AuthMechanism];
15
+
16
+ /** @internal */
17
+ export const AUTH_MECHS_AUTH_SRC_EXTERNAL = new Set<AuthMechanism>([
18
+ AuthMechanism.MONGODB_GSSAPI,
19
+ AuthMechanism.MONGODB_AWS,
20
+ AuthMechanism.MONGODB_OIDC,
21
+ AuthMechanism.MONGODB_X509
22
+ ]);
@@ -0,0 +1,344 @@
1
+ import { saslprep } from '@mongodb-js/saslprep';
2
+ import * as crypto from 'crypto';
3
+
4
+ import { Binary, type Document } from '../../bson';
5
+ import {
6
+ MongoInvalidArgumentError,
7
+ MongoMissingCredentialsError,
8
+ MongoRuntimeError
9
+ } from '../../error';
10
+ import { ns, randomBytes } from '../../utils';
11
+ import type { HandshakeDocument } from '../connect';
12
+ import { type AuthContext, AuthProvider } from './auth_provider';
13
+ import type { MongoCredentials } from './mongo_credentials';
14
+ import { AuthMechanism } from './providers';
15
+
16
+ type CryptoMethod = 'sha1' | 'sha256';
17
+
18
+ class ScramSHA extends AuthProvider {
19
+ cryptoMethod: CryptoMethod;
20
+
21
+ constructor(cryptoMethod: CryptoMethod) {
22
+ super();
23
+ this.cryptoMethod = cryptoMethod || 'sha1';
24
+ }
25
+
26
+ override async prepare(
27
+ handshakeDoc: HandshakeDocument,
28
+ authContext: AuthContext
29
+ ): Promise<HandshakeDocument> {
30
+ const cryptoMethod = this.cryptoMethod;
31
+ const credentials = authContext.credentials;
32
+ if (!credentials) {
33
+ throw new MongoMissingCredentialsError('AuthContext must provide credentials.');
34
+ }
35
+
36
+ const nonce = await randomBytes(24);
37
+ // store the nonce for later use
38
+ authContext.nonce = nonce;
39
+
40
+ const request = {
41
+ ...handshakeDoc,
42
+ speculativeAuthenticate: {
43
+ ...makeFirstMessage(cryptoMethod, credentials, nonce),
44
+ db: credentials.source
45
+ }
46
+ };
47
+
48
+ return request;
49
+ }
50
+
51
+ override async auth(authContext: AuthContext) {
52
+ const { reauthenticating, response } = authContext;
53
+ if (response?.speculativeAuthenticate && !reauthenticating) {
54
+ return await continueScramConversation(
55
+ this.cryptoMethod,
56
+ response.speculativeAuthenticate,
57
+ authContext
58
+ );
59
+ }
60
+ return await executeScram(this.cryptoMethod, authContext);
61
+ }
62
+ }
63
+
64
+ function cleanUsername(username: string) {
65
+ return username.replace('=', '=3D').replace(',', '=2C');
66
+ }
67
+
68
+ function clientFirstMessageBare(username: string, nonce: Buffer) {
69
+ // NOTE: This is done b/c Javascript uses UTF-16, but the server is hashing in UTF-8.
70
+ // Since the username is not sasl-prep-d, we need to do this here.
71
+ return Buffer.concat([
72
+ Buffer.from('n=', 'utf8'),
73
+ Buffer.from(username, 'utf8'),
74
+ Buffer.from(',r=', 'utf8'),
75
+ Buffer.from(nonce.toString('base64'), 'utf8')
76
+ ]);
77
+ }
78
+
79
+ function makeFirstMessage(
80
+ cryptoMethod: CryptoMethod,
81
+ credentials: MongoCredentials,
82
+ nonce: Buffer
83
+ ) {
84
+ const username = cleanUsername(credentials.username);
85
+ const mechanism =
86
+ cryptoMethod === 'sha1' ? AuthMechanism.MONGODB_SCRAM_SHA1 : AuthMechanism.MONGODB_SCRAM_SHA256;
87
+
88
+ // NOTE: This is done b/c Javascript uses UTF-16, but the server is hashing in UTF-8.
89
+ // Since the username is not sasl-prep-d, we need to do this here.
90
+ return {
91
+ saslStart: 1,
92
+ mechanism,
93
+ payload: new Binary(
94
+ Buffer.concat([Buffer.from('n,,', 'utf8'), clientFirstMessageBare(username, nonce)])
95
+ ),
96
+ autoAuthorize: 1,
97
+ options: { skipEmptyExchange: true }
98
+ };
99
+ }
100
+
101
+ async function executeScram(cryptoMethod: CryptoMethod, authContext: AuthContext): Promise<void> {
102
+ const { connection, credentials } = authContext;
103
+ if (!credentials) {
104
+ throw new MongoMissingCredentialsError('AuthContext must provide credentials.');
105
+ }
106
+ if (!authContext.nonce) {
107
+ throw new MongoInvalidArgumentError('AuthContext must contain a valid nonce property');
108
+ }
109
+ const nonce = authContext.nonce;
110
+ const db = credentials.source;
111
+
112
+ const saslStartCmd = makeFirstMessage(cryptoMethod, credentials, nonce);
113
+ const response = await connection.command(ns(`${db}.$cmd`), saslStartCmd, undefined);
114
+ await continueScramConversation(cryptoMethod, response, authContext);
115
+ }
116
+
117
+ async function continueScramConversation(
118
+ cryptoMethod: CryptoMethod,
119
+ response: Document,
120
+ authContext: AuthContext
121
+ ): Promise<void> {
122
+ const connection = authContext.connection;
123
+ const credentials = authContext.credentials;
124
+ if (!credentials) {
125
+ throw new MongoMissingCredentialsError('AuthContext must provide credentials.');
126
+ }
127
+ if (!authContext.nonce) {
128
+ throw new MongoInvalidArgumentError('Unable to continue SCRAM without valid nonce');
129
+ }
130
+ const nonce = authContext.nonce;
131
+
132
+ const db = credentials.source;
133
+ const username = cleanUsername(credentials.username);
134
+ const password = credentials.password;
135
+
136
+ const processedPassword =
137
+ cryptoMethod === 'sha256' ? saslprep(password) : passwordDigest(username, password);
138
+
139
+ const payload: Binary = Buffer.isBuffer(response.payload)
140
+ ? new Binary(response.payload)
141
+ : response.payload;
142
+
143
+ const dict = parsePayload(payload);
144
+
145
+ const iterations = parseInt(dict.i, 10);
146
+ if (iterations && iterations < 4096) {
147
+ // TODO(NODE-3483)
148
+ throw new MongoRuntimeError(`Server returned an invalid iteration count ${iterations}`);
149
+ }
150
+
151
+ const salt = dict.s;
152
+ const rnonce = dict.r;
153
+ if (rnonce.startsWith('nonce')) {
154
+ // TODO(NODE-3483)
155
+ throw new MongoRuntimeError(`Server returned an invalid nonce: ${rnonce}`);
156
+ }
157
+
158
+ // Set up start of proof
159
+ const withoutProof = `c=biws,r=${rnonce}`;
160
+ const saltedPassword = HI(
161
+ processedPassword,
162
+ Buffer.from(salt, 'base64'),
163
+ iterations,
164
+ cryptoMethod
165
+ );
166
+
167
+ const clientKey = HMAC(cryptoMethod, saltedPassword, 'Client Key');
168
+ const serverKey = HMAC(cryptoMethod, saltedPassword, 'Server Key');
169
+ const storedKey = H(cryptoMethod, clientKey);
170
+ const authMessage = [
171
+ clientFirstMessageBare(username, nonce),
172
+ payload.toString('utf8'),
173
+ withoutProof
174
+ ].join(',');
175
+
176
+ const clientSignature = HMAC(cryptoMethod, storedKey, authMessage);
177
+ const clientProof = `p=${xor(clientKey, clientSignature)}`;
178
+ const clientFinal = [withoutProof, clientProof].join(',');
179
+
180
+ const serverSignature = HMAC(cryptoMethod, serverKey, authMessage);
181
+ const saslContinueCmd = {
182
+ saslContinue: 1,
183
+ conversationId: response.conversationId,
184
+ payload: new Binary(Buffer.from(clientFinal))
185
+ };
186
+
187
+ const r = await connection.command(ns(`${db}.$cmd`), saslContinueCmd, undefined);
188
+ const parsedResponse = parsePayload(r.payload);
189
+
190
+ if (!compareDigest(Buffer.from(parsedResponse.v, 'base64'), serverSignature)) {
191
+ throw new MongoRuntimeError('Server returned an invalid signature');
192
+ }
193
+
194
+ if (r.done !== false) {
195
+ // If the server sends r.done === true we can save one RTT
196
+ return;
197
+ }
198
+
199
+ const retrySaslContinueCmd = {
200
+ saslContinue: 1,
201
+ conversationId: r.conversationId,
202
+ payload: Buffer.alloc(0)
203
+ };
204
+
205
+ await connection.command(ns(`${db}.$cmd`), retrySaslContinueCmd, undefined);
206
+ }
207
+
208
+ function parsePayload(payload: Binary) {
209
+ const payloadStr = payload.toString('utf8');
210
+ const dict: Document = {};
211
+ const parts = payloadStr.split(',');
212
+ for (let i = 0; i < parts.length; i++) {
213
+ const valueParts = (parts[i].match(/^([^=]*)=(.*)$/) ?? []).slice(1);
214
+ dict[valueParts[0]] = valueParts[1];
215
+ }
216
+ return dict;
217
+ }
218
+
219
+ function passwordDigest(username: string, password: string) {
220
+ if (typeof username !== 'string') {
221
+ throw new MongoInvalidArgumentError('Username must be a string');
222
+ }
223
+
224
+ if (typeof password !== 'string') {
225
+ throw new MongoInvalidArgumentError('Password must be a string');
226
+ }
227
+
228
+ if (password.length === 0) {
229
+ throw new MongoInvalidArgumentError('Password cannot be empty');
230
+ }
231
+
232
+ let md5: crypto.Hash;
233
+ try {
234
+ md5 = crypto.createHash('md5');
235
+ } catch (err) {
236
+ if (crypto.getFips()) {
237
+ // This error is (slightly) more helpful than what comes from OpenSSL directly, e.g.
238
+ // 'Error: error:060800C8:digital envelope routines:EVP_DigestInit_ex:disabled for FIPS'
239
+ throw new Error('Auth mechanism SCRAM-SHA-1 is not supported in FIPS mode');
240
+ }
241
+ throw err;
242
+ }
243
+ md5.update(`${username}:mongo:${password}`, 'utf8');
244
+ return md5.digest('hex');
245
+ }
246
+
247
+ // XOR two buffers
248
+ function xor(a: Buffer, b: Buffer) {
249
+ if (!Buffer.isBuffer(a)) {
250
+ a = Buffer.from(a);
251
+ }
252
+
253
+ if (!Buffer.isBuffer(b)) {
254
+ b = Buffer.from(b);
255
+ }
256
+
257
+ const length = Math.max(a.length, b.length);
258
+ const res = [];
259
+
260
+ for (let i = 0; i < length; i += 1) {
261
+ res.push(a[i] ^ b[i]);
262
+ }
263
+
264
+ return Buffer.from(res).toString('base64');
265
+ }
266
+
267
+ function H(method: CryptoMethod, text: Buffer) {
268
+ return crypto.createHash(method).update(text).digest();
269
+ }
270
+
271
+ function HMAC(method: CryptoMethod, key: Buffer, text: Buffer | string) {
272
+ return crypto.createHmac(method, key).update(text).digest();
273
+ }
274
+
275
+ interface HICache {
276
+ [key: string]: Buffer;
277
+ }
278
+
279
+ let _hiCache: HICache = {};
280
+ let _hiCacheCount = 0;
281
+ function _hiCachePurge() {
282
+ _hiCache = {};
283
+ _hiCacheCount = 0;
284
+ }
285
+
286
+ const hiLengthMap = {
287
+ sha256: 32,
288
+ sha1: 20
289
+ };
290
+
291
+ function HI(data: string, salt: Buffer, iterations: number, cryptoMethod: CryptoMethod) {
292
+ // omit the work if already generated
293
+ const key = [data, salt.toString('base64'), iterations].join('_');
294
+ if (_hiCache[key] != null) {
295
+ return _hiCache[key];
296
+ }
297
+
298
+ // generate the salt
299
+ const saltedData = crypto.pbkdf2Sync(
300
+ data,
301
+ salt,
302
+ iterations,
303
+ hiLengthMap[cryptoMethod],
304
+ cryptoMethod
305
+ );
306
+
307
+ // cache a copy to speed up the next lookup, but prevent unbounded cache growth
308
+ if (_hiCacheCount >= 200) {
309
+ _hiCachePurge();
310
+ }
311
+
312
+ _hiCache[key] = saltedData;
313
+ _hiCacheCount += 1;
314
+ return saltedData;
315
+ }
316
+
317
+ function compareDigest(lhs: Buffer, rhs: Uint8Array) {
318
+ if (lhs.length !== rhs.length) {
319
+ return false;
320
+ }
321
+
322
+ if (typeof crypto.timingSafeEqual === 'function') {
323
+ return crypto.timingSafeEqual(lhs, rhs);
324
+ }
325
+
326
+ let result = 0;
327
+ for (let i = 0; i < lhs.length; i++) {
328
+ result |= lhs[i] ^ rhs[i];
329
+ }
330
+
331
+ return result === 0;
332
+ }
333
+
334
+ export class ScramSHA1 extends ScramSHA {
335
+ constructor() {
336
+ super('sha1');
337
+ }
338
+ }
339
+
340
+ export class ScramSHA256 extends ScramSHA {
341
+ constructor() {
342
+ super('sha256');
343
+ }
344
+ }
@@ -0,0 +1,43 @@
1
+ import type { Document } from '../../bson';
2
+ import { MongoMissingCredentialsError } from '../../error';
3
+ import { ns } from '../../utils';
4
+ import type { HandshakeDocument } from '../connect';
5
+ import { type AuthContext, AuthProvider } from './auth_provider';
6
+ import type { MongoCredentials } from './mongo_credentials';
7
+
8
+ export class X509 extends AuthProvider {
9
+ override async prepare(
10
+ handshakeDoc: HandshakeDocument,
11
+ authContext: AuthContext
12
+ ): Promise<HandshakeDocument> {
13
+ const { credentials } = authContext;
14
+ if (!credentials) {
15
+ throw new MongoMissingCredentialsError('AuthContext must provide credentials.');
16
+ }
17
+ return { ...handshakeDoc, speculativeAuthenticate: x509AuthenticateCommand(credentials) };
18
+ }
19
+
20
+ override async auth(authContext: AuthContext) {
21
+ const connection = authContext.connection;
22
+ const credentials = authContext.credentials;
23
+ if (!credentials) {
24
+ throw new MongoMissingCredentialsError('AuthContext must provide credentials.');
25
+ }
26
+ const response = authContext.response;
27
+
28
+ if (response?.speculativeAuthenticate) {
29
+ return;
30
+ }
31
+
32
+ await connection.command(ns('$external.$cmd'), x509AuthenticateCommand(credentials), undefined);
33
+ }
34
+ }
35
+
36
+ function x509AuthenticateCommand(credentials: MongoCredentials) {
37
+ const command: Document = { authenticate: 1, mechanism: 'MONGODB-X509' };
38
+ if (credentials.username) {
39
+ command.user = credentials.username;
40
+ }
41
+
42
+ return command;
43
+ }