@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,54 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const isOperator = require('./isOperator');
|
|
4
|
+
|
|
5
|
+
module.exports = function castFilterPath(ctx, schematype, val) {
|
|
6
|
+
const any$conditionals = Object.keys(val).some(isOperator);
|
|
7
|
+
|
|
8
|
+
if (!any$conditionals) {
|
|
9
|
+
return schematype.castForQuery(
|
|
10
|
+
null,
|
|
11
|
+
val,
|
|
12
|
+
ctx
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const ks = Object.keys(val);
|
|
17
|
+
|
|
18
|
+
let k = ks.length;
|
|
19
|
+
|
|
20
|
+
while (k--) {
|
|
21
|
+
const $cond = ks[k];
|
|
22
|
+
const nested = val[$cond];
|
|
23
|
+
|
|
24
|
+
if ($cond === '$not') {
|
|
25
|
+
if (nested && schematype && !schematype.embeddedSchemaType && !schematype.Constructor) {
|
|
26
|
+
const _keys = Object.keys(nested);
|
|
27
|
+
if (_keys.length && isOperator(_keys[0])) {
|
|
28
|
+
for (const key of Object.keys(nested)) {
|
|
29
|
+
nested[key] = schematype.castForQuery(
|
|
30
|
+
key,
|
|
31
|
+
nested[key],
|
|
32
|
+
ctx
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
} else {
|
|
36
|
+
val[$cond] = schematype.castForQuery(
|
|
37
|
+
$cond,
|
|
38
|
+
nested,
|
|
39
|
+
ctx
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
} else {
|
|
45
|
+
val[$cond] = schematype.castForQuery(
|
|
46
|
+
$cond,
|
|
47
|
+
nested,
|
|
48
|
+
ctx
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return val;
|
|
54
|
+
};
|
|
@@ -0,0 +1,643 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const CastError = require('../../error/cast');
|
|
4
|
+
const MongooseError = require('../../error/mongooseError');
|
|
5
|
+
const SchemaString = require('../../schema/string');
|
|
6
|
+
const StrictModeError = require('../../error/strict');
|
|
7
|
+
const ValidationError = require('../../error/validation');
|
|
8
|
+
const castNumber = require('../../cast/number');
|
|
9
|
+
const cast = require('../../cast');
|
|
10
|
+
const getConstructorName = require('../getConstructorName');
|
|
11
|
+
const getDiscriminatorByValue = require('../discriminator/getDiscriminatorByValue');
|
|
12
|
+
const getEmbeddedDiscriminatorPath = require('./getEmbeddedDiscriminatorPath');
|
|
13
|
+
const handleImmutable = require('./handleImmutable');
|
|
14
|
+
const moveImmutableProperties = require('../update/moveImmutableProperties');
|
|
15
|
+
const schemaMixedSymbol = require('../../schema/symbols').schemaMixedSymbol;
|
|
16
|
+
const setDottedPath = require('../path/setDottedPath');
|
|
17
|
+
const utils = require('../../utils');
|
|
18
|
+
const { internalToObjectOptions } = require('../../options');
|
|
19
|
+
|
|
20
|
+
const mongodbUpdateOperators = new Set([
|
|
21
|
+
'$currentDate',
|
|
22
|
+
'$inc',
|
|
23
|
+
'$min',
|
|
24
|
+
'$max',
|
|
25
|
+
'$mul',
|
|
26
|
+
'$rename',
|
|
27
|
+
'$set',
|
|
28
|
+
'$setOnInsert',
|
|
29
|
+
'$unset',
|
|
30
|
+
'$addToSet',
|
|
31
|
+
'$pop',
|
|
32
|
+
'$pull',
|
|
33
|
+
'$push',
|
|
34
|
+
'$pullAll',
|
|
35
|
+
'$bit'
|
|
36
|
+
]);
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Casts an update op based on the given schema
|
|
40
|
+
*
|
|
41
|
+
* @param {Schema} schema
|
|
42
|
+
* @param {Object} obj
|
|
43
|
+
* @param {Object} [options]
|
|
44
|
+
* @param {Boolean|String} [options.strict] defaults to true
|
|
45
|
+
* @param {Query} context passed to setters
|
|
46
|
+
* @return {Boolean} true iff the update is non-empty
|
|
47
|
+
* @api private
|
|
48
|
+
*/
|
|
49
|
+
module.exports = function castUpdate(schema, obj, options, context, filter) {
|
|
50
|
+
if (obj == null) {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
options = options || {};
|
|
54
|
+
// Update pipeline
|
|
55
|
+
if (Array.isArray(obj)) {
|
|
56
|
+
const len = obj.length;
|
|
57
|
+
for (let i = 0; i < len; ++i) {
|
|
58
|
+
const ops = Object.keys(obj[i]);
|
|
59
|
+
for (const op of ops) {
|
|
60
|
+
obj[i][op] = castPipelineOperator(op, obj[i][op]);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return obj;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (schema != null &&
|
|
67
|
+
filter != null &&
|
|
68
|
+
utils.hasUserDefinedProperty(filter, schema.options.discriminatorKey) &&
|
|
69
|
+
typeof filter[schema.options.discriminatorKey] !== 'object' &&
|
|
70
|
+
schema.discriminators != null) {
|
|
71
|
+
const discriminatorValue = filter[schema.options.discriminatorKey];
|
|
72
|
+
const byValue = getDiscriminatorByValue(context.model.discriminators, discriminatorValue);
|
|
73
|
+
schema = schema.discriminators[discriminatorValue] ||
|
|
74
|
+
byValue?.schema ||
|
|
75
|
+
schema;
|
|
76
|
+
} else if (schema != null &&
|
|
77
|
+
options.overwriteDiscriminatorKey &&
|
|
78
|
+
utils.hasUserDefinedProperty(obj, schema.options.discriminatorKey) &&
|
|
79
|
+
schema.discriminators != null) {
|
|
80
|
+
const discriminatorValue = obj[schema.options.discriminatorKey];
|
|
81
|
+
const byValue = getDiscriminatorByValue(context.model.discriminators, discriminatorValue);
|
|
82
|
+
schema = schema.discriminators[discriminatorValue] ||
|
|
83
|
+
byValue?.schema ||
|
|
84
|
+
schema;
|
|
85
|
+
} else if (schema != null &&
|
|
86
|
+
options.overwriteDiscriminatorKey &&
|
|
87
|
+
obj.$set != null &&
|
|
88
|
+
utils.hasUserDefinedProperty(obj.$set, schema.options.discriminatorKey) &&
|
|
89
|
+
schema.discriminators != null) {
|
|
90
|
+
const discriminatorValue = obj.$set[schema.options.discriminatorKey];
|
|
91
|
+
const byValue = getDiscriminatorByValue(context.model.discriminators, discriminatorValue);
|
|
92
|
+
schema = schema.discriminators[discriminatorValue] ||
|
|
93
|
+
byValue?.schema ||
|
|
94
|
+
schema;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (options.upsert) {
|
|
98
|
+
moveImmutableProperties(schema, obj, context);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const ops = Object.keys(obj);
|
|
102
|
+
let i = ops.length;
|
|
103
|
+
const ret = {};
|
|
104
|
+
let val;
|
|
105
|
+
let hasDollarKey = false;
|
|
106
|
+
|
|
107
|
+
filter = filter || {};
|
|
108
|
+
while (i--) {
|
|
109
|
+
const op = ops[i];
|
|
110
|
+
if (!mongodbUpdateOperators.has(op)) {
|
|
111
|
+
// fix up $set sugar
|
|
112
|
+
if (!ret.$set) {
|
|
113
|
+
if (obj.$set) {
|
|
114
|
+
ret.$set = obj.$set;
|
|
115
|
+
} else {
|
|
116
|
+
ret.$set = {};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
ret.$set[op] = obj[op];
|
|
120
|
+
ops.splice(i, 1);
|
|
121
|
+
if (!~ops.indexOf('$set')) ops.push('$set');
|
|
122
|
+
} else if (op === '$set') {
|
|
123
|
+
if (!ret.$set) {
|
|
124
|
+
ret[op] = obj[op];
|
|
125
|
+
}
|
|
126
|
+
} else {
|
|
127
|
+
ret[op] = obj[op];
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// cast each value
|
|
131
|
+
i = ops.length;
|
|
132
|
+
while (i--) {
|
|
133
|
+
const op = ops[i];
|
|
134
|
+
val = ret[op];
|
|
135
|
+
hasDollarKey = hasDollarKey || op.startsWith('$');
|
|
136
|
+
if (val?.$__) {
|
|
137
|
+
val = val.toObject(internalToObjectOptions);
|
|
138
|
+
ret[op] = val;
|
|
139
|
+
}
|
|
140
|
+
if (val &&
|
|
141
|
+
typeof val === 'object' &&
|
|
142
|
+
!Buffer.isBuffer(val) &&
|
|
143
|
+
mongodbUpdateOperators.has(op)) {
|
|
144
|
+
walkUpdatePath(schema, val, op, options, context, filter);
|
|
145
|
+
} else {
|
|
146
|
+
const msg = 'Invalid atomic update value for ' + op + '. '
|
|
147
|
+
+ 'Expected an object, received ' + typeof val;
|
|
148
|
+
throw new Error(msg);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (op.startsWith('$') && utils.isEmptyObject(val)) {
|
|
152
|
+
delete ret[op];
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (utils.hasOwnKeys(ret) === false &&
|
|
157
|
+
options.upsert &&
|
|
158
|
+
utils.hasOwnKeys(filter)) {
|
|
159
|
+
// Trick the driver into allowing empty upserts to work around
|
|
160
|
+
// https://github.com/mongodb/node-mongodb-native/pull/2490
|
|
161
|
+
// Shallow clone to avoid passing defaults in re: gh-13962
|
|
162
|
+
return { $setOnInsert: { ...filter } };
|
|
163
|
+
}
|
|
164
|
+
return ret;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
/*!
|
|
168
|
+
* ignore
|
|
169
|
+
*/
|
|
170
|
+
|
|
171
|
+
function castPipelineOperator(op, val) {
|
|
172
|
+
if (op === '$unset') {
|
|
173
|
+
if (typeof val !== 'string' && (!Array.isArray(val) || val.find(v => typeof v !== 'string'))) {
|
|
174
|
+
throw new MongooseError('Invalid $unset in pipeline, must be ' +
|
|
175
|
+
' a string or an array of strings');
|
|
176
|
+
}
|
|
177
|
+
return val;
|
|
178
|
+
}
|
|
179
|
+
if (op === '$project') {
|
|
180
|
+
if (val == null || typeof val !== 'object') {
|
|
181
|
+
throw new MongooseError('Invalid $project in pipeline, must be an object');
|
|
182
|
+
}
|
|
183
|
+
return val;
|
|
184
|
+
}
|
|
185
|
+
if (op === '$addFields' || op === '$set') {
|
|
186
|
+
if (val == null || typeof val !== 'object') {
|
|
187
|
+
throw new MongooseError('Invalid ' + op + ' in pipeline, must be an object');
|
|
188
|
+
}
|
|
189
|
+
return val;
|
|
190
|
+
} else if (op === '$replaceRoot' || op === '$replaceWith') {
|
|
191
|
+
if (val == null || typeof val !== 'object') {
|
|
192
|
+
throw new MongooseError('Invalid ' + op + ' in pipeline, must be an object');
|
|
193
|
+
}
|
|
194
|
+
return val;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
throw new MongooseError('Invalid update pipeline operator: "' + op + '"');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Walk each path of obj and cast its values
|
|
202
|
+
* according to its schema.
|
|
203
|
+
*
|
|
204
|
+
* @param {Schema} schema
|
|
205
|
+
* @param {Object} obj part of a query
|
|
206
|
+
* @param {String} op the atomic operator ($pull, $set, etc)
|
|
207
|
+
* @param {Object} [options]
|
|
208
|
+
* @param {Boolean|String} [options.strict]
|
|
209
|
+
* @param {Query} context
|
|
210
|
+
* @param {Object} filter
|
|
211
|
+
* @param {String} pref path prefix (internal only)
|
|
212
|
+
* @return {Bool} true if this path has keys to update
|
|
213
|
+
* @api private
|
|
214
|
+
*/
|
|
215
|
+
|
|
216
|
+
function walkUpdatePath(schema, obj, op, options, context, filter, prefix) {
|
|
217
|
+
const strict = options.strict;
|
|
218
|
+
prefix = prefix ? prefix + '.' : '';
|
|
219
|
+
const keys = Object.keys(obj);
|
|
220
|
+
let i = keys.length;
|
|
221
|
+
let hasKeys = false;
|
|
222
|
+
let schematype;
|
|
223
|
+
let key;
|
|
224
|
+
let val;
|
|
225
|
+
|
|
226
|
+
let aggregatedError = null;
|
|
227
|
+
|
|
228
|
+
const strictMode = strict ?? schema.options.strict;
|
|
229
|
+
|
|
230
|
+
while (i--) {
|
|
231
|
+
key = keys[i];
|
|
232
|
+
val = obj[key];
|
|
233
|
+
|
|
234
|
+
// `$pull` is special because we need to cast the RHS as a query, not as
|
|
235
|
+
// an update.
|
|
236
|
+
if (op === '$pull') {
|
|
237
|
+
schematype = schema._getSchema(prefix + key);
|
|
238
|
+
if (schematype == null) {
|
|
239
|
+
const _res = getEmbeddedDiscriminatorPath(schema, obj, filter, prefix + key, options);
|
|
240
|
+
if (_res.schematype != null) {
|
|
241
|
+
schematype = _res.schematype;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (schematype?.schema != null) {
|
|
245
|
+
obj[key] = cast(schematype.schema, obj[key], options, context);
|
|
246
|
+
hasKeys = true;
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const discriminatorKey = (prefix ? prefix + key : key);
|
|
252
|
+
if (
|
|
253
|
+
schema.discriminatorMapping != null &&
|
|
254
|
+
discriminatorKey === schema.options.discriminatorKey &&
|
|
255
|
+
schema.discriminatorMapping.value !== obj[key] &&
|
|
256
|
+
!options.overwriteDiscriminatorKey
|
|
257
|
+
) {
|
|
258
|
+
if (strictMode === 'throw') {
|
|
259
|
+
const err = new Error('Can\'t modify discriminator key "' + discriminatorKey + '" on discriminator model');
|
|
260
|
+
aggregatedError = _appendError(err, context, discriminatorKey, aggregatedError);
|
|
261
|
+
continue;
|
|
262
|
+
} else if (strictMode) {
|
|
263
|
+
delete obj[key];
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (getConstructorName(val) === 'Object') {
|
|
269
|
+
// watch for embedded doc schemas
|
|
270
|
+
schematype = schema._getSchema(prefix + key);
|
|
271
|
+
|
|
272
|
+
if (schematype == null) {
|
|
273
|
+
const _res = getEmbeddedDiscriminatorPath(schema, obj, filter, prefix + key, options);
|
|
274
|
+
if (_res.schematype != null) {
|
|
275
|
+
schematype = _res.schematype;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (op !== '$setOnInsert' &&
|
|
280
|
+
handleImmutable(schematype, strict, obj, key, prefix + key, options, context)) {
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (schematype && (schematype.embeddedSchemaType || schematype.Constructor) && op in castOps) {
|
|
285
|
+
// embedded doc schema
|
|
286
|
+
if ('$each' in val) {
|
|
287
|
+
hasKeys = true;
|
|
288
|
+
try {
|
|
289
|
+
obj[key] = {
|
|
290
|
+
$each: castUpdateVal(schematype, val.$each, op, key, context, prefix + key)
|
|
291
|
+
};
|
|
292
|
+
} catch (error) {
|
|
293
|
+
aggregatedError = _appendError(error, context, key, aggregatedError);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (val.$slice != null) {
|
|
297
|
+
obj[key].$slice = val.$slice | 0;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (val.$sort) {
|
|
301
|
+
obj[key].$sort = val.$sort;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if (val.$position != null) {
|
|
305
|
+
obj[key].$position = castNumber(val.$position);
|
|
306
|
+
}
|
|
307
|
+
} else {
|
|
308
|
+
if (schematype?.$isSingleNested) {
|
|
309
|
+
const _strict = strict == null ? schematype.schema.options.strict : strict;
|
|
310
|
+
try {
|
|
311
|
+
obj[key] = schematype.castForQuery(null, val, context, { strict: _strict });
|
|
312
|
+
} catch (error) {
|
|
313
|
+
aggregatedError = _appendError(error, context, key, aggregatedError);
|
|
314
|
+
}
|
|
315
|
+
} else {
|
|
316
|
+
try {
|
|
317
|
+
obj[key] = castUpdateVal(schematype, val, op, key, context, prefix + key);
|
|
318
|
+
} catch (error) {
|
|
319
|
+
aggregatedError = _appendError(error, context, key, aggregatedError);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (obj[key] === void 0) {
|
|
324
|
+
delete obj[key];
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
hasKeys = true;
|
|
329
|
+
}
|
|
330
|
+
} else if ((op === '$currentDate') || (op in castOps && schematype)) {
|
|
331
|
+
// $currentDate can take an object
|
|
332
|
+
try {
|
|
333
|
+
obj[key] = castUpdateVal(schematype, val, op, key, context, prefix + key);
|
|
334
|
+
} catch (error) {
|
|
335
|
+
aggregatedError = _appendError(error, context, key, aggregatedError);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (obj[key] === void 0) {
|
|
339
|
+
delete obj[key];
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
hasKeys = true;
|
|
344
|
+
} else if (op === '$rename') {
|
|
345
|
+
const schematype = new SchemaString(`${prefix}${key}.$rename`);
|
|
346
|
+
try {
|
|
347
|
+
obj[key] = castUpdateVal(schematype, val, op, key, context, prefix + key);
|
|
348
|
+
} catch (error) {
|
|
349
|
+
aggregatedError = _appendError(error, context, key, aggregatedError);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
if (obj[key] === void 0) {
|
|
353
|
+
delete obj[key];
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
hasKeys = true;
|
|
358
|
+
} else {
|
|
359
|
+
const pathToCheck = (prefix + key);
|
|
360
|
+
const v = schema._getPathType(pathToCheck);
|
|
361
|
+
let _strict = strict;
|
|
362
|
+
if (v?.schema && _strict == null) {
|
|
363
|
+
_strict = v.schema.options.strict;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
if (v.pathType === 'undefined') {
|
|
367
|
+
if (_strict === 'throw') {
|
|
368
|
+
throw new StrictModeError(pathToCheck);
|
|
369
|
+
} else if (_strict) {
|
|
370
|
+
delete obj[key];
|
|
371
|
+
continue;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// gh-2314
|
|
376
|
+
// we should be able to set a schema-less field
|
|
377
|
+
// to an empty object literal
|
|
378
|
+
hasKeys |= walkUpdatePath(schema, val, op, options, context, filter, prefix + key) ||
|
|
379
|
+
(utils.isObject(val) && utils.hasOwnKeys(val) === false);
|
|
380
|
+
}
|
|
381
|
+
} else {
|
|
382
|
+
const isModifier = (key === '$each' || key === '$or' || key === '$and' || key === '$in');
|
|
383
|
+
if (isModifier && !prefix) {
|
|
384
|
+
throw new MongooseError('Invalid update: Unexpected modifier "' + key + '" as a key in operator. '
|
|
385
|
+
+ 'Did you mean something like { $addToSet: { fieldName: { $each: [...] } } }? '
|
|
386
|
+
+ 'Modifiers such as "$each", "$or", "$and", "$in" must appear under a valid field path.');
|
|
387
|
+
}
|
|
388
|
+
const checkPath = isModifier ? prefix : prefix + key;
|
|
389
|
+
schematype = schema._getSchema(checkPath);
|
|
390
|
+
|
|
391
|
+
// You can use `$setOnInsert` with immutable keys
|
|
392
|
+
if (op !== '$setOnInsert' &&
|
|
393
|
+
handleImmutable(schematype, strict, obj, key, prefix + key, options, context)) {
|
|
394
|
+
continue;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
let pathDetails = schema._getPathType(checkPath);
|
|
398
|
+
|
|
399
|
+
// If no schema type, check for embedded discriminators because the
|
|
400
|
+
// filter or update may imply an embedded discriminator type. See #8378
|
|
401
|
+
if (schematype == null) {
|
|
402
|
+
const _res = getEmbeddedDiscriminatorPath(schema, obj, filter, checkPath, options);
|
|
403
|
+
if (_res.schematype != null) {
|
|
404
|
+
schematype = _res.schematype;
|
|
405
|
+
pathDetails = _res.type;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
let isStrict = strict;
|
|
410
|
+
if (pathDetails?.schema && strict == null) {
|
|
411
|
+
isStrict = pathDetails.schema.options.strict;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
const skip = isStrict &&
|
|
415
|
+
!schematype &&
|
|
416
|
+
!/real|nested/.test(pathDetails.pathType);
|
|
417
|
+
|
|
418
|
+
if (skip) {
|
|
419
|
+
// Even if strict is `throw`, avoid throwing an error because of
|
|
420
|
+
// virtuals because of #6731
|
|
421
|
+
if (isStrict === 'throw' && schema.virtuals[checkPath] == null) {
|
|
422
|
+
throw new StrictModeError(prefix + key);
|
|
423
|
+
} else {
|
|
424
|
+
delete obj[key];
|
|
425
|
+
}
|
|
426
|
+
} else {
|
|
427
|
+
if (op === '$rename') {
|
|
428
|
+
if (obj[key] == null) {
|
|
429
|
+
throw new CastError('String', obj[key], `${prefix}${key}.$rename`);
|
|
430
|
+
}
|
|
431
|
+
const schematype = new SchemaString(`${prefix}${key}.$rename`, null, null, schema);
|
|
432
|
+
obj[key] = schematype.castForQuery(null, obj[key], context);
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
try {
|
|
437
|
+
if (prefix.length === 0 || key.indexOf('.') === -1) {
|
|
438
|
+
obj[key] = castUpdateVal(schematype, val, op, key, context, prefix + key);
|
|
439
|
+
} else if (isStrict !== false || schematype != null) {
|
|
440
|
+
// Setting a nested dotted path that's in the schema. We don't allow paths with '.' in
|
|
441
|
+
// a schema, so replace the dotted path with a nested object to avoid ending up with
|
|
442
|
+
// dotted properties in the updated object. See (gh-10200)
|
|
443
|
+
setDottedPath(obj, key, castUpdateVal(schematype, val, op, key, context, prefix + key));
|
|
444
|
+
delete obj[key];
|
|
445
|
+
}
|
|
446
|
+
} catch (error) {
|
|
447
|
+
aggregatedError = _appendError(error, context, key, aggregatedError);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
if (Array.isArray(obj[key]) && (op === '$addToSet' || op === '$push') && key !== '$each') {
|
|
451
|
+
if (schematype &&
|
|
452
|
+
schematype.embeddedSchemaType &&
|
|
453
|
+
!schematype.embeddedSchemaType.$isMongooseArray &&
|
|
454
|
+
!schematype.embeddedSchemaType[schemaMixedSymbol]) {
|
|
455
|
+
obj[key] = { $each: obj[key] };
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
if (obj[key] === void 0) {
|
|
460
|
+
delete obj[key];
|
|
461
|
+
continue;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
hasKeys = true;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
if (aggregatedError != null) {
|
|
470
|
+
throw aggregatedError;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
return hasKeys;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/*!
|
|
477
|
+
* ignore
|
|
478
|
+
*/
|
|
479
|
+
|
|
480
|
+
function _appendError(error, query, key, aggregatedError) {
|
|
481
|
+
if (typeof query !== 'object' || !query.options.multipleCastError) {
|
|
482
|
+
throw error;
|
|
483
|
+
}
|
|
484
|
+
aggregatedError = aggregatedError || new ValidationError();
|
|
485
|
+
aggregatedError.addError(key, error);
|
|
486
|
+
return aggregatedError;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* These operators should be cast to numbers instead
|
|
491
|
+
* of their path schema type.
|
|
492
|
+
* @api private
|
|
493
|
+
*/
|
|
494
|
+
|
|
495
|
+
const numberOps = {
|
|
496
|
+
$pop: 1,
|
|
497
|
+
$inc: 1
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* These ops require no casting because the RHS doesn't do anything.
|
|
502
|
+
* @api private
|
|
503
|
+
*/
|
|
504
|
+
|
|
505
|
+
const noCastOps = {
|
|
506
|
+
$unset: 1
|
|
507
|
+
};
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* These operators require casting docs
|
|
511
|
+
* to real Documents for Update operations.
|
|
512
|
+
* @api private
|
|
513
|
+
*/
|
|
514
|
+
|
|
515
|
+
const castOps = {
|
|
516
|
+
$push: 1,
|
|
517
|
+
$addToSet: 1,
|
|
518
|
+
$set: 1,
|
|
519
|
+
$setOnInsert: 1
|
|
520
|
+
};
|
|
521
|
+
|
|
522
|
+
/*!
|
|
523
|
+
* ignore
|
|
524
|
+
*/
|
|
525
|
+
|
|
526
|
+
const overwriteOps = {
|
|
527
|
+
$set: 1,
|
|
528
|
+
$setOnInsert: 1
|
|
529
|
+
};
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* Casts `val` according to `schema` and atomic `op`.
|
|
533
|
+
*
|
|
534
|
+
* @param {SchemaType} schema
|
|
535
|
+
* @param {Object} val
|
|
536
|
+
* @param {String} op the atomic operator ($pull, $set, etc)
|
|
537
|
+
* @param {String} $conditional
|
|
538
|
+
* @param {Query} context
|
|
539
|
+
* @param {String} path
|
|
540
|
+
* @api private
|
|
541
|
+
*/
|
|
542
|
+
|
|
543
|
+
function castUpdateVal(schema, val, op, $conditional, context, path) {
|
|
544
|
+
if (!schema) {
|
|
545
|
+
// non-existing schema path
|
|
546
|
+
if (op in numberOps) {
|
|
547
|
+
try {
|
|
548
|
+
return castNumber(val);
|
|
549
|
+
} catch {
|
|
550
|
+
throw new CastError('number', val, path);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
return val;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
const cond = schema.$isMongooseArray
|
|
557
|
+
&& op in castOps
|
|
558
|
+
&& (utils.isObject(val) || Array.isArray(val));
|
|
559
|
+
if (cond && !overwriteOps[op]) {
|
|
560
|
+
// Cast values for ops that add data to MongoDB.
|
|
561
|
+
// Ensures embedded documents get ObjectIds etc.
|
|
562
|
+
let schemaArrayDepth = 0;
|
|
563
|
+
let cur = schema;
|
|
564
|
+
while (cur.$isMongooseArray) {
|
|
565
|
+
++schemaArrayDepth;
|
|
566
|
+
cur = cur.embeddedSchemaType;
|
|
567
|
+
}
|
|
568
|
+
let arrayDepth = 0;
|
|
569
|
+
let _val = val;
|
|
570
|
+
while (Array.isArray(_val)) {
|
|
571
|
+
++arrayDepth;
|
|
572
|
+
_val = _val[0];
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
const additionalNesting = schemaArrayDepth - arrayDepth;
|
|
576
|
+
while (arrayDepth < schemaArrayDepth) {
|
|
577
|
+
val = [val];
|
|
578
|
+
++arrayDepth;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
let tmp = schema.applySetters(Array.isArray(val) ? val : [val], context);
|
|
582
|
+
|
|
583
|
+
for (let i = 0; i < additionalNesting; ++i) {
|
|
584
|
+
tmp = tmp[0];
|
|
585
|
+
}
|
|
586
|
+
return tmp;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
if (op in noCastOps) {
|
|
590
|
+
return val;
|
|
591
|
+
}
|
|
592
|
+
if (op in numberOps) {
|
|
593
|
+
// Null and undefined not allowed for $pop, $inc
|
|
594
|
+
if (val == null) {
|
|
595
|
+
throw new CastError('number', val, schema.path);
|
|
596
|
+
}
|
|
597
|
+
if (op === '$inc') {
|
|
598
|
+
// Support `$inc` with long, int32, etc. (gh-4283)
|
|
599
|
+
return schema.castForQuery(
|
|
600
|
+
null,
|
|
601
|
+
val,
|
|
602
|
+
context
|
|
603
|
+
);
|
|
604
|
+
}
|
|
605
|
+
try {
|
|
606
|
+
return castNumber(val);
|
|
607
|
+
} catch {
|
|
608
|
+
throw new CastError('number', val, schema.path);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
if (op === '$currentDate') {
|
|
612
|
+
if (typeof val === 'object') {
|
|
613
|
+
return { $type: val.$type };
|
|
614
|
+
}
|
|
615
|
+
return Boolean(val);
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
if (mongodbUpdateOperators.has($conditional)) {
|
|
619
|
+
return schema.castForQuery(
|
|
620
|
+
$conditional,
|
|
621
|
+
val,
|
|
622
|
+
context
|
|
623
|
+
);
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
if (overwriteOps[op]) {
|
|
627
|
+
const skipQueryCastForUpdate = val != null
|
|
628
|
+
&& schema.$isMongooseArray
|
|
629
|
+
&& schema.$fullPath != null
|
|
630
|
+
&& !schema.$fullPath.match(/\d+$/);
|
|
631
|
+
const applySetters = schema[schemaMixedSymbol] != null;
|
|
632
|
+
if (skipQueryCastForUpdate || applySetters) {
|
|
633
|
+
return schema.applySetters(val, context);
|
|
634
|
+
}
|
|
635
|
+
return schema.castForQuery(
|
|
636
|
+
null,
|
|
637
|
+
val,
|
|
638
|
+
context
|
|
639
|
+
);
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
return schema.castForQuery(null, val, context);
|
|
643
|
+
}
|