@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
package/lib/utils.js
ADDED
|
@@ -0,0 +1,1054 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/*!
|
|
4
|
+
* Module dependencies.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const UUID = require('mongodb/lib/bson').UUID;
|
|
8
|
+
const ms = require('ms');
|
|
9
|
+
const mpath = require('mpath');
|
|
10
|
+
const ObjectId = require('./types/objectid');
|
|
11
|
+
const PopulateOptions = require('./options/populateOptions');
|
|
12
|
+
const clone = require('./helpers/clone');
|
|
13
|
+
const immediate = require('./helpers/immediate');
|
|
14
|
+
const isObject = require('./helpers/isObject');
|
|
15
|
+
const isMongooseArray = require('./types/array/isMongooseArray');
|
|
16
|
+
const isMongooseDocumentArray = require('./types/documentArray/isMongooseDocumentArray');
|
|
17
|
+
const isBsonType = require('./helpers/isBsonType');
|
|
18
|
+
const isPOJO = require('./helpers/isPOJO');
|
|
19
|
+
const getFunctionName = require('./helpers/getFunctionName');
|
|
20
|
+
const isMongooseObject = require('./helpers/isMongooseObject');
|
|
21
|
+
const schemaMerge = require('./helpers/schema/merge');
|
|
22
|
+
const specialProperties = require('./helpers/specialProperties');
|
|
23
|
+
const { trustedSymbol } = require('./helpers/query/trusted');
|
|
24
|
+
|
|
25
|
+
let Document;
|
|
26
|
+
|
|
27
|
+
exports.specialProperties = specialProperties;
|
|
28
|
+
|
|
29
|
+
exports.isMongooseArray = isMongooseArray.isMongooseArray;
|
|
30
|
+
exports.isMongooseDocumentArray = isMongooseDocumentArray.isMongooseDocumentArray;
|
|
31
|
+
exports.registerMongooseArray = isMongooseArray.registerMongooseArray;
|
|
32
|
+
exports.registerMongooseDocumentArray = isMongooseDocumentArray.registerMongooseDocumentArray;
|
|
33
|
+
|
|
34
|
+
const oneSpaceRE = /\s/;
|
|
35
|
+
const manySpaceRE = /\s+/;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Produces a collection name from model `name`. By default, just returns
|
|
39
|
+
* the model name
|
|
40
|
+
*
|
|
41
|
+
* @param {String} name a model name
|
|
42
|
+
* @param {Function} pluralize function that pluralizes the collection name
|
|
43
|
+
* @return {String} a collection name
|
|
44
|
+
* @api private
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
exports.toCollectionName = function(name, pluralize) {
|
|
48
|
+
if (name === 'system.profile') {
|
|
49
|
+
return name;
|
|
50
|
+
}
|
|
51
|
+
if (name === 'system.indexes') {
|
|
52
|
+
return name;
|
|
53
|
+
}
|
|
54
|
+
if (typeof pluralize === 'function') {
|
|
55
|
+
if (typeof name !== 'string') {
|
|
56
|
+
throw new TypeError('Collection name must be a string');
|
|
57
|
+
}
|
|
58
|
+
if (name.length === 0) {
|
|
59
|
+
throw new TypeError('Collection name cannot be empty');
|
|
60
|
+
}
|
|
61
|
+
return pluralize(name);
|
|
62
|
+
}
|
|
63
|
+
return name;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Determines if `a` and `b` are deep equal.
|
|
68
|
+
*
|
|
69
|
+
* Modified from node/lib/assert.js
|
|
70
|
+
*
|
|
71
|
+
* @param {any} a a value to compare to `b`
|
|
72
|
+
* @param {any} b a value to compare to `a`
|
|
73
|
+
* @return {Boolean}
|
|
74
|
+
* @api private
|
|
75
|
+
*/
|
|
76
|
+
|
|
77
|
+
exports.deepEqual = function deepEqual(a, b) {
|
|
78
|
+
if (a === b) {
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (typeof a !== 'object' || typeof b !== 'object') {
|
|
83
|
+
return a === b;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (a instanceof Date && b instanceof Date) {
|
|
87
|
+
return a.getTime() === b.getTime();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if ((isBsonType(a, 'ObjectId') && isBsonType(b, 'ObjectId')) ||
|
|
91
|
+
(isBsonType(a, 'Decimal128') && isBsonType(b, 'Decimal128'))) {
|
|
92
|
+
return a.toString() === b.toString();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (a instanceof RegExp && b instanceof RegExp) {
|
|
96
|
+
return a.source === b.source &&
|
|
97
|
+
a.ignoreCase === b.ignoreCase &&
|
|
98
|
+
a.multiline === b.multiline &&
|
|
99
|
+
a.global === b.global &&
|
|
100
|
+
a.dotAll === b.dotAll &&
|
|
101
|
+
a.unicode === b.unicode &&
|
|
102
|
+
a.sticky === b.sticky &&
|
|
103
|
+
a.hasIndices === b.hasIndices;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (a == null || b == null) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (a.prototype !== b.prototype) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (a instanceof Map || b instanceof Map) {
|
|
115
|
+
if (!(a instanceof Map) || !(b instanceof Map)) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
return deepEqual(Array.from(a.keys()), Array.from(b.keys())) &&
|
|
119
|
+
deepEqual(Array.from(a.values()), Array.from(b.values()));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Handle MongooseNumbers
|
|
123
|
+
if (a instanceof Number && b instanceof Number) {
|
|
124
|
+
return a.valueOf() === b.valueOf();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (Buffer.isBuffer(a)) {
|
|
128
|
+
return exports.buffer.areEqual(a, b);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (Array.isArray(a) || Array.isArray(b)) {
|
|
132
|
+
if (!Array.isArray(a) || !Array.isArray(b)) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
const len = a.length;
|
|
136
|
+
if (len !== b.length) {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
for (let i = 0; i < len; ++i) {
|
|
140
|
+
if (!deepEqual(a[i], b[i])) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (a.$__ != null) {
|
|
148
|
+
a = a._doc;
|
|
149
|
+
} else if (isMongooseObject(a)) {
|
|
150
|
+
a = a.toObject();
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (b.$__ != null) {
|
|
154
|
+
b = b._doc;
|
|
155
|
+
} else if (isMongooseObject(b)) {
|
|
156
|
+
b = b.toObject();
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const ka = Object.keys(a);
|
|
160
|
+
const kb = Object.keys(b);
|
|
161
|
+
const kaLength = ka.length;
|
|
162
|
+
|
|
163
|
+
// having the same number of owned properties (keys incorporates
|
|
164
|
+
// hasOwnProperty)
|
|
165
|
+
if (kaLength !== kb.length) {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// ~~~cheap key test
|
|
170
|
+
for (let i = kaLength - 1; i >= 0; i--) {
|
|
171
|
+
if (ka[i] !== kb[i]) {
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// equivalent values for every corresponding key, and
|
|
177
|
+
// ~~~possibly expensive deep test
|
|
178
|
+
for (const key of ka) {
|
|
179
|
+
if (!deepEqual(a[key], b[key])) {
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return true;
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Get the last element of an array
|
|
189
|
+
* @param {Array} arr
|
|
190
|
+
*/
|
|
191
|
+
|
|
192
|
+
exports.last = function(arr) {
|
|
193
|
+
if (arr == null) {
|
|
194
|
+
return void 0;
|
|
195
|
+
}
|
|
196
|
+
if (arr.length > 0) {
|
|
197
|
+
return arr[arr.length - 1];
|
|
198
|
+
}
|
|
199
|
+
return void 0;
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
/*!
|
|
203
|
+
* ignore
|
|
204
|
+
*/
|
|
205
|
+
|
|
206
|
+
exports.cloneArrays = function cloneArrays(arr) {
|
|
207
|
+
if (!Array.isArray(arr)) {
|
|
208
|
+
return arr;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return arr.map(el => exports.cloneArrays(el));
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
/*!
|
|
215
|
+
* ignore
|
|
216
|
+
*/
|
|
217
|
+
|
|
218
|
+
exports.omit = function omit(obj, keys) {
|
|
219
|
+
if (keys == null) {
|
|
220
|
+
return Object.assign({}, obj);
|
|
221
|
+
}
|
|
222
|
+
if (!Array.isArray(keys)) {
|
|
223
|
+
keys = [keys];
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const ret = Object.assign({}, obj);
|
|
227
|
+
for (const key of keys) {
|
|
228
|
+
delete ret[key];
|
|
229
|
+
}
|
|
230
|
+
return ret;
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Simplified version of `clone()` that only clones POJOs and arrays. Skips documents, dates, objectids, etc.
|
|
235
|
+
* @param {*} val
|
|
236
|
+
* @returns
|
|
237
|
+
*/
|
|
238
|
+
|
|
239
|
+
exports.clonePOJOsAndArrays = function clonePOJOsAndArrays(val) {
|
|
240
|
+
if (val == null) {
|
|
241
|
+
return val;
|
|
242
|
+
}
|
|
243
|
+
// Skip documents because we assume they'll be cloned later. See gh-15312 for how documents are handled with `merge()`.
|
|
244
|
+
if (val.$__ != null) {
|
|
245
|
+
return val;
|
|
246
|
+
}
|
|
247
|
+
if (isPOJO(val)) {
|
|
248
|
+
val = { ...val };
|
|
249
|
+
for (const key of Object.keys(val)) {
|
|
250
|
+
val[key] = exports.clonePOJOsAndArrays(val[key]);
|
|
251
|
+
}
|
|
252
|
+
return val;
|
|
253
|
+
}
|
|
254
|
+
if (Array.isArray(val)) {
|
|
255
|
+
val = [...val];
|
|
256
|
+
for (let i = 0; i < val.length; ++i) {
|
|
257
|
+
val[i] = exports.clonePOJOsAndArrays(val[i]);
|
|
258
|
+
}
|
|
259
|
+
return val;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return val;
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Merges `from` into `to` without overwriting existing properties.
|
|
267
|
+
*
|
|
268
|
+
* @param {Object} to
|
|
269
|
+
* @param {Object} from
|
|
270
|
+
* @param {Object} [options]
|
|
271
|
+
* @param {String} [path]
|
|
272
|
+
* @api private
|
|
273
|
+
*/
|
|
274
|
+
|
|
275
|
+
exports.merge = function merge(to, from, options, path) {
|
|
276
|
+
options = options || {};
|
|
277
|
+
|
|
278
|
+
if (from == null) {
|
|
279
|
+
return to;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const keys = Object.keys(from);
|
|
283
|
+
let i = 0;
|
|
284
|
+
const len = keys.length;
|
|
285
|
+
let key;
|
|
286
|
+
|
|
287
|
+
if (from[trustedSymbol]) {
|
|
288
|
+
to[trustedSymbol] = from[trustedSymbol];
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
path = path || '';
|
|
292
|
+
const omitNested = options.omitNested || {};
|
|
293
|
+
|
|
294
|
+
while (i < len) {
|
|
295
|
+
key = keys[i++];
|
|
296
|
+
if (options.omit && options.omit[key]) {
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
if (omitNested[path]) {
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
if (specialProperties.has(key)) {
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
if (to[key] == null) {
|
|
306
|
+
to[key] = exports.clonePOJOsAndArrays(from[key]);
|
|
307
|
+
} else if (exports.isObject(from[key])) {
|
|
308
|
+
if (!exports.isObject(to[key])) {
|
|
309
|
+
to[key] = {};
|
|
310
|
+
}
|
|
311
|
+
if (from[key] != null) {
|
|
312
|
+
// Skip merging schemas if we're creating a discriminator schema and
|
|
313
|
+
// base schema has a given path as a single nested but discriminator schema
|
|
314
|
+
// has the path as a document array, or vice versa (gh-9534)
|
|
315
|
+
if (options.isDiscriminatorSchemaMerge &&
|
|
316
|
+
(from[key].$isSingleNested && to[key].$isMongooseDocumentArray) ||
|
|
317
|
+
(from[key].$isMongooseDocumentArray && to[key].$isSingleNested)) {
|
|
318
|
+
continue;
|
|
319
|
+
} else if (from[key].instanceOfSchema) {
|
|
320
|
+
if (to[key].instanceOfSchema) {
|
|
321
|
+
schemaMerge(to[key], from[key].clone(), options.isDiscriminatorSchemaMerge);
|
|
322
|
+
} else {
|
|
323
|
+
to[key] = from[key].clone();
|
|
324
|
+
}
|
|
325
|
+
continue;
|
|
326
|
+
} else if (isBsonType(from[key], 'ObjectId')) {
|
|
327
|
+
to[key] = new ObjectId(from[key]);
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
merge(to[key], from[key], options, path ? path + '.' + key : key);
|
|
332
|
+
} else if (options.overwrite) {
|
|
333
|
+
to[key] = from[key];
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return to;
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Applies toObject recursively.
|
|
342
|
+
*
|
|
343
|
+
* @param {Document|Array|Object} obj
|
|
344
|
+
* @return {Object}
|
|
345
|
+
* @api private
|
|
346
|
+
*/
|
|
347
|
+
|
|
348
|
+
exports.toObject = function toObject(obj) {
|
|
349
|
+
Document || (Document = require('./document'));
|
|
350
|
+
let ret;
|
|
351
|
+
|
|
352
|
+
if (obj == null) {
|
|
353
|
+
return obj;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
if (obj instanceof Document) {
|
|
357
|
+
return obj.toObject();
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
if (Array.isArray(obj)) {
|
|
361
|
+
ret = [];
|
|
362
|
+
|
|
363
|
+
for (const doc of obj) {
|
|
364
|
+
ret.push(toObject(doc));
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
return ret;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
if (exports.isPOJO(obj)) {
|
|
371
|
+
ret = {};
|
|
372
|
+
|
|
373
|
+
if (obj[trustedSymbol]) {
|
|
374
|
+
ret[trustedSymbol] = obj[trustedSymbol];
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
for (const k of Object.keys(obj)) {
|
|
378
|
+
if (specialProperties.has(k)) {
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
ret[k] = toObject(obj[k]);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
return ret;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
return obj;
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
exports.isObject = isObject;
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Determines if `arg` is a plain old JavaScript object (POJO). Specifically,
|
|
394
|
+
* `arg` must be an object but not an instance of any special class, like String,
|
|
395
|
+
* ObjectId, etc.
|
|
396
|
+
*
|
|
397
|
+
* `Object.getPrototypeOf()` is part of ES5: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf
|
|
398
|
+
*
|
|
399
|
+
* @param {Object|Array|String|Function|RegExp|any} arg
|
|
400
|
+
* @api private
|
|
401
|
+
* @return {Boolean}
|
|
402
|
+
*/
|
|
403
|
+
|
|
404
|
+
exports.isPOJO = require('./helpers/isPOJO');
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Determines if `arg` is an object that isn't an instance of a built-in value
|
|
408
|
+
* class, like Array, Buffer, ObjectId, etc.
|
|
409
|
+
* @param {Any} val
|
|
410
|
+
*/
|
|
411
|
+
|
|
412
|
+
exports.isNonBuiltinObject = function isNonBuiltinObject(val) {
|
|
413
|
+
return typeof val === 'object' &&
|
|
414
|
+
!exports.isNativeObject(val) &&
|
|
415
|
+
!exports.isMongooseType(val) &&
|
|
416
|
+
!(val instanceof UUID) &&
|
|
417
|
+
val != null;
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Determines if `obj` is a built-in object like an array, date, boolean,
|
|
422
|
+
* etc.
|
|
423
|
+
* @param {Any} arg
|
|
424
|
+
*/
|
|
425
|
+
|
|
426
|
+
exports.isNativeObject = function(arg) {
|
|
427
|
+
return Array.isArray(arg) ||
|
|
428
|
+
arg instanceof Date ||
|
|
429
|
+
arg instanceof Boolean ||
|
|
430
|
+
arg instanceof Number ||
|
|
431
|
+
arg instanceof String;
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Determines if `val` is an object that has no own keys
|
|
436
|
+
* @param {Any} val
|
|
437
|
+
*/
|
|
438
|
+
|
|
439
|
+
exports.isEmptyObject = function isEmptyObject(val) {
|
|
440
|
+
if (val == null || typeof val !== 'object') {
|
|
441
|
+
return false;
|
|
442
|
+
}
|
|
443
|
+
return exports.hasOwnKeys(val) === false;
|
|
444
|
+
};
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Determines if `obj` has any own keys. Assumes obj is already an object.
|
|
448
|
+
* Faster than Object.keys(obj).length > 0.
|
|
449
|
+
* @param {Object} obj
|
|
450
|
+
*/
|
|
451
|
+
|
|
452
|
+
exports.hasOwnKeys = function hasOwnKeys(obj) {
|
|
453
|
+
for (const key in obj) {
|
|
454
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
455
|
+
return true;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
return false;
|
|
459
|
+
};
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Search if `obj` or any POJOs nested underneath `obj` has a property named
|
|
463
|
+
* `key`
|
|
464
|
+
* @param {Object} obj
|
|
465
|
+
* @param {String} key
|
|
466
|
+
*/
|
|
467
|
+
|
|
468
|
+
exports.hasKey = function hasKey(obj, key) {
|
|
469
|
+
const props = Object.keys(obj);
|
|
470
|
+
for (const prop of props) {
|
|
471
|
+
if (prop === key) {
|
|
472
|
+
return true;
|
|
473
|
+
}
|
|
474
|
+
if (exports.isPOJO(obj[prop]) && exports.hasKey(obj[prop], key)) {
|
|
475
|
+
return true;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
return false;
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* process.nextTick helper.
|
|
483
|
+
*
|
|
484
|
+
* Wraps `callback` in a try/catch + nextTick.
|
|
485
|
+
*
|
|
486
|
+
* node-mongodb-native has a habit of state corruption when an error is immediately thrown from within a collection callback.
|
|
487
|
+
*
|
|
488
|
+
* @param {Function} callback
|
|
489
|
+
* @api private
|
|
490
|
+
*/
|
|
491
|
+
|
|
492
|
+
exports.tick = function tick(callback) {
|
|
493
|
+
if (typeof callback !== 'function') {
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
return function() {
|
|
497
|
+
try {
|
|
498
|
+
callback.apply(this, arguments);
|
|
499
|
+
} catch (err) {
|
|
500
|
+
// only nextTick on err to get out of
|
|
501
|
+
// the event loop and avoid state corruption.
|
|
502
|
+
immediate(function() {
|
|
503
|
+
throw err;
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
};
|
|
507
|
+
};
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* Returns true if `v` is an object that can be serialized as a primitive in
|
|
511
|
+
* MongoDB
|
|
512
|
+
* @param {Any} v
|
|
513
|
+
*/
|
|
514
|
+
|
|
515
|
+
exports.isMongooseType = function(v) {
|
|
516
|
+
return isBsonType(v, 'ObjectId') || isBsonType(v, 'Decimal128') || v instanceof Buffer;
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
exports.isMongooseObject = isMongooseObject;
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* Converts `expires` options of index objects to `expiresAfterSeconds` options for MongoDB.
|
|
523
|
+
*
|
|
524
|
+
* @param {Object} object
|
|
525
|
+
* @api private
|
|
526
|
+
*/
|
|
527
|
+
|
|
528
|
+
exports.expires = function expires(object) {
|
|
529
|
+
if (!(object && object.constructor.name === 'Object')) {
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
if (!('expires' in object)) {
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
object.expireAfterSeconds = (typeof object.expires !== 'string')
|
|
537
|
+
? object.expires
|
|
538
|
+
: Math.round(ms(object.expires) / 1000);
|
|
539
|
+
delete object.expires;
|
|
540
|
+
};
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* populate helper
|
|
544
|
+
* @param {String} path
|
|
545
|
+
* @param {String} select
|
|
546
|
+
* @param {Model} model
|
|
547
|
+
* @param {Object} match
|
|
548
|
+
* @param {Object} options
|
|
549
|
+
* @param {Any} subPopulate
|
|
550
|
+
* @param {Boolean} justOne
|
|
551
|
+
* @param {Boolean} count
|
|
552
|
+
*/
|
|
553
|
+
|
|
554
|
+
exports.populate = function populate(path, select, model, match, options, subPopulate, justOne, count) {
|
|
555
|
+
// might have passed an object specifying all arguments
|
|
556
|
+
let obj = null;
|
|
557
|
+
if (arguments.length === 1) {
|
|
558
|
+
if (path instanceof PopulateOptions) {
|
|
559
|
+
// If reusing old populate docs, avoid reusing `_docs` because that may
|
|
560
|
+
// lead to bugs and memory leaks. See gh-11641
|
|
561
|
+
path._docs = {};
|
|
562
|
+
path._childDocs = [];
|
|
563
|
+
return [path];
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
if (Array.isArray(path)) {
|
|
567
|
+
const singles = makeSingles(path);
|
|
568
|
+
return singles.map(o => exports.populate(o)[0]);
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
if (exports.isObject(path)) {
|
|
572
|
+
obj = Object.assign({}, path);
|
|
573
|
+
} else {
|
|
574
|
+
obj = { path: path };
|
|
575
|
+
}
|
|
576
|
+
} else if (typeof model === 'object') {
|
|
577
|
+
obj = {
|
|
578
|
+
path: path,
|
|
579
|
+
select: select,
|
|
580
|
+
match: model,
|
|
581
|
+
options: match
|
|
582
|
+
};
|
|
583
|
+
} else {
|
|
584
|
+
obj = {
|
|
585
|
+
path: path,
|
|
586
|
+
select: select,
|
|
587
|
+
model: model,
|
|
588
|
+
match: match,
|
|
589
|
+
options: options,
|
|
590
|
+
populate: subPopulate,
|
|
591
|
+
justOne: justOne,
|
|
592
|
+
count: count
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
if (typeof obj.path !== 'string' && !(Array.isArray(obj.path) && obj.path.every(el => typeof el === 'string'))) {
|
|
597
|
+
throw new TypeError('utils.populate: invalid path. Expected string or array of strings. Got typeof `' + typeof path + '`');
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
return _populateObj(obj);
|
|
601
|
+
|
|
602
|
+
// The order of select/conditions args is opposite Model.find but
|
|
603
|
+
// necessary to keep backward compatibility (select could be
|
|
604
|
+
// an array, string, or object literal).
|
|
605
|
+
function makeSingles(arr) {
|
|
606
|
+
const ret = [];
|
|
607
|
+
arr.forEach(function(obj) {
|
|
608
|
+
if (oneSpaceRE.test(obj.path)) {
|
|
609
|
+
const paths = obj.path.split(manySpaceRE);
|
|
610
|
+
paths.forEach(function(p) {
|
|
611
|
+
const copy = Object.assign({}, obj);
|
|
612
|
+
copy.path = p;
|
|
613
|
+
ret.push(copy);
|
|
614
|
+
});
|
|
615
|
+
} else {
|
|
616
|
+
ret.push(obj);
|
|
617
|
+
}
|
|
618
|
+
});
|
|
619
|
+
|
|
620
|
+
return ret;
|
|
621
|
+
}
|
|
622
|
+
};
|
|
623
|
+
|
|
624
|
+
function _populateObj(obj) {
|
|
625
|
+
if (Array.isArray(obj.populate)) {
|
|
626
|
+
const ret = [];
|
|
627
|
+
obj.populate.forEach(function(obj) {
|
|
628
|
+
if (oneSpaceRE.test(obj.path)) {
|
|
629
|
+
const copy = Object.assign({}, obj);
|
|
630
|
+
const paths = copy.path.split(manySpaceRE);
|
|
631
|
+
paths.forEach(function(p) {
|
|
632
|
+
copy.path = p;
|
|
633
|
+
ret.push(exports.populate(copy)[0]);
|
|
634
|
+
});
|
|
635
|
+
} else {
|
|
636
|
+
ret.push(exports.populate(obj)[0]);
|
|
637
|
+
}
|
|
638
|
+
});
|
|
639
|
+
obj.populate = exports.populate(ret);
|
|
640
|
+
} else if (obj.populate != null && typeof obj.populate === 'object') {
|
|
641
|
+
obj.populate = exports.populate(obj.populate);
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
const ret = [];
|
|
645
|
+
const paths = oneSpaceRE.test(obj.path)
|
|
646
|
+
? obj.path.split(manySpaceRE)
|
|
647
|
+
: Array.isArray(obj.path)
|
|
648
|
+
? obj.path
|
|
649
|
+
: [obj.path];
|
|
650
|
+
if (obj.options != null) {
|
|
651
|
+
obj.options = clone(obj.options);
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
for (const path of paths) {
|
|
655
|
+
ret.push(new PopulateOptions(Object.assign({}, obj, { path: path })));
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
return ret;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
/**
|
|
662
|
+
* Return the value of `obj` at the given `path`.
|
|
663
|
+
*
|
|
664
|
+
* @param {String} path
|
|
665
|
+
* @param {Object} obj
|
|
666
|
+
* @param {Any} map
|
|
667
|
+
*/
|
|
668
|
+
|
|
669
|
+
exports.getValue = function(path, obj, map) {
|
|
670
|
+
return mpath.get(path, obj, getValueLookup, map);
|
|
671
|
+
};
|
|
672
|
+
|
|
673
|
+
/*!
|
|
674
|
+
* ignore
|
|
675
|
+
*/
|
|
676
|
+
|
|
677
|
+
const mapGetterOptions = Object.freeze({ getters: false });
|
|
678
|
+
|
|
679
|
+
function getValueLookup(obj, part) {
|
|
680
|
+
if (part === '$*' && obj instanceof Map) {
|
|
681
|
+
return obj;
|
|
682
|
+
}
|
|
683
|
+
let _from = obj?._doc || obj;
|
|
684
|
+
if (_from?.isMongooseArrayProxy) {
|
|
685
|
+
_from = _from.__array;
|
|
686
|
+
}
|
|
687
|
+
return _from instanceof Map ?
|
|
688
|
+
_from.get(part, mapGetterOptions) :
|
|
689
|
+
_from[part];
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
/**
|
|
693
|
+
* Sets the value of `obj` at the given `path`.
|
|
694
|
+
*
|
|
695
|
+
* @param {String} path
|
|
696
|
+
* @param {Anything} val
|
|
697
|
+
* @param {Object} obj
|
|
698
|
+
* @param {Any} map
|
|
699
|
+
* @param {Any} _copying
|
|
700
|
+
*/
|
|
701
|
+
|
|
702
|
+
exports.setValue = function(path, val, obj, map, _copying) {
|
|
703
|
+
mpath.set(path, val, obj, '_doc', map, _copying);
|
|
704
|
+
};
|
|
705
|
+
|
|
706
|
+
/**
|
|
707
|
+
* Returns an array of values from object `o`.
|
|
708
|
+
*
|
|
709
|
+
* @param {Object} o
|
|
710
|
+
* @return {Array}
|
|
711
|
+
* @api private
|
|
712
|
+
*/
|
|
713
|
+
|
|
714
|
+
exports.object = {};
|
|
715
|
+
exports.object.vals = function vals(o) {
|
|
716
|
+
if (o == null) {
|
|
717
|
+
return [];
|
|
718
|
+
}
|
|
719
|
+
const keys = Object.keys(o);
|
|
720
|
+
let i = keys.length;
|
|
721
|
+
const ret = [];
|
|
722
|
+
|
|
723
|
+
while (i--) {
|
|
724
|
+
ret.push(o[keys[i]]);
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
return ret;
|
|
728
|
+
};
|
|
729
|
+
|
|
730
|
+
|
|
731
|
+
/**
|
|
732
|
+
* Determine if `val` is null or undefined
|
|
733
|
+
*
|
|
734
|
+
* @param {Any} val
|
|
735
|
+
* @return {Boolean}
|
|
736
|
+
*/
|
|
737
|
+
|
|
738
|
+
exports.isNullOrUndefined = function(val) {
|
|
739
|
+
return val == null;
|
|
740
|
+
};
|
|
741
|
+
|
|
742
|
+
/*!
|
|
743
|
+
* ignore
|
|
744
|
+
*/
|
|
745
|
+
|
|
746
|
+
exports.array = {};
|
|
747
|
+
|
|
748
|
+
/**
|
|
749
|
+
* Flattens an array.
|
|
750
|
+
*
|
|
751
|
+
* [ 1, [ 2, 3, [4] ]] -> [1,2,3,4]
|
|
752
|
+
*
|
|
753
|
+
* @param {Array} arr
|
|
754
|
+
* @param {Function} [filter] If passed, will be invoked with each item in the array. If `filter` returns a falsy value, the item will not be included in the results.
|
|
755
|
+
* @param {Array} ret
|
|
756
|
+
* @return {Array}
|
|
757
|
+
* @api private
|
|
758
|
+
*/
|
|
759
|
+
|
|
760
|
+
exports.array.flatten = function flatten(arr, filter, ret) {
|
|
761
|
+
ret || (ret = []);
|
|
762
|
+
|
|
763
|
+
arr.forEach(function(item) {
|
|
764
|
+
if (Array.isArray(item)) {
|
|
765
|
+
flatten(item, filter, ret);
|
|
766
|
+
} else {
|
|
767
|
+
if (!filter || filter(item)) {
|
|
768
|
+
ret.push(item);
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
});
|
|
772
|
+
|
|
773
|
+
return ret;
|
|
774
|
+
};
|
|
775
|
+
|
|
776
|
+
/*!
|
|
777
|
+
* ignore
|
|
778
|
+
*/
|
|
779
|
+
|
|
780
|
+
exports.hasUserDefinedProperty = function(obj, key) {
|
|
781
|
+
if (obj == null) {
|
|
782
|
+
return false;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
if (Array.isArray(key)) {
|
|
786
|
+
for (const k of key) {
|
|
787
|
+
if (exports.hasUserDefinedProperty(obj, k)) {
|
|
788
|
+
return true;
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
return false;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
if (Object.hasOwn(obj, key)) {
|
|
795
|
+
return true;
|
|
796
|
+
}
|
|
797
|
+
if (typeof obj === 'object' && key in obj) {
|
|
798
|
+
const v = obj[key];
|
|
799
|
+
return v !== Object.prototype[key] && v !== Array.prototype[key];
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
return false;
|
|
803
|
+
};
|
|
804
|
+
|
|
805
|
+
/*!
|
|
806
|
+
* ignore
|
|
807
|
+
*/
|
|
808
|
+
|
|
809
|
+
const MAX_ARRAY_INDEX = Math.pow(2, 32) - 1;
|
|
810
|
+
|
|
811
|
+
exports.isArrayIndex = function(val) {
|
|
812
|
+
if (typeof val === 'number') {
|
|
813
|
+
return val >= 0 && val <= MAX_ARRAY_INDEX;
|
|
814
|
+
}
|
|
815
|
+
if (typeof val === 'string') {
|
|
816
|
+
if (!/^\d+$/.test(val)) {
|
|
817
|
+
return false;
|
|
818
|
+
}
|
|
819
|
+
val = +val;
|
|
820
|
+
return val >= 0 && val <= MAX_ARRAY_INDEX;
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
return false;
|
|
824
|
+
};
|
|
825
|
+
|
|
826
|
+
/**
|
|
827
|
+
* Removes duplicate values from an array
|
|
828
|
+
*
|
|
829
|
+
* [1, 2, 3, 3, 5] => [1, 2, 3, 5]
|
|
830
|
+
* [ ObjectId("550988ba0c19d57f697dc45e"), ObjectId("550988ba0c19d57f697dc45e") ]
|
|
831
|
+
* => [ObjectId("550988ba0c19d57f697dc45e")]
|
|
832
|
+
*
|
|
833
|
+
* @param {Array} arr
|
|
834
|
+
* @return {Array}
|
|
835
|
+
* @api private
|
|
836
|
+
*/
|
|
837
|
+
|
|
838
|
+
exports.array.unique = function(arr) {
|
|
839
|
+
const primitives = new Set();
|
|
840
|
+
const ids = new Set();
|
|
841
|
+
const ret = [];
|
|
842
|
+
|
|
843
|
+
for (const item of arr) {
|
|
844
|
+
if (typeof item === 'number' || typeof item === 'string' || item == null) {
|
|
845
|
+
if (primitives.has(item)) {
|
|
846
|
+
continue;
|
|
847
|
+
}
|
|
848
|
+
ret.push(item);
|
|
849
|
+
primitives.add(item);
|
|
850
|
+
} else if (isBsonType(item, 'ObjectId')) {
|
|
851
|
+
if (ids.has(item.toString())) {
|
|
852
|
+
continue;
|
|
853
|
+
}
|
|
854
|
+
ret.push(item);
|
|
855
|
+
ids.add(item.toString());
|
|
856
|
+
} else {
|
|
857
|
+
ret.push(item);
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
return ret;
|
|
862
|
+
};
|
|
863
|
+
|
|
864
|
+
exports.buffer = {};
|
|
865
|
+
|
|
866
|
+
/**
|
|
867
|
+
* Determines if two buffers are equal.
|
|
868
|
+
*
|
|
869
|
+
* @param {Buffer} a
|
|
870
|
+
* @param {Object} b
|
|
871
|
+
*/
|
|
872
|
+
|
|
873
|
+
exports.buffer.areEqual = function(a, b) {
|
|
874
|
+
if (!Buffer.isBuffer(a)) {
|
|
875
|
+
return false;
|
|
876
|
+
}
|
|
877
|
+
if (!Buffer.isBuffer(b)) {
|
|
878
|
+
return false;
|
|
879
|
+
}
|
|
880
|
+
return a.equals(b);
|
|
881
|
+
};
|
|
882
|
+
|
|
883
|
+
exports.getFunctionName = getFunctionName;
|
|
884
|
+
|
|
885
|
+
/**
|
|
886
|
+
* Decorate buffers
|
|
887
|
+
* @param {Object} destination
|
|
888
|
+
* @param {Object} source
|
|
889
|
+
*/
|
|
890
|
+
|
|
891
|
+
exports.decorate = function(destination, source) {
|
|
892
|
+
for (const key in source) {
|
|
893
|
+
if (specialProperties.has(key)) {
|
|
894
|
+
continue;
|
|
895
|
+
}
|
|
896
|
+
destination[key] = source[key];
|
|
897
|
+
}
|
|
898
|
+
};
|
|
899
|
+
|
|
900
|
+
/**
|
|
901
|
+
* merges to with a copy of from
|
|
902
|
+
*
|
|
903
|
+
* @param {Object} to
|
|
904
|
+
* @param {Object} fromObj
|
|
905
|
+
* @api private
|
|
906
|
+
*/
|
|
907
|
+
|
|
908
|
+
exports.mergeClone = function(to, fromObj) {
|
|
909
|
+
if (isMongooseObject(fromObj)) {
|
|
910
|
+
fromObj = fromObj.toObject({
|
|
911
|
+
transform: false,
|
|
912
|
+
virtuals: false,
|
|
913
|
+
depopulate: true,
|
|
914
|
+
getters: false,
|
|
915
|
+
flattenDecimals: false
|
|
916
|
+
});
|
|
917
|
+
}
|
|
918
|
+
const keys = Object.keys(fromObj);
|
|
919
|
+
const len = keys.length;
|
|
920
|
+
let i = 0;
|
|
921
|
+
let key;
|
|
922
|
+
|
|
923
|
+
while (i < len) {
|
|
924
|
+
key = keys[i++];
|
|
925
|
+
if (specialProperties.has(key)) {
|
|
926
|
+
continue;
|
|
927
|
+
}
|
|
928
|
+
if (typeof to[key] === 'undefined') {
|
|
929
|
+
to[key] = clone(fromObj[key], {
|
|
930
|
+
transform: false,
|
|
931
|
+
virtuals: false,
|
|
932
|
+
depopulate: true,
|
|
933
|
+
getters: false,
|
|
934
|
+
flattenDecimals: false
|
|
935
|
+
});
|
|
936
|
+
} else {
|
|
937
|
+
let val = fromObj[key];
|
|
938
|
+
if (val?.valueOf && !(val instanceof Date)) {
|
|
939
|
+
val = val.valueOf();
|
|
940
|
+
}
|
|
941
|
+
if (exports.isObject(val)) {
|
|
942
|
+
let obj = val;
|
|
943
|
+
if (isMongooseObject(val) && !val.isMongooseBuffer) {
|
|
944
|
+
obj = obj.toObject({
|
|
945
|
+
transform: false,
|
|
946
|
+
virtuals: false,
|
|
947
|
+
depopulate: true,
|
|
948
|
+
getters: false,
|
|
949
|
+
flattenDecimals: false
|
|
950
|
+
});
|
|
951
|
+
}
|
|
952
|
+
if (val.isMongooseBuffer) {
|
|
953
|
+
obj = Buffer.from(obj);
|
|
954
|
+
}
|
|
955
|
+
exports.mergeClone(to[key], obj);
|
|
956
|
+
} else {
|
|
957
|
+
to[key] = clone(val, {
|
|
958
|
+
flattenDecimals: false
|
|
959
|
+
});
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
};
|
|
964
|
+
|
|
965
|
+
/**
|
|
966
|
+
* Executes a function on each element of an array (like _.each)
|
|
967
|
+
*
|
|
968
|
+
* @param {Array} arr
|
|
969
|
+
* @param {Function} fn
|
|
970
|
+
* @api private
|
|
971
|
+
*/
|
|
972
|
+
|
|
973
|
+
exports.each = function(arr, fn) {
|
|
974
|
+
for (const item of arr) {
|
|
975
|
+
fn(item);
|
|
976
|
+
}
|
|
977
|
+
};
|
|
978
|
+
|
|
979
|
+
/**
|
|
980
|
+
* Rename an object key, while preserving its position in the object
|
|
981
|
+
*
|
|
982
|
+
* @param {Object} oldObj
|
|
983
|
+
* @param {String|Number} oldKey
|
|
984
|
+
* @param {String|Number} newKey
|
|
985
|
+
* @api private
|
|
986
|
+
*/
|
|
987
|
+
exports.renameObjKey = function(oldObj, oldKey, newKey) {
|
|
988
|
+
const keys = Object.keys(oldObj);
|
|
989
|
+
return keys.reduce(
|
|
990
|
+
(acc, val) => {
|
|
991
|
+
if (val === oldKey) {
|
|
992
|
+
acc[newKey] = oldObj[oldKey];
|
|
993
|
+
} else {
|
|
994
|
+
acc[val] = oldObj[val];
|
|
995
|
+
}
|
|
996
|
+
return acc;
|
|
997
|
+
},
|
|
998
|
+
{}
|
|
999
|
+
);
|
|
1000
|
+
};
|
|
1001
|
+
|
|
1002
|
+
/*!
|
|
1003
|
+
* ignore
|
|
1004
|
+
*/
|
|
1005
|
+
|
|
1006
|
+
exports.getOption = function(name) {
|
|
1007
|
+
const sources = Array.prototype.slice.call(arguments, 1);
|
|
1008
|
+
|
|
1009
|
+
for (const source of sources) {
|
|
1010
|
+
if (source == null) {
|
|
1011
|
+
continue;
|
|
1012
|
+
}
|
|
1013
|
+
if (source[name] != null) {
|
|
1014
|
+
return source[name];
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
return null;
|
|
1019
|
+
};
|
|
1020
|
+
|
|
1021
|
+
/*!
|
|
1022
|
+
* ignore
|
|
1023
|
+
*/
|
|
1024
|
+
|
|
1025
|
+
exports.noop = function() {};
|
|
1026
|
+
|
|
1027
|
+
exports.errorToPOJO = function errorToPOJO(error) {
|
|
1028
|
+
const isError = error instanceof Error;
|
|
1029
|
+
if (!isError) {
|
|
1030
|
+
throw new Error('`error` must be `instanceof Error`.');
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
const ret = {};
|
|
1034
|
+
for (const properyName of Object.getOwnPropertyNames(error)) {
|
|
1035
|
+
ret[properyName] = error[properyName];
|
|
1036
|
+
}
|
|
1037
|
+
return ret;
|
|
1038
|
+
};
|
|
1039
|
+
|
|
1040
|
+
/*!
|
|
1041
|
+
* ignore
|
|
1042
|
+
*/
|
|
1043
|
+
|
|
1044
|
+
exports.warn = function warn(message) {
|
|
1045
|
+
return process.emitWarning(message, { code: 'MONGOOSE' });
|
|
1046
|
+
};
|
|
1047
|
+
|
|
1048
|
+
|
|
1049
|
+
exports.injectTimestampsOption = function injectTimestampsOption(writeOperation, timestampsOption) {
|
|
1050
|
+
if (timestampsOption == null) {
|
|
1051
|
+
return;
|
|
1052
|
+
}
|
|
1053
|
+
writeOperation.timestamps = timestampsOption;
|
|
1054
|
+
};
|