mongoose 8.0.2 → 8.0.4
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/dist/browser.umd.js +1 -1
- package/lib/cursor/changeStream.js +0 -12
- package/lib/document.js +19 -6
- package/lib/helpers/clone.js +1 -1
- package/lib/helpers/discriminator/applyEmbeddedDiscriminators.js +30 -0
- package/lib/helpers/document/applyDefaults.js +3 -1
- package/lib/helpers/indexes/getRelatedIndexes.js +5 -1
- package/lib/helpers/model/castBulkWrite.js +8 -6
- package/lib/helpers/populate/assignVals.js +5 -0
- package/lib/helpers/projection/hasIncludedChildren.js +1 -0
- package/lib/helpers/projection/isExclusive.js +2 -3
- package/lib/helpers/projection/isNestedProjection.js +8 -0
- package/lib/helpers/query/castUpdate.js +5 -1
- package/lib/model.js +3 -1
- package/lib/mongoose.js +3 -0
- package/lib/query.js +11 -36
- package/lib/queryHelpers.js +3 -2
- package/lib/schema/array.js +2 -2
- package/lib/schema/bigint.js +11 -4
- package/lib/schema/boolean.js +9 -4
- package/lib/schema/buffer.js +21 -12
- package/lib/schema/date.js +15 -8
- package/lib/schema/decimal128.js +7 -8
- package/lib/schema/documentArray.js +1 -7
- package/lib/schema/number.js +22 -13
- package/lib/schema/objectId.js +7 -7
- package/lib/schema/string.js +11 -3
- package/lib/schema/subdocument.js +3 -7
- package/lib/schema/uuid.js +12 -5
- package/lib/schema.js +11 -9
- package/lib/schemaType.js +8 -1
- package/lib/types/subdocument.js +3 -3
- package/lib/utils.js +0 -33
- package/package.json +8 -8
- package/types/document.d.ts +2 -2
- package/types/index.d.ts +3 -0
- package/types/inferschematype.d.ts +13 -12
- package/types/models.d.ts +21 -12
- package/types/query.d.ts +57 -39
|
@@ -60,12 +60,6 @@ class ChangeStream extends EventEmitter {
|
|
|
60
60
|
|
|
61
61
|
driverChangeStreamEvents.forEach(ev => {
|
|
62
62
|
this.driverChangeStream.on(ev, data => {
|
|
63
|
-
// Sometimes Node driver still polls after close, so
|
|
64
|
-
// avoid any uncaught exceptions due to closed change streams
|
|
65
|
-
// See tests for gh-7022
|
|
66
|
-
if (ev === 'error' && this.closed) {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
63
|
if (data != null && data.fullDocument != null && this.options && this.options.hydrate) {
|
|
70
64
|
data.fullDocument = this.options.model.hydrate(data.fullDocument);
|
|
71
65
|
}
|
|
@@ -83,12 +77,6 @@ class ChangeStream extends EventEmitter {
|
|
|
83
77
|
|
|
84
78
|
driverChangeStreamEvents.forEach(ev => {
|
|
85
79
|
this.driverChangeStream.on(ev, data => {
|
|
86
|
-
// Sometimes Node driver still polls after close, so
|
|
87
|
-
// avoid any uncaught exceptions due to closed change streams
|
|
88
|
-
// See tests for gh-7022
|
|
89
|
-
if (ev === 'error' && this.closed) {
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
80
|
if (data != null && data.fullDocument != null && this.options && this.options.hydrate) {
|
|
93
81
|
data.fullDocument = this.options.model.hydrate(data.fullDocument);
|
|
94
82
|
}
|
package/lib/document.js
CHANGED
|
@@ -1122,6 +1122,8 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1122
1122
|
} else {
|
|
1123
1123
|
throw new StrictModeError(key);
|
|
1124
1124
|
}
|
|
1125
|
+
} else if (pathtype === 'nested' && valForKey == null) {
|
|
1126
|
+
this.$set(pathName, valForKey, constructing, options);
|
|
1125
1127
|
}
|
|
1126
1128
|
} else if (valForKey !== void 0) {
|
|
1127
1129
|
this.$set(pathName, valForKey, constructing, options);
|
|
@@ -2229,12 +2231,15 @@ Document.prototype[documentModifiedPaths] = Document.prototype.modifiedPaths;
|
|
|
2229
2231
|
* doc.isDirectModified('documents') // false
|
|
2230
2232
|
*
|
|
2231
2233
|
* @param {String} [path] optional
|
|
2234
|
+
* @param {Object} [options]
|
|
2235
|
+
* @param {Boolean} [options.ignoreAtomics=false] If true, doesn't return true if path is underneath an array that was modified with atomic operations like `push()`
|
|
2232
2236
|
* @return {Boolean}
|
|
2233
2237
|
* @api public
|
|
2234
2238
|
*/
|
|
2235
2239
|
|
|
2236
|
-
Document.prototype.isModified = function(paths, modifiedPaths) {
|
|
2240
|
+
Document.prototype.isModified = function(paths, options, modifiedPaths) {
|
|
2237
2241
|
if (paths) {
|
|
2242
|
+
const ignoreAtomics = options && options.ignoreAtomics;
|
|
2238
2243
|
const directModifiedPathsObj = this.$__.activePaths.states.modify;
|
|
2239
2244
|
if (directModifiedPathsObj == null) {
|
|
2240
2245
|
return false;
|
|
@@ -2255,7 +2260,16 @@ Document.prototype.isModified = function(paths, modifiedPaths) {
|
|
|
2255
2260
|
return !!~modified.indexOf(path);
|
|
2256
2261
|
});
|
|
2257
2262
|
|
|
2258
|
-
|
|
2263
|
+
let directModifiedPaths = Object.keys(directModifiedPathsObj);
|
|
2264
|
+
if (ignoreAtomics) {
|
|
2265
|
+
directModifiedPaths = directModifiedPaths.filter(path => {
|
|
2266
|
+
const value = this.$__getValue(path);
|
|
2267
|
+
if (value != null && value[arrayAtomicsSymbol] != null && value[arrayAtomicsSymbol].$set === undefined) {
|
|
2268
|
+
return false;
|
|
2269
|
+
}
|
|
2270
|
+
return true;
|
|
2271
|
+
});
|
|
2272
|
+
}
|
|
2259
2273
|
return isModifiedChild || paths.some(function(path) {
|
|
2260
2274
|
return directModifiedPaths.some(function(mod) {
|
|
2261
2275
|
return mod === path || path.startsWith(mod + '.');
|
|
@@ -2677,7 +2691,7 @@ function _getPathsToValidate(doc, pathsToValidate, pathsToSkip) {
|
|
|
2677
2691
|
paths.delete(fullPathToSubdoc + '.' + modifiedPath);
|
|
2678
2692
|
}
|
|
2679
2693
|
|
|
2680
|
-
if (doc.$isModified(fullPathToSubdoc, modifiedPaths) &&
|
|
2694
|
+
if (doc.$isModified(fullPathToSubdoc, null, modifiedPaths) &&
|
|
2681
2695
|
!doc.isDirectModified(fullPathToSubdoc) &&
|
|
2682
2696
|
!doc.$isDefault(fullPathToSubdoc)) {
|
|
2683
2697
|
paths.add(fullPathToSubdoc);
|
|
@@ -3691,8 +3705,7 @@ Document.prototype.$toObject = function(options, json) {
|
|
|
3691
3705
|
const schemaOptions = this.$__schema && this.$__schema.options || {};
|
|
3692
3706
|
// merge base default options with Schema's set default options if available.
|
|
3693
3707
|
// `clone` is necessary here because `utils.options` directly modifies the second input.
|
|
3694
|
-
defaultOptions =
|
|
3695
|
-
defaultOptions = utils.options(defaultOptions, clone(schemaOptions[path] || {}));
|
|
3708
|
+
defaultOptions = { ...defaultOptions, ...baseOptions, ...schemaOptions[path] };
|
|
3696
3709
|
|
|
3697
3710
|
// If options do not exist or is not an object, set it to empty object
|
|
3698
3711
|
options = utils.isPOJO(options) ? { ...options } : {};
|
|
@@ -3754,7 +3767,7 @@ Document.prototype.$toObject = function(options, json) {
|
|
|
3754
3767
|
}
|
|
3755
3768
|
|
|
3756
3769
|
// merge default options with input options.
|
|
3757
|
-
options =
|
|
3770
|
+
options = { ...defaultOptions, ...options };
|
|
3758
3771
|
options._isNested = true;
|
|
3759
3772
|
options.json = json;
|
|
3760
3773
|
options.minimize = _minimize;
|
package/lib/helpers/clone.js
CHANGED
|
@@ -54,7 +54,7 @@ function clone(obj, options, isArrayChild) {
|
|
|
54
54
|
ret = obj.toObject(options);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
if (options && options.minimize && isSingleNested && Object.keys(ret).length === 0) {
|
|
57
|
+
if (options && options.minimize && !obj.constructor.$__required && isSingleNested && Object.keys(ret).length === 0) {
|
|
58
58
|
return undefined;
|
|
59
59
|
}
|
|
60
60
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
module.exports = applyEmbeddedDiscriminators;
|
|
4
|
+
|
|
5
|
+
function applyEmbeddedDiscriminators(schema, seen = new WeakSet()) {
|
|
6
|
+
if (seen.has(schema)) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
seen.add(schema);
|
|
10
|
+
for (const path of Object.keys(schema.paths)) {
|
|
11
|
+
const schemaType = schema.paths[path];
|
|
12
|
+
if (!schemaType.schema) {
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
applyEmbeddedDiscriminators(schemaType.schema, seen);
|
|
16
|
+
if (!schemaType.schema._applyDiscriminators) {
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
if (schemaType._appliedDiscriminators) {
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
for (const disc of schemaType.schema._applyDiscriminators.keys()) {
|
|
23
|
+
schemaType.discriminator(
|
|
24
|
+
disc,
|
|
25
|
+
schemaType.schema._applyDiscriminators.get(disc)
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
schemaType._appliedDiscriminators = true;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const isNestedProjection = require('../projection/isNestedProjection');
|
|
4
|
+
|
|
3
5
|
module.exports = function applyDefaults(doc, fields, exclude, hasIncludedChildren, isBeforeSetters, pathsToSkip) {
|
|
4
6
|
const paths = Object.keys(doc.$__schema.paths);
|
|
5
7
|
const plen = paths.length;
|
|
@@ -32,7 +34,7 @@ module.exports = function applyDefaults(doc, fields, exclude, hasIncludedChildre
|
|
|
32
34
|
}
|
|
33
35
|
} else if (exclude === false && fields && !included) {
|
|
34
36
|
const hasSubpaths = type.$isSingleNested || type.$isMongooseDocumentArray;
|
|
35
|
-
if (curPath in fields || (j === len - 1 && hasSubpaths && hasIncludedChildren != null && hasIncludedChildren[curPath])) {
|
|
37
|
+
if ((curPath in fields && !isNestedProjection(fields[curPath])) || (j === len - 1 && hasSubpaths && hasIncludedChildren != null && hasIncludedChildren[curPath])) {
|
|
36
38
|
included = true;
|
|
37
39
|
} else if (hasIncludedChildren != null && !hasIncludedChildren[curPath]) {
|
|
38
40
|
break;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const hasDollarKeys = require('../query/hasDollarKeys');
|
|
4
|
+
|
|
3
5
|
function getRelatedSchemaIndexes(model, schemaIndexes) {
|
|
4
6
|
return getRelatedIndexes({
|
|
5
7
|
baseModelName: model.baseModelName,
|
|
@@ -46,7 +48,9 @@ function getRelatedIndexes({
|
|
|
46
48
|
|
|
47
49
|
return indexes.filter(index => {
|
|
48
50
|
const partialFilterExpression = getPartialFilterExpression(index, indexesType);
|
|
49
|
-
return !partialFilterExpression
|
|
51
|
+
return !partialFilterExpression
|
|
52
|
+
|| !partialFilterExpression[discriminatorKey]
|
|
53
|
+
|| (hasDollarKeys(partialFilterExpression[discriminatorKey]) && !('$eq' in partialFilterExpression[discriminatorKey]));
|
|
50
54
|
});
|
|
51
55
|
}
|
|
52
56
|
|
|
@@ -6,6 +6,7 @@ const applyTimestampsToChildren = require('../update/applyTimestampsToChildren')
|
|
|
6
6
|
const applyTimestampsToUpdate = require('../update/applyTimestampsToUpdate');
|
|
7
7
|
const cast = require('../../cast');
|
|
8
8
|
const castUpdate = require('../query/castUpdate');
|
|
9
|
+
const clone = require('../clone');
|
|
9
10
|
const decorateUpdateWithVersionKey = require('../update/decorateUpdateWithVersionKey');
|
|
10
11
|
const { inspect } = require('util');
|
|
11
12
|
const setDefaultsOnInsert = require('../setDefaultsOnInsert');
|
|
@@ -64,30 +65,32 @@ module.exports = function castBulkWrite(originalModel, op, options) {
|
|
|
64
65
|
const schema = model.schema;
|
|
65
66
|
const strict = options.strict != null ? options.strict : model.schema.options.strict;
|
|
66
67
|
|
|
68
|
+
const update = clone(op['updateOne']['update']);
|
|
69
|
+
|
|
67
70
|
_addDiscriminatorToObject(schema, op['updateOne']['filter']);
|
|
68
71
|
|
|
69
72
|
if (model.schema.$timestamps != null && op['updateOne'].timestamps !== false) {
|
|
70
73
|
const createdAt = model.schema.$timestamps.createdAt;
|
|
71
74
|
const updatedAt = model.schema.$timestamps.updatedAt;
|
|
72
|
-
applyTimestampsToUpdate(now, createdAt, updatedAt,
|
|
75
|
+
applyTimestampsToUpdate(now, createdAt, updatedAt, update, {});
|
|
73
76
|
}
|
|
74
77
|
|
|
75
78
|
if (op['updateOne'].timestamps !== false) {
|
|
76
|
-
applyTimestampsToChildren(now,
|
|
79
|
+
applyTimestampsToChildren(now, update, model.schema);
|
|
77
80
|
}
|
|
78
81
|
|
|
79
82
|
const shouldSetDefaultsOnInsert = op['updateOne'].setDefaultsOnInsert == null ?
|
|
80
83
|
globalSetDefaultsOnInsert :
|
|
81
84
|
op['updateOne'].setDefaultsOnInsert;
|
|
82
85
|
if (shouldSetDefaultsOnInsert !== false) {
|
|
83
|
-
setDefaultsOnInsert(op['updateOne']['filter'], model.schema,
|
|
86
|
+
setDefaultsOnInsert(op['updateOne']['filter'], model.schema, update, {
|
|
84
87
|
setDefaultsOnInsert: true,
|
|
85
88
|
upsert: op['updateOne'].upsert
|
|
86
89
|
});
|
|
87
90
|
}
|
|
88
91
|
|
|
89
92
|
decorateUpdateWithVersionKey(
|
|
90
|
-
|
|
93
|
+
update,
|
|
91
94
|
op['updateOne'],
|
|
92
95
|
model.schema.options.versionKey
|
|
93
96
|
);
|
|
@@ -96,8 +99,7 @@ module.exports = function castBulkWrite(originalModel, op, options) {
|
|
|
96
99
|
strict: strict,
|
|
97
100
|
upsert: op['updateOne'].upsert
|
|
98
101
|
});
|
|
99
|
-
|
|
100
|
-
op['updateOne']['update'] = castUpdate(model.schema, op['updateOne']['update'], {
|
|
102
|
+
op['updateOne']['update'] = castUpdate(model.schema, update, {
|
|
101
103
|
strict: strict,
|
|
102
104
|
upsert: op['updateOne'].upsert
|
|
103
105
|
}, model, op['updateOne']['filter']);
|
|
@@ -39,8 +39,10 @@ module.exports = function assignVals(o) {
|
|
|
39
39
|
const options = o.options;
|
|
40
40
|
const count = o.count && o.isVirtual;
|
|
41
41
|
let i;
|
|
42
|
+
let setValueIndex = 0;
|
|
42
43
|
|
|
43
44
|
function setValue(val) {
|
|
45
|
+
++setValueIndex;
|
|
44
46
|
if (count) {
|
|
45
47
|
return val;
|
|
46
48
|
}
|
|
@@ -80,11 +82,14 @@ module.exports = function assignVals(o) {
|
|
|
80
82
|
return valueFilter(val[0], options, populateOptions, _allIds);
|
|
81
83
|
} else if (o.justOne === false && !Array.isArray(val)) {
|
|
82
84
|
return valueFilter([val], options, populateOptions, _allIds);
|
|
85
|
+
} else if (o.justOne === true && !Array.isArray(val) && Array.isArray(_allIds)) {
|
|
86
|
+
return valueFilter(val, options, populateOptions, val == null ? val : _allIds[setValueIndex - 1]);
|
|
83
87
|
}
|
|
84
88
|
return valueFilter(val, options, populateOptions, _allIds);
|
|
85
89
|
}
|
|
86
90
|
|
|
87
91
|
for (i = 0; i < docs.length; ++i) {
|
|
92
|
+
setValueIndex = 0;
|
|
88
93
|
const _path = o.path.endsWith('.$*') ? o.path.slice(0, -3) : o.path;
|
|
89
94
|
const existingVal = mpath.get(_path, docs[i], lookupLocalFields);
|
|
90
95
|
if (existingVal == null && !getVirtual(o.originalModel.schema, _path)) {
|
|
@@ -12,13 +12,12 @@ module.exports = function isExclusive(projection) {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
const keys = Object.keys(projection);
|
|
15
|
-
let ki = keys.length;
|
|
16
15
|
let exclude = null;
|
|
17
16
|
|
|
18
|
-
if (
|
|
17
|
+
if (keys.length === 1 && keys[0] === '_id') {
|
|
19
18
|
exclude = !projection._id;
|
|
20
19
|
} else {
|
|
21
|
-
|
|
20
|
+
for (let ki = 0; ki < keys.length; ++ki) {
|
|
22
21
|
// Does this projection explicitly define inclusion/exclusion?
|
|
23
22
|
// Explicitly avoid `$meta` and `$slice`
|
|
24
23
|
const key = keys[ki];
|
|
@@ -13,6 +13,7 @@ const moveImmutableProperties = require('../update/moveImmutableProperties');
|
|
|
13
13
|
const schemaMixedSymbol = require('../../schema/symbols').schemaMixedSymbol;
|
|
14
14
|
const setDottedPath = require('../path/setDottedPath');
|
|
15
15
|
const utils = require('../../utils');
|
|
16
|
+
const { internalToObjectOptions } = require('../../options');
|
|
16
17
|
|
|
17
18
|
const mongodbUpdateOperators = new Set([
|
|
18
19
|
'$currentDate',
|
|
@@ -99,7 +100,10 @@ module.exports = function castUpdate(schema, obj, options, context, filter) {
|
|
|
99
100
|
const op = ops[i];
|
|
100
101
|
val = ret[op];
|
|
101
102
|
hasDollarKey = hasDollarKey || op.startsWith('$');
|
|
102
|
-
|
|
103
|
+
if (val != null && val.$__) {
|
|
104
|
+
val = val.toObject(internalToObjectOptions);
|
|
105
|
+
ret[op] = val;
|
|
106
|
+
}
|
|
103
107
|
if (val &&
|
|
104
108
|
typeof val === 'object' &&
|
|
105
109
|
!Buffer.isBuffer(val) &&
|
package/lib/model.js
CHANGED
|
@@ -4298,9 +4298,11 @@ function populate(model, docs, options, callback) {
|
|
|
4298
4298
|
// _id back off before returning the result.
|
|
4299
4299
|
if (typeof select === 'string') {
|
|
4300
4300
|
select = select.replace(excludeIdRegGlobal, ' ');
|
|
4301
|
+
} else if (Array.isArray(select)) {
|
|
4302
|
+
select = select.filter(field => field !== '-_id');
|
|
4301
4303
|
} else {
|
|
4302
4304
|
// preserve original select conditions by copying
|
|
4303
|
-
select =
|
|
4305
|
+
select = { ...select };
|
|
4304
4306
|
delete select._id;
|
|
4305
4307
|
}
|
|
4306
4308
|
}
|
package/lib/mongoose.js
CHANGED
|
@@ -30,6 +30,7 @@ const sanitizeFilter = require('./helpers/query/sanitizeFilter');
|
|
|
30
30
|
const isBsonType = require('./helpers/isBsonType');
|
|
31
31
|
const MongooseError = require('./error/mongooseError');
|
|
32
32
|
const SetOptionError = require('./error/setOptionError');
|
|
33
|
+
const applyEmbeddedDiscriminators = require('./helpers/discriminator/applyEmbeddedDiscriminators');
|
|
33
34
|
|
|
34
35
|
const defaultMongooseSymbol = Symbol.for('mongoose:default');
|
|
35
36
|
|
|
@@ -627,6 +628,8 @@ Mongoose.prototype._model = function(name, schema, collection, options) {
|
|
|
627
628
|
}
|
|
628
629
|
}
|
|
629
630
|
|
|
631
|
+
applyEmbeddedDiscriminators(schema);
|
|
632
|
+
|
|
630
633
|
return model;
|
|
631
634
|
};
|
|
632
635
|
|
package/lib/query.js
CHANGED
|
@@ -2498,12 +2498,12 @@ Query.prototype._findOne = async function _findOne() {
|
|
|
2498
2498
|
// don't pass in the conditions because we already merged them in
|
|
2499
2499
|
const doc = await this.mongooseCollection.findOne(this._conditions, options);
|
|
2500
2500
|
return new Promise((resolve, reject) => {
|
|
2501
|
-
this._completeOne(doc, null,
|
|
2501
|
+
this._completeOne(doc, null, (err, res) => {
|
|
2502
2502
|
if (err) {
|
|
2503
2503
|
return reject(err);
|
|
2504
2504
|
}
|
|
2505
2505
|
resolve(res);
|
|
2506
|
-
})
|
|
2506
|
+
});
|
|
2507
2507
|
});
|
|
2508
2508
|
};
|
|
2509
2509
|
|
|
@@ -3303,12 +3303,12 @@ Query.prototype._findOneAndUpdate = async function _findOneAndUpdate() {
|
|
|
3303
3303
|
const doc = !options.includeResultMetadata ? res : res.value;
|
|
3304
3304
|
|
|
3305
3305
|
return new Promise((resolve, reject) => {
|
|
3306
|
-
this._completeOne(doc, res,
|
|
3306
|
+
this._completeOne(doc, res, (err, res) => {
|
|
3307
3307
|
if (err) {
|
|
3308
3308
|
return reject(err);
|
|
3309
3309
|
}
|
|
3310
3310
|
resolve(res);
|
|
3311
|
-
})
|
|
3311
|
+
});
|
|
3312
3312
|
});
|
|
3313
3313
|
};
|
|
3314
3314
|
|
|
@@ -3399,12 +3399,12 @@ Query.prototype._findOneAndDelete = async function _findOneAndDelete() {
|
|
|
3399
3399
|
const doc = !includeResultMetadata ? res : res.value;
|
|
3400
3400
|
|
|
3401
3401
|
return new Promise((resolve, reject) => {
|
|
3402
|
-
this._completeOne(doc, res,
|
|
3402
|
+
this._completeOne(doc, res, (err, res) => {
|
|
3403
3403
|
if (err) {
|
|
3404
3404
|
return reject(err);
|
|
3405
3405
|
}
|
|
3406
3406
|
resolve(res);
|
|
3407
|
-
})
|
|
3407
|
+
});
|
|
3408
3408
|
});
|
|
3409
3409
|
};
|
|
3410
3410
|
|
|
@@ -3553,12 +3553,12 @@ Query.prototype._findOneAndReplace = async function _findOneAndReplace() {
|
|
|
3553
3553
|
|
|
3554
3554
|
const doc = !includeResultMetadata ? res : res.value;
|
|
3555
3555
|
return new Promise((resolve, reject) => {
|
|
3556
|
-
this._completeOne(doc, res,
|
|
3556
|
+
this._completeOne(doc, res, (err, res) => {
|
|
3557
3557
|
if (err) {
|
|
3558
3558
|
return reject(err);
|
|
3559
3559
|
}
|
|
3560
3560
|
resolve(res);
|
|
3561
|
-
})
|
|
3561
|
+
});
|
|
3562
3562
|
});
|
|
3563
3563
|
};
|
|
3564
3564
|
|
|
@@ -4382,28 +4382,6 @@ function _executePreHooks(query, op) {
|
|
|
4382
4382
|
});
|
|
4383
4383
|
}
|
|
4384
4384
|
|
|
4385
|
-
/*!
|
|
4386
|
-
* ignore
|
|
4387
|
-
*/
|
|
4388
|
-
|
|
4389
|
-
function _wrapThunkCallback(query, cb) {
|
|
4390
|
-
return function(error, res) {
|
|
4391
|
-
if (error != null) {
|
|
4392
|
-
return cb(error);
|
|
4393
|
-
}
|
|
4394
|
-
|
|
4395
|
-
for (const fn of query._transforms) {
|
|
4396
|
-
try {
|
|
4397
|
-
res = fn(res);
|
|
4398
|
-
} catch (error) {
|
|
4399
|
-
return cb(error);
|
|
4400
|
-
}
|
|
4401
|
-
}
|
|
4402
|
-
|
|
4403
|
-
return cb(null, res);
|
|
4404
|
-
};
|
|
4405
|
-
}
|
|
4406
|
-
|
|
4407
4385
|
/**
|
|
4408
4386
|
* Executes the query returning a `Promise` which will be
|
|
4409
4387
|
* resolved with either the doc(s) or rejected with the error.
|
|
@@ -4791,16 +4769,14 @@ Query.prototype._castFields = function _castFields(fields) {
|
|
|
4791
4769
|
elemMatchKeys,
|
|
4792
4770
|
keys,
|
|
4793
4771
|
key,
|
|
4794
|
-
out
|
|
4795
|
-
i;
|
|
4772
|
+
out;
|
|
4796
4773
|
|
|
4797
4774
|
if (fields) {
|
|
4798
4775
|
keys = Object.keys(fields);
|
|
4799
4776
|
elemMatchKeys = [];
|
|
4800
|
-
i = keys.length;
|
|
4801
4777
|
|
|
4802
4778
|
// collect $elemMatch args
|
|
4803
|
-
|
|
4779
|
+
for (let i = 0; i < keys.length; ++i) {
|
|
4804
4780
|
key = keys[i];
|
|
4805
4781
|
if (fields[key].$elemMatch) {
|
|
4806
4782
|
selected || (selected = {});
|
|
@@ -4819,8 +4795,7 @@ Query.prototype._castFields = function _castFields(fields) {
|
|
|
4819
4795
|
}
|
|
4820
4796
|
|
|
4821
4797
|
// apply the casted field args
|
|
4822
|
-
i = elemMatchKeys.length;
|
|
4823
|
-
while (i--) {
|
|
4798
|
+
for (let i = 0; i < elemMatchKeys.length; ++i) {
|
|
4824
4799
|
key = elemMatchKeys[i];
|
|
4825
4800
|
fields[key] = out[key];
|
|
4826
4801
|
}
|
package/lib/queryHelpers.js
CHANGED
|
@@ -180,11 +180,12 @@ exports.applyPaths = function applyPaths(fields, schema) {
|
|
|
180
180
|
if (!isDefiningProjection(field)) {
|
|
181
181
|
continue;
|
|
182
182
|
}
|
|
183
|
-
// `_id: 1, name: 0` is a mixed inclusive/exclusive projection in
|
|
184
|
-
// MongoDB 4.0 and earlier, but not in later versions.
|
|
185
183
|
if (keys[keyIndex] === '_id' && keys.length > 1) {
|
|
186
184
|
continue;
|
|
187
185
|
}
|
|
186
|
+
if (keys[keyIndex] === schema.options.discriminatorKey && keys.length > 1 && field != null && !field) {
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
188
189
|
exclude = !field;
|
|
189
190
|
break;
|
|
190
191
|
}
|
package/lib/schema/array.js
CHANGED
|
@@ -638,14 +638,14 @@ handle.$and = createLogicalQueryOperatorHandler('$and');
|
|
|
638
638
|
handle.$nor = createLogicalQueryOperatorHandler('$nor');
|
|
639
639
|
|
|
640
640
|
function createLogicalQueryOperatorHandler(op) {
|
|
641
|
-
return function logicalQueryOperatorHandler(val) {
|
|
641
|
+
return function logicalQueryOperatorHandler(val, context) {
|
|
642
642
|
if (!Array.isArray(val)) {
|
|
643
643
|
throw new TypeError('conditional ' + op + ' requires an array');
|
|
644
644
|
}
|
|
645
645
|
|
|
646
646
|
const ret = [];
|
|
647
647
|
for (const obj of val) {
|
|
648
|
-
ret.push(cast(this.casterConstructor.schema, obj, null, this && this.$$context));
|
|
648
|
+
ret.push(cast(this.casterConstructor.schema ?? context.schema, obj, null, this && this.$$context));
|
|
649
649
|
}
|
|
650
650
|
|
|
651
651
|
return ret;
|
package/lib/schema/bigint.js
CHANGED
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
const CastError = require('../error/cast');
|
|
8
8
|
const SchemaType = require('../schemaType');
|
|
9
9
|
const castBigInt = require('../cast/bigint');
|
|
10
|
-
const utils = require('../utils');
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* BigInt SchemaType constructor.
|
|
@@ -177,12 +176,13 @@ SchemaBigInt.prototype.cast = function(value) {
|
|
|
177
176
|
* ignore
|
|
178
177
|
*/
|
|
179
178
|
|
|
180
|
-
SchemaBigInt.$conditionalHandlers =
|
|
179
|
+
SchemaBigInt.$conditionalHandlers = {
|
|
180
|
+
...SchemaType.prototype.$conditionalHandlers,
|
|
181
181
|
$gt: handleSingle,
|
|
182
182
|
$gte: handleSingle,
|
|
183
183
|
$lt: handleSingle,
|
|
184
184
|
$lte: handleSingle
|
|
185
|
-
}
|
|
185
|
+
};
|
|
186
186
|
|
|
187
187
|
/*!
|
|
188
188
|
* ignore
|
|
@@ -212,7 +212,14 @@ SchemaBigInt.prototype.castForQuery = function($conditional, val, context) {
|
|
|
212
212
|
return this.applySetters(null, val, context);
|
|
213
213
|
}
|
|
214
214
|
|
|
215
|
-
|
|
215
|
+
try {
|
|
216
|
+
return this.applySetters(val, context);
|
|
217
|
+
} catch (err) {
|
|
218
|
+
if (err instanceof CastError && err.path === this.path && this.$fullPath != null) {
|
|
219
|
+
err.path = this.$fullPath;
|
|
220
|
+
}
|
|
221
|
+
throw err;
|
|
222
|
+
}
|
|
216
223
|
};
|
|
217
224
|
|
|
218
225
|
/**
|
package/lib/schema/boolean.js
CHANGED
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
const CastError = require('../error/cast');
|
|
8
8
|
const SchemaType = require('../schemaType');
|
|
9
9
|
const castBoolean = require('../cast/boolean');
|
|
10
|
-
const utils = require('../utils');
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* Boolean SchemaType constructor.
|
|
@@ -235,8 +234,7 @@ SchemaBoolean.prototype.cast = function(value) {
|
|
|
235
234
|
}
|
|
236
235
|
};
|
|
237
236
|
|
|
238
|
-
SchemaBoolean.$conditionalHandlers =
|
|
239
|
-
utils.options(SchemaType.prototype.$conditionalHandlers, {});
|
|
237
|
+
SchemaBoolean.$conditionalHandlers = { ...SchemaType.prototype.$conditionalHandlers };
|
|
240
238
|
|
|
241
239
|
/**
|
|
242
240
|
* Casts contents for queries.
|
|
@@ -258,7 +256,14 @@ SchemaBoolean.prototype.castForQuery = function($conditional, val, context) {
|
|
|
258
256
|
return this.applySetters(null, val, context);
|
|
259
257
|
}
|
|
260
258
|
|
|
261
|
-
|
|
259
|
+
try {
|
|
260
|
+
return this.applySetters(val, context);
|
|
261
|
+
} catch (err) {
|
|
262
|
+
if (err instanceof CastError && err.path === this.path && this.$fullPath != null) {
|
|
263
|
+
err.path = this.$fullPath;
|
|
264
|
+
}
|
|
265
|
+
throw err;
|
|
266
|
+
}
|
|
262
267
|
};
|
|
263
268
|
|
|
264
269
|
/**
|
package/lib/schema/buffer.js
CHANGED
|
@@ -250,17 +250,17 @@ function handleSingle(val, context) {
|
|
|
250
250
|
return this.castForQuery(null, val, context);
|
|
251
251
|
}
|
|
252
252
|
|
|
253
|
-
SchemaBuffer.prototype.$conditionalHandlers =
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
253
|
+
SchemaBuffer.prototype.$conditionalHandlers = {
|
|
254
|
+
...SchemaType.prototype.$conditionalHandlers,
|
|
255
|
+
$bitsAllClear: handleBitwiseOperator,
|
|
256
|
+
$bitsAnyClear: handleBitwiseOperator,
|
|
257
|
+
$bitsAllSet: handleBitwiseOperator,
|
|
258
|
+
$bitsAnySet: handleBitwiseOperator,
|
|
259
|
+
$gt: handleSingle,
|
|
260
|
+
$gte: handleSingle,
|
|
261
|
+
$lt: handleSingle,
|
|
262
|
+
$lte: handleSingle
|
|
263
|
+
};
|
|
264
264
|
|
|
265
265
|
/**
|
|
266
266
|
* Casts contents for queries.
|
|
@@ -279,7 +279,16 @@ SchemaBuffer.prototype.castForQuery = function($conditional, val, context) {
|
|
|
279
279
|
}
|
|
280
280
|
return handler.call(this, val);
|
|
281
281
|
}
|
|
282
|
-
|
|
282
|
+
|
|
283
|
+
let casted;
|
|
284
|
+
try {
|
|
285
|
+
casted = this.applySetters(val, context);
|
|
286
|
+
} catch (err) {
|
|
287
|
+
if (err instanceof CastError && err.path === this.path && this.$fullPath != null) {
|
|
288
|
+
err.path = this.$fullPath;
|
|
289
|
+
}
|
|
290
|
+
throw err;
|
|
291
|
+
}
|
|
283
292
|
return casted ? casted.toObject({ transform: false, virtuals: false }) : casted;
|
|
284
293
|
};
|
|
285
294
|
|
package/lib/schema/date.js
CHANGED
|
@@ -388,13 +388,13 @@ function handleSingle(val) {
|
|
|
388
388
|
return this.cast(val);
|
|
389
389
|
}
|
|
390
390
|
|
|
391
|
-
SchemaDate.prototype.$conditionalHandlers =
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
391
|
+
SchemaDate.prototype.$conditionalHandlers = {
|
|
392
|
+
...SchemaType.prototype.$conditionalHandlers,
|
|
393
|
+
$gt: handleSingle,
|
|
394
|
+
$gte: handleSingle,
|
|
395
|
+
$lt: handleSingle,
|
|
396
|
+
$lte: handleSingle
|
|
397
|
+
};
|
|
398
398
|
|
|
399
399
|
|
|
400
400
|
/**
|
|
@@ -407,7 +407,14 @@ SchemaDate.prototype.$conditionalHandlers =
|
|
|
407
407
|
|
|
408
408
|
SchemaDate.prototype.castForQuery = function($conditional, val, context) {
|
|
409
409
|
if ($conditional == null) {
|
|
410
|
-
|
|
410
|
+
try {
|
|
411
|
+
return this.applySetters(val, context);
|
|
412
|
+
} catch (err) {
|
|
413
|
+
if (err instanceof CastError && err.path === this.path && this.$fullPath != null) {
|
|
414
|
+
err.path = this.$fullPath;
|
|
415
|
+
}
|
|
416
|
+
throw err;
|
|
417
|
+
}
|
|
411
418
|
}
|
|
412
419
|
|
|
413
420
|
const handler = this.$conditionalHandlers[$conditional];
|