mongoose 8.15.1 → 8.15.2
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/README.md +1 -1
- package/dist/browser.umd.js +1 -1
- package/lib/document.js +13 -4
- package/lib/helpers/populate/assignVals.js +18 -1
- package/lib/helpers/populate/getVirtual.js +31 -0
- package/lib/helpers/updateValidators.js +3 -1
- package/lib/model.js +9 -5
- package/lib/schema.js +22 -4
- package/lib/types/array/index.js +1 -6
- package/lib/types/documentArray/index.js +1 -6
- package/package.json +9 -8
- package/types/models.d.ts +1 -1
package/lib/document.js
CHANGED
|
@@ -1302,7 +1302,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1302
1302
|
let cur = this._doc;
|
|
1303
1303
|
let curPath = '';
|
|
1304
1304
|
for (i = 0; i < parts.length - 1; ++i) {
|
|
1305
|
-
cur = cur[parts[i]];
|
|
1305
|
+
cur = cur instanceof Map ? cur.get(parts[i]) : cur[parts[i]];
|
|
1306
1306
|
curPath += (curPath.length !== 0 ? '.' : '') + parts[i];
|
|
1307
1307
|
if (!cur) {
|
|
1308
1308
|
this.$set(curPath, {});
|
|
@@ -1433,9 +1433,9 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1433
1433
|
setterContext = getDeepestSubdocumentForPath(this, parts, this.schema);
|
|
1434
1434
|
}
|
|
1435
1435
|
if (options != null && options.overwriteImmutable) {
|
|
1436
|
-
val = schema.applySetters(val, setterContext, false, priorVal, { overwriteImmutable: true });
|
|
1436
|
+
val = schema.applySetters(val, setterContext, false, priorVal, { path, overwriteImmutable: true });
|
|
1437
1437
|
} else {
|
|
1438
|
-
val = schema.applySetters(val, setterContext, false, priorVal);
|
|
1438
|
+
val = schema.applySetters(val, setterContext, false, priorVal, { path });
|
|
1439
1439
|
}
|
|
1440
1440
|
}
|
|
1441
1441
|
|
|
@@ -2710,7 +2710,13 @@ function _getPathsToValidate(doc, pathsToValidate, pathsToSkip, isNestedValidate
|
|
|
2710
2710
|
Object.keys(doc.$__.activePaths.getStatePaths('init')).forEach(addToPaths);
|
|
2711
2711
|
Object.keys(doc.$__.activePaths.getStatePaths('modify')).forEach(addToPaths);
|
|
2712
2712
|
Object.keys(doc.$__.activePaths.getStatePaths('default')).forEach(addToPaths);
|
|
2713
|
-
function addToPaths(p) {
|
|
2713
|
+
function addToPaths(p) {
|
|
2714
|
+
if (p.endsWith('.$*')) {
|
|
2715
|
+
// Skip $* paths - they represent map schemas, not actual document paths
|
|
2716
|
+
return;
|
|
2717
|
+
}
|
|
2718
|
+
paths.add(p);
|
|
2719
|
+
}
|
|
2714
2720
|
|
|
2715
2721
|
if (!isNestedValidate) {
|
|
2716
2722
|
// If we're validating a subdocument, all this logic will run anyway on the top-level document, so skip for subdocuments.
|
|
@@ -2750,6 +2756,9 @@ function _getPathsToValidate(doc, pathsToValidate, pathsToSkip, isNestedValidate
|
|
|
2750
2756
|
}
|
|
2751
2757
|
|
|
2752
2758
|
const subdocParent = subdoc.$parent();
|
|
2759
|
+
if (subdocParent == null) {
|
|
2760
|
+
throw new Error('Cannot validate subdocument that does not have a parent');
|
|
2761
|
+
}
|
|
2753
2762
|
if (doc.$isModified(fullPathToSubdoc, null, modifiedPaths) &&
|
|
2754
2763
|
// Avoid using isDirectModified() here because that does additional checks on whether the parent path
|
|
2755
2764
|
// is direct modified, which can cause performance issues re: gh-14897
|
|
@@ -144,7 +144,24 @@ module.exports = function assignVals(o) {
|
|
|
144
144
|
if (Array.isArray(valueToSet)) {
|
|
145
145
|
valueToSet = valueToSet.map(v => v == null ? void 0 : v);
|
|
146
146
|
}
|
|
147
|
-
mpath.set(
|
|
147
|
+
mpath.set(
|
|
148
|
+
_path,
|
|
149
|
+
valueToSet,
|
|
150
|
+
docs[i],
|
|
151
|
+
// Handle setting paths underneath maps using $* by converting arrays into maps of values
|
|
152
|
+
function lookup(obj, part, val) {
|
|
153
|
+
if (arguments.length >= 3) {
|
|
154
|
+
obj[part] = val;
|
|
155
|
+
return obj[part];
|
|
156
|
+
}
|
|
157
|
+
if (obj instanceof Map && part === '$*') {
|
|
158
|
+
return [...obj.values()];
|
|
159
|
+
}
|
|
160
|
+
return obj[part];
|
|
161
|
+
},
|
|
162
|
+
setValue,
|
|
163
|
+
false
|
|
164
|
+
);
|
|
148
165
|
continue;
|
|
149
166
|
}
|
|
150
167
|
|
|
@@ -58,6 +58,37 @@ function getVirtual(schema, name) {
|
|
|
58
58
|
nestedSchemaPath += (nestedSchemaPath.length > 0 ? '.' : '') + cur;
|
|
59
59
|
cur = '';
|
|
60
60
|
continue;
|
|
61
|
+
} else if (schema.paths[cur]?.$isSchemaMap && schema.paths[cur].$__schemaType?.schema) {
|
|
62
|
+
schema = schema.paths[cur].$__schemaType.schema;
|
|
63
|
+
++i;
|
|
64
|
+
const rest = parts.slice(i + 1).join('.');
|
|
65
|
+
|
|
66
|
+
if (schema.virtuals[rest]) {
|
|
67
|
+
if (i === parts.length - 2) {
|
|
68
|
+
return {
|
|
69
|
+
virtual: schema.virtuals[rest],
|
|
70
|
+
nestedSchemaPath: [nestedSchemaPath, cur, '$*'].filter(v => !!v).join('.')
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (i + 1 < parts.length && schema.discriminators) {
|
|
77
|
+
for (const key of Object.keys(schema.discriminators)) {
|
|
78
|
+
const res = getVirtual(schema.discriminators[key], rest);
|
|
79
|
+
if (res != null) {
|
|
80
|
+
const _path = [nestedSchemaPath, cur, res.nestedSchemaPath, '$*'].
|
|
81
|
+
filter(v => !!v).join('.');
|
|
82
|
+
return {
|
|
83
|
+
virtual: res.virtual,
|
|
84
|
+
nestedSchemaPath: _path
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
nestedSchemaPath += (nestedSchemaPath.length > 0 ? '.' : '') + '$*' + cur;
|
|
91
|
+
cur = '';
|
|
61
92
|
}
|
|
62
93
|
|
|
63
94
|
if (schema.discriminators) {
|
|
@@ -147,6 +147,9 @@ module.exports = function(query, schema, castedDoc, options, callback) {
|
|
|
147
147
|
return callback(null);
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
|
+
if (schemaPath.$isSingleNested) {
|
|
151
|
+
alreadyValidated.push(updates[i]);
|
|
152
|
+
}
|
|
150
153
|
|
|
151
154
|
schemaPath.doValidate(v, function(err) {
|
|
152
155
|
if (schemaPath.schema != null &&
|
|
@@ -246,4 +249,3 @@ module.exports = function(query, schema, castedDoc, options, callback) {
|
|
|
246
249
|
};
|
|
247
250
|
}
|
|
248
251
|
};
|
|
249
|
-
|
package/lib/model.js
CHANGED
|
@@ -460,8 +460,8 @@ Model.prototype.$__handleSave = function(options, callback) {
|
|
|
460
460
|
return;
|
|
461
461
|
}
|
|
462
462
|
|
|
463
|
-
// store the modified paths before the document is reset
|
|
464
|
-
this.$__.modifiedPaths = this.modifiedPaths();
|
|
463
|
+
// store the modified paths before the document is reset in case we need to generate version error.
|
|
464
|
+
this.$__.modifiedPaths = this.modifiedPaths().concat(Object.keys(this.$__.activePaths.getStatePaths('default')));
|
|
465
465
|
this.$__reset();
|
|
466
466
|
|
|
467
467
|
_setIsNew(this, false);
|
|
@@ -562,13 +562,13 @@ Model.prototype.$__save = function(options, callback) {
|
|
|
562
562
|
* ignore
|
|
563
563
|
*/
|
|
564
564
|
|
|
565
|
-
function generateVersionError(doc, modifiedPaths) {
|
|
565
|
+
function generateVersionError(doc, modifiedPaths, defaultPaths) {
|
|
566
566
|
const key = doc.$__schema.options.versionKey;
|
|
567
567
|
if (!key) {
|
|
568
568
|
return null;
|
|
569
569
|
}
|
|
570
570
|
const version = doc.$__getValue(key) || 0;
|
|
571
|
-
return new VersionError(doc, version, modifiedPaths);
|
|
571
|
+
return new VersionError(doc, version, modifiedPaths.concat(defaultPaths));
|
|
572
572
|
}
|
|
573
573
|
|
|
574
574
|
/**
|
|
@@ -626,7 +626,11 @@ Model.prototype.save = async function save(options) {
|
|
|
626
626
|
if (this.$__.timestamps != null) {
|
|
627
627
|
options.timestamps = this.$__.timestamps;
|
|
628
628
|
}
|
|
629
|
-
this.$__.$versionError = generateVersionError(
|
|
629
|
+
this.$__.$versionError = generateVersionError(
|
|
630
|
+
this,
|
|
631
|
+
this.modifiedPaths(),
|
|
632
|
+
Object.keys(this.$__.activePaths.getStatePaths('default'))
|
|
633
|
+
);
|
|
630
634
|
|
|
631
635
|
if (parallelSave) {
|
|
632
636
|
this.$__handleReject(parallelSave);
|
package/lib/schema.js
CHANGED
|
@@ -1482,10 +1482,24 @@ function getMapPath(schema, path) {
|
|
|
1482
1482
|
return null;
|
|
1483
1483
|
}
|
|
1484
1484
|
for (const val of schema.mapPaths) {
|
|
1485
|
-
const
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1485
|
+
const cleanPath = val.path.replace(/\.\$\*/g, '');
|
|
1486
|
+
if (path === cleanPath || (path.startsWith(cleanPath + '.') && path.slice(cleanPath.length + 1).indexOf('.') === -1)) {
|
|
1487
|
+
return val;
|
|
1488
|
+
} else if (val.schema && path.startsWith(cleanPath + '.')) {
|
|
1489
|
+
let remnant = path.slice(cleanPath.length + 1);
|
|
1490
|
+
remnant = remnant.slice(remnant.indexOf('.') + 1);
|
|
1491
|
+
return val.schema.paths[remnant];
|
|
1492
|
+
} else if (val.$isSchemaMap && path.startsWith(cleanPath + '.')) {
|
|
1493
|
+
let remnant = path.slice(cleanPath.length + 1);
|
|
1494
|
+
remnant = remnant.slice(remnant.indexOf('.') + 1);
|
|
1495
|
+
const presplitPath = val.$__schemaType._presplitPath;
|
|
1496
|
+
if (remnant.indexOf('.') === -1 && presplitPath[presplitPath.length - 1] === '$*') {
|
|
1497
|
+
// Handle map of map of primitives
|
|
1498
|
+
return val.$__schemaType;
|
|
1499
|
+
} else if (remnant.indexOf('.') !== -1 && val.$__schemaType.schema && presplitPath[presplitPath.length - 1] === '$*') {
|
|
1500
|
+
// map of map of subdocs (recursive)
|
|
1501
|
+
return val.$__schemaType.schema.path(remnant.slice(remnant.indexOf('.') + 1));
|
|
1502
|
+
}
|
|
1489
1503
|
}
|
|
1490
1504
|
}
|
|
1491
1505
|
|
|
@@ -2608,6 +2622,10 @@ Schema.prototype.virtual = function(name, options) {
|
|
|
2608
2622
|
const remnant = parts.slice(i + 1).join('.');
|
|
2609
2623
|
this.paths[cur].schema.virtual(remnant, options);
|
|
2610
2624
|
break;
|
|
2625
|
+
} else if (this.paths[cur].$isSchemaMap) {
|
|
2626
|
+
const remnant = parts.slice(i + 2).join('.');
|
|
2627
|
+
this.paths[cur].$__schemaType.schema.virtual(remnant, options);
|
|
2628
|
+
break;
|
|
2611
2629
|
}
|
|
2612
2630
|
|
|
2613
2631
|
cur += '.' + parts[i + 1];
|
package/lib/types/array/index.js
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
'use strict';
|
|
6
6
|
|
|
7
|
-
const Document = require('../../document');
|
|
8
7
|
const mongooseArrayMethods = require('./methods');
|
|
9
8
|
|
|
10
9
|
const arrayAtomicsSymbol = require('../../helpers/symbols').arrayAtomicsSymbol;
|
|
@@ -73,11 +72,7 @@ function MongooseArray(values, path, doc, schematype) {
|
|
|
73
72
|
internals[arrayAtomicsSymbol] = values[arrayAtomicsSymbol];
|
|
74
73
|
}
|
|
75
74
|
|
|
76
|
-
|
|
77
|
-
// can happen if there was a null somewhere up the chain (see #3020)
|
|
78
|
-
// RB Jun 17, 2015 updated to check for presence of expected paths instead
|
|
79
|
-
// to make more proof against unusual node environments
|
|
80
|
-
if (doc != null && doc instanceof Document) {
|
|
75
|
+
if (doc != null && doc.$__) {
|
|
81
76
|
internals[arrayParentSymbol] = doc;
|
|
82
77
|
internals[arraySchemaSymbol] = schematype || doc.schema.path(path);
|
|
83
78
|
}
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
|
|
7
7
|
const ArrayMethods = require('../array/methods');
|
|
8
8
|
const DocumentArrayMethods = require('./methods');
|
|
9
|
-
const Document = require('../../document');
|
|
10
9
|
|
|
11
10
|
const arrayAtomicsSymbol = require('../../helpers/symbols').arrayAtomicsSymbol;
|
|
12
11
|
const arrayAtomicsBackupSymbol = require('../../helpers/symbols').arrayAtomicsBackupSymbol;
|
|
@@ -51,11 +50,7 @@ function MongooseDocumentArray(values, path, doc, schematype) {
|
|
|
51
50
|
internals[arrayPathSymbol] = path;
|
|
52
51
|
internals.__array = __array;
|
|
53
52
|
|
|
54
|
-
|
|
55
|
-
// can happen if there was a null somewhere up the chain (see #3020 && #3034)
|
|
56
|
-
// RB Jun 17, 2015 updated to check for presence of expected paths instead
|
|
57
|
-
// to make more proof against unusual node environments
|
|
58
|
-
if (doc && doc instanceof Document) {
|
|
53
|
+
if (doc && doc.$__) {
|
|
59
54
|
internals[arrayParentSymbol] = doc;
|
|
60
55
|
internals[arraySchemaSymbol] = doc.$__schema.path(path);
|
|
61
56
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongoose",
|
|
3
3
|
"description": "Mongoose MongoDB ODM",
|
|
4
|
-
"version": "8.15.
|
|
4
|
+
"version": "8.15.2",
|
|
5
5
|
"author": "Guillermo Rauch <guillermo@learnboost.com>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mongodb",
|
|
@@ -29,12 +29,12 @@
|
|
|
29
29
|
"sift": "17.1.3"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@babel/core": "7.27.
|
|
33
|
-
"@babel/preset-env": "7.27.
|
|
32
|
+
"@babel/core": "7.27.4",
|
|
33
|
+
"@babel/preset-env": "7.27.2",
|
|
34
34
|
"@mongodb-js/mongodb-downloader": "^0.3.9",
|
|
35
35
|
"@typescript-eslint/eslint-plugin": "^8.19.1",
|
|
36
36
|
"@typescript-eslint/parser": "^8.19.1",
|
|
37
|
-
"acquit": "1.
|
|
37
|
+
"acquit": "1.4.0",
|
|
38
38
|
"acquit-ignore": "0.2.1",
|
|
39
39
|
"acquit-require": "0.1.1",
|
|
40
40
|
"ajv": "8.17.1",
|
|
@@ -53,10 +53,10 @@
|
|
|
53
53
|
"highlight.js": "11.11.1",
|
|
54
54
|
"lodash.isequal": "4.5.0",
|
|
55
55
|
"lodash.isequalwith": "4.4.0",
|
|
56
|
-
"markdownlint-cli2": "^0.
|
|
57
|
-
"marked": "15.0.
|
|
56
|
+
"markdownlint-cli2": "^0.18.1",
|
|
57
|
+
"marked": "15.0.12",
|
|
58
58
|
"mkdirp": "^3.0.1",
|
|
59
|
-
"mocha": "11.
|
|
59
|
+
"mocha": "11.5.0",
|
|
60
60
|
"moment": "2.30.1",
|
|
61
61
|
"mongodb-memory-server": "10.1.4",
|
|
62
62
|
"mongodb-runner": "^5.8.2",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"tsd": "0.32.0",
|
|
70
70
|
"typescript": "5.8.3",
|
|
71
71
|
"uuid": "11.1.0",
|
|
72
|
-
"webpack": "5.99.
|
|
72
|
+
"webpack": "5.99.9"
|
|
73
73
|
},
|
|
74
74
|
"directories": {
|
|
75
75
|
"lib": "./lib/mongoose"
|
|
@@ -102,6 +102,7 @@
|
|
|
102
102
|
"release-6x": "git pull origin 6.x && git push origin 6.x && git push origin 6.x --tags && npm publish --tag 6x",
|
|
103
103
|
"mongo": "node ./tools/repl.js",
|
|
104
104
|
"publish-7x": "npm publish --tag 7x",
|
|
105
|
+
"create-separate-require-instance": "rm -rf ./node_modules/mongoose-separate-require-instance && node ./scripts/create-tarball && tar -xzf mongoose.tgz -C ./node_modules && mv ./node_modules/package ./node_modules/mongoose-separate-require-instance",
|
|
105
106
|
"test": "mocha --exit ./test/*.test.js",
|
|
106
107
|
"test-deno": "deno run --allow-env --allow-read --allow-net --allow-run --allow-sys --allow-write ./test/deno.mjs",
|
|
107
108
|
"test-rs": "START_REPLICA_SET=1 mocha --timeout 30000 --exit ./test/*.test.js",
|
package/types/models.d.ts
CHANGED
|
@@ -482,7 +482,7 @@ declare module 'mongoose' {
|
|
|
482
482
|
* Shortcut for creating a new Document from existing raw data, pre-saved in the DB.
|
|
483
483
|
* The document returned has no paths marked as modified initially.
|
|
484
484
|
*/
|
|
485
|
-
hydrate(obj: any, projection?:
|
|
485
|
+
hydrate(obj: any, projection?: ProjectionType<TRawDocType>, options?: HydrateOptions): THydratedDocumentType;
|
|
486
486
|
|
|
487
487
|
/**
|
|
488
488
|
* This function is responsible for building [indexes](https://www.mongodb.com/docs/manual/indexes/),
|