@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.
- package/LICENSE.md +22 -0
- package/README.md +397 -0
- package/SECURITY.md +1 -0
- package/eslint.config.mjs +198 -0
- package/index.js +64 -0
- package/lib/aggregate.js +1189 -0
- package/lib/cast/bigint.js +46 -0
- package/lib/cast/boolean.js +32 -0
- package/lib/cast/date.js +41 -0
- package/lib/cast/decimal128.js +39 -0
- package/lib/cast/double.js +50 -0
- package/lib/cast/int32.js +36 -0
- package/lib/cast/number.js +42 -0
- package/lib/cast/objectid.js +29 -0
- package/lib/cast/string.js +37 -0
- package/lib/cast/uuid.js +35 -0
- package/lib/cast.js +436 -0
- package/lib/collection.js +321 -0
- package/lib/connection.js +1855 -0
- package/lib/connectionState.js +26 -0
- package/lib/constants.js +73 -0
- package/lib/cursor/aggregationCursor.js +466 -0
- package/lib/cursor/changeStream.js +198 -0
- package/lib/cursor/queryCursor.js +622 -0
- package/lib/document.js +5521 -0
- package/lib/driver.js +15 -0
- package/lib/drivers/SPEC.md +4 -0
- package/lib/drivers/node-mongodb-native/bulkWriteResult.js +5 -0
- package/lib/drivers/node-mongodb-native/collection.js +393 -0
- package/lib/drivers/node-mongodb-native/connection.js +506 -0
- package/lib/drivers/node-mongodb-native/index.js +10 -0
- package/lib/error/browserMissingSchema.js +29 -0
- package/lib/error/bulkSaveIncompleteError.js +44 -0
- package/lib/error/bulkWriteError.js +41 -0
- package/lib/error/cast.js +158 -0
- package/lib/error/createCollectionsError.js +26 -0
- package/lib/error/divergentArray.js +40 -0
- package/lib/error/eachAsyncMultiError.js +41 -0
- package/lib/error/index.js +237 -0
- package/lib/error/invalidSchemaOption.js +32 -0
- package/lib/error/messages.js +47 -0
- package/lib/error/missingSchema.js +33 -0
- package/lib/error/mongooseError.js +13 -0
- package/lib/error/notFound.js +47 -0
- package/lib/error/objectExpected.js +31 -0
- package/lib/error/objectParameter.js +31 -0
- package/lib/error/overwriteModel.js +31 -0
- package/lib/error/parallelSave.js +33 -0
- package/lib/error/parallelValidate.js +33 -0
- package/lib/error/serverSelection.js +62 -0
- package/lib/error/setOptionError.js +103 -0
- package/lib/error/strict.js +35 -0
- package/lib/error/strictPopulate.js +31 -0
- package/lib/error/syncIndexes.js +30 -0
- package/lib/error/validation.js +97 -0
- package/lib/error/validator.js +100 -0
- package/lib/error/version.js +38 -0
- package/lib/helpers/aggregate/prepareDiscriminatorPipeline.js +39 -0
- package/lib/helpers/aggregate/stringifyFunctionOperators.js +50 -0
- package/lib/helpers/arrayDepth.js +33 -0
- package/lib/helpers/clone.js +204 -0
- package/lib/helpers/common.js +127 -0
- package/lib/helpers/createJSONSchemaTypeDefinition.js +24 -0
- package/lib/helpers/cursor/eachAsync.js +225 -0
- package/lib/helpers/discriminator/applyEmbeddedDiscriminators.js +36 -0
- package/lib/helpers/discriminator/areDiscriminatorValuesEqual.js +16 -0
- package/lib/helpers/discriminator/checkEmbeddedDiscriminatorKeyProjection.js +12 -0
- package/lib/helpers/discriminator/getConstructor.js +29 -0
- package/lib/helpers/discriminator/getDiscriminatorByValue.js +28 -0
- package/lib/helpers/discriminator/getSchemaDiscriminatorByValue.js +27 -0
- package/lib/helpers/discriminator/mergeDiscriminatorSchema.js +91 -0
- package/lib/helpers/document/applyDefaults.js +132 -0
- package/lib/helpers/document/applyTimestamps.js +106 -0
- package/lib/helpers/document/applyVirtuals.js +147 -0
- package/lib/helpers/document/cleanModifiedSubpaths.js +45 -0
- package/lib/helpers/document/compile.js +238 -0
- package/lib/helpers/document/getDeepestSubdocumentForPath.js +38 -0
- package/lib/helpers/document/getEmbeddedDiscriminatorPath.js +53 -0
- package/lib/helpers/document/handleSpreadDoc.js +35 -0
- package/lib/helpers/each.js +25 -0
- package/lib/helpers/error/combinePathErrors.js +22 -0
- package/lib/helpers/firstKey.js +8 -0
- package/lib/helpers/get.js +65 -0
- package/lib/helpers/getConstructorName.js +16 -0
- package/lib/helpers/getDefaultBulkwriteResult.js +18 -0
- package/lib/helpers/getFunctionName.js +10 -0
- package/lib/helpers/immediate.js +16 -0
- package/lib/helpers/indexes/applySchemaCollation.js +13 -0
- package/lib/helpers/indexes/decorateDiscriminatorIndexOptions.js +14 -0
- package/lib/helpers/indexes/getRelatedIndexes.js +63 -0
- package/lib/helpers/indexes/isDefaultIdIndex.js +18 -0
- package/lib/helpers/indexes/isIndexEqual.js +95 -0
- package/lib/helpers/indexes/isIndexSpecEqual.js +32 -0
- package/lib/helpers/indexes/isTextIndex.js +16 -0
- package/lib/helpers/indexes/isTimeseriesIndex.js +16 -0
- package/lib/helpers/isAsyncFunction.js +9 -0
- package/lib/helpers/isBsonType.js +15 -0
- package/lib/helpers/isMongooseObject.js +22 -0
- package/lib/helpers/isObject.js +16 -0
- package/lib/helpers/isPOJO.js +12 -0
- package/lib/helpers/isPromise.js +6 -0
- package/lib/helpers/isSimpleValidator.js +22 -0
- package/lib/helpers/minimize.js +41 -0
- package/lib/helpers/model/applyDefaultsToPOJO.js +52 -0
- package/lib/helpers/model/applyHooks.js +140 -0
- package/lib/helpers/model/applyMethods.js +70 -0
- package/lib/helpers/model/applyStaticHooks.js +33 -0
- package/lib/helpers/model/applyStatics.js +13 -0
- package/lib/helpers/model/castBulkWrite.js +316 -0
- package/lib/helpers/model/decorateBulkWriteResult.js +8 -0
- package/lib/helpers/model/discriminator.js +265 -0
- package/lib/helpers/model/pushNestedArrayPaths.js +15 -0
- package/lib/helpers/omitUndefined.js +20 -0
- package/lib/helpers/once.js +12 -0
- package/lib/helpers/parallelLimit.js +37 -0
- package/lib/helpers/path/parentPaths.js +18 -0
- package/lib/helpers/path/setDottedPath.js +33 -0
- package/lib/helpers/pluralize.js +95 -0
- package/lib/helpers/populate/assignRawDocsToIdStructure.js +129 -0
- package/lib/helpers/populate/assignVals.js +360 -0
- package/lib/helpers/populate/createPopulateQueryFilter.js +97 -0
- package/lib/helpers/populate/getModelsMapForPopulate.js +776 -0
- package/lib/helpers/populate/getSchemaTypes.js +228 -0
- package/lib/helpers/populate/getVirtual.js +103 -0
- package/lib/helpers/populate/leanPopulateMap.js +7 -0
- package/lib/helpers/populate/lookupLocalFields.js +40 -0
- package/lib/helpers/populate/markArraySubdocsPopulated.js +49 -0
- package/lib/helpers/populate/modelNamesFromRefPath.js +66 -0
- package/lib/helpers/populate/removeDeselectedForeignField.js +31 -0
- package/lib/helpers/populate/setPopulatedVirtualValue.js +33 -0
- package/lib/helpers/populate/skipPopulateValue.js +10 -0
- package/lib/helpers/populate/validateRef.js +19 -0
- package/lib/helpers/printJestWarning.js +21 -0
- package/lib/helpers/processConnectionOptions.js +65 -0
- package/lib/helpers/projection/applyProjection.js +83 -0
- package/lib/helpers/projection/hasIncludedChildren.js +41 -0
- package/lib/helpers/projection/isDefiningProjection.js +18 -0
- package/lib/helpers/projection/isExclusive.js +37 -0
- package/lib/helpers/projection/isInclusive.js +39 -0
- package/lib/helpers/projection/isNestedProjection.js +8 -0
- package/lib/helpers/projection/isPathExcluded.js +40 -0
- package/lib/helpers/projection/isPathSelectedInclusive.js +28 -0
- package/lib/helpers/projection/isSubpath.js +14 -0
- package/lib/helpers/projection/parseProjection.js +33 -0
- package/lib/helpers/query/applyGlobalOption.js +29 -0
- package/lib/helpers/query/cast$expr.js +287 -0
- package/lib/helpers/query/castFilterPath.js +54 -0
- package/lib/helpers/query/castUpdate.js +643 -0
- package/lib/helpers/query/getEmbeddedDiscriminatorPath.js +103 -0
- package/lib/helpers/query/handleImmutable.js +44 -0
- package/lib/helpers/query/handleReadPreferenceAliases.js +23 -0
- package/lib/helpers/query/hasDollarKeys.js +23 -0
- package/lib/helpers/query/isOperator.js +14 -0
- package/lib/helpers/query/sanitizeFilter.js +38 -0
- package/lib/helpers/query/sanitizeProjection.js +14 -0
- package/lib/helpers/query/selectPopulatedFields.js +62 -0
- package/lib/helpers/query/trusted.js +13 -0
- package/lib/helpers/query/validOps.js +3 -0
- package/lib/helpers/schema/addAutoId.js +7 -0
- package/lib/helpers/schema/applyBuiltinPlugins.js +12 -0
- package/lib/helpers/schema/applyPlugins.js +55 -0
- package/lib/helpers/schema/applyReadConcern.js +20 -0
- package/lib/helpers/schema/applyWriteConcern.js +39 -0
- package/lib/helpers/schema/cleanPositionalOperators.js +12 -0
- package/lib/helpers/schema/getIndexes.js +171 -0
- package/lib/helpers/schema/getKeysInSchemaOrder.js +28 -0
- package/lib/helpers/schema/getPath.js +43 -0
- package/lib/helpers/schema/getSubdocumentStrictValue.js +32 -0
- package/lib/helpers/schema/handleIdOption.js +20 -0
- package/lib/helpers/schema/handleTimestampOption.js +24 -0
- package/lib/helpers/schema/idGetter.js +34 -0
- package/lib/helpers/schema/merge.js +36 -0
- package/lib/helpers/schematype/handleImmutable.js +50 -0
- package/lib/helpers/setDefaultsOnInsert.js +158 -0
- package/lib/helpers/specialProperties.js +3 -0
- package/lib/helpers/symbols.js +20 -0
- package/lib/helpers/timers.js +3 -0
- package/lib/helpers/timestamps/setDocumentTimestamps.js +26 -0
- package/lib/helpers/timestamps/setupTimestamps.js +116 -0
- package/lib/helpers/topology/allServersUnknown.js +12 -0
- package/lib/helpers/topology/isAtlas.js +31 -0
- package/lib/helpers/topology/isSSLError.js +16 -0
- package/lib/helpers/update/applyTimestampsToChildren.js +193 -0
- package/lib/helpers/update/applyTimestampsToUpdate.js +131 -0
- package/lib/helpers/update/castArrayFilters.js +113 -0
- package/lib/helpers/update/decorateUpdateWithVersionKey.js +35 -0
- package/lib/helpers/update/modifiedPaths.js +33 -0
- package/lib/helpers/update/moveImmutableProperties.js +53 -0
- package/lib/helpers/update/removeUnusedArrayFilters.js +32 -0
- package/lib/helpers/update/updatedPathsByArrayFilter.js +27 -0
- package/lib/helpers/updateValidators.js +193 -0
- package/lib/index.js +17 -0
- package/lib/internal.js +46 -0
- package/lib/model.js +5010 -0
- package/lib/modifiedPathsSnapshot.js +9 -0
- package/lib/mongoose.js +1411 -0
- package/lib/options/populateOptions.js +36 -0
- package/lib/options/propertyOptions.js +8 -0
- package/lib/options/saveOptions.js +16 -0
- package/lib/options/schemaArrayOptions.js +78 -0
- package/lib/options/schemaBufferOptions.js +38 -0
- package/lib/options/schemaDateOptions.js +71 -0
- package/lib/options/schemaDocumentArrayOptions.js +68 -0
- package/lib/options/schemaMapOptions.js +43 -0
- package/lib/options/schemaNumberOptions.js +101 -0
- package/lib/options/schemaObjectIdOptions.js +64 -0
- package/lib/options/schemaStringOptions.js +138 -0
- package/lib/options/schemaSubdocumentOptions.js +66 -0
- package/lib/options/schemaTypeOptions.js +244 -0
- package/lib/options/schemaUnionOptions.js +32 -0
- package/lib/options/virtualOptions.js +164 -0
- package/lib/options.js +17 -0
- package/lib/plugins/index.js +6 -0
- package/lib/plugins/saveSubdocs.js +76 -0
- package/lib/plugins/sharding.js +84 -0
- package/lib/plugins/trackTransaction.js +84 -0
- package/lib/plugins/validateBeforeSave.js +41 -0
- package/lib/query.js +5673 -0
- package/lib/queryHelpers.js +387 -0
- package/lib/schema/array.js +699 -0
- package/lib/schema/bigint.js +282 -0
- package/lib/schema/boolean.js +332 -0
- package/lib/schema/buffer.js +343 -0
- package/lib/schema/date.js +467 -0
- package/lib/schema/decimal128.js +263 -0
- package/lib/schema/documentArray.js +656 -0
- package/lib/schema/documentArrayElement.js +137 -0
- package/lib/schema/double.js +246 -0
- package/lib/schema/index.js +32 -0
- package/lib/schema/int32.js +289 -0
- package/lib/schema/map.js +201 -0
- package/lib/schema/mixed.js +146 -0
- package/lib/schema/number.js +510 -0
- package/lib/schema/objectId.js +333 -0
- package/lib/schema/operators/bitwise.js +38 -0
- package/lib/schema/operators/exists.js +12 -0
- package/lib/schema/operators/geospatial.js +107 -0
- package/lib/schema/operators/helpers.js +32 -0
- package/lib/schema/operators/text.js +39 -0
- package/lib/schema/operators/type.js +20 -0
- package/lib/schema/string.js +733 -0
- package/lib/schema/subdocument.js +436 -0
- package/lib/schema/symbols.js +5 -0
- package/lib/schema/union.js +113 -0
- package/lib/schema/uuid.js +305 -0
- package/lib/schema.js +3226 -0
- package/lib/schemaType.js +1835 -0
- package/lib/stateMachine.js +232 -0
- package/lib/types/array/index.js +119 -0
- package/lib/types/array/isMongooseArray.js +5 -0
- package/lib/types/array/methods/index.js +1095 -0
- package/lib/types/arraySubdocument.js +207 -0
- package/lib/types/buffer.js +294 -0
- package/lib/types/decimal128.js +13 -0
- package/lib/types/documentArray/index.js +113 -0
- package/lib/types/documentArray/isMongooseDocumentArray.js +5 -0
- package/lib/types/documentArray/methods/index.js +415 -0
- package/lib/types/double.js +13 -0
- package/lib/types/index.js +23 -0
- package/lib/types/map.js +419 -0
- package/lib/types/objectid.js +41 -0
- package/lib/types/subdocument.js +464 -0
- package/lib/types/uuid.js +13 -0
- package/lib/utils.js +1054 -0
- package/lib/validOptions.js +42 -0
- package/lib/virtualType.js +204 -0
- package/package.json +148 -0
- package/types/aggregate.d.ts +180 -0
- package/types/augmentations.d.ts +9 -0
- package/types/callback.d.ts +8 -0
- package/types/collection.d.ts +49 -0
- package/types/connection.d.ts +297 -0
- package/types/cursor.d.ts +67 -0
- package/types/document.d.ts +374 -0
- package/types/error.d.ts +143 -0
- package/types/expressions.d.ts +3053 -0
- package/types/helpers.d.ts +32 -0
- package/types/index.d.ts +1056 -0
- package/types/indexes.d.ts +97 -0
- package/types/inferhydrateddoctype.d.ts +115 -0
- package/types/inferrawdoctype.d.ts +135 -0
- package/types/inferschematype.d.ts +337 -0
- package/types/middlewares.d.ts +59 -0
- package/types/models.d.ts +1306 -0
- package/types/mongooseoptions.d.ts +228 -0
- package/types/pipelinestage.d.ts +333 -0
- package/types/populate.d.ts +53 -0
- package/types/query.d.ts +934 -0
- package/types/schemaoptions.d.ts +282 -0
- package/types/schematypes.d.ts +654 -0
- package/types/session.d.ts +32 -0
- package/types/types.d.ts +109 -0
- package/types/utility.d.ts +175 -0
- package/types/validation.d.ts +39 -0
- 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;
|
package/lib/constants.js
ADDED
|
@@ -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;
|