mongodb 4.0.0 → 4.1.2

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 (246) hide show
  1. package/README.md +62 -30
  2. package/lib/bson.js +1 -0
  3. package/lib/bson.js.map +1 -1
  4. package/lib/bulk/common.js +53 -30
  5. package/lib/bulk/common.js.map +1 -1
  6. package/lib/bulk/ordered.js +3 -2
  7. package/lib/bulk/ordered.js.map +1 -1
  8. package/lib/bulk/unordered.js +3 -2
  9. package/lib/bulk/unordered.js.map +1 -1
  10. package/lib/change_stream.js +23 -13
  11. package/lib/change_stream.js.map +1 -1
  12. package/lib/cmap/auth/auth_provider.js +2 -1
  13. package/lib/cmap/auth/auth_provider.js.map +1 -1
  14. package/lib/cmap/auth/gssapi.js +5 -4
  15. package/lib/cmap/auth/gssapi.js.map +1 -1
  16. package/lib/cmap/auth/mongo_credentials.js +9 -5
  17. package/lib/cmap/auth/mongo_credentials.js.map +1 -1
  18. package/lib/cmap/auth/mongocr.js +2 -2
  19. package/lib/cmap/auth/mongocr.js.map +1 -1
  20. package/lib/cmap/auth/mongodb_aws.js +32 -32
  21. package/lib/cmap/auth/mongodb_aws.js.map +1 -1
  22. package/lib/cmap/auth/plain.js +1 -1
  23. package/lib/cmap/auth/plain.js.map +1 -1
  24. package/lib/cmap/auth/scram.js +15 -12
  25. package/lib/cmap/auth/scram.js.map +1 -1
  26. package/lib/cmap/auth/x509.js +2 -2
  27. package/lib/cmap/auth/x509.js.map +1 -1
  28. package/lib/cmap/command_monitoring_events.js +26 -10
  29. package/lib/cmap/command_monitoring_events.js.map +1 -1
  30. package/lib/cmap/commands.js +9 -5
  31. package/lib/cmap/commands.js.map +1 -1
  32. package/lib/cmap/connect.js +23 -9
  33. package/lib/cmap/connect.js.map +1 -1
  34. package/lib/cmap/connection.js +43 -46
  35. package/lib/cmap/connection.js.map +1 -1
  36. package/lib/cmap/connection_pool.js +113 -15
  37. package/lib/cmap/connection_pool.js.map +1 -1
  38. package/lib/cmap/connection_pool_events.js +3 -1
  39. package/lib/cmap/connection_pool_events.js.map +1 -1
  40. package/lib/cmap/errors.js +3 -3
  41. package/lib/cmap/errors.js.map +1 -1
  42. package/lib/cmap/message_stream.js +1 -1
  43. package/lib/cmap/message_stream.js.map +1 -1
  44. package/lib/cmap/metrics.js +62 -0
  45. package/lib/cmap/metrics.js.map +1 -0
  46. package/lib/cmap/stream_description.js +3 -1
  47. package/lib/cmap/stream_description.js.map +1 -1
  48. package/lib/cmap/wire_protocol/compression.js +22 -9
  49. package/lib/cmap/wire_protocol/compression.js.map +1 -1
  50. package/lib/cmap/wire_protocol/shared.js +1 -1
  51. package/lib/cmap/wire_protocol/shared.js.map +1 -1
  52. package/lib/collection.js +23 -18
  53. package/lib/collection.js.map +1 -1
  54. package/lib/connection_string.js +76 -30
  55. package/lib/connection_string.js.map +1 -1
  56. package/lib/cursor/abstract_cursor.js +75 -68
  57. package/lib/cursor/abstract_cursor.js.map +1 -1
  58. package/lib/cursor/aggregation_cursor.js +47 -9
  59. package/lib/cursor/aggregation_cursor.js.map +1 -1
  60. package/lib/cursor/find_cursor.js +53 -13
  61. package/lib/cursor/find_cursor.js.map +1 -1
  62. package/lib/db.js +21 -14
  63. package/lib/db.js.map +1 -1
  64. package/lib/deps.js +16 -5
  65. package/lib/deps.js.map +1 -1
  66. package/lib/encrypter.js +5 -8
  67. package/lib/encrypter.js.map +1 -1
  68. package/lib/error.js +230 -34
  69. package/lib/error.js.map +1 -1
  70. package/lib/explain.js +2 -2
  71. package/lib/explain.js.map +1 -1
  72. package/lib/gridfs/download.js +22 -47
  73. package/lib/gridfs/download.js.map +1 -1
  74. package/lib/gridfs/index.js +4 -3
  75. package/lib/gridfs/index.js.map +1 -1
  76. package/lib/gridfs/upload.js +13 -21
  77. package/lib/gridfs/upload.js.map +1 -1
  78. package/lib/index.js +27 -2
  79. package/lib/index.js.map +1 -1
  80. package/lib/logger.js +3 -2
  81. package/lib/logger.js.map +1 -1
  82. package/lib/mongo_client.js +5 -8
  83. package/lib/mongo_client.js.map +1 -1
  84. package/lib/mongo_types.js.map +1 -1
  85. package/lib/operations/add_user.js +2 -3
  86. package/lib/operations/add_user.js.map +1 -1
  87. package/lib/operations/aggregate.js +12 -9
  88. package/lib/operations/aggregate.js.map +1 -1
  89. package/lib/operations/command.js +5 -7
  90. package/lib/operations/command.js.map +1 -1
  91. package/lib/operations/common_functions.js +1 -1
  92. package/lib/operations/common_functions.js.map +1 -1
  93. package/lib/operations/connect.js +3 -2
  94. package/lib/operations/connect.js.map +1 -1
  95. package/lib/operations/count.js +1 -1
  96. package/lib/operations/count.js.map +1 -1
  97. package/lib/operations/count_documents.js +1 -1
  98. package/lib/operations/count_documents.js.map +1 -1
  99. package/lib/operations/delete.js +5 -5
  100. package/lib/operations/delete.js.map +1 -1
  101. package/lib/operations/distinct.js +2 -2
  102. package/lib/operations/distinct.js.map +1 -1
  103. package/lib/operations/estimated_document_count.js +5 -1
  104. package/lib/operations/estimated_document_count.js.map +1 -1
  105. package/lib/operations/eval.js.map +1 -1
  106. package/lib/operations/execute_operation.js +31 -17
  107. package/lib/operations/execute_operation.js.map +1 -1
  108. package/lib/operations/find.js +13 -9
  109. package/lib/operations/find.js.map +1 -1
  110. package/lib/operations/find_and_modify.js +9 -9
  111. package/lib/operations/find_and_modify.js.map +1 -1
  112. package/lib/operations/indexes.js +8 -3
  113. package/lib/operations/indexes.js.map +1 -1
  114. package/lib/operations/insert.js +5 -3
  115. package/lib/operations/insert.js.map +1 -1
  116. package/lib/operations/is_capped.js +2 -1
  117. package/lib/operations/is_capped.js.map +1 -1
  118. package/lib/operations/list_collections.js +6 -3
  119. package/lib/operations/list_collections.js.map +1 -1
  120. package/lib/operations/map_reduce.js +1 -1
  121. package/lib/operations/map_reduce.js.map +1 -1
  122. package/lib/operations/operation.js +3 -1
  123. package/lib/operations/operation.js.map +1 -1
  124. package/lib/operations/options_operation.js +2 -1
  125. package/lib/operations/options_operation.js.map +1 -1
  126. package/lib/operations/profiling_level.js +4 -2
  127. package/lib/operations/profiling_level.js.map +1 -1
  128. package/lib/operations/set_profiling_level.js +4 -2
  129. package/lib/operations/set_profiling_level.js.map +1 -1
  130. package/lib/operations/update.js +12 -12
  131. package/lib/operations/update.js.map +1 -1
  132. package/lib/operations/validate_collection.js +6 -5
  133. package/lib/operations/validate_collection.js.map +1 -1
  134. package/lib/promise_provider.js +1 -1
  135. package/lib/promise_provider.js.map +1 -1
  136. package/lib/read_preference.js +8 -8
  137. package/lib/read_preference.js.map +1 -1
  138. package/lib/sdam/common.js +12 -10
  139. package/lib/sdam/common.js.map +1 -1
  140. package/lib/sdam/server.js +90 -25
  141. package/lib/sdam/server.js.map +1 -1
  142. package/lib/sdam/server_description.js +9 -4
  143. package/lib/sdam/server_description.js.map +1 -1
  144. package/lib/sdam/server_selection.js +10 -4
  145. package/lib/sdam/server_selection.js.map +1 -1
  146. package/lib/sdam/srv_polling.js +1 -1
  147. package/lib/sdam/srv_polling.js.map +1 -1
  148. package/lib/sdam/topology.js +42 -21
  149. package/lib/sdam/topology.js.map +1 -1
  150. package/lib/sdam/topology_description.js +7 -3
  151. package/lib/sdam/topology_description.js.map +1 -1
  152. package/lib/sessions.js +132 -31
  153. package/lib/sessions.js.map +1 -1
  154. package/lib/sort.js +3 -3
  155. package/lib/sort.js.map +1 -1
  156. package/lib/transactions.js +15 -7
  157. package/lib/transactions.js.map +1 -1
  158. package/lib/utils.js +60 -20
  159. package/lib/utils.js.map +1 -1
  160. package/mongodb.d.ts +523 -138
  161. package/mongodb.ts34.d.ts +480 -141
  162. package/package.json +44 -48
  163. package/src/bson.ts +1 -0
  164. package/src/bulk/common.ts +83 -43
  165. package/src/bulk/ordered.ts +4 -3
  166. package/src/bulk/unordered.ts +4 -3
  167. package/src/change_stream.ts +46 -29
  168. package/src/cmap/auth/auth_provider.ts +3 -2
  169. package/src/cmap/auth/gssapi.ts +15 -5
  170. package/src/cmap/auth/mongo_credentials.ts +22 -8
  171. package/src/cmap/auth/mongocr.ts +3 -3
  172. package/src/cmap/auth/mongodb_aws.ts +52 -39
  173. package/src/cmap/auth/plain.ts +2 -2
  174. package/src/cmap/auth/scram.ts +23 -13
  175. package/src/cmap/auth/x509.ts +3 -3
  176. package/src/cmap/command_monitoring_events.ts +36 -14
  177. package/src/cmap/commands.ts +12 -6
  178. package/src/cmap/connect.ts +42 -12
  179. package/src/cmap/connection.ts +54 -62
  180. package/src/cmap/connection_pool.ts +141 -20
  181. package/src/cmap/connection_pool_events.ts +8 -1
  182. package/src/cmap/errors.ts +3 -4
  183. package/src/cmap/message_stream.ts +2 -4
  184. package/src/cmap/metrics.ts +58 -0
  185. package/src/cmap/stream_description.ts +6 -1
  186. package/src/cmap/wire_protocol/compression.ts +26 -13
  187. package/src/cmap/wire_protocol/shared.ts +4 -2
  188. package/src/collection.ts +75 -70
  189. package/src/connection_string.ts +97 -34
  190. package/src/cursor/abstract_cursor.ts +141 -104
  191. package/src/cursor/aggregation_cursor.ts +34 -20
  192. package/src/cursor/find_cursor.ts +41 -21
  193. package/src/db.ts +19 -18
  194. package/src/deps.ts +110 -22
  195. package/src/encrypter.ts +6 -12
  196. package/src/error.ts +264 -48
  197. package/src/explain.ts +3 -3
  198. package/src/gridfs/download.ts +48 -53
  199. package/src/gridfs/index.ts +5 -4
  200. package/src/gridfs/upload.ts +32 -33
  201. package/src/index.ts +42 -4
  202. package/src/logger.ts +6 -3
  203. package/src/mongo_client.ts +20 -23
  204. package/src/mongo_types.ts +19 -20
  205. package/src/operations/add_user.ts +4 -5
  206. package/src/operations/aggregate.ts +18 -17
  207. package/src/operations/command.ts +7 -10
  208. package/src/operations/common_functions.ts +2 -3
  209. package/src/operations/connect.ts +4 -3
  210. package/src/operations/count.ts +2 -2
  211. package/src/operations/count_documents.ts +2 -2
  212. package/src/operations/delete.ts +8 -6
  213. package/src/operations/distinct.ts +5 -3
  214. package/src/operations/estimated_document_count.ts +5 -1
  215. package/src/operations/eval.ts +1 -1
  216. package/src/operations/execute_operation.ts +41 -20
  217. package/src/operations/find.ts +25 -16
  218. package/src/operations/find_and_modify.ts +12 -10
  219. package/src/operations/indexes.ts +39 -8
  220. package/src/operations/insert.ts +7 -4
  221. package/src/operations/is_capped.ts +3 -2
  222. package/src/operations/list_collections.ts +9 -6
  223. package/src/operations/map_reduce.ts +4 -2
  224. package/src/operations/operation.ts +7 -2
  225. package/src/operations/options_operation.ts +3 -2
  226. package/src/operations/profiling_level.ts +5 -3
  227. package/src/operations/set_profiling_level.ts +9 -3
  228. package/src/operations/update.ts +17 -13
  229. package/src/operations/validate_collection.ts +7 -6
  230. package/src/promise_provider.ts +2 -2
  231. package/src/read_preference.ts +11 -9
  232. package/src/sdam/common.ts +11 -9
  233. package/src/sdam/server.ts +168 -69
  234. package/src/sdam/server_description.ts +16 -4
  235. package/src/sdam/server_selection.ts +15 -7
  236. package/src/sdam/srv_polling.ts +2 -2
  237. package/src/sdam/topology.ts +67 -36
  238. package/src/sdam/topology_description.ts +11 -4
  239. package/src/sessions.ts +194 -37
  240. package/src/sort.ts +6 -4
  241. package/src/transactions.ts +18 -9
  242. package/src/utils.ts +73 -20
  243. package/HISTORY.md +0 -2993
  244. package/lib/operations/find_one.js +0 -34
  245. package/lib/operations/find_one.js.map +0 -1
  246. package/src/operations/find_one.ts +0 -43
package/src/utils.ts CHANGED
@@ -1,10 +1,19 @@
1
1
  import * as os from 'os';
2
2
  import * as crypto from 'crypto';
3
3
  import { PromiseProvider } from './promise_provider';
4
- import { AnyError, MongoParseError, MongoDriverError } from './error';
4
+ import {
5
+ AnyError,
6
+ MongoParseError,
7
+ MongoRuntimeError,
8
+ MongoCompatibilityError,
9
+ MongoNotConnectedError,
10
+ MongoInvalidArgumentError,
11
+ MongoExpiredSessionError
12
+ } from './error';
5
13
  import { WriteConcern, WriteConcernOptions, W } from './write_concern';
6
14
  import type { Server } from './sdam/server';
7
15
  import type { Topology } from './sdam/topology';
16
+ import { ServerType } from './sdam/common';
8
17
  import type { Db } from './db';
9
18
  import type { Collection } from './collection';
10
19
  import type { OperationOptions, Hint } from './operations/operation';
@@ -18,6 +27,7 @@ import type { MongoClient } from './mongo_client';
18
27
  import type { CommandOperationOptions, OperationParent } from './operations/command';
19
28
  import { ReadPreference } from './read_preference';
20
29
  import { URL } from 'url';
30
+ import { MAX_SUPPORTED_WIRE_VERSION } from './cmap/wire_protocol/constants';
21
31
 
22
32
  /**
23
33
  * MongoDB Driver style callback
@@ -54,27 +64,30 @@ export function getSingleProperty(
54
64
  */
55
65
  export function checkCollectionName(collectionName: string): void {
56
66
  if ('string' !== typeof collectionName) {
57
- throw new MongoDriverError('collection name must be a String');
67
+ throw new MongoInvalidArgumentError('Collection name must be a String');
58
68
  }
59
69
 
60
70
  if (!collectionName || collectionName.indexOf('..') !== -1) {
61
- throw new MongoDriverError('collection names cannot be empty');
71
+ throw new MongoInvalidArgumentError('Collection names cannot be empty');
62
72
  }
63
73
 
64
74
  if (
65
75
  collectionName.indexOf('$') !== -1 &&
66
76
  collectionName.match(/((^\$cmd)|(oplog\.\$main))/) == null
67
77
  ) {
68
- throw new MongoDriverError("collection names must not contain '$'");
78
+ // TODO(NODE-3483): Use MongoNamespace static method
79
+ throw new MongoInvalidArgumentError("Collection names must not contain '$'");
69
80
  }
70
81
 
71
82
  if (collectionName.match(/^\.|\.$/) != null) {
72
- throw new MongoDriverError("collection names must not start or end with '.'");
83
+ // TODO(NODE-3483): Use MongoNamespace static method
84
+ throw new MongoInvalidArgumentError("Collection names must not start or end with '.'");
73
85
  }
74
86
 
75
87
  // Validate that we are not passing 0x00 in the collection name
76
88
  if (collectionName.indexOf('\x00') !== -1) {
77
- throw new MongoDriverError('collection names cannot contain a null character');
89
+ // TODO(NODE-3483): Use MongoNamespace static method
90
+ throw new MongoInvalidArgumentError('Collection names cannot contain a null character');
78
91
  }
79
92
  }
80
93
 
@@ -149,9 +162,9 @@ export function parseIndexOptions(indexSpec: IndexSpecification): IndexOptions {
149
162
  } else if (isObject(indexSpec)) {
150
163
  // {location:'2d', type:1}
151
164
  keys = Object.keys(indexSpec);
152
- keys.forEach(key => {
153
- indexes.push(key + '_' + indexSpec[key]);
154
- fieldHash[key] = indexSpec[key];
165
+ Object.entries(indexSpec).forEach(([key, value]) => {
166
+ indexes.push(key + '_' + value);
167
+ fieldHash[key] = value;
155
168
  });
156
169
  }
157
170
 
@@ -228,7 +241,8 @@ export function executeLegacyOperation(
228
241
  const Promise = PromiseProvider.get();
229
242
 
230
243
  if (!Array.isArray(args)) {
231
- throw new MongoDriverError('This method requires an array of arguments to apply');
244
+ // TODO(NODE-3483)
245
+ throw new MongoRuntimeError('This method requires an array of arguments to apply');
232
246
  }
233
247
 
234
248
  options = options ?? {};
@@ -248,7 +262,7 @@ export function executeLegacyOperation(
248
262
  const optionsIndex = args.length - 2;
249
263
  args[optionsIndex] = Object.assign({}, args[optionsIndex], { session: session });
250
264
  } else if (opOptions.session && opOptions.session.hasEnded) {
251
- throw new MongoDriverError('Use of expired sessions is not permitted');
265
+ throw new MongoExpiredSessionError();
252
266
  }
253
267
  }
254
268
 
@@ -289,7 +303,8 @@ export function executeLegacyOperation(
289
303
 
290
304
  // Return a Promise
291
305
  if (args[args.length - 1] != null) {
292
- throw new MongoDriverError('final argument to `executeLegacyOperation` must be a callback');
306
+ // TODO(NODE-3483)
307
+ throw new MongoRuntimeError('Final argument to `executeLegacyOperation` must be a callback');
293
308
  }
294
309
 
295
310
  return new Promise<any>((resolve, reject) => {
@@ -399,7 +414,7 @@ export function decorateWithCollation(
399
414
  if (capabilities && capabilities.commandsTakeCollation) {
400
415
  command.collation = options.collation;
401
416
  } else {
402
- throw new MongoDriverError(`Current topology does not support collation`);
417
+ throw new MongoCompatibilityError(`Current topology does not support collation`);
403
418
  }
404
419
  }
405
420
  }
@@ -458,7 +473,7 @@ export function getTopology<T>(provider: MongoClient | Db | Collection<T>): Topo
458
473
  return provider.s.db.s.client.topology;
459
474
  }
460
475
 
461
- throw new MongoDriverError('MongoClient must be connected to perform this operation');
476
+ throw new MongoNotConnectedError('MongoClient must be connected to perform this operation');
462
477
  }
463
478
 
464
479
  /**
@@ -574,7 +589,8 @@ export class MongoDBNamespace {
574
589
 
575
590
  static fromString(namespace?: string): MongoDBNamespace {
576
591
  if (!namespace) {
577
- throw new MongoDriverError(`Cannot parse namespace from "${namespace}"`);
592
+ // TODO(NODE-3483): Replace with MongoNamespaceError
593
+ throw new MongoRuntimeError(`Cannot parse namespace from "${namespace}"`);
578
594
  }
579
595
 
580
596
  const [db, ...collection] = namespace.split('.');
@@ -663,6 +679,13 @@ export function uuidV4(): Buffer {
663
679
  */
664
680
  export function maxWireVersion(topologyOrServer?: Connection | Topology | Server): number {
665
681
  if (topologyOrServer) {
682
+ if (topologyOrServer.loadBalanced) {
683
+ // Since we do not have a monitor, we assume the load balanced server is always
684
+ // pointed at the latest mongodb version. There is a risk that for on-prem
685
+ // deployments that don't upgrade immediately that this could alert to the
686
+ // application that a feature is avaiable that is actually not.
687
+ return MAX_SUPPORTED_WIRE_VERSION;
688
+ }
666
689
  if (topologyOrServer.ismaster) {
667
690
  return topologyOrServer.ismaster.maxWireVersion;
668
691
  }
@@ -677,7 +700,7 @@ export function maxWireVersion(topologyOrServer?: Connection | Topology | Server
677
700
  if (
678
701
  topologyOrServer.description &&
679
702
  'maxWireVersion' in topologyOrServer.description &&
680
- 'undefined' !== typeof topologyOrServer.description.maxWireVersion
703
+ topologyOrServer.description.maxWireVersion != null
681
704
  ) {
682
705
  return topologyOrServer.description.maxWireVersion;
683
706
  }
@@ -827,7 +850,7 @@ export function makeStateMachine(stateTable: StateTable): StateTransitionFunctio
827
850
  return function stateTransition(target, newState) {
828
851
  const legalStates = stateTable[target.s.state];
829
852
  if (legalStates && legalStates.indexOf(newState) < 0) {
830
- throw new MongoDriverError(
853
+ throw new MongoRuntimeError(
831
854
  `illegal state transition from [${target.s.state}] => [${newState}], allowed: [${legalStates}]`
832
855
  );
833
856
  }
@@ -921,7 +944,7 @@ export function now(): number {
921
944
  /** @internal */
922
945
  export function calculateDurationInMs(started: number): number {
923
946
  if (typeof started !== 'number') {
924
- throw new MongoDriverError('numeric value required to calculate duration');
947
+ throw new MongoInvalidArgumentError('Numeric value required to calculate duration');
925
948
  }
926
949
 
927
950
  const elapsed = now() - started;
@@ -1222,7 +1245,7 @@ export class BufferPool {
1222
1245
  /** Reads the requested number of bytes, optionally consuming them */
1223
1246
  read(size: number, consume = true): Buffer {
1224
1247
  if (typeof size !== 'number' || size < 0) {
1225
- throw new MongoDriverError('Parameter size must be a non-negative number');
1248
+ throw new MongoInvalidArgumentError('Argument "size" must be a non-negative number');
1226
1249
  }
1227
1250
 
1228
1251
  if (size > this[kLength]) {
@@ -1324,7 +1347,7 @@ export class HostAddress {
1324
1347
  throw new MongoParseError('Invalid port (zero) with hostname');
1325
1348
  }
1326
1349
  } else {
1327
- throw new MongoDriverError('Either socketPath or host must be defined.');
1350
+ throw new MongoInvalidArgumentError('Either socketPath or host must be defined.');
1328
1351
  }
1329
1352
  Object.freeze(this);
1330
1353
  }
@@ -1385,3 +1408,33 @@ export function emitWarningOnce(message: string): void {
1385
1408
  return emitWarning(message);
1386
1409
  }
1387
1410
  }
1411
+
1412
+ /**
1413
+ * Takes a JS object and joins the values into a string separated by ', '
1414
+ */
1415
+ export function enumToString(en: Record<string, unknown>): string {
1416
+ return Object.values(en).join(', ');
1417
+ }
1418
+
1419
+ /**
1420
+ * Determine if a server supports retryable writes.
1421
+ *
1422
+ * @internal
1423
+ */
1424
+ export function supportsRetryableWrites(server: Server): boolean {
1425
+ return (
1426
+ !!server.loadBalanced ||
1427
+ (server.description.maxWireVersion >= 6 &&
1428
+ !!server.description.logicalSessionTimeoutMinutes &&
1429
+ server.description.type !== ServerType.Standalone)
1430
+ );
1431
+ }
1432
+
1433
+ export function parsePackageVersion({ version }: { version: string }): {
1434
+ major: number;
1435
+ minor: number;
1436
+ patch: number;
1437
+ } {
1438
+ const [major, minor, patch] = version.split('.').map((n: string) => Number.parseInt(n, 10));
1439
+ return { major, minor, patch };
1440
+ }