mongoose 8.6.3 → 8.7.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/cast.js +11 -1
- package/lib/connection.js +9 -0
- package/lib/constants.js +37 -0
- package/lib/document.js +35 -64
- package/lib/drivers/node-mongodb-native/connection.js +12 -0
- package/lib/error/browserMissingSchema.js +4 -3
- package/lib/error/bulkSaveIncompleteError.js +44 -0
- package/lib/error/divergentArray.js +7 -5
- package/lib/error/invalidSchemaOption.js +7 -5
- package/lib/error/missingSchema.js +7 -5
- package/lib/error/notFound.js +6 -4
- package/lib/error/objectExpected.js +8 -7
- package/lib/error/objectParameter.js +11 -9
- package/lib/error/overwriteModel.js +6 -5
- package/lib/error/parallelSave.js +9 -6
- package/lib/error/parallelValidate.js +8 -6
- package/lib/error/setOptionError.js +8 -6
- package/lib/error/strict.js +11 -9
- package/lib/error/strictPopulate.js +10 -8
- package/lib/error/validation.js +9 -7
- package/lib/error/validator.js +8 -7
- package/lib/error/version.js +10 -8
- package/lib/helpers/document/applyVirtuals.js +146 -0
- package/lib/helpers/model/applyStaticHooks.js +14 -5
- package/lib/helpers/projection/isExclusive.js +6 -3
- package/lib/helpers/projection/isInclusive.js +2 -1
- package/lib/helpers/query/castUpdate.js +20 -3
- package/lib/model.js +42 -4
- package/lib/schemaType.js +19 -0
- package/lib/types/array/methods/index.js +26 -0
- package/package.json +2 -2
- package/types/document.d.ts +0 -3
- package/types/index.d.ts +7 -3
- package/types/models.d.ts +3 -0
- package/types/schematypes.d.ts +3 -0
package/lib/error/version.js
CHANGED
|
@@ -6,15 +6,17 @@
|
|
|
6
6
|
|
|
7
7
|
const MongooseError = require('./mongooseError');
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Version Error constructor.
|
|
11
|
+
*
|
|
12
|
+
* @param {Document} doc
|
|
13
|
+
* @param {Number} currentVersion
|
|
14
|
+
* @param {Array<String>} modifiedPaths
|
|
15
|
+
* @api private
|
|
16
|
+
*/
|
|
17
|
+
|
|
9
18
|
class VersionError extends MongooseError {
|
|
10
|
-
|
|
11
|
-
* Version Error constructor.
|
|
12
|
-
*
|
|
13
|
-
* @param {Document} doc
|
|
14
|
-
* @param {Number} currentVersion
|
|
15
|
-
* @param {Array<String>} modifiedPaths
|
|
16
|
-
* @api private
|
|
17
|
-
*/
|
|
19
|
+
|
|
18
20
|
constructor(doc, currentVersion, modifiedPaths) {
|
|
19
21
|
const modifiedPathsStr = modifiedPaths.join(', ');
|
|
20
22
|
super('No matching document found for id "' + doc._doc._id +
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const mpath = require('mpath');
|
|
4
|
+
|
|
5
|
+
module.exports = applyVirtuals;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Apply a given schema's virtuals to a given POJO
|
|
9
|
+
*
|
|
10
|
+
* @param {Schema} schema
|
|
11
|
+
* @param {Object} obj
|
|
12
|
+
* @param {Array<string>} [virtuals] optional whitelist of virtuals to apply
|
|
13
|
+
* @returns
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
function applyVirtuals(schema, obj, virtuals) {
|
|
17
|
+
if (obj == null) {
|
|
18
|
+
return obj;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let virtualsForChildren = virtuals;
|
|
22
|
+
let toApply = null;
|
|
23
|
+
|
|
24
|
+
if (Array.isArray(virtuals)) {
|
|
25
|
+
virtualsForChildren = [];
|
|
26
|
+
toApply = [];
|
|
27
|
+
for (const virtual of virtuals) {
|
|
28
|
+
if (virtual.length === 1) {
|
|
29
|
+
toApply.push(virtual[0]);
|
|
30
|
+
} else {
|
|
31
|
+
virtualsForChildren.push(virtual);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
applyVirtualsToChildren(schema, obj, virtualsForChildren);
|
|
37
|
+
return applyVirtualsToDoc(schema, obj, toApply);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Apply virtuals to any subdocuments
|
|
42
|
+
*
|
|
43
|
+
* @param {Schema} schema subdocument schema
|
|
44
|
+
* @param {Object} res subdocument
|
|
45
|
+
* @param {Array<String>} [virtuals] optional whitelist of virtuals to apply
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
function applyVirtualsToChildren(schema, res, virtuals) {
|
|
49
|
+
let attachedVirtuals = false;
|
|
50
|
+
for (const childSchema of schema.childSchemas) {
|
|
51
|
+
const _path = childSchema.model.path;
|
|
52
|
+
const _schema = childSchema.schema;
|
|
53
|
+
if (!_path) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const _obj = mpath.get(_path, res);
|
|
57
|
+
if (_obj == null || (Array.isArray(_obj) && _obj.flat(Infinity).length === 0)) {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let virtualsForChild = null;
|
|
62
|
+
if (Array.isArray(virtuals)) {
|
|
63
|
+
virtualsForChild = [];
|
|
64
|
+
for (const virtual of virtuals) {
|
|
65
|
+
if (virtual[0] == _path) {
|
|
66
|
+
virtualsForChild.push(virtual.slice(1));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (virtualsForChild.length === 0) {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
applyVirtuals(_schema, _obj, virtualsForChild);
|
|
76
|
+
attachedVirtuals = true;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (virtuals && virtuals.length && !attachedVirtuals) {
|
|
80
|
+
applyVirtualsToDoc(schema, res, virtuals);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Apply virtuals to a given document. Does not apply virtuals to subdocuments: use `applyVirtualsToChildren` instead
|
|
86
|
+
*
|
|
87
|
+
* @param {Schema} schema
|
|
88
|
+
* @param {Object} doc
|
|
89
|
+
* @param {Array<String>} [virtuals] optional whitelist of virtuals to apply
|
|
90
|
+
* @returns
|
|
91
|
+
*/
|
|
92
|
+
|
|
93
|
+
function applyVirtualsToDoc(schema, obj, virtuals) {
|
|
94
|
+
if (obj == null || typeof obj !== 'object') {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (Array.isArray(obj)) {
|
|
98
|
+
for (const el of obj) {
|
|
99
|
+
applyVirtualsToDoc(schema, el, virtuals);
|
|
100
|
+
}
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (schema.discriminators && Object.keys(schema.discriminators).length > 0) {
|
|
105
|
+
for (const discriminatorKey of Object.keys(schema.discriminators)) {
|
|
106
|
+
const discriminator = schema.discriminators[discriminatorKey];
|
|
107
|
+
const key = discriminator.discriminatorMapping.key;
|
|
108
|
+
const value = discriminator.discriminatorMapping.value;
|
|
109
|
+
if (obj[key] == value) {
|
|
110
|
+
schema = discriminator;
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (virtuals == null) {
|
|
117
|
+
virtuals = Object.keys(schema.virtuals);
|
|
118
|
+
}
|
|
119
|
+
for (const virtual of virtuals) {
|
|
120
|
+
if (schema.virtuals[virtual] == null) {
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
const virtualType = schema.virtuals[virtual];
|
|
124
|
+
const sp = Array.isArray(virtual)
|
|
125
|
+
? virtual
|
|
126
|
+
: virtual.indexOf('.') === -1
|
|
127
|
+
? [virtual]
|
|
128
|
+
: virtual.split('.');
|
|
129
|
+
let cur = obj;
|
|
130
|
+
for (let i = 0; i < sp.length - 1; ++i) {
|
|
131
|
+
cur[sp[i]] = sp[i] in cur ? cur[sp[i]] : {};
|
|
132
|
+
cur = cur[sp[i]];
|
|
133
|
+
}
|
|
134
|
+
let val = virtualType.applyGetters(cur[sp[sp.length - 1]], obj);
|
|
135
|
+
const isPopulateVirtual =
|
|
136
|
+
virtualType.options && (virtualType.options.ref || virtualType.options.refPath);
|
|
137
|
+
if (isPopulateVirtual && val === undefined) {
|
|
138
|
+
if (virtualType.options.justOne) {
|
|
139
|
+
val = null;
|
|
140
|
+
} else {
|
|
141
|
+
val = [];
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
cur[sp[sp.length - 1]] = val;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const middlewareFunctions = require('../../constants').queryMiddlewareFunctions;
|
|
4
3
|
const promiseOrCallback = require('../promiseOrCallback');
|
|
4
|
+
const { queryMiddlewareFunctions, aggregateMiddlewareFunctions, modelMiddlewareFunctions, documentMiddlewareFunctions } = require('../../constants');
|
|
5
|
+
|
|
6
|
+
const middlewareFunctions = Array.from(
|
|
7
|
+
new Set([
|
|
8
|
+
...queryMiddlewareFunctions,
|
|
9
|
+
...aggregateMiddlewareFunctions,
|
|
10
|
+
...modelMiddlewareFunctions,
|
|
11
|
+
...documentMiddlewareFunctions
|
|
12
|
+
])
|
|
13
|
+
);
|
|
5
14
|
|
|
6
15
|
module.exports = function applyStaticHooks(model, hooks, statics) {
|
|
7
16
|
const kareemOptions = {
|
|
@@ -9,8 +18,11 @@ module.exports = function applyStaticHooks(model, hooks, statics) {
|
|
|
9
18
|
numCallbackParams: 1
|
|
10
19
|
};
|
|
11
20
|
|
|
21
|
+
model.$__insertMany = hooks.createWrapper('insertMany',
|
|
22
|
+
model.$__insertMany, model, kareemOptions);
|
|
23
|
+
|
|
12
24
|
hooks = hooks.filter(hook => {
|
|
13
|
-
// If the custom static overwrites an existing
|
|
25
|
+
// If the custom static overwrites an existing middleware, don't apply
|
|
14
26
|
// middleware to it by default. This avoids a potential backwards breaking
|
|
15
27
|
// change with plugins like `mongoose-delete` that use statics to overwrite
|
|
16
28
|
// built-in Mongoose functions.
|
|
@@ -20,9 +32,6 @@ module.exports = function applyStaticHooks(model, hooks, statics) {
|
|
|
20
32
|
return hook.model !== false;
|
|
21
33
|
});
|
|
22
34
|
|
|
23
|
-
model.$__insertMany = hooks.createWrapper('insertMany',
|
|
24
|
-
model.$__insertMany, model, kareemOptions);
|
|
25
|
-
|
|
26
35
|
for (const key of Object.keys(statics)) {
|
|
27
36
|
if (hooks.hasHooks(key)) {
|
|
28
37
|
const original = model[key];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const isDefiningProjection = require('./isDefiningProjection');
|
|
4
|
+
const isPOJO = require('../isPOJO');
|
|
4
5
|
|
|
5
6
|
/*!
|
|
6
7
|
* ignore
|
|
@@ -22,10 +23,12 @@ module.exports = function isExclusive(projection) {
|
|
|
22
23
|
// Explicitly avoid `$meta` and `$slice`
|
|
23
24
|
const key = keys[ki];
|
|
24
25
|
if (key !== '_id' && isDefiningProjection(projection[key])) {
|
|
25
|
-
exclude = (projection[key]
|
|
26
|
-
isExclusive(projection[key]) :
|
|
26
|
+
exclude = isPOJO(projection[key]) ?
|
|
27
|
+
(isExclusive(projection[key]) ?? exclude) :
|
|
27
28
|
!projection[key];
|
|
28
|
-
|
|
29
|
+
if (exclude != null) {
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
29
32
|
}
|
|
30
33
|
}
|
|
31
34
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const isDefiningProjection = require('./isDefiningProjection');
|
|
4
|
+
const isPOJO = require('../isPOJO');
|
|
4
5
|
|
|
5
6
|
/*!
|
|
6
7
|
* ignore
|
|
@@ -26,7 +27,7 @@ module.exports = function isInclusive(projection) {
|
|
|
26
27
|
// If field is truthy (1, true, etc.) and not an object, then this
|
|
27
28
|
// projection must be inclusive. If object, assume its $meta, $slice, etc.
|
|
28
29
|
if (isDefiningProjection(projection[prop]) && !!projection[prop]) {
|
|
29
|
-
if (projection[prop]
|
|
30
|
+
if (isPOJO(projection[prop])) {
|
|
30
31
|
return isInclusive(projection[prop]);
|
|
31
32
|
} else {
|
|
32
33
|
return !!projection[prop];
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const CastError = require('../../error/cast');
|
|
4
4
|
const MongooseError = require('../../error/mongooseError');
|
|
5
|
+
const SchemaString = require('../../schema/string');
|
|
5
6
|
const StrictModeError = require('../../error/strict');
|
|
6
7
|
const ValidationError = require('../../error/validation');
|
|
7
8
|
const castNumber = require('../../cast/number');
|
|
@@ -307,6 +308,20 @@ function walkUpdatePath(schema, obj, op, options, context, filter, pref) {
|
|
|
307
308
|
continue;
|
|
308
309
|
}
|
|
309
310
|
|
|
311
|
+
hasKeys = true;
|
|
312
|
+
} else if (op === '$rename') {
|
|
313
|
+
const schematype = new SchemaString(`${prefix}${key}.$rename`);
|
|
314
|
+
try {
|
|
315
|
+
obj[key] = castUpdateVal(schematype, val, op, key, context, prefix + key);
|
|
316
|
+
} catch (error) {
|
|
317
|
+
aggregatedError = _appendError(error, context, key, aggregatedError);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (obj[key] === void 0) {
|
|
321
|
+
delete obj[key];
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
|
|
310
325
|
hasKeys = true;
|
|
311
326
|
} else {
|
|
312
327
|
const pathToCheck = (prefix + key);
|
|
@@ -372,10 +387,12 @@ function walkUpdatePath(schema, obj, op, options, context, filter, pref) {
|
|
|
372
387
|
delete obj[key];
|
|
373
388
|
}
|
|
374
389
|
} else {
|
|
375
|
-
// gh-1845 temporary fix: ignore $rename. See gh-3027 for tracking
|
|
376
|
-
// improving this.
|
|
377
390
|
if (op === '$rename') {
|
|
378
|
-
|
|
391
|
+
if (obj[key] == null) {
|
|
392
|
+
throw new CastError('String', obj[key], `${prefix}${key}.$rename`);
|
|
393
|
+
}
|
|
394
|
+
const schematype = new SchemaString(`${prefix}${key}.$rename`);
|
|
395
|
+
obj[key] = schematype.castForQuery(null, obj[key], context);
|
|
379
396
|
continue;
|
|
380
397
|
}
|
|
381
398
|
|
package/lib/model.js
CHANGED
|
@@ -31,6 +31,7 @@ const applySchemaCollation = require('./helpers/indexes/applySchemaCollation');
|
|
|
31
31
|
const applyStaticHooks = require('./helpers/model/applyStaticHooks');
|
|
32
32
|
const applyStatics = require('./helpers/model/applyStatics');
|
|
33
33
|
const applyWriteConcern = require('./helpers/schema/applyWriteConcern');
|
|
34
|
+
const applyVirtualsHelper = require('./helpers/document/applyVirtuals');
|
|
34
35
|
const assignVals = require('./helpers/populate/assignVals');
|
|
35
36
|
const castBulkWrite = require('./helpers/model/castBulkWrite');
|
|
36
37
|
const clone = require('./helpers/clone');
|
|
@@ -64,6 +65,7 @@ const STATES = require('./connectionState');
|
|
|
64
65
|
const util = require('util');
|
|
65
66
|
const utils = require('./utils');
|
|
66
67
|
const minimize = require('./helpers/minimize');
|
|
68
|
+
const MongooseBulkSaveIncompleteError = require('./error/bulkSaveIncompleteError');
|
|
67
69
|
|
|
68
70
|
const modelCollectionSymbol = Symbol('mongoose#Model#collection');
|
|
69
71
|
const modelDbSymbol = Symbol('mongoose#Model#db');
|
|
@@ -3418,11 +3420,10 @@ Model.bulkSave = async function bulkSave(documents, options) {
|
|
|
3418
3420
|
|
|
3419
3421
|
const matchedCount = bulkWriteResult?.matchedCount ?? 0;
|
|
3420
3422
|
const insertedCount = bulkWriteResult?.insertedCount ?? 0;
|
|
3421
|
-
if (writeOperations.length > 0 && matchedCount + insertedCount
|
|
3422
|
-
throw new
|
|
3423
|
-
writeOperations.filter(op => op.updateOne).map(op => op.updateOne.filter),
|
|
3423
|
+
if (writeOperations.length > 0 && matchedCount + insertedCount < writeOperations.length && !bulkWriteError) {
|
|
3424
|
+
throw new MongooseBulkSaveIncompleteError(
|
|
3424
3425
|
this.modelName,
|
|
3425
|
-
|
|
3426
|
+
documents,
|
|
3426
3427
|
bulkWriteResult
|
|
3427
3428
|
);
|
|
3428
3429
|
}
|
|
@@ -3488,6 +3489,9 @@ function handleSuccessfulWrite(document) {
|
|
|
3488
3489
|
*/
|
|
3489
3490
|
|
|
3490
3491
|
Model.applyDefaults = function applyDefaults(doc) {
|
|
3492
|
+
if (doc == null) {
|
|
3493
|
+
return doc;
|
|
3494
|
+
}
|
|
3491
3495
|
if (doc.$__ != null) {
|
|
3492
3496
|
applyDefaultsHelper(doc, doc.$__.fields, doc.$__.exclude);
|
|
3493
3497
|
|
|
@@ -3503,6 +3507,40 @@ Model.applyDefaults = function applyDefaults(doc) {
|
|
|
3503
3507
|
return doc;
|
|
3504
3508
|
};
|
|
3505
3509
|
|
|
3510
|
+
/**
|
|
3511
|
+
* Apply this model's virtuals to a given POJO. Virtuals execute with the POJO as the context `this`.
|
|
3512
|
+
*
|
|
3513
|
+
* #### Example:
|
|
3514
|
+
*
|
|
3515
|
+
* const userSchema = new Schema({ name: String });
|
|
3516
|
+
* userSchema.virtual('upper').get(function() { return this.name.toUpperCase(); });
|
|
3517
|
+
* const User = mongoose.model('User', userSchema);
|
|
3518
|
+
*
|
|
3519
|
+
* const obj = { name: 'John' };
|
|
3520
|
+
* User.applyVirtuals(obj);
|
|
3521
|
+
* obj.name; // 'John'
|
|
3522
|
+
* obj.upper; // 'JOHN', Mongoose applied the return value of the virtual to the given object
|
|
3523
|
+
*
|
|
3524
|
+
* @param {Object} obj object or document to apply virtuals on
|
|
3525
|
+
* @param {Array<string>} [virtualsToApply] optional whitelist of virtuals to apply
|
|
3526
|
+
* @returns {Object} obj
|
|
3527
|
+
* @api public
|
|
3528
|
+
*/
|
|
3529
|
+
|
|
3530
|
+
Model.applyVirtuals = function applyVirtuals(obj, virtualsToApply) {
|
|
3531
|
+
if (obj == null) {
|
|
3532
|
+
return obj;
|
|
3533
|
+
}
|
|
3534
|
+
// Nothing to do if this is already a hydrated document - it should already have virtuals
|
|
3535
|
+
if (obj.$__ != null) {
|
|
3536
|
+
return obj;
|
|
3537
|
+
}
|
|
3538
|
+
|
|
3539
|
+
applyVirtualsHelper(this.schema, obj, virtualsToApply);
|
|
3540
|
+
|
|
3541
|
+
return obj;
|
|
3542
|
+
};
|
|
3543
|
+
|
|
3506
3544
|
/**
|
|
3507
3545
|
* Cast the given POJO to the model's schema
|
|
3508
3546
|
*
|
package/lib/schemaType.js
CHANGED
|
@@ -1724,6 +1724,25 @@ SchemaType.prototype.clone = function() {
|
|
|
1724
1724
|
return schematype;
|
|
1725
1725
|
};
|
|
1726
1726
|
|
|
1727
|
+
/**
|
|
1728
|
+
* Returns the embedded schema type, if any. For arrays, document arrays, and maps, `getEmbeddedSchemaType()`
|
|
1729
|
+
* returns the schema type of the array's elements (or map's elements). For other types, `getEmbeddedSchemaType()`
|
|
1730
|
+
* returns `undefined`.
|
|
1731
|
+
*
|
|
1732
|
+
* #### Example:
|
|
1733
|
+
*
|
|
1734
|
+
* const schema = new Schema({ name: String, tags: [String] });
|
|
1735
|
+
* schema.path('name').getEmbeddedSchemaType(); // undefined
|
|
1736
|
+
* schema.path('tags').getEmbeddedSchemaType(); // SchemaString { path: 'tags', ... }
|
|
1737
|
+
*
|
|
1738
|
+
* @returns {SchemaType} embedded schematype
|
|
1739
|
+
* @api public
|
|
1740
|
+
*/
|
|
1741
|
+
|
|
1742
|
+
SchemaType.prototype.getEmbeddedSchemaType = function getEmbeddedSchemaType() {
|
|
1743
|
+
return this.$embeddedSchemaType;
|
|
1744
|
+
};
|
|
1745
|
+
|
|
1727
1746
|
/*!
|
|
1728
1747
|
* Module exports.
|
|
1729
1748
|
*/
|
|
@@ -410,6 +410,7 @@ const methods = {
|
|
|
410
410
|
|
|
411
411
|
addToSet() {
|
|
412
412
|
_checkManualPopulation(this, arguments);
|
|
413
|
+
_depopulateIfNecessary(this, arguments);
|
|
413
414
|
|
|
414
415
|
const values = [].map.call(arguments, this._mapCast, this);
|
|
415
416
|
const added = [];
|
|
@@ -691,6 +692,7 @@ const methods = {
|
|
|
691
692
|
}
|
|
692
693
|
|
|
693
694
|
_checkManualPopulation(this, values);
|
|
695
|
+
_depopulateIfNecessary(this, values);
|
|
694
696
|
|
|
695
697
|
values = [].map.call(values, this._mapCast, this);
|
|
696
698
|
let ret;
|
|
@@ -1009,6 +1011,30 @@ function _checkManualPopulation(arr, docs) {
|
|
|
1009
1011
|
}
|
|
1010
1012
|
}
|
|
1011
1013
|
|
|
1014
|
+
/*!
|
|
1015
|
+
* If `docs` isn't all instances of the right model, depopulate `arr`
|
|
1016
|
+
*/
|
|
1017
|
+
|
|
1018
|
+
function _depopulateIfNecessary(arr, docs) {
|
|
1019
|
+
const ref = arr == null ?
|
|
1020
|
+
null :
|
|
1021
|
+
arr[arraySchemaSymbol] && arr[arraySchemaSymbol].caster && arr[arraySchemaSymbol].caster.options && arr[arraySchemaSymbol].caster.options.ref || null;
|
|
1022
|
+
const parentDoc = arr[arrayParentSymbol];
|
|
1023
|
+
const path = arr[arrayPathSymbol];
|
|
1024
|
+
if (!ref || !parentDoc.populated(path)) {
|
|
1025
|
+
return;
|
|
1026
|
+
}
|
|
1027
|
+
for (const doc of docs) {
|
|
1028
|
+
if (doc == null) {
|
|
1029
|
+
continue;
|
|
1030
|
+
}
|
|
1031
|
+
if (typeof doc !== 'object' || doc instanceof String || doc instanceof Number || doc instanceof Buffer || utils.isMongooseType(doc)) {
|
|
1032
|
+
parentDoc.depopulate(path);
|
|
1033
|
+
break;
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1012
1038
|
const returnVanillaArrayMethods = [
|
|
1013
1039
|
'filter',
|
|
1014
1040
|
'flat',
|
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.7.0",
|
|
5
5
|
"author": "Guillermo Rauch <guillermo@learnboost.com>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mongodb",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"bson": "^6.7.0",
|
|
23
23
|
"kareem": "2.6.3",
|
|
24
|
-
"mongodb": "6.
|
|
24
|
+
"mongodb": "6.9.0",
|
|
25
25
|
"mpath": "0.9.0",
|
|
26
26
|
"mquery": "5.0.0",
|
|
27
27
|
"ms": "2.1.3",
|
package/types/document.d.ts
CHANGED
|
@@ -24,9 +24,6 @@ declare module 'mongoose' {
|
|
|
24
24
|
/** This documents _id. */
|
|
25
25
|
_id: T;
|
|
26
26
|
|
|
27
|
-
/** This documents __v. */
|
|
28
|
-
__v?: any;
|
|
29
|
-
|
|
30
27
|
/** Assert that a given path or paths is populated. Throws an error if not populated. */
|
|
31
28
|
$assertPopulated<Paths = {}>(path: string | string[], values?: Partial<Paths>): Omit<this, keyof Paths> & Paths;
|
|
32
29
|
|
package/types/index.d.ts
CHANGED
|
@@ -138,6 +138,10 @@ declare module 'mongoose' {
|
|
|
138
138
|
? IfAny<U, T & { _id: Types.ObjectId }, T & Required<{ _id: U }>>
|
|
139
139
|
: T & { _id: Types.ObjectId };
|
|
140
140
|
|
|
141
|
+
export type Default__v<T> = T extends { __v?: infer U }
|
|
142
|
+
? T
|
|
143
|
+
: T & { __v?: number };
|
|
144
|
+
|
|
141
145
|
/** Helper type for getting the hydrated document type from the raw document type. The hydrated document type is what `new MyModel()` returns. */
|
|
142
146
|
export type HydratedDocument<
|
|
143
147
|
DocType,
|
|
@@ -147,12 +151,12 @@ declare module 'mongoose' {
|
|
|
147
151
|
DocType,
|
|
148
152
|
any,
|
|
149
153
|
TOverrides extends Record<string, never> ?
|
|
150
|
-
Document<unknown, TQueryHelpers, DocType> & Require_id<DocType
|
|
154
|
+
Document<unknown, TQueryHelpers, DocType> & Default__v<Require_id<DocType>> :
|
|
151
155
|
IfAny<
|
|
152
156
|
TOverrides,
|
|
153
|
-
Document<unknown, TQueryHelpers, DocType> & Require_id<DocType
|
|
157
|
+
Document<unknown, TQueryHelpers, DocType> & Default__v<Require_id<DocType>>,
|
|
154
158
|
Document<unknown, TQueryHelpers, DocType> & MergeType<
|
|
155
|
-
Require_id<DocType
|
|
159
|
+
Default__v<Require_id<DocType>>,
|
|
156
160
|
TOverrides
|
|
157
161
|
>
|
|
158
162
|
>
|
package/types/models.d.ts
CHANGED
|
@@ -290,6 +290,9 @@ declare module 'mongoose' {
|
|
|
290
290
|
applyDefaults(obj: AnyObject): AnyObject;
|
|
291
291
|
applyDefaults(obj: TRawDocType): TRawDocType;
|
|
292
292
|
|
|
293
|
+
/* Apply virtuals to the given POJO. */
|
|
294
|
+
applyVirtuals(obj: AnyObject, virtalsToApply?: string[]): AnyObject;
|
|
295
|
+
|
|
293
296
|
/**
|
|
294
297
|
* Sends multiple `insertOne`, `updateOne`, `updateMany`, `replaceOne`,
|
|
295
298
|
* `deleteOne`, and/or `deleteMany` operations to the MongoDB server in one
|
package/types/schematypes.d.ts
CHANGED
|
@@ -232,6 +232,9 @@ declare module 'mongoose' {
|
|
|
232
232
|
/** Adds a getter to this schematype. */
|
|
233
233
|
get(fn: Function): this;
|
|
234
234
|
|
|
235
|
+
/** Gets this SchemaType's embedded SchemaType, if any */
|
|
236
|
+
getEmbeddedSchemaType<T = any, DocType = any>(): SchemaType<T, DocType> | undefined;
|
|
237
|
+
|
|
235
238
|
/**
|
|
236
239
|
* Defines this path as immutable. Mongoose prevents you from changing
|
|
237
240
|
* immutable paths unless the parent document has [`isNew: true`](/docs/api/document.html#document_Document-isNew).
|