Skip to content

Commit c41f32c

Browse files
committed
Merge branch 'master' into 8.11
2 parents be82200 + 1a2faa7 commit c41f32c

File tree

7 files changed

+59
-10
lines changed

7 files changed

+59
-10
lines changed

CHANGELOG.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,6 @@
123123
* fix: disallow using $where in match
124124
* perf: cache results from getAllSubdocs() on saveOptions, only loop through known subdoc properties #15055 #15029
125125
* fix(model+query): support overwriteDiscriminatorKey for bulkWrite updateOne and updateMany, allow inferring discriminator key from update #15046 #15040
126-
=======
127-
>>>>>>> 7.x
128126

129127
7.8.3 / 2024-11-26
130128
==================

docs/typescript/subdocuments.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,11 @@ Define a separate `THydratedDocumentType` and pass it as the 5th generic param t
3838
`THydratedDocumentType` controls what type Mongoose uses for "hydrated documents", that is, what `await UserModel.findOne()`, `UserModel.hydrate()`, and `new UserModel()` return.
3939

4040
```ts
41+
import { HydratedSingleSubdocument } from 'mongoose';
42+
4143
// Define property overrides for hydrated documents
4244
type THydratedUserDocument = {
43-
names?: mongoose.Types.Subdocument<Names>
45+
names?: HydratedSingleSubdocument<Names>
4446
}
4547
type UserModelType = mongoose.Model<User, {}, {}, {}, THydratedUserDocument>;
4648

@@ -51,6 +53,7 @@ const UserModel = mongoose.model<User, UserModelType>('User', userSchema);
5153

5254
const doc = new UserModel({ names: { _id: '0'.repeat(24), firstName: 'foo' } });
5355
doc.names!.ownerDocument(); // Works, `names` is a subdocument!
56+
doc.names!.firstName; // 'foo'
5457
```
5558

5659
## Subdocument Arrays
@@ -81,4 +84,5 @@ const UserModel = model<User, UserModelType>('User', new Schema<User, UserModelT
8184

8285
const doc = new UserModel({});
8386
doc.names[0].ownerDocument(); // Works!
87+
doc.names[0].firstName; // string
8488
```

lib/helpers/query/castUpdate.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,16 @@ module.exports = function castUpdate(schema, obj, options, context, filter) {
8282
schema = schema.discriminators[discriminatorValue] ||
8383
(byValue && byValue.schema) ||
8484
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 && byValue.schema) ||
94+
schema;
8595
}
8696

8797
if (options.upsert) {

test/model.test.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4174,7 +4174,7 @@ describe('Model', function() {
41744174
assert.strictEqual(r2.testArray[0].nonexistentProp, undefined);
41754175
});
41764176

4177-
it('handles overwriteDiscriminatorKey (gh-15040)', async function() {
4177+
it('handles overwriteDiscriminatorKey (gh-15218) (gh-15040)', async function() {
41784178
const dSchema1 = new mongoose.Schema({
41794179
field1: String
41804180
});
@@ -4202,7 +4202,7 @@ describe('Model', function() {
42024202
assert.equal(r1.field1, 'field1');
42034203
assert.equal(r1.key, type1Key);
42044204

4205-
const field2 = 'field2';
4205+
let field2 = 'field2';
42064206
await TestModel.bulkWrite([{
42074207
updateOne: {
42084208
filter: { _id: r1._id },
@@ -4214,7 +4214,13 @@ describe('Model', function() {
42144214
}
42154215
}]);
42164216

4217-
const r2 = await TestModel.findById(r1._id);
4217+
let r2 = await TestModel.findById(r1._id);
4218+
assert.equal(r2.key, type2Key);
4219+
assert.equal(r2.field2, field2);
4220+
4221+
field2 = 'field2 updated again';
4222+
await TestModel.updateOne({ _id: r1._id }, { $set: { key: type2Key, field2 } }, { overwriteDiscriminatorKey: true });
4223+
r2 = await TestModel.findById(r1._id);
42184224
assert.equal(r2.key, type2Key);
42194225
assert.equal(r2.field2, field2);
42204226
});

test/schema.number.test.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use strict';
22

3+
const assert = require('assert');
34
const start = require('./common');
45

56
const mongoose = start.mongoose;
@@ -18,4 +19,26 @@ describe('SchemaNumber', function() {
1819
});
1920
});
2021
});
22+
23+
it('allows calling `min()` with no message arg (gh-15236)', async function() {
24+
const schema = new Schema({ x: { type: Number } });
25+
schema.path('x').min(0);
26+
27+
const err = await new Promise((resolve) => {
28+
schema.path('x').doValidate(-1, err => {
29+
resolve(err);
30+
});
31+
});
32+
assert.ok(err);
33+
assert.equal(err.message, 'Path `x` (-1) is less than minimum allowed value (0).');
34+
35+
schema.path('x').min(0, 'Invalid value!');
36+
37+
const err2 = await new Promise((resolve) => {
38+
schema.path('x').doValidate(-1, err => {
39+
resolve(err);
40+
});
41+
});
42+
assert.equal(err2.message, 'Invalid value!');
43+
});
2144
});

test/types/schema.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1725,3 +1725,11 @@ async function gh12959() {
17251725
const leanDoc = await TestModel.findOne().lean().orFail();
17261726
expectType<number>(leanDoc.__v);
17271727
}
1728+
1729+
async function gh15236() {
1730+
const schema = new Schema({
1731+
myNum: { type: Number }
1732+
});
1733+
1734+
schema.path<Schema.Types.Number>('myNum').min(0);
1735+
}

types/schematypes.d.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -389,10 +389,10 @@ declare module 'mongoose' {
389389
expires(when: number | string): this;
390390

391391
/** Sets a maximum date validator. */
392-
max(value: NativeDate, message: string): this;
392+
max(value: NativeDate, message?: string): this;
393393

394394
/** Sets a minimum date validator. */
395-
min(value: NativeDate, message: string): this;
395+
min(value: NativeDate, message?: string): this;
396396

397397
/** Default options for this SchemaType */
398398
defaultOptions: Record<string, any>;
@@ -457,10 +457,10 @@ declare module 'mongoose' {
457457
enum(vals: number[]): this;
458458

459459
/** Sets a maximum number validator. */
460-
max(value: number, message: string): this;
460+
max(value: number, message?: string): this;
461461

462462
/** Sets a minimum number validator. */
463-
min(value: number, message: string): this;
463+
min(value: number, message?: string): this;
464464

465465
/** Default options for this SchemaType */
466466
defaultOptions: Record<string, any>;

0 commit comments

Comments
 (0)