Skip to content

Commit c97d91c

Browse files
committed
Merge branch '7.x'
2 parents 4d7f71d + 4a38517 commit c97d91c

27 files changed

+306
-148
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
7.6.7 / 2023-12-06
2+
==================
3+
* fix: avoid minimizing single nested subdocs if they are required #14151 #14058
4+
* fix(populate): allow deselecting discriminator key when populating #14155 #3230
5+
* fix: allow adding discriminators using Schema.prototype.discriminator() to subdocuments after defining parent schema #14131 #14109
6+
* fix(schema): avoid creating unnecessary clone of schematype in nested array so nested document arrays use correct constructor #14128 #14101
7+
* fix(populate): call transform object with single id instead of array when populating a justOne path under an array #14135 #14073
8+
* types: add back mistakenly removed findByIdAndRemove() function signature #14136 #14132
9+
110
8.0.2 / 2023-11-28
211
==================
312
* fix(populate): set populated docs in correct order when populating virtual underneath doc array with justOne #14105

docs/version-support.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ We ship all new bug fixes and features to 7.x.
1010

1111
## Mongoose 6
1212

13-
Mongoose 6.x (released August 24, 2021) is currently in legacy support.
14-
We will continue to ship bug fixes to Mongoose 6 until August 24, 2023.
15-
After August 24, 2023, we will only ship security fixes, and backport requested fixes to Mongoose 6.
13+
Mongoose 6.x (released August 24, 2021) is currently only receiving security fixes and requested bug fixes as of August 24, 2023.
1614
Please open a [bug report on GitHub](https://github.com/Automattic/mongoose/issues/new?assignees=&labels=&template=bug.yml) to request backporting a fix to Mongoose 6.
1715

1816
We are **not** actively backporting any new features from Mongoose 7 into Mongoose 6.

lib/document.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3691,8 +3691,7 @@ Document.prototype.$toObject = function(options, json) {
36913691
const schemaOptions = this.$__schema && this.$__schema.options || {};
36923692
// merge base default options with Schema's set default options if available.
36933693
// `clone` is necessary here because `utils.options` directly modifies the second input.
3694-
defaultOptions = utils.options(defaultOptions, clone(baseOptions));
3695-
defaultOptions = utils.options(defaultOptions, clone(schemaOptions[path] || {}));
3694+
defaultOptions = { ...defaultOptions, ...baseOptions, ...schemaOptions[path] };
36963695

36973696
// If options do not exist or is not an object, set it to empty object
36983697
options = utils.isPOJO(options) ? { ...options } : {};
@@ -3754,7 +3753,7 @@ Document.prototype.$toObject = function(options, json) {
37543753
}
37553754

37563755
// merge default options with input options.
3757-
options = utils.options(defaultOptions, options);
3756+
options = { ...defaultOptions, ...options };
37583757
options._isNested = true;
37593758
options.json = json;
37603759
options.minimize = _minimize;

lib/helpers/clone.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ function clone(obj, options, isArrayChild) {
5454
ret = obj.toObject(options);
5555
}
5656

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) {
5858
return undefined;
5959
}
6060

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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+
for (const disc of schemaType.schema._applyDiscriminators.keys()) {
20+
schemaType.discriminator(disc, schemaType.schema._applyDiscriminators.get(disc));
21+
}
22+
}
23+
}

lib/helpers/populate/assignVals.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@ module.exports = function assignVals(o) {
3939
const options = o.options;
4040
const count = o.count && o.isVirtual;
4141
let i;
42+
let setValueIndex = 0;
4243

4344
function setValue(val) {
45+
++setValueIndex;
4446
if (count) {
4547
return val;
4648
}
@@ -80,11 +82,14 @@ module.exports = function assignVals(o) {
8082
return valueFilter(val[0], options, populateOptions, _allIds);
8183
} else if (o.justOne === false && !Array.isArray(val)) {
8284
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]);
8387
}
8488
return valueFilter(val, options, populateOptions, _allIds);
8589
}
8690

8791
for (i = 0; i < docs.length; ++i) {
92+
setValueIndex = 0;
8893
const _path = o.path.endsWith('.$*') ? o.path.slice(0, -3) : o.path;
8994
const existingVal = mpath.get(_path, docs[i], lookupLocalFields);
9095
if (existingVal == null && !getVirtual(o.originalModel.schema, _path)) {

lib/helpers/projection/isExclusive.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,12 @@ module.exports = function isExclusive(projection) {
1212
}
1313

1414
const keys = Object.keys(projection);
15-
let ki = keys.length;
1615
let exclude = null;
1716

18-
if (ki === 1 && keys[0] === '_id') {
17+
if (keys.length === 1 && keys[0] === '_id') {
1918
exclude = !projection._id;
2019
} else {
21-
while (ki--) {
20+
for (let ki = 0; ki < keys.length; ++ki) {
2221
// Does this projection explicitly define inclusion/exclusion?
2322
// Explicitly avoid `$meta` and `$slice`
2423
const key = keys[ki];

lib/model.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4300,7 +4300,7 @@ function populate(model, docs, options, callback) {
43004300
select = select.replace(excludeIdRegGlobal, ' ');
43014301
} else {
43024302
// preserve original select conditions by copying
4303-
select = utils.object.shallowCopy(select);
4303+
select = { ...select };
43044304
delete select._id;
43054305
}
43064306
}

lib/mongoose.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const sanitizeFilter = require('./helpers/query/sanitizeFilter');
3030
const isBsonType = require('./helpers/isBsonType');
3131
const MongooseError = require('./error/mongooseError');
3232
const SetOptionError = require('./error/setOptionError');
33+
const applyEmbeddedDiscriminators = require('./helpers/discriminator/applyEmbeddedDiscriminators');
3334

3435
const defaultMongooseSymbol = Symbol.for('mongoose:default');
3536

@@ -627,6 +628,8 @@ Mongoose.prototype._model = function(name, schema, collection, options) {
627628
}
628629
}
629630

631+
applyEmbeddedDiscriminators(schema);
632+
630633
return model;
631634
};
632635

lib/query.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4791,16 +4791,14 @@ Query.prototype._castFields = function _castFields(fields) {
47914791
elemMatchKeys,
47924792
keys,
47934793
key,
4794-
out,
4795-
i;
4794+
out;
47964795

47974796
if (fields) {
47984797
keys = Object.keys(fields);
47994798
elemMatchKeys = [];
4800-
i = keys.length;
48014799

48024800
// collect $elemMatch args
4803-
while (i--) {
4801+
for (let i = 0; i < keys.length; ++i) {
48044802
key = keys[i];
48054803
if (fields[key].$elemMatch) {
48064804
selected || (selected = {});
@@ -4819,8 +4817,7 @@ Query.prototype._castFields = function _castFields(fields) {
48194817
}
48204818

48214819
// apply the casted field args
4822-
i = elemMatchKeys.length;
4823-
while (i--) {
4820+
for (let i = 0; i < elemMatchKeys.length; ++i) {
48244821
key = elemMatchKeys[i];
48254822
fields[key] = out[key];
48264823
}

0 commit comments

Comments
 (0)