mongoose 8.12.1 → 8.13.0
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/aggregationCursor.js +45 -2
- package/lib/document.js +4 -4
- package/lib/helpers/populate/getSchemaTypes.js +2 -2
- package/lib/model.js +1 -1
- package/lib/mongoose.js +4 -0
- package/lib/schema/date.js +1 -1
- package/package.json +2 -2
- package/types/indexes.d.ts +1 -1
- package/types/utility.d.ts +8 -0
|
@@ -8,6 +8,7 @@ const MongooseError = require('../error/mongooseError');
|
|
|
8
8
|
const Readable = require('stream').Readable;
|
|
9
9
|
const eachAsync = require('../helpers/cursor/eachAsync');
|
|
10
10
|
const immediate = require('../helpers/immediate');
|
|
11
|
+
const kareem = require('kareem');
|
|
11
12
|
const util = require('util');
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -62,7 +63,11 @@ util.inherits(AggregationCursor, Readable);
|
|
|
62
63
|
|
|
63
64
|
function _init(model, c, agg) {
|
|
64
65
|
if (!model.collection.buffer) {
|
|
65
|
-
model.hooks.execPre('aggregate', agg, function() {
|
|
66
|
+
model.hooks.execPre('aggregate', agg, function(err) {
|
|
67
|
+
if (err != null) {
|
|
68
|
+
_handlePreHookError(c, err);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
66
71
|
if (typeof agg.options?.cursor?.transform === 'function') {
|
|
67
72
|
c._transforms.push(agg.options.cursor.transform);
|
|
68
73
|
}
|
|
@@ -72,7 +77,12 @@ function _init(model, c, agg) {
|
|
|
72
77
|
});
|
|
73
78
|
} else {
|
|
74
79
|
model.collection.emitter.once('queue', function() {
|
|
75
|
-
model.hooks.execPre('aggregate', agg, function() {
|
|
80
|
+
model.hooks.execPre('aggregate', agg, function(err) {
|
|
81
|
+
if (err != null) {
|
|
82
|
+
_handlePreHookError(c, err);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
76
86
|
if (typeof agg.options?.cursor?.transform === 'function') {
|
|
77
87
|
c._transforms.push(agg.options.cursor.transform);
|
|
78
88
|
}
|
|
@@ -84,6 +94,38 @@ function _init(model, c, agg) {
|
|
|
84
94
|
}
|
|
85
95
|
}
|
|
86
96
|
|
|
97
|
+
/**
|
|
98
|
+
* Handles error emitted from pre middleware. In particular, checks for `skipWrappedFunction`, which allows skipping
|
|
99
|
+
* the actual aggregation and overwriting the function's return value. Because aggregation cursors don't return a value,
|
|
100
|
+
* we need to make sure the user doesn't accidentally set a value in skipWrappedFunction.
|
|
101
|
+
*
|
|
102
|
+
* @param {QueryCursor} queryCursor
|
|
103
|
+
* @param {Error} err
|
|
104
|
+
* @returns
|
|
105
|
+
*/
|
|
106
|
+
|
|
107
|
+
function _handlePreHookError(queryCursor, err) {
|
|
108
|
+
if (err instanceof kareem.skipWrappedFunction) {
|
|
109
|
+
const resultValue = err.args[0];
|
|
110
|
+
if (resultValue != null && (!Array.isArray(resultValue) || resultValue.length)) {
|
|
111
|
+
const err = new MongooseError(
|
|
112
|
+
'Cannot `skipMiddlewareFunction()` with a value when using ' +
|
|
113
|
+
'`.aggregate().cursor()`, value must be nullish or empty array, got "' +
|
|
114
|
+
util.inspect(resultValue) +
|
|
115
|
+
'".'
|
|
116
|
+
);
|
|
117
|
+
queryCursor._markError(err);
|
|
118
|
+
queryCursor.listeners('error').length > 0 && queryCursor.emit('error', err);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
queryCursor.emit('cursor', null);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
queryCursor._markError(err);
|
|
125
|
+
queryCursor.listeners('error').length > 0 && queryCursor.emit('error', err);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
|
|
87
129
|
/**
|
|
88
130
|
* Necessary to satisfy the Readable API
|
|
89
131
|
* @method _read
|
|
@@ -424,6 +466,7 @@ function _next(ctx, cb) {
|
|
|
424
466
|
err => callback(err)
|
|
425
467
|
);
|
|
426
468
|
} else {
|
|
469
|
+
ctx.once('error', cb);
|
|
427
470
|
ctx.once('cursor', function() {
|
|
428
471
|
_next(ctx, cb);
|
|
429
472
|
});
|
package/lib/document.js
CHANGED
|
@@ -747,8 +747,8 @@ function init(self, obj, doc, opts, prefix) {
|
|
|
747
747
|
for (let index = 0; index < len; ++index) {
|
|
748
748
|
i = keys[index];
|
|
749
749
|
// avoid prototype pollution
|
|
750
|
-
if (i
|
|
751
|
-
|
|
750
|
+
if (specialProperties.has(i)) {
|
|
751
|
+
continue;
|
|
752
752
|
}
|
|
753
753
|
path = prefix ? prefix + i : i;
|
|
754
754
|
schemaType = docSchema.path(path);
|
|
@@ -756,7 +756,7 @@ function init(self, obj, doc, opts, prefix) {
|
|
|
756
756
|
// necessary. This is *only* to catch the case where we queried using the
|
|
757
757
|
// base model and the discriminated model has a projection
|
|
758
758
|
if (docSchema.$isRootDiscriminator && !self.$__isSelected(path)) {
|
|
759
|
-
|
|
759
|
+
continue;
|
|
760
760
|
}
|
|
761
761
|
|
|
762
762
|
const value = obj[i];
|
|
@@ -1720,7 +1720,7 @@ Document.prototype.$__set = function(pathToMark, path, options, constructing, pa
|
|
|
1720
1720
|
const last = next === l;
|
|
1721
1721
|
cur += (cur ? '.' + parts[i] : parts[i]);
|
|
1722
1722
|
if (specialProperties.has(parts[i])) {
|
|
1723
|
-
|
|
1723
|
+
continue;
|
|
1724
1724
|
}
|
|
1725
1725
|
|
|
1726
1726
|
if (last) {
|
|
@@ -178,8 +178,8 @@ module.exports = function getSchemaTypes(model, schema, doc, path) {
|
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
const fullPath = nestedPath.concat([trypath]).join('.');
|
|
181
|
-
if (topLevelDoc != null && topLevelDoc.$__ && topLevelDoc.$populated(fullPath) && p < parts.length) {
|
|
182
|
-
const model =
|
|
181
|
+
if (topLevelDoc != null && topLevelDoc.$__ && topLevelDoc.$populated(fullPath, true) && p < parts.length) {
|
|
182
|
+
const model = topLevelDoc.$populated(fullPath, true).options[populateModelSymbol];
|
|
183
183
|
if (model != null) {
|
|
184
184
|
const ret = search(
|
|
185
185
|
parts.slice(p),
|
package/lib/model.js
CHANGED
|
@@ -3603,7 +3603,7 @@ Model.bulkSave = async function bulkSave(documents, options) {
|
|
|
3603
3603
|
}
|
|
3604
3604
|
await Promise.all(successfulDocuments.map(document => handleSuccessfulWrite(document)));
|
|
3605
3605
|
|
|
3606
|
-
if (bulkWriteError
|
|
3606
|
+
if (bulkWriteError != null) {
|
|
3607
3607
|
throw bulkWriteError;
|
|
3608
3608
|
}
|
|
3609
3609
|
|
package/lib/mongoose.js
CHANGED
|
@@ -179,6 +179,10 @@ Mongoose.prototype.setDriver = function setDriver(driver) {
|
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
+
if (driver.SchemaTypes != null) {
|
|
183
|
+
Object.assign(mongoose.Schema.Types, driver.SchemaTypes);
|
|
184
|
+
}
|
|
185
|
+
|
|
182
186
|
const Connection = driver.Connection;
|
|
183
187
|
const oldDefaultConnection = _mongoose.connections[0];
|
|
184
188
|
_mongoose.connections = [new Connection(_mongoose)];
|
package/lib/schema/date.js
CHANGED
|
@@ -150,7 +150,7 @@ SchemaDate._defaultCaster = v => {
|
|
|
150
150
|
* // expire in 24 hours
|
|
151
151
|
* new Schema({ createdAt: { type: Date, expires: 60*60*24 }});
|
|
152
152
|
*
|
|
153
|
-
* `expires` utilizes the `ms` module from [
|
|
153
|
+
* `expires` utilizes the `ms` module from [vercel](https://github.com/vercel/ms) allowing us to use a friendlier syntax:
|
|
154
154
|
*
|
|
155
155
|
* #### Example:
|
|
156
156
|
*
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongoose",
|
|
3
3
|
"description": "Mongoose MongoDB ODM",
|
|
4
|
-
"version": "8.
|
|
4
|
+
"version": "8.13.0",
|
|
5
5
|
"author": "Guillermo Rauch <guillermo@learnboost.com>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mongodb",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"bson": "^6.10.3",
|
|
24
24
|
"kareem": "2.6.3",
|
|
25
|
-
"mongodb": "~6.
|
|
25
|
+
"mongodb": "~6.15.0",
|
|
26
26
|
"mpath": "0.9.0",
|
|
27
27
|
"mquery": "5.0.0",
|
|
28
28
|
"ms": "2.1.3",
|
package/types/indexes.d.ts
CHANGED
|
@@ -68,7 +68,7 @@ declare module 'mongoose' {
|
|
|
68
68
|
|
|
69
69
|
type IndexOptions = Omit<mongodb.CreateIndexesOptions, 'expires' | 'weights' | 'unique'> & {
|
|
70
70
|
/**
|
|
71
|
-
* `expires` utilizes the `ms` module from [
|
|
71
|
+
* `expires` utilizes the `ms` module from [vercel](https://github.com/vercel/ms) allowing us to use a friendlier syntax:
|
|
72
72
|
*
|
|
73
73
|
* @example
|
|
74
74
|
* ```js
|
package/types/utility.d.ts
CHANGED
|
@@ -93,4 +93,12 @@ type AddThisParameter<T, D> = {
|
|
|
93
93
|
: T[K];
|
|
94
94
|
};
|
|
95
95
|
|
|
96
|
+
/**
|
|
97
|
+
* @summary Adds timestamp fields to a type
|
|
98
|
+
* @description Adds createdAt and updatedAt fields of type Date, or custom timestamp fields if specified
|
|
99
|
+
* @param {T} T The type to add timestamp fields to
|
|
100
|
+
* @param {P} P Optional SchemaTimestampsConfig or boolean to customize timestamp field names
|
|
101
|
+
* @returns T with timestamp fields added
|
|
102
|
+
*/
|
|
103
|
+
export type WithTimestamps<T, P extends SchemaTimestampsConfig | boolean = true> = ResolveTimestamps<T, { timestamps: P }>;
|
|
96
104
|
}
|