@depup/mongoose 9.1.3-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 (295) hide show
  1. package/LICENSE.md +22 -0
  2. package/README.md +397 -0
  3. package/SECURITY.md +1 -0
  4. package/eslint.config.mjs +198 -0
  5. package/index.js +64 -0
  6. package/lib/aggregate.js +1189 -0
  7. package/lib/cast/bigint.js +46 -0
  8. package/lib/cast/boolean.js +32 -0
  9. package/lib/cast/date.js +41 -0
  10. package/lib/cast/decimal128.js +39 -0
  11. package/lib/cast/double.js +50 -0
  12. package/lib/cast/int32.js +36 -0
  13. package/lib/cast/number.js +42 -0
  14. package/lib/cast/objectid.js +29 -0
  15. package/lib/cast/string.js +37 -0
  16. package/lib/cast/uuid.js +35 -0
  17. package/lib/cast.js +436 -0
  18. package/lib/collection.js +321 -0
  19. package/lib/connection.js +1855 -0
  20. package/lib/connectionState.js +26 -0
  21. package/lib/constants.js +73 -0
  22. package/lib/cursor/aggregationCursor.js +466 -0
  23. package/lib/cursor/changeStream.js +198 -0
  24. package/lib/cursor/queryCursor.js +622 -0
  25. package/lib/document.js +5521 -0
  26. package/lib/driver.js +15 -0
  27. package/lib/drivers/SPEC.md +4 -0
  28. package/lib/drivers/node-mongodb-native/bulkWriteResult.js +5 -0
  29. package/lib/drivers/node-mongodb-native/collection.js +393 -0
  30. package/lib/drivers/node-mongodb-native/connection.js +506 -0
  31. package/lib/drivers/node-mongodb-native/index.js +10 -0
  32. package/lib/error/browserMissingSchema.js +29 -0
  33. package/lib/error/bulkSaveIncompleteError.js +44 -0
  34. package/lib/error/bulkWriteError.js +41 -0
  35. package/lib/error/cast.js +158 -0
  36. package/lib/error/createCollectionsError.js +26 -0
  37. package/lib/error/divergentArray.js +40 -0
  38. package/lib/error/eachAsyncMultiError.js +41 -0
  39. package/lib/error/index.js +237 -0
  40. package/lib/error/invalidSchemaOption.js +32 -0
  41. package/lib/error/messages.js +47 -0
  42. package/lib/error/missingSchema.js +33 -0
  43. package/lib/error/mongooseError.js +13 -0
  44. package/lib/error/notFound.js +47 -0
  45. package/lib/error/objectExpected.js +31 -0
  46. package/lib/error/objectParameter.js +31 -0
  47. package/lib/error/overwriteModel.js +31 -0
  48. package/lib/error/parallelSave.js +33 -0
  49. package/lib/error/parallelValidate.js +33 -0
  50. package/lib/error/serverSelection.js +62 -0
  51. package/lib/error/setOptionError.js +103 -0
  52. package/lib/error/strict.js +35 -0
  53. package/lib/error/strictPopulate.js +31 -0
  54. package/lib/error/syncIndexes.js +30 -0
  55. package/lib/error/validation.js +97 -0
  56. package/lib/error/validator.js +100 -0
  57. package/lib/error/version.js +38 -0
  58. package/lib/helpers/aggregate/prepareDiscriminatorPipeline.js +39 -0
  59. package/lib/helpers/aggregate/stringifyFunctionOperators.js +50 -0
  60. package/lib/helpers/arrayDepth.js +33 -0
  61. package/lib/helpers/clone.js +204 -0
  62. package/lib/helpers/common.js +127 -0
  63. package/lib/helpers/createJSONSchemaTypeDefinition.js +24 -0
  64. package/lib/helpers/cursor/eachAsync.js +225 -0
  65. package/lib/helpers/discriminator/applyEmbeddedDiscriminators.js +36 -0
  66. package/lib/helpers/discriminator/areDiscriminatorValuesEqual.js +16 -0
  67. package/lib/helpers/discriminator/checkEmbeddedDiscriminatorKeyProjection.js +12 -0
  68. package/lib/helpers/discriminator/getConstructor.js +29 -0
  69. package/lib/helpers/discriminator/getDiscriminatorByValue.js +28 -0
  70. package/lib/helpers/discriminator/getSchemaDiscriminatorByValue.js +27 -0
  71. package/lib/helpers/discriminator/mergeDiscriminatorSchema.js +91 -0
  72. package/lib/helpers/document/applyDefaults.js +132 -0
  73. package/lib/helpers/document/applyTimestamps.js +106 -0
  74. package/lib/helpers/document/applyVirtuals.js +147 -0
  75. package/lib/helpers/document/cleanModifiedSubpaths.js +45 -0
  76. package/lib/helpers/document/compile.js +238 -0
  77. package/lib/helpers/document/getDeepestSubdocumentForPath.js +38 -0
  78. package/lib/helpers/document/getEmbeddedDiscriminatorPath.js +53 -0
  79. package/lib/helpers/document/handleSpreadDoc.js +35 -0
  80. package/lib/helpers/each.js +25 -0
  81. package/lib/helpers/error/combinePathErrors.js +22 -0
  82. package/lib/helpers/firstKey.js +8 -0
  83. package/lib/helpers/get.js +65 -0
  84. package/lib/helpers/getConstructorName.js +16 -0
  85. package/lib/helpers/getDefaultBulkwriteResult.js +18 -0
  86. package/lib/helpers/getFunctionName.js +10 -0
  87. package/lib/helpers/immediate.js +16 -0
  88. package/lib/helpers/indexes/applySchemaCollation.js +13 -0
  89. package/lib/helpers/indexes/decorateDiscriminatorIndexOptions.js +14 -0
  90. package/lib/helpers/indexes/getRelatedIndexes.js +63 -0
  91. package/lib/helpers/indexes/isDefaultIdIndex.js +18 -0
  92. package/lib/helpers/indexes/isIndexEqual.js +95 -0
  93. package/lib/helpers/indexes/isIndexSpecEqual.js +32 -0
  94. package/lib/helpers/indexes/isTextIndex.js +16 -0
  95. package/lib/helpers/indexes/isTimeseriesIndex.js +16 -0
  96. package/lib/helpers/isAsyncFunction.js +9 -0
  97. package/lib/helpers/isBsonType.js +15 -0
  98. package/lib/helpers/isMongooseObject.js +22 -0
  99. package/lib/helpers/isObject.js +16 -0
  100. package/lib/helpers/isPOJO.js +12 -0
  101. package/lib/helpers/isPromise.js +6 -0
  102. package/lib/helpers/isSimpleValidator.js +22 -0
  103. package/lib/helpers/minimize.js +41 -0
  104. package/lib/helpers/model/applyDefaultsToPOJO.js +52 -0
  105. package/lib/helpers/model/applyHooks.js +140 -0
  106. package/lib/helpers/model/applyMethods.js +70 -0
  107. package/lib/helpers/model/applyStaticHooks.js +33 -0
  108. package/lib/helpers/model/applyStatics.js +13 -0
  109. package/lib/helpers/model/castBulkWrite.js +316 -0
  110. package/lib/helpers/model/decorateBulkWriteResult.js +8 -0
  111. package/lib/helpers/model/discriminator.js +265 -0
  112. package/lib/helpers/model/pushNestedArrayPaths.js +15 -0
  113. package/lib/helpers/omitUndefined.js +20 -0
  114. package/lib/helpers/once.js +12 -0
  115. package/lib/helpers/parallelLimit.js +37 -0
  116. package/lib/helpers/path/parentPaths.js +18 -0
  117. package/lib/helpers/path/setDottedPath.js +33 -0
  118. package/lib/helpers/pluralize.js +95 -0
  119. package/lib/helpers/populate/assignRawDocsToIdStructure.js +129 -0
  120. package/lib/helpers/populate/assignVals.js +360 -0
  121. package/lib/helpers/populate/createPopulateQueryFilter.js +97 -0
  122. package/lib/helpers/populate/getModelsMapForPopulate.js +776 -0
  123. package/lib/helpers/populate/getSchemaTypes.js +228 -0
  124. package/lib/helpers/populate/getVirtual.js +103 -0
  125. package/lib/helpers/populate/leanPopulateMap.js +7 -0
  126. package/lib/helpers/populate/lookupLocalFields.js +40 -0
  127. package/lib/helpers/populate/markArraySubdocsPopulated.js +49 -0
  128. package/lib/helpers/populate/modelNamesFromRefPath.js +66 -0
  129. package/lib/helpers/populate/removeDeselectedForeignField.js +31 -0
  130. package/lib/helpers/populate/setPopulatedVirtualValue.js +33 -0
  131. package/lib/helpers/populate/skipPopulateValue.js +10 -0
  132. package/lib/helpers/populate/validateRef.js +19 -0
  133. package/lib/helpers/printJestWarning.js +21 -0
  134. package/lib/helpers/processConnectionOptions.js +65 -0
  135. package/lib/helpers/projection/applyProjection.js +83 -0
  136. package/lib/helpers/projection/hasIncludedChildren.js +41 -0
  137. package/lib/helpers/projection/isDefiningProjection.js +18 -0
  138. package/lib/helpers/projection/isExclusive.js +37 -0
  139. package/lib/helpers/projection/isInclusive.js +39 -0
  140. package/lib/helpers/projection/isNestedProjection.js +8 -0
  141. package/lib/helpers/projection/isPathExcluded.js +40 -0
  142. package/lib/helpers/projection/isPathSelectedInclusive.js +28 -0
  143. package/lib/helpers/projection/isSubpath.js +14 -0
  144. package/lib/helpers/projection/parseProjection.js +33 -0
  145. package/lib/helpers/query/applyGlobalOption.js +29 -0
  146. package/lib/helpers/query/cast$expr.js +287 -0
  147. package/lib/helpers/query/castFilterPath.js +54 -0
  148. package/lib/helpers/query/castUpdate.js +643 -0
  149. package/lib/helpers/query/getEmbeddedDiscriminatorPath.js +103 -0
  150. package/lib/helpers/query/handleImmutable.js +44 -0
  151. package/lib/helpers/query/handleReadPreferenceAliases.js +23 -0
  152. package/lib/helpers/query/hasDollarKeys.js +23 -0
  153. package/lib/helpers/query/isOperator.js +14 -0
  154. package/lib/helpers/query/sanitizeFilter.js +38 -0
  155. package/lib/helpers/query/sanitizeProjection.js +14 -0
  156. package/lib/helpers/query/selectPopulatedFields.js +62 -0
  157. package/lib/helpers/query/trusted.js +13 -0
  158. package/lib/helpers/query/validOps.js +3 -0
  159. package/lib/helpers/schema/addAutoId.js +7 -0
  160. package/lib/helpers/schema/applyBuiltinPlugins.js +12 -0
  161. package/lib/helpers/schema/applyPlugins.js +55 -0
  162. package/lib/helpers/schema/applyReadConcern.js +20 -0
  163. package/lib/helpers/schema/applyWriteConcern.js +39 -0
  164. package/lib/helpers/schema/cleanPositionalOperators.js +12 -0
  165. package/lib/helpers/schema/getIndexes.js +171 -0
  166. package/lib/helpers/schema/getKeysInSchemaOrder.js +28 -0
  167. package/lib/helpers/schema/getPath.js +43 -0
  168. package/lib/helpers/schema/getSubdocumentStrictValue.js +32 -0
  169. package/lib/helpers/schema/handleIdOption.js +20 -0
  170. package/lib/helpers/schema/handleTimestampOption.js +24 -0
  171. package/lib/helpers/schema/idGetter.js +34 -0
  172. package/lib/helpers/schema/merge.js +36 -0
  173. package/lib/helpers/schematype/handleImmutable.js +50 -0
  174. package/lib/helpers/setDefaultsOnInsert.js +158 -0
  175. package/lib/helpers/specialProperties.js +3 -0
  176. package/lib/helpers/symbols.js +20 -0
  177. package/lib/helpers/timers.js +3 -0
  178. package/lib/helpers/timestamps/setDocumentTimestamps.js +26 -0
  179. package/lib/helpers/timestamps/setupTimestamps.js +116 -0
  180. package/lib/helpers/topology/allServersUnknown.js +12 -0
  181. package/lib/helpers/topology/isAtlas.js +31 -0
  182. package/lib/helpers/topology/isSSLError.js +16 -0
  183. package/lib/helpers/update/applyTimestampsToChildren.js +193 -0
  184. package/lib/helpers/update/applyTimestampsToUpdate.js +131 -0
  185. package/lib/helpers/update/castArrayFilters.js +113 -0
  186. package/lib/helpers/update/decorateUpdateWithVersionKey.js +35 -0
  187. package/lib/helpers/update/modifiedPaths.js +33 -0
  188. package/lib/helpers/update/moveImmutableProperties.js +53 -0
  189. package/lib/helpers/update/removeUnusedArrayFilters.js +32 -0
  190. package/lib/helpers/update/updatedPathsByArrayFilter.js +27 -0
  191. package/lib/helpers/updateValidators.js +193 -0
  192. package/lib/index.js +17 -0
  193. package/lib/internal.js +46 -0
  194. package/lib/model.js +5010 -0
  195. package/lib/modifiedPathsSnapshot.js +9 -0
  196. package/lib/mongoose.js +1411 -0
  197. package/lib/options/populateOptions.js +36 -0
  198. package/lib/options/propertyOptions.js +8 -0
  199. package/lib/options/saveOptions.js +16 -0
  200. package/lib/options/schemaArrayOptions.js +78 -0
  201. package/lib/options/schemaBufferOptions.js +38 -0
  202. package/lib/options/schemaDateOptions.js +71 -0
  203. package/lib/options/schemaDocumentArrayOptions.js +68 -0
  204. package/lib/options/schemaMapOptions.js +43 -0
  205. package/lib/options/schemaNumberOptions.js +101 -0
  206. package/lib/options/schemaObjectIdOptions.js +64 -0
  207. package/lib/options/schemaStringOptions.js +138 -0
  208. package/lib/options/schemaSubdocumentOptions.js +66 -0
  209. package/lib/options/schemaTypeOptions.js +244 -0
  210. package/lib/options/schemaUnionOptions.js +32 -0
  211. package/lib/options/virtualOptions.js +164 -0
  212. package/lib/options.js +17 -0
  213. package/lib/plugins/index.js +6 -0
  214. package/lib/plugins/saveSubdocs.js +76 -0
  215. package/lib/plugins/sharding.js +84 -0
  216. package/lib/plugins/trackTransaction.js +84 -0
  217. package/lib/plugins/validateBeforeSave.js +41 -0
  218. package/lib/query.js +5673 -0
  219. package/lib/queryHelpers.js +387 -0
  220. package/lib/schema/array.js +699 -0
  221. package/lib/schema/bigint.js +282 -0
  222. package/lib/schema/boolean.js +332 -0
  223. package/lib/schema/buffer.js +343 -0
  224. package/lib/schema/date.js +467 -0
  225. package/lib/schema/decimal128.js +263 -0
  226. package/lib/schema/documentArray.js +656 -0
  227. package/lib/schema/documentArrayElement.js +137 -0
  228. package/lib/schema/double.js +246 -0
  229. package/lib/schema/index.js +32 -0
  230. package/lib/schema/int32.js +289 -0
  231. package/lib/schema/map.js +201 -0
  232. package/lib/schema/mixed.js +146 -0
  233. package/lib/schema/number.js +510 -0
  234. package/lib/schema/objectId.js +333 -0
  235. package/lib/schema/operators/bitwise.js +38 -0
  236. package/lib/schema/operators/exists.js +12 -0
  237. package/lib/schema/operators/geospatial.js +107 -0
  238. package/lib/schema/operators/helpers.js +32 -0
  239. package/lib/schema/operators/text.js +39 -0
  240. package/lib/schema/operators/type.js +20 -0
  241. package/lib/schema/string.js +733 -0
  242. package/lib/schema/subdocument.js +436 -0
  243. package/lib/schema/symbols.js +5 -0
  244. package/lib/schema/union.js +113 -0
  245. package/lib/schema/uuid.js +305 -0
  246. package/lib/schema.js +3226 -0
  247. package/lib/schemaType.js +1835 -0
  248. package/lib/stateMachine.js +232 -0
  249. package/lib/types/array/index.js +119 -0
  250. package/lib/types/array/isMongooseArray.js +5 -0
  251. package/lib/types/array/methods/index.js +1095 -0
  252. package/lib/types/arraySubdocument.js +207 -0
  253. package/lib/types/buffer.js +294 -0
  254. package/lib/types/decimal128.js +13 -0
  255. package/lib/types/documentArray/index.js +113 -0
  256. package/lib/types/documentArray/isMongooseDocumentArray.js +5 -0
  257. package/lib/types/documentArray/methods/index.js +415 -0
  258. package/lib/types/double.js +13 -0
  259. package/lib/types/index.js +23 -0
  260. package/lib/types/map.js +419 -0
  261. package/lib/types/objectid.js +41 -0
  262. package/lib/types/subdocument.js +464 -0
  263. package/lib/types/uuid.js +13 -0
  264. package/lib/utils.js +1054 -0
  265. package/lib/validOptions.js +42 -0
  266. package/lib/virtualType.js +204 -0
  267. package/package.json +148 -0
  268. package/types/aggregate.d.ts +180 -0
  269. package/types/augmentations.d.ts +9 -0
  270. package/types/callback.d.ts +8 -0
  271. package/types/collection.d.ts +49 -0
  272. package/types/connection.d.ts +297 -0
  273. package/types/cursor.d.ts +67 -0
  274. package/types/document.d.ts +374 -0
  275. package/types/error.d.ts +143 -0
  276. package/types/expressions.d.ts +3053 -0
  277. package/types/helpers.d.ts +32 -0
  278. package/types/index.d.ts +1056 -0
  279. package/types/indexes.d.ts +97 -0
  280. package/types/inferhydrateddoctype.d.ts +115 -0
  281. package/types/inferrawdoctype.d.ts +135 -0
  282. package/types/inferschematype.d.ts +337 -0
  283. package/types/middlewares.d.ts +59 -0
  284. package/types/models.d.ts +1306 -0
  285. package/types/mongooseoptions.d.ts +228 -0
  286. package/types/pipelinestage.d.ts +333 -0
  287. package/types/populate.d.ts +53 -0
  288. package/types/query.d.ts +934 -0
  289. package/types/schemaoptions.d.ts +282 -0
  290. package/types/schematypes.d.ts +654 -0
  291. package/types/session.d.ts +32 -0
  292. package/types/types.d.ts +109 -0
  293. package/types/utility.d.ts +175 -0
  294. package/types/validation.d.ts +39 -0
  295. package/types/virtuals.d.ts +14 -0
@@ -0,0 +1,26 @@
1
+
2
+ /*!
3
+ * Connection states
4
+ */
5
+
6
+ 'use strict';
7
+
8
+ const STATES = module.exports = exports = Object.create(null);
9
+
10
+ const disconnected = 'disconnected';
11
+ const connected = 'connected';
12
+ const connecting = 'connecting';
13
+ const disconnecting = 'disconnecting';
14
+ const uninitialized = 'uninitialized';
15
+
16
+ STATES[0] = disconnected;
17
+ STATES[1] = connected;
18
+ STATES[2] = connecting;
19
+ STATES[3] = disconnecting;
20
+ STATES[99] = uninitialized;
21
+
22
+ STATES[disconnected] = 0;
23
+ STATES[connected] = 1;
24
+ STATES[connecting] = 2;
25
+ STATES[disconnecting] = 3;
26
+ STATES[uninitialized] = 99;
@@ -0,0 +1,73 @@
1
+ 'use strict';
2
+
3
+ /*!
4
+ * ignore
5
+ */
6
+
7
+ const queryOperations = Object.freeze([
8
+ // Read
9
+ 'countDocuments',
10
+ 'distinct',
11
+ 'estimatedDocumentCount',
12
+ 'find',
13
+ 'findOne',
14
+ // Update
15
+ 'findOneAndReplace',
16
+ 'findOneAndUpdate',
17
+ 'replaceOne',
18
+ 'updateMany',
19
+ 'updateOne',
20
+ // Delete
21
+ 'deleteMany',
22
+ 'deleteOne',
23
+ 'findOneAndDelete'
24
+ ]);
25
+
26
+ exports.queryOperations = queryOperations;
27
+
28
+ /*!
29
+ * ignore
30
+ */
31
+
32
+ const queryMiddlewareFunctions = queryOperations.concat([
33
+ 'validate'
34
+ ]);
35
+
36
+ exports.queryMiddlewareFunctions = queryMiddlewareFunctions;
37
+
38
+ /*!
39
+ * ignore
40
+ */
41
+
42
+ const aggregateMiddlewareFunctions = [
43
+ 'aggregate'
44
+ ];
45
+
46
+ exports.aggregateMiddlewareFunctions = aggregateMiddlewareFunctions;
47
+
48
+ /*!
49
+ * ignore
50
+ */
51
+
52
+ const modelMiddlewareFunctions = [
53
+ 'bulkWrite',
54
+ 'createCollection',
55
+ 'insertMany'
56
+ ];
57
+
58
+ exports.modelMiddlewareFunctions = modelMiddlewareFunctions;
59
+
60
+ /*!
61
+ * ignore
62
+ */
63
+
64
+ const documentMiddlewareFunctions = [
65
+ 'validate',
66
+ 'save',
67
+ 'remove',
68
+ 'updateOne',
69
+ 'deleteOne',
70
+ 'init'
71
+ ];
72
+
73
+ exports.documentMiddlewareFunctions = documentMiddlewareFunctions;
@@ -0,0 +1,466 @@
1
+ /*!
2
+ * Module dependencies.
3
+ */
4
+
5
+ 'use strict';
6
+
7
+ const MongooseError = require('../error/mongooseError');
8
+ const Readable = require('stream').Readable;
9
+ const eachAsync = require('../helpers/cursor/eachAsync');
10
+ const immediate = require('../helpers/immediate');
11
+ const kareem = require('kareem');
12
+ const util = require('util');
13
+
14
+ /**
15
+ * An AggregationCursor is a concurrency primitive for processing aggregation
16
+ * results one document at a time. It is analogous to QueryCursor.
17
+ *
18
+ * An AggregationCursor fulfills the Node.js streams3 API,
19
+ * in addition to several other mechanisms for loading documents from MongoDB
20
+ * one at a time.
21
+ *
22
+ * Creating an AggregationCursor executes the model's pre aggregate hooks,
23
+ * but **not** the model's post aggregate hooks.
24
+ *
25
+ * Unless you're an advanced user, do **not** instantiate this class directly.
26
+ * Use [`Aggregate#cursor()`](https://mongoosejs.com/docs/api/aggregate.html#Aggregate.prototype.cursor()) instead.
27
+ *
28
+ * @param {Aggregate} agg
29
+ * @inherits Readable https://nodejs.org/api/stream.html#class-streamreadable
30
+ * @event `cursor`: Emitted when the cursor is created
31
+ * @event `error`: Emitted when an error occurred
32
+ * @event `data`: Emitted when the stream is flowing and the next doc is ready
33
+ * @event `end`: Emitted when the stream is exhausted
34
+ * @api public
35
+ */
36
+
37
+ function AggregationCursor(agg) {
38
+ // set autoDestroy=true because on node 12 it's by default false
39
+ // gh-10902 need autoDestroy to destroy correctly and emit 'close' event
40
+ Readable.call(this, { autoDestroy: true, objectMode: true });
41
+
42
+ this.cursor = null;
43
+ this.agg = agg;
44
+ this._transforms = [];
45
+ const connection = agg._connection;
46
+ const model = agg._model;
47
+ delete agg.options.cursor.useMongooseAggCursor;
48
+ this._mongooseOptions = {};
49
+
50
+ if (connection) {
51
+ this.cursor = connection.db.aggregate(agg._pipeline, agg.options || {});
52
+ setImmediate(() => this.emit('cursor', this.cursor));
53
+ } else {
54
+ _init(model, this, agg);
55
+ }
56
+ }
57
+
58
+ util.inherits(AggregationCursor, Readable);
59
+
60
+ /*!
61
+ * ignore
62
+ */
63
+
64
+ function _init(model, c, agg) {
65
+ if (!model.collection.buffer) {
66
+ model.hooks.execPre('aggregate', agg).then(() => onPreComplete(null), err => onPreComplete(err));
67
+ } else {
68
+ model.collection.emitter.once('queue', function() {
69
+ model.hooks.execPre('aggregate', agg).then(() => onPreComplete(null), err => onPreComplete(err));
70
+ });
71
+ }
72
+
73
+ function onPreComplete(err) {
74
+ if (err != null) {
75
+ _handlePreHookError(c, err);
76
+ return;
77
+ }
78
+ if (typeof agg.options?.cursor?.transform === 'function') {
79
+ c._transforms.push(agg.options.cursor.transform);
80
+ }
81
+
82
+ c.cursor = model.collection.aggregate(agg._pipeline, agg.options || {});
83
+ c.emit('cursor', c.cursor);
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Handles error emitted from pre middleware. In particular, checks for `skipWrappedFunction`, which allows skipping
89
+ * the actual aggregation and overwriting the function's return value. Because aggregation cursors don't return a value,
90
+ * we need to make sure the user doesn't accidentally set a value in skipWrappedFunction.
91
+ *
92
+ * @param {QueryCursor} queryCursor
93
+ * @param {Error} err
94
+ * @returns
95
+ */
96
+
97
+ function _handlePreHookError(queryCursor, err) {
98
+ if (err instanceof kareem.skipWrappedFunction) {
99
+ const resultValue = err.args[0];
100
+ if (resultValue != null && (!Array.isArray(resultValue) || resultValue.length)) {
101
+ const err = new MongooseError(
102
+ 'Cannot `skipMiddlewareFunction()` with a value when using ' +
103
+ '`.aggregate().cursor()`, value must be nullish or empty array, got "' +
104
+ util.inspect(resultValue) +
105
+ '".'
106
+ );
107
+ queryCursor._markError(err);
108
+ queryCursor.listeners('error').length > 0 && queryCursor.emit('error', err);
109
+ return;
110
+ }
111
+ queryCursor.emit('cursor', null);
112
+ return;
113
+ }
114
+ queryCursor._markError(err);
115
+ queryCursor.listeners('error').length > 0 && queryCursor.emit('error', err);
116
+ }
117
+
118
+
119
+ /**
120
+ * Necessary to satisfy the Readable API
121
+ * @method _read
122
+ * @memberOf AggregationCursor
123
+ * @instance
124
+ * @api private
125
+ */
126
+
127
+ AggregationCursor.prototype._read = function() {
128
+ const _this = this;
129
+ _next(this, function(error, doc) {
130
+ if (error) {
131
+ return _this.emit('error', error);
132
+ }
133
+ if (!doc) {
134
+ _this.push(null);
135
+ _this.cursor.close(function(error) {
136
+ if (error) {
137
+ return _this.emit('error', error);
138
+ }
139
+ });
140
+ return;
141
+ }
142
+ _this.push(doc);
143
+ });
144
+ };
145
+
146
+ if (Symbol.asyncIterator != null) {
147
+ const msg = 'Mongoose does not support using async iterators with an ' +
148
+ 'existing aggregation cursor. See https://bit.ly/mongoose-async-iterate-aggregation';
149
+
150
+ AggregationCursor.prototype[Symbol.asyncIterator] = function() {
151
+ throw new MongooseError(msg);
152
+ };
153
+ }
154
+
155
+ /**
156
+ * Registers a transform function which subsequently maps documents retrieved
157
+ * via the streams interface or `.next()`
158
+ *
159
+ * #### Example:
160
+ *
161
+ * // Map documents returned by `data` events
162
+ * Thing.
163
+ * find({ name: /^hello/ }).
164
+ * cursor().
165
+ * map(function (doc) {
166
+ * doc.foo = "bar";
167
+ * return doc;
168
+ * })
169
+ * on('data', function(doc) { console.log(doc.foo); });
170
+ *
171
+ * // Or map documents returned by `.next()`
172
+ * const cursor = Thing.find({ name: /^hello/ }).
173
+ * cursor().
174
+ * map(function (doc) {
175
+ * doc.foo = "bar";
176
+ * return doc;
177
+ * });
178
+ * cursor.next(function(error, doc) {
179
+ * console.log(doc.foo);
180
+ * });
181
+ *
182
+ * @param {Function} fn
183
+ * @return {AggregationCursor}
184
+ * @memberOf AggregationCursor
185
+ * @api public
186
+ * @method map
187
+ */
188
+
189
+ Object.defineProperty(AggregationCursor.prototype, 'map', {
190
+ value: function(fn) {
191
+ this._transforms.push(fn);
192
+ return this;
193
+ },
194
+ enumerable: true,
195
+ configurable: true,
196
+ writable: true
197
+ });
198
+
199
+ /**
200
+ * Marks this cursor as errored
201
+ * @method _markError
202
+ * @instance
203
+ * @memberOf AggregationCursor
204
+ * @api private
205
+ */
206
+
207
+ AggregationCursor.prototype._markError = function(error) {
208
+ this._error = error;
209
+ return this;
210
+ };
211
+
212
+ /**
213
+ * Marks this cursor as closed. Will stop streaming and subsequent calls to
214
+ * `next()` will error.
215
+ *
216
+ * @return {Promise}
217
+ * @api public
218
+ * @method close
219
+ * @emits "close"
220
+ * @see AggregationCursor.close https://mongodb.github.io/node-mongodb-native/4.9/classes/AggregationCursor.html#close
221
+ */
222
+
223
+ AggregationCursor.prototype.close = async function close() {
224
+ if (typeof arguments[0] === 'function') {
225
+ throw new MongooseError('AggregationCursor.prototype.close() no longer accepts a callback');
226
+ }
227
+ try {
228
+ await this.cursor.close();
229
+ } catch (error) {
230
+ this.listeners('error').length > 0 && this.emit('error', error);
231
+ throw error;
232
+ }
233
+ this.emit('close');
234
+ };
235
+
236
+ /**
237
+ * Marks this cursor as destroyed. Will stop streaming and subsequent calls to
238
+ * `next()` will error.
239
+ *
240
+ * @return {this}
241
+ * @api private
242
+ * @method _destroy
243
+ */
244
+
245
+ AggregationCursor.prototype._destroy = function _destroy(_err, callback) {
246
+ let waitForCursor = null;
247
+ if (!this.cursor) {
248
+ waitForCursor = new Promise((resolve) => {
249
+ this.once('cursor', resolve);
250
+ });
251
+ } else {
252
+ waitForCursor = Promise.resolve();
253
+ }
254
+
255
+ waitForCursor
256
+ .then(() => this.cursor.close())
257
+ .then(() => {
258
+ this._closed = true;
259
+ callback();
260
+ })
261
+ .catch(error => {
262
+ callback(error);
263
+ });
264
+ return this;
265
+ };
266
+
267
+ /**
268
+ * Get the next document from this cursor. Will return `null` when there are
269
+ * no documents left.
270
+ *
271
+ * @return {Promise}
272
+ * @api public
273
+ * @method next
274
+ */
275
+
276
+ AggregationCursor.prototype.next = async function next() {
277
+ if (typeof arguments[0] === 'function') {
278
+ throw new MongooseError('AggregationCursor.prototype.next() no longer accepts a callback');
279
+ }
280
+ return new Promise((resolve, reject) => {
281
+ _next(this, (err, res) => {
282
+ if (err != null) {
283
+ return reject(err);
284
+ }
285
+ resolve(res);
286
+ });
287
+ });
288
+ };
289
+
290
+ /**
291
+ * Execute `fn` for every document in the cursor. If `fn` returns a promise,
292
+ * will wait for the promise to resolve before iterating on to the next one.
293
+ * Returns a promise that resolves when done.
294
+ *
295
+ * @param {Function} fn
296
+ * @param {Object} [options]
297
+ * @param {Number} [options.parallel] the number of promises to execute in parallel. Defaults to 1.
298
+ * @param {Number} [options.batchSize=null] if set, Mongoose will call `fn` with an array of at most `batchSize` documents, instead of a single document
299
+ * @param {Boolean} [options.continueOnError=false] if true, `eachAsync()` iterates through all docs even if `fn` throws an error. If false, `eachAsync()` throws an error immediately if the given function `fn()` throws an error.
300
+ * @return {Promise}
301
+ * @api public
302
+ * @method eachAsync
303
+ */
304
+
305
+ AggregationCursor.prototype.eachAsync = function(fn, opts) {
306
+ if (typeof arguments[2] === 'function') {
307
+ throw new MongooseError('AggregationCursor.prototype.eachAsync() no longer accepts a callback');
308
+ }
309
+ const _this = this;
310
+ if (typeof opts === 'function') {
311
+ opts = {};
312
+ }
313
+ opts = opts || {};
314
+
315
+ return eachAsync(function(cb) { return _next(_this, cb); }, fn, opts);
316
+ };
317
+
318
+ /**
319
+ * Returns an asyncIterator for use with [`for/await/of` loops](https://thecodebarbarian.com/getting-started-with-async-iterators-in-node-js)
320
+ * You do not need to call this function explicitly, the JavaScript runtime
321
+ * will call it for you.
322
+ *
323
+ * #### Example:
324
+ *
325
+ * // Async iterator without explicitly calling `cursor()`. Mongoose still
326
+ * // creates an AggregationCursor instance internally.
327
+ * const agg = Model.aggregate([{ $match: { age: { $gte: 25 } } }]);
328
+ * for await (const doc of agg) {
329
+ * console.log(doc.name);
330
+ * }
331
+ *
332
+ * // You can also use an AggregationCursor instance for async iteration
333
+ * const cursor = Model.aggregate([{ $match: { age: { $gte: 25 } } }]).cursor();
334
+ * for await (const doc of cursor) {
335
+ * console.log(doc.name);
336
+ * }
337
+ *
338
+ * Node.js 10.x supports async iterators natively without any flags. You can
339
+ * enable async iterators in Node.js 8.x using the [`--harmony_async_iteration` flag](https://github.com/tc39/proposal-async-iteration/issues/117#issuecomment-346695187).
340
+ *
341
+ * **Note:** This function is not set if `Symbol.asyncIterator` is undefined. If
342
+ * `Symbol.asyncIterator` is undefined, that means your Node.js version does not
343
+ * support async iterators.
344
+ *
345
+ * @method [Symbol.asyncIterator]
346
+ * @memberOf AggregationCursor
347
+ * @instance
348
+ * @api public
349
+ */
350
+
351
+ if (Symbol.asyncIterator != null) {
352
+ AggregationCursor.prototype[Symbol.asyncIterator] = function() {
353
+ return this.transformNull()._transformForAsyncIterator();
354
+ };
355
+ }
356
+
357
+ /*!
358
+ * ignore
359
+ */
360
+
361
+ AggregationCursor.prototype._transformForAsyncIterator = function() {
362
+ if (this._transforms.indexOf(_transformForAsyncIterator) === -1) {
363
+ this.map(_transformForAsyncIterator);
364
+ }
365
+ return this;
366
+ };
367
+
368
+ /*!
369
+ * ignore
370
+ */
371
+
372
+ AggregationCursor.prototype.transformNull = function(val) {
373
+ if (arguments.length === 0) {
374
+ val = true;
375
+ }
376
+ this._mongooseOptions.transformNull = val;
377
+ return this;
378
+ };
379
+
380
+ /*!
381
+ * ignore
382
+ */
383
+
384
+ function _transformForAsyncIterator(doc) {
385
+ return doc == null ? { done: true } : { value: doc, done: false };
386
+ }
387
+
388
+ /**
389
+ * Adds a [cursor flag](https://mongodb.github.io/node-mongodb-native/4.9/classes/AggregationCursor.html#addCursorFlag).
390
+ * Useful for setting the `noCursorTimeout` and `tailable` flags.
391
+ *
392
+ * @param {String} flag
393
+ * @param {Boolean} value
394
+ * @return {AggregationCursor} this
395
+ * @api public
396
+ * @method addCursorFlag
397
+ */
398
+
399
+ AggregationCursor.prototype.addCursorFlag = function(flag, value) {
400
+ const _this = this;
401
+ _waitForCursor(this, function() {
402
+ _this.cursor.addCursorFlag(flag, value);
403
+ });
404
+ return this;
405
+ };
406
+
407
+ /*!
408
+ * ignore
409
+ */
410
+
411
+ function _waitForCursor(ctx, cb) {
412
+ if (ctx.cursor) {
413
+ return cb();
414
+ }
415
+ ctx.once('cursor', function() {
416
+ cb();
417
+ });
418
+ }
419
+
420
+ /**
421
+ * Get the next doc from the underlying cursor and mongooseify it
422
+ * (populate, etc.)
423
+ * @param {Any} ctx
424
+ * @param {Function} cb
425
+ * @api private
426
+ */
427
+
428
+ function _next(ctx, cb) {
429
+ let callback = cb;
430
+ if (ctx._transforms.length) {
431
+ callback = function(err, doc) {
432
+ if (err || (doc === null && !ctx._mongooseOptions.transformNull)) {
433
+ return cb(err, doc);
434
+ }
435
+ cb(err, ctx._transforms.reduce(function(doc, fn) {
436
+ return fn(doc);
437
+ }, doc));
438
+ };
439
+ }
440
+
441
+ if (ctx._error) {
442
+ return immediate(function() {
443
+ callback(ctx._error);
444
+ });
445
+ }
446
+
447
+ if (ctx.cursor) {
448
+ return ctx.cursor.next().then(
449
+ doc => {
450
+ if (!doc) {
451
+ return callback(null, null);
452
+ }
453
+
454
+ callback(null, doc);
455
+ },
456
+ err => callback(err)
457
+ );
458
+ } else {
459
+ ctx.once('error', cb);
460
+ ctx.once('cursor', function() {
461
+ _next(ctx, cb);
462
+ });
463
+ }
464
+ }
465
+
466
+ module.exports = AggregationCursor;