Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8.0 #13937

Merged
merged 123 commits into from
Oct 24, 2023
Merged

8.0 #13937

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
123 commits
Select commit Hold shift + click to select a range
61e9041
made the changes but some failing tests
IslandRhythms Jul 17, 2023
d9fd789
Merge branch 'IslandRhythms/gh-13369' of github.com:Automattic/mongoo…
vkarpov15 Jul 17, 2023
5954b30
remove `count()`
IslandRhythms Jul 18, 2023
c507968
allow null values for enum
IslandRhythms Jul 18, 2023
886c941
fix:lint
IslandRhythms Jul 18, 2023
66c4a8e
throw error after all the saves are done
IslandRhythms Jul 18, 2023
1e3c96f
fix:lint
IslandRhythms Jul 18, 2023
363f2aa
remove count from one more spot
vkarpov15 Jul 18, 2023
760c187
Update schema.validation.test.js
vkarpov15 Jul 18, 2023
1a69e7c
Merge pull request #13618 from Automattic/IslandRhythms/gh-13598
vkarpov15 Jul 18, 2023
fffa85d
Merge pull request #13620 from Automattic/IslandRhythms/gh-3044
vkarpov15 Jul 18, 2023
6254c9c
made adjustments
IslandRhythms Jul 19, 2023
2798cfd
Merge pull request #13621 from Automattic/IslandRhythms/4628
vkarpov15 Jul 19, 2023
dd56c53
feat: change all symbols to use a consistent name
hasezoey Jul 21, 2023
cdad34b
Merge pull request #13641 from hasezoey/8consistentSymbol
vkarpov15 Jul 25, 2023
92876b5
Merge branch 'master' into 8.0
vkarpov15 Jul 26, 2023
df6ad8e
Merge branch '8.0' into IslandRhythms/gh-13369
vkarpov15 Jul 26, 2023
9fbed32
BREAKING CHANGE: make model.prototype.deleteOne() return query, not p…
vkarpov15 Jul 26, 2023
c9a8f16
Merge pull request #13660 from Automattic/IslandRhythms/gh-13369
vkarpov15 Aug 1, 2023
69beff1
upgrade eslint packages
AbdelrahmanHafez Aug 2, 2023
1442574
add parserOptions to eslint ts files
AbdelrahmanHafez Aug 2, 2023
4bbf929
try linting using node 18
AbdelrahmanHafez Aug 2, 2023
16ff5cd
use node 14 for tsd
AbdelrahmanHafez Aug 2, 2023
d52b0c0
Merge branch 'master' into 8.0
vkarpov15 Aug 3, 2023
746e4a7
Merge pull request #13694 from Automattic/upgrade-eslint
vkarpov15 Aug 3, 2023
03877e9
Merge branch 'master' into 8.0
vkarpov15 Aug 18, 2023
750c6e2
BREAKING CHANGE: use MongoDB node driver 6, drop support for `rawResu…
vkarpov15 Aug 18, 2023
ae68be8
Merge branch 'master' into 8.0
vkarpov15 Aug 24, 2023
c833ee2
BREAKING CHANGE: stop using mquery for `updateX()`, `deleteX()`, `sor…
vkarpov15 Aug 24, 2023
f4f69e3
Merge pull request #13777 from Automattic/vkarpov15/gh-13617
vkarpov15 Aug 25, 2023
633f3b9
Merge branch 'master' into 8.0
vkarpov15 Aug 31, 2023
baf703c
BREAKING CHANGE: use mongodb driver 6.0.0, bson ^6.0.0
vkarpov15 Aug 31, 2023
68790ee
Merge branch '8.0' of github.com:Automattic/mongoose into 8.0
vkarpov15 Aug 31, 2023
f9d17ff
BREAKING CHANGE: require Node 16
vkarpov15 Sep 1, 2023
719cf19
test: fix tests for bson ObjectId no longer allowing 12 char strings
vkarpov15 Sep 1, 2023
db8f62c
test: fix tests
vkarpov15 Sep 1, 2023
92151a9
docs: add migrating to 8 docs
vkarpov15 Sep 1, 2023
8dee6eb
Merge branch '8.0' into vkarpov15/mongodb-node-driver-6
vkarpov15 Sep 1, 2023
9eccbb6
docs: fix markdown lint
vkarpov15 Sep 1, 2023
e3101ae
Update docs/migrating_to_8.md
vkarpov15 Sep 1, 2023
e16da72
Merge branch 'master' into 8.0
vkarpov15 Sep 5, 2023
e7f74c8
BREAKING CHANGE: make `Model.validate()` use `Model.castObject()` to …
vkarpov15 Sep 5, 2023
b951883
BREAKING CHANGE: Safer types for `Model.distinct` and `Query.distinct`.
kaulsh Sep 7, 2023
6c01869
BREAKING CHANGE: rename SchemaType classes to consistently start with…
vkarpov15 Sep 7, 2023
1f79e2c
Merge pull request #13836 from kaulshashank/safer-distinct-return-type
vkarpov15 Sep 8, 2023
49a00ea
Merge pull request #13827 from Automattic/vkarpov15/gh-12668
vkarpov15 Sep 8, 2023
771a304
BREAKING CHANGE: apply minimize by default when updating document
vkarpov15 Sep 8, 2023
4d281a1
Merge branch 'master' into 8.0
vkarpov15 Sep 8, 2023
9664809
Merge branch '8.0' of github.com:Automattic/mongoose into 8.0
vkarpov15 Sep 8, 2023
b36fd11
fix(discriminator): make base schema paths come before discriminator …
vkarpov15 Sep 9, 2023
6ddbcb8
Update lib/helpers/minimize.js
vkarpov15 Sep 12, 2023
7661bec
BREAKING CHANGE: rename top-level files to camel case
vkarpov15 Sep 12, 2023
312dcda
Merge pull request #13857 from Automattic/vkarpov15/gh-13308
vkarpov15 Sep 14, 2023
5aff0a9
Merge branch 'master' into 8.0
vkarpov15 Sep 14, 2023
1c1ba69
refactor: address code review comments by moving tree copy into merge…
vkarpov15 Sep 14, 2023
3211b45
Merge branch '8.0' into vkarpov15/gh-13309
vkarpov15 Sep 14, 2023
d6982ed
refactor: use camelCase for schematype file names
vkarpov15 Sep 14, 2023
6d0b072
Merge pull request #13837 from Automattic/vkarpov15/gh-13309
vkarpov15 Sep 14, 2023
7b5b354
Merge branch '8.0' into vkarpov15/gh-13794
vkarpov15 Sep 15, 2023
71fce29
Merge pull request #13846 from Automattic/vkarpov15/gh-13794
vkarpov15 Sep 15, 2023
17d6987
Merge branch '8.0' into vkarpov15/mongodb-node-driver-6
vkarpov15 Sep 15, 2023
824bc42
Merge branch 'vkarpov15/mongodb-node-driver-6' of github.com:Automatt…
vkarpov15 Sep 15, 2023
6d10a1f
fix(model): correctly pass session when calling Document.prototype.de…
vkarpov15 Sep 15, 2023
31517c7
Merge pull request #13753 from Automattic/vkarpov15/mongodb-node-driv…
vkarpov15 Sep 15, 2023
200a94c
remove id setter
IslandRhythms Sep 15, 2023
ef6282d
chore(docs/source/api): fix filenames
hasezoey Sep 15, 2023
77d5b19
Merge pull request #13864 from Automattic/IslandRhythms/remove-id-setter
vkarpov15 Sep 15, 2023
e8e187f
undo PR 13854
IslandRhythms Sep 18, 2023
4b35a71
Merge pull request #13877 from Automattic/IslandRhythms/undo-13854
vkarpov15 Sep 19, 2023
01202a5
Merge pull request #13865 from hasezoey/fixDocFilename
vkarpov15 Sep 25, 2023
2348b7a
docs(migrating_to_8): add id setter change to migration guide
vkarpov15 Sep 26, 2023
8527c8d
Merge branch '8.0' into vkarpov15/gh-13782
vkarpov15 Sep 26, 2023
d5e9176
Merge pull request #13843 from Automattic/vkarpov15/gh-13782
vkarpov15 Sep 26, 2023
905b28b
BREAKING CHANGE: allow `null` for optional fields in TypeScript
vkarpov15 Sep 26, 2023
5cbe563
docs(migrating_to_8): add note about `null` for optional keys in Type…
vkarpov15 Sep 26, 2023
11ae61f
Merge branch 'master' into 8.0
vkarpov15 Sep 26, 2023
9aa8cdf
Update docs/migrating_to_8.md
vkarpov15 Sep 28, 2023
3ec26a0
BREAKING CHANGE: rename lib/index.js -> lib/mongoose.js
vkarpov15 Sep 28, 2023
2b9bb5d
BREAKING CHANGE: add back lib/index.js as a wrapper around lib/mongoo…
vkarpov15 Sep 28, 2023
d808a54
BREAKING CHANGE: use mongooseCollection for all query operations
vkarpov15 Sep 28, 2023
9c5c2da
chore: rename ArraySubdocument -> arraySubdocument
vkarpov15 Sep 29, 2023
d7ff262
chore: rename ArraySubdocument -> arraySubdocument
vkarpov15 Sep 29, 2023
51a590f
test: add test case re: #13145, #13903
vkarpov15 Sep 29, 2023
e18378d
chore: some more file renames to camelCase
vkarpov15 Sep 29, 2023
8e9ae87
BREAKING CHANGE: camelCase remaining file names
vkarpov15 Sep 30, 2023
eb3f23d
docs: correct filenames
vkarpov15 Sep 30, 2023
e1999be
fix: push up missing files re: #13308
vkarpov15 Sep 30, 2023
0d92202
docs(migrating_to_8): fix no ending-new-line (lint)
hasezoey Oct 1, 2023
fb5b6e8
Merge pull request #13909 from Automattic/vkarpov15/gh-13308-2
vkarpov15 Oct 1, 2023
73f9412
Merge pull request #13910 from hasezoey/fixmd
vkarpov15 Oct 3, 2023
0cc0ac3
Merge branch '8.0' into vkarpov15/gh-12748
vkarpov15 Oct 4, 2023
f7afc96
Merge pull request #13901 from Automattic/vkarpov15/gh-12748
vkarpov15 Oct 4, 2023
9ce4153
Merge branch 'master' into 8.0
vkarpov15 Oct 4, 2023
b8d40f1
fix merge conflicts
vkarpov15 Oct 4, 2023
6e8e06b
Merge branch '8.0' into vkarpov15/gh-4292-2
vkarpov15 Oct 4, 2023
1494a84
fix another merge conflict
vkarpov15 Oct 4, 2023
65aef58
Merge pull request #13905 from Automattic/vkarpov15/gh-4292-2
vkarpov15 Oct 4, 2023
24b6c3b
feat: bump mongodb -> 6.1.0
vkarpov15 Oct 5, 2023
352bf5f
fix(document): fix import file naming
hasezoey Oct 7, 2023
e159400
Merge pull request #13950 from hasezoey/fiximport
vkarpov15 Oct 9, 2023
81cba56
Merge branch 'master' into 8.0
vkarpov15 Oct 13, 2023
f6e5a50
docs: add note about deleteOne() changes re: #13369
vkarpov15 Oct 13, 2023
d14e94d
BREAKING CHANGE: remove support for overwrite option setting findOneA…
vkarpov15 Oct 17, 2023
f50d88d
refactor: avoid relying on overwrite option for timestamps and castin…
vkarpov15 Oct 17, 2023
7722af4
refactor: remove `overwrite` from castUpdate
vkarpov15 Oct 17, 2023
f6ed0eb
refactor: remove remaining usage of `overwrite` option
vkarpov15 Oct 17, 2023
4a2cb0b
types(models): make all properties to Model constructor optional
vkarpov15 Oct 17, 2023
eefe935
Merge branch 'master' into 8.0
vkarpov15 Oct 19, 2023
b630afb
docs(migrating_to_8): add missing issues to migration guide
vkarpov15 Oct 19, 2023
c5b16fe
test: add additional assert re: code review comment
vkarpov15 Oct 19, 2023
84ac690
Merge branch '8.0' into vkarpov15/gh-13578
vkarpov15 Oct 20, 2023
d6cd1db
test: fix a couple of failing tests
vkarpov15 Oct 20, 2023
c7f110e
docs(migrating_to_8): add note about `overwrite` to migration guide
vkarpov15 Oct 20, 2023
8fe5c36
docs: fix lint
vkarpov15 Oct 20, 2023
ce66e23
fix lint
vkarpov15 Oct 20, 2023
30888e3
test: fix typescript tests
vkarpov15 Oct 20, 2023
f923f6c
Merge pull request #13989 from Automattic/vkarpov15/gh-13578
vkarpov15 Oct 24, 2023
8d61a7d
Merge branch '8.0' into vkarpov15/gh-13897
vkarpov15 Oct 24, 2023
d3d2ec4
docs(migrating_to_8): add note about #13897 to migration guide
vkarpov15 Oct 24, 2023
9e9ad37
Merge branch 'master' into 8.0
vkarpov15 Oct 24, 2023
b567ec6
feat: upgrade to MongoDB driver 6.2.0
vkarpov15 Oct 24, 2023
572e018
chore: add 8.0.0-rc0 changelog
vkarpov15 Oct 24, 2023
502ec4b
Merge pull request #13990 from Automattic/vkarpov15/gh-13897
vkarpov15 Oct 24, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ module.exports = {
'**/*.md/*.ts',
'**/*.md/*.typescript'
],
parserOptions: {
project: './tsconfig.json'
},
extends: [
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended'
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3.8.1
with:
node-version: 14
node-version: 18

- run: npm install

Expand All @@ -39,7 +39,7 @@ jobs:
strategy:
fail-fast: false
matrix:
node: [14, 16, 18, 20]
node: [16, 18, 20]
os: [ubuntu-20.04, ubuntu-22.04]
mongodb: [4.4.18, 5.0.14, 6.0.4]
include:
Expand Down Expand Up @@ -108,7 +108,7 @@ jobs:
- name: Setup Deno
uses: denoland/setup-deno@v1
with:
deno-version: v1.34.x
deno-version: v1.36.x
- run: deno --version
- run: npm install
- name: Run Deno tests
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tsd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3.8.1
with:
node-version: 14
node-version: 18

- run: npm install

Expand Down
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
8.0.0-rc0 / 2023-10-24
======================
* BREAKING CHANGE: use MongoDB node driver 6, drop support for rawResult option and findOneAndRemove() #13753
* BREAKING CHANGE: apply minimize by default when updating document #13843
* BREAKING CHANGE: remove `id` setter #13784
* BREAKING CHANGE: remove overwrite option for updateOne(), findOneAndUpdate(), etc. #13989 #13578
* BREAKING CHANGE: make model.prototype.deleteOne() return query, not promise #13660 #13369
* BREAKING CHANGE: remove `Model.count()`, `Query.prototype.count()` #13618 #13598
* BREAKING CHANGE: allow null values for string enum #13620 #3044
* BREAKING CHANGE: make base schema paths come before discriminator schema paths when running setters, validators, etc. #13846 #13794
* BREAKING CHANGE: make Model.validate() use Model.castObject() to cast, and return casted copy of object instead of modifying in place #13287 #12668
* BREAKING CHANGE: make internal file names all camelCase #13950 #13909 #13308
* BREAKING CHANGE: make create() wait for all documents to finish inserting or error out before throwing an error if ordered = false #13621 #4628
* BREAKING CHANGE: refactor out `mongoose/lib/mongoose.js` file to allow importing Mongoose without MongoDB driver #13905
* BREAKING CHANGE(types): allow `null` for optional fields #13901
* BREAKING CHANGE(types): infer return types types for Model.distinct and Query.distinct #13836 [kaulshashank](https://github.com/kaulshashank)

7.6.3 / 2023-10-17
==================
* fix(populate): handle multiple spaces when specifying paths to populate using space-delimited paths #13984 #13951
Expand Down
2 changes: 0 additions & 2 deletions docs/middleware.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ In query middleware functions, `this` refers to the query.
* [find](api/query.html#query_Query-find)
* [findOne](api/query.html#query_Query-findOne)
* [findOneAndDelete](api/query.html#query_Query-findOneAndDelete)
* [findOneAndRemove](api/query.html#query_Query-findOneAndRemove)
* [findOneAndReplace](api/query.html#query_Query-findOneAndReplace)
* [findOneAndUpdate](api/query.html#query_Query-findOneAndUpdate)
* [remove](api/model.html#model_Model-remove)
Expand Down Expand Up @@ -81,7 +80,6 @@ Here are the possible strings that can be passed to `pre()`
* find
* findOne
* findOneAndDelete
* findOneAndRemove
* findOneAndReplace
* findOneAndUpdate
* init
Expand Down
300 changes: 300 additions & 0 deletions docs/migrating_to_8.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,300 @@
# Migrating from 7.x to 8.x

<style>
ul > li {
padding: 4px 0px;
}
</style>

There are several backwards-breaking changes
you should be aware of when migrating from Mongoose 7.x to Mongoose 8.x.

If you're still on Mongoose 6.x or earlier, please read the [Mongoose 6.x to 7.x migration guide](migrating_to_7.html) and upgrade to Mongoose 7.x first before upgrading to Mongoose 8.

* [Removed `rawResult` option for `findOneAndUpdate()`](#removed-rawresult-option-for-findoneandupdate)
* [`Document.prototype.deleteOne()` now returns a query](#document-prototype-deleteone-now-returns-a-query)
* [MongoDB Node Driver 6.0](#mongodb-node-driver-6)
* [Removed `findOneAndRemove()`](#removed-findoneandremove)
* [Removed `count()`](#removed-count)
* [Removed id Setter](#removed-id-setter)
* [`null` is valid for non-required string enums](#null-is-valid-for-non-required-string-enums)
* [Apply minimize when `save()` updates an existing document](#apply-minimize-when-save-updates-an-existing-document)
* [Apply base schema paths before discriminator paths](#apply-base-schema-paths-before-discriminator-paths)
* [Removed `overwrite` option for `findOneAndUpdate()`](#removed-overwrite-option-for-findoneandupdate)
* [Changed behavior for `findOneAndUpdate()` with `orFail()` and upsert](#changed-behavior-for-findoneandupdate-with-orfail-and-upsert)
* [`create()` waits until all saves are done before throwing any error](#create-waits-until-all-saves-are-done-before-throwing-any-error)
* [`Model.validate()` returns copy of object](#model-validate-returns-copy-of-object)
* [Allow `null` For Optional Fields in TypeScript](#allow-null-for-optional-fields-in-typescript)
* [Model constructor properties are all optional in TypeScript](#model-constructor-properties-are-all-optional-in-typescript)
* [Infer `distinct()` return types from schema](#infer-distinct-return-types-from-schema)

<h2 id="removed-rawresult-option-for-findoneandupdate"><a href="#removed-rawresult-option-for-findoneandupdate">Removed <code>rawResult</code> option for <code>findOneAndUpdate()</code></a></h2>

The `rawResult` option for `findOneAndUpdate()`, `findOneAndReplace()`, and `findOneAndDelete()` has been replaced by the `includeResultMetadata` option.

```javascript
const filter = { name: 'Will Riker' };
const update = { age: 29 };

const res = await Character.findOneAndUpdate(filter, update, {
new: true,
upsert: true,
// Replace `rawResult: true` with `includeResultMetadata: true`
includeResultMetadata: true
});
```

`includeResultMetadata` in Mongoose 8 behaves identically to `rawResult`.

<h2 id="document-prototype-deleteone-now-returns-a-query"><a href="#document-prototype-deleteone-now-returns-a-query"><code>Document.prototype.deleteOne</code> now returns a query</a></h2>

In Mongoose 7, `doc.deleteOne()` returned a promise that resolved to `doc`.
In Mongoose 8, `doc.deleteOne()` returns a query for easier chaining, as well as consistency with `doc.updateOne()`.

```javascript
const numberOne = await Character.findOne({ name: 'Will Riker' });

// In Mongoose 7, q is a Promise that resolves to `numberOne`
// In Mongoose 8, q is a Query.
const q = numberOne.deleteOne();

// In Mongoose 7, `res === numberOne`
// In Mongoose 8, `res` is a `DeleteResult`.
const res = await q;
```

<h2 id="mongodb-node-driver-6"><a href="#mongodb-node-driver-6">MongoDB Node Driver 6</a></h2>

Mongoose 8 uses [v6.x of the MongoDB Node driver](https://github.com/mongodb/node-mongodb-native/blob/main/HISTORY.md#600-2023-08-28).
There's a few noteable changes in MongoDB Node driver v6 that affect Mongoose:

1. The `ObjectId` constructor no longer accepts strings of length 12. In Mongoose 7, `new mongoose.Types.ObjectId('12charstring')` was perfectly valid. In Mongoose 8, `new mongoose.Types.ObjectId('12charstring')` throws an error.

<h2 id="removed-findoneandremove"><a href="#removed-findoneandremove">Removed <code>findOneAndRemove()</code></a></h2>

In Mongoose 7, `findOneAndRemove()` was an alias for `findOneAndDelete()` that Mongoose supported for backwards compatibility.
Mongoose 8 no longer supports `findOneAndRemove()`.
Use `findOneAndDelete()` instead.

<h2 id="removed-count"><a href="#removed-count">Removed <code>count()</code></a></h2>

`Model.count()` and `Query.prototype.count()` were removed in Mongoose 8. Use `Model.countDocuments()` and `Query.prototype.countDocuments()` instead.

<h2 id="removed-id-setter"><a href="#removed-id-setter">Removed id Setter</a></h2>

In Mongoose 7.4, Mongoose introduced an `id` setter that made `doc.id = '0'.repeat(24)` equivalent to `doc._id = '0'.repeat(24)`.
In Mongoose 8, that setter is now removed.

<h2 id="null-is-valid-for-non-required-string-enums"><a href="#null-is-valid-for-non-required-string-enums"><code>null</code> is valid for non-required string enums</a></h2>

Before Mongoose 8, setting a string path with an `enum` to `null` would lead to a validation error, even if that path wasn't `required`.
In Mongoose 8, it is valid to set a string path to `null` if `required` is not set, even with `enum`.

```javascript
const schema = new Schema({
status: {
type: String,
enum: ['on', 'off']
}
});
const Test = mongoose.model('Test', schema);

// Works fine in Mongoose 8
// Throws a `ValidationError` in Mongoose 7
await Test.create({ status: null });
```

<h2 id="apply-minimize-when-save-updates-an-existing-document"><a href="#apply-minimize-when-save-updates-an-existing-document">Apply minimize when <code>save()</code> updates an existing document</a></h2>

In Mongoose 7, Mongoose would only apply minimize when saving a new document, not when updating an existing document.

```javascript
const schema = new Schema({
nested: {
field1: Number
}
});
const Test = mongoose.model('Test', schema);

// Both Mongoose 7 and Mongoose 8 strip out empty objects when saving
// a new document in MongoDB by default
const { _id } = await Test.create({ nested: {} });
let rawDoc = await Test.findById(_id).lean();
rawDoc.nested; // undefined

// Mongoose 8 will also strip out empty objects when saving an
// existing document in MongoDB
const doc = await Test.findById(_id);
doc.nested = {};
doc.markModified('nested');
await doc.save();

let rawDoc = await Test.findById(_id).lean();
rawDoc.nested; // undefined in Mongoose 8, {} in Mongoose 7
```

<h2 id="apply-base-schema-paths-before-discriminator-paths"><a href="#apply-base-schema-paths-before-discriminator-paths">Apply base schema paths before discriminator paths</a></h2>

This means that, in Mongoose 8, getters and setters on discriminator paths run *after* getters and setters on base paths.
In Mongoose 7, getters and setters on discriminator paths ran *before* getters and setters on base paths.

```javascript

const schema = new Schema({
name: {
type: String,
get(v) {
console.log('Base schema getter');
return v;
}
}
});

const Test = mongoose.model('Test', schema);
const D = Test.discriminator('D', new Schema({
otherProp: {
type: String,
get(v) {
console.log('Discriminator schema getter');
return v;
}
}
}));

const doc = new D({ name: 'test', otherProp: 'test' });
// In Mongoose 8, prints "Base schema getter" followed by "Discriminator schema getter"
// In Mongoose 7, prints "Discriminator schema getter" followed by "Base schema getter"
console.log(doc.toObject({ getters: true }));
```

<h2 id="removed-overwrite-option-for-findoneandupdate"><a href="#removed-overwrite-option-for-findoneandupdate">Removed <code>overwrite</code> option for <code>findOneAndUpdate()</code></a></h2>

Mongoose 7 and earlier supported an `overwrite` option for `findOneAndUpdate()`, `updateOne()`, and `update()`.
Before Mongoose 7, `overwrite` would skip wrapping the `update` parameter in `$set`, which meant that `findOneAndUpdate()` and `update()` would overwrite the matched document.
In Mongoose 7, setting `overwrite` would convert `findOneAndUpdate()` to `findOneAndReplace()` and `updateOne()` to `replaceOne()` to retain backwards compatibility.

In Mongoose 8, the `overwrite` option is no longer supported.
If you want to overwrite the entire document, use `findOneAndReplace()` or `replaceOne()`.

<h2 id="changed-behavior-for-findoneandupdate-with-orfail-and-upsert"><a href="#changed-behavior-for-findoneandupdate-with-orfail-and-upsert">Changed behavior for <code>findOneAndUpdate()</code> with <code>orFail()</code> and upsert</a></h2>

In Mongoose 7, `findOneAndUpdate(filter, update, { upsert: true }).orFail()` would throw a `DocumentNotFoundError` if a new document was upserted.
In other words, `findOneAndUpdate().orFail()` always threw an error if no document was found, even if a new document was upserted.

In Mongoose 8, `findOneAndUpdate(filter, update, { upsert: true }).orFail()` always succeeds.
`findOneAndUpdate().orFail()` now throws a `DocumentNotFoundError` if there's no document returned, rather than if no document was found.

<h2 id="create-waits-until-all-saves-are-done-before-throwing-any-error"><a href="#create-waits-until-all-saves-are-done-before-throwing-any-error"><code>create()</code> waits until all saves are done before throwing any error</a></h2>

In Mongoose 7, `create()` would immediately throw if any `save()` threw an error by default.
Mongoose 8 instead waits for all `save()` calls to finish before throwing the first error that occurred.
So `create()` will throw the same error in both Mongoose 7 and Mongoose 8, Mongoose 8 just may take longer to throw the error.

```javascript
const schema = new Schema({
name: {
type: String,
enum: ['Badger', 'Mushroom']
}
});
schema.pre('save', async function() {
await new Promise(resolve => setTimeout(resolve, 1000));
});
const Test = mongoose.model('Test', schema);

const err = await Test.create([
{ name: 'Badger' },
{ name: 'Mushroom' },
{ name: 'Cow' }
]).then(() => null, err => err);
err; // ValidationError

// In Mongoose 7, there would be 0 documents, because `Test.create()`
// would throw before 'Badger' and 'Mushroom' are inserted
// In Mongoose 8, there will be 2 documents. `Test.create()` waits until
// 'Badger' and 'Mushroom' are inserted before throwing.
await Test.countDocuments();
```

<h2 id="model-validate-returns-copy-of-object"><a href="#model-validate-returns-copy-of-object"><code>Model.validate()</code> returns copy of object</a></h2>

In Mongoose 7, `Model.validate()` would potentially modify the passed in object.
Mongoose 8 instead copies the passed in object first.

```javascript
const schema = new Schema({ answer: Number });
const Test = mongoose.model('Test', schema);

const obj = { answer: '42' };
const res = Test.validate(obj);

typeof obj.answer; // 'string' in Mongoose 8, 'number' in Mongoose 7
typeof res.answer; // 'number' in both Mongoose 7 and Mongoose 8
```

<h2 id="allow-null-for-optional-fields-in-typescript"><a href="#allow-null-for-optional-fields-in-typescript">Allow <code>null</code> For Optional Fields in TypeScript</a></h2>

In Mongoose 8, automatically inferred schema types in TypeScript allow `null` for optional fields.
In Mongoose 7, optional fields only allowed `undefined`, not `null`.

```typescript
const schema = new Schema({ name: String });
const TestModel = model('Test', schema);

const doc = new TestModel();

// In Mongoose 8, this type is `string | null | undefined`.
// In Mongoose 7, this type is `string | undefined`
doc.name;
```

<h2 id="model-constructor-properties-are-all-optional-in-typescript"><a href="#model-constructor-properties-are-all-optional-in-typescript">Model constructor properties are all optional in TypeScript</a></h2>

In Mongoose 8, no properties are required on model constructors by default.

```ts
import {Schema, model, Model} from 'mongoose';

interface IDocument {
name: string;
createdAt: Date;
updatedAt: Date;
}

const documentSchema = new Schema<IDocument>(
{ name: { type: String, required: true } },
{ timestamps: true }
);

const TestModel = model<IDocument>('Document', documentSchema);

// Would throw a compile error in Mongoose 7, compiles in Mongoose 8
const newDoc = new TestModel({
name: 'Foo'
});

// Explicitly pass generic param to constructor to specify the expected
// type of the model constructor param. The following will cause TS
// to complain about missing `createdAt` and `updatedAt` in Mongoose 8.
const newDoc2 = new TestModel<IDocument>({
name: 'Foo'
});
```

<h2 id="infer-distinct-return-types-from-schema"><a href="#infer-distinct-return-types-from-schema">Infer <code>distinct()</code> return types from schema</a></h2>

```ts
interface User {
name: string;
email: string;
avatar?: string;
}
const schema = new Schema<User>({
name: { type: String, required: true },
email: { type: String, required: true },
avatar: String
});

// Works in Mongoose 8. Compile error in Mongoose 7.
const names: string[] = await MyModel.distinct('name');
```
2 changes: 1 addition & 1 deletion docs/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ If you attempt to `save()` a document from a View, you will get an error from th

## Yet more

The [API docs](api/model.html#model_Model) cover many additional methods available like [count](api/model.html#model_Model-count), [mapReduce](api/model.html#model_Model-mapReduce), [aggregate](api/model.html#model_Model-aggregate), and [more](api/model.html#model_Model-findOneAndRemove).
The [API docs](api/model.html#model_Model) cover many additional methods available like [count](api/model.html#model_Model-count), [mapReduce](api/model.html#model_Model-mapReduce), [aggregate](api/model.html#model_Model-aggregate), and more.

## Next Up

Expand Down
Loading