Skip to content

Commit

Permalink
Merge branch '8.3' into IslandRhythms/gh-9583
Browse files Browse the repository at this point in the history
  • Loading branch information
vkarpov15 committed Mar 20, 2024
2 parents c96b5bb + 1f53635 commit 5950c86
Show file tree
Hide file tree
Showing 48 changed files with 820 additions and 187 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/benchmark.yml
Expand Up @@ -26,7 +26,7 @@ jobs:
with:
fetch-depth: 0
- name: Setup node
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 16

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/documentation.yml
Expand Up @@ -31,7 +31,7 @@ jobs:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- name: Setup node
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 16

Expand All @@ -52,7 +52,7 @@ jobs:
- run: git fetch --depth=1 --tags # download all tags for documentation

- name: Setup node
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 16

Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/test.yml
Expand Up @@ -25,7 +25,7 @@ jobs:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- name: Setup node
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 18

Expand Down Expand Up @@ -61,7 +61,7 @@ jobs:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- name: Setup node
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: ${{ matrix.node }}

Expand Down Expand Up @@ -96,7 +96,7 @@ jobs:
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Setup node
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 16
- name: Load MongoDB binary cache
Expand Down Expand Up @@ -124,7 +124,7 @@ jobs:
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Setup node
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 16
- run: npm install
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tidelift-alignment.yml
Expand Up @@ -17,7 +17,7 @@ jobs:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Setup node
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 16
- name: Alignment
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/tsd.yml
Expand Up @@ -23,7 +23,7 @@ jobs:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- name: Setup node
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 18

Expand All @@ -41,7 +41,7 @@ jobs:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- name: Setup node
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 14

Expand Down
45 changes: 45 additions & 0 deletions CHANGELOG.md
@@ -1,3 +1,42 @@
8.2.2 / 2024-03-15
==================
* fix(model): improve update minimizing to only minimize top-level properties in the update #14437 #14420 #13782
* fix: add Null check in case schema.options['type'][0] is undefined #14431 [Atharv-Bobde](https://github.com/Atharv-Bobde)
* types: consistently infer array of objects in schema as a DocumentArray #14430 #14367
* types: add TypeScript interface for the new PipelineStage - Vector Search - solving issue #14428 #14429 [jkorach](https://github.com/jkorach)
* types: add pre and post function types on Query class #14433 #14432 [IICarst](https://github.com/IICarst)
* types(model): make bulkWrite() types more flexible to account for casting #14423
* docs: update version support documentation for mongoose 5 & 6 #14427 [hasezoey](https://github.com/hasezoey)

7.6.10 / 2024-03-13
===================
* docs(model): add extra note about lean option for insertMany() skipping casting #14415
* docs(mongoose): add options.overwriteModel details to mongoose.model() docs #14422

8.2.1 / 2024-03-04
==================
* fix(document): make $clone avoid converting subdocs into POJOs #14395 #14353
* fix(connection): avoid unhandled error on createConnection() if on('error') handler registered #14390 #14377
* fix(schema): avoid applying default write concern to operations that are in a transaction #14391 #11382
* types(querycursor): correct cursor async iterator type with populate() support #14384 #14374
* types: missing typescript details on options params of updateMany, updateOne, etc. #14382 #14379 #14378 [FaizBShah](https://github.com/FaizBShah) [sderrow](https://github.com/sderrow)
* types: allow Record<string, string> as valid query select argument #14371 [sderrow](https://github.com/sderrow)

6.12.7 / 2024-03-01
===================
* perf(model): make insertMany() lean option skip hydrating Mongoose docs #14376 #14372
* perf(document+schema): small optimizations to make init() faster #14383 #14113
* fix(connection): don't modify passed options object to `openUri()` #14370 #13376 #13335
* fix(ChangeStream): bubble up resumeTokenChanged changeStream event #14355 #14349 [3150](https://github.com/3150)

7.6.9 / 2024-02-26
==================
* fix(document): handle embedded recursive discriminators on nested path defined using Schema.prototype.discriminator #14256 #14245
* types(model): correct return type for findByIdAndDelete() #14233 #14190
* docs(connections): add note about using asPromise() with createConnection() for error handling #14364 #14266
* docs(model+query+findoneandupdate): add more details about overwriteDiscriminatorKey option to docs #14264 #14246

<<<<<<< HEAD
8.2.0 / 2024-02-22
==================
* feat(model): add recompileSchema() function to models to allow applying schema changes after compiling #14306 #14296
Expand Down Expand Up @@ -55,6 +94,12 @@
* docs: update TLS/SSL guide for Mongoose v8 - MongoDB v6 driver deprecations #14170 [andylwelch](https://github.com/andylwelch)
* docs: update findOneAndUpdate tutorial to use includeResultMetadata #14208 #14207
* docs: clarify disabling _id on subdocs #14195 #14194
=======
6.12.6 / 2024-01-22
===================
* fix(collection): correctly handle buffer timeouts with find() #14277
* fix(document): allow calling push() with different $position arguments #14254
>>>>>>> 7.x
7.6.8 / 2024-01-08
==================
Expand Down
18 changes: 13 additions & 5 deletions docs/connections.md
Expand Up @@ -426,16 +426,24 @@ The `mongoose.createConnection()` function takes the same arguments as
const conn = mongoose.createConnection('mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]', options);
```

This [connection](api/connection.html#connection_Connection) object is then used to
create and retrieve [models](api/model.html#model_Model). Models are
**always** scoped to a single connection.
This [connection](api/connection.html#connection_Connection) object is then used to create and retrieve [models](api/model.html#model_Model).
Models are **always** scoped to a single connection.

```javascript
const UserModel = conn.model('User', userSchema);
```

If you use multiple connections, you should make sure you export schemas,
**not** models. Exporting a model from a file is called the *export model pattern*.
The `createConnection()` function returns a connection instance, not a promise.
If you want to use `await` to make sure Mongoose successfully connects to MongoDB, use the [`asPromise()` function](api/connection.html#Connection.prototype.asPromise()):

```javascript
// `asPromise()` returns a promise that resolves to the connection
// once the connection succeeds, or rejects if connection failed.
const conn = await mongoose.createConnection(connectionString).asPromise();
```

If you use multiple connections, you should make sure you export schemas, **not** models.
Exporting a model from a file is called the *export model pattern*.
The export model pattern is limited because you can only use one connection.

```javascript
Expand Down
38 changes: 37 additions & 1 deletion docs/tutorials/findoneandupdate.md
Expand Up @@ -7,10 +7,18 @@ However, there are some cases where you need to use [`findOneAndUpdate()`](https
* [Atomic Updates](#atomic-updates)
* [Upsert](#upsert)
* [The `includeResultMetadata` Option](#includeresultmetadata)
* [Updating Discriminator Keys](#updating-discriminator-keys)

## Getting Started

As the name implies, `findOneAndUpdate()` finds the first document that matches a given `filter`, applies an `update`, and returns the document. By default, `findOneAndUpdate()` returns the document as it was **before** `update` was applied.
As the name implies, `findOneAndUpdate()` finds the first document that matches a given `filter`, applies an `update`, and returns the document.
The `findOneAndUpdate()` function has the following signature:

```javascript
function findOneAndUpdate(filter, update, options) {}
```

By default, `findOneAndUpdate()` returns the document as it was **before** `update` was applied.

```acquit
[require:Tutorial.*findOneAndUpdate.*basic case]
Expand Down Expand Up @@ -78,3 +86,31 @@ Here's what the `res` object from the above example looks like:
age: 29 },
ok: 1 }
```

## Updating Discriminator Keys

Mongoose prevents updating the [discriminator key](../discriminators.html#discriminator-keys) using `findOneAndUpdate()` by default.
For example, suppose you have the following discriminator models.

```javascript
const eventSchema = new mongoose.Schema({ time: Date });
const Event = db.model('Event', eventSchema);

const ClickedLinkEvent = Event.discriminator(
'ClickedLink',
new mongoose.Schema({ url: String })
);

const SignedUpEvent = Event.discriminator(
'SignedUp',
new mongoose.Schema({ username: String })
);
```

Mongoose will remove `__t` (the default discriminator key) from the `update` parameter, if `__t` is set.
This is to prevent unintentional updates to the discriminator key; for example, if you're passing untrusted user input to the `update` parameter.
However, you can tell Mongoose to allow updating the discriminator key by setting the `overwriteDiscriminatorKey` option to `true` as shown below.

```acquit
[require:use overwriteDiscriminatorKey to change discriminator key]
```
12 changes: 1 addition & 11 deletions docs/version-support.md
Expand Up @@ -13,19 +13,9 @@ We ship all new bug fixes and features to 7.x.
Mongoose 6.x (released August 24, 2021) is currently only receiving security fixes and requested bug fixes as of August 24, 2023.
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.

We are **not** actively backporting any new features from Mongoose 7 into Mongoose 6.
Until August 24, 2023, we will backport requested features into Mongoose 6; please open a [feature request on GitHub](https://github.com/Automattic/mongoose/issues/new?assignees=&labels=enhancement%2Cnew+feature&template=feature.yml) to request backporting a feature into Mongoose 6.
After August 24, 2023, we will not backport any new features into Mongoose 6.

Mongoose 6.x end of life (EOL) is January 1, 2025.
Mongoose 6.x will no longer receive any updates, security or otherwise, after that date.

## Mongoose 5

Mongoose 5.x (released January 17, 2018) is currently only receiving security fixes and requested bug fixes.
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 5.
We will **not** backport any new features from Mongoose 6 or Mongoose 7 into Mongoose 5.
This includes support for newer versions of MongoDB: we do not intend to add support for MongoDB 5 or higher to Mongoose 5.x.

Mongoose 5.x end of life (EOL) is March 1, 2024.
Mongoose 5.x will no longer receive any updates, security or otherwise, after that date.
Mongoose 5.x (released January 17, 2018) is End-of-Life (EOL) since March 1, 2024. Mongoose 5.x will no longer receive any updates, security or otherwise.
24 changes: 24 additions & 0 deletions lib/connection.js
Expand Up @@ -829,6 +829,30 @@ Connection.prototype.openUri = async function openUri(uri, options) {
return this;
};

/*!
* Treat `on('error')` handlers as handling the initialConnection promise
* to avoid uncaught exceptions when using `on('error')`. See gh-14377.
*/

Connection.prototype.on = function on(event, callback) {
if (event === 'error' && this.$initialConnection) {
this.$initialConnection.catch(() => {});
}
return EventEmitter.prototype.on.call(this, event, callback);
};

/*!
* Treat `once('error')` handlers as handling the initialConnection promise
* to avoid uncaught exceptions when using `on('error')`. See gh-14377.
*/

Connection.prototype.once = function on(event, callback) {
if (event === 'error' && this.$initialConnection) {
this.$initialConnection.catch(() => {});
}
return EventEmitter.prototype.once.call(this, event, callback);
};

/*!
* ignore
*/
Expand Down
31 changes: 17 additions & 14 deletions lib/document.js
Expand Up @@ -742,7 +742,7 @@ function init(self, obj, doc, opts, prefix) {
if (i === '__proto__' || i === 'constructor') {
return;
}
path = prefix + i;
path = prefix ? prefix + i : i;
schemaType = docSchema.path(path);
// Should still work if not a model-level discriminator, but should not be
// necessary. This is *only* to catch the case where we queried using the
Expand All @@ -751,37 +751,39 @@ function init(self, obj, doc, opts, prefix) {
return;
}

if (!schemaType && utils.isPOJO(obj[i])) {
const value = obj[i];
if (!schemaType && utils.isPOJO(value)) {
// assume nested object
if (!doc[i]) {
doc[i] = {};
if (!strict && !(i in docSchema.tree) && !(i in docSchema.methods) && !(i in docSchema.virtuals)) {
self[i] = doc[i];
}
}
init(self, obj[i], doc[i], opts, path + '.');
init(self, value, doc[i], opts, path + '.');
} else if (!schemaType) {
doc[i] = obj[i];
doc[i] = value;
if (!strict && !prefix) {
self[i] = obj[i];
self[i] = value;
}
} else {
// Retain order when overwriting defaults
if (doc.hasOwnProperty(i) && obj[i] !== void 0 && !opts.hydratedPopulatedDocs) {
if (doc.hasOwnProperty(i) && value !== void 0 && !opts.hydratedPopulatedDocs) {
delete doc[i];
}
if (obj[i] === null) {
if (value === null) {
doc[i] = schemaType._castNullish(null);
} else if (obj[i] !== undefined) {
const wasPopulated = obj[i].$__ == null ? null : obj[i].$__.wasPopulated;
if ((schemaType && !wasPopulated) && !opts.hydratedPopulatedDocs) {
} else if (value !== undefined) {
const wasPopulated = value.$__ == null ? null : value.$__.wasPopulated;

if (schemaType && !wasPopulated && !opts.hydratedPopulatedDocs) {
try {
if (opts && opts.setters) {
// Call applySetters with `init = false` because otherwise setters are a noop
const overrideInit = false;
doc[i] = schemaType.applySetters(obj[i], self, overrideInit);
doc[i] = schemaType.applySetters(value, self, overrideInit);
} else {
doc[i] = schemaType.cast(obj[i], self, true);
doc[i] = schemaType.cast(value, self, true);
}
} catch (e) {
self.invalidate(e.path, new ValidatorError({
Expand All @@ -793,7 +795,7 @@ function init(self, obj, doc, opts, prefix) {
}));
}
} else {
doc[i] = obj[i];
doc[i] = value;
}
}
// mark as hydrated
Expand Down Expand Up @@ -1388,6 +1390,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
if (schema.options &&
Array.isArray(schema.options[typeKey]) &&
schema.options[typeKey].length &&
schema.options[typeKey][0] &&
schema.options[typeKey][0].ref &&
_isManuallyPopulatedArray(val, schema.options[typeKey][0].ref)) {
popOpts = { [populateModelSymbol]: val[0].constructor };
Expand Down Expand Up @@ -4743,7 +4746,7 @@ Document.prototype.$clone = function() {
const clonedDoc = new Model();
clonedDoc.$isNew = this.$isNew;
if (this._doc) {
clonedDoc._doc = clone(this._doc);
clonedDoc._doc = clone(this._doc, { retainDocuments: true });
}
if (this.$__) {
const Cache = this.$__.constructor;
Expand Down
7 changes: 3 additions & 4 deletions lib/drivers/node-mongodb-native/collection.js
Expand Up @@ -136,11 +136,10 @@ function iter(i) {
let promise = null;
let timeout = null;
if (syncCollectionMethods[i] && typeof lastArg === 'function') {
this.addQueue(() => {
lastArg.call(this, null, this[i].apply(this, _args.slice(0, _args.length - 1)));
}, []);
this.addQueue(i, _args);
callback = lastArg;
} else if (syncCollectionMethods[i]) {
promise = new Promise((resolve, reject) => {
promise = new this.Promise((resolve, reject) => {
callback = function collectionOperationCallback(err, res) {
if (timeout != null) {
clearTimeout(timeout);
Expand Down

0 comments on commit 5950c86

Please sign in to comment.