mongoose 8.14.0 → 8.14.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/dist/browser.umd.js +1 -1
- package/lib/helpers/populate/assignRawDocsToIdStructure.js +2 -0
- package/lib/helpers/query/getEmbeddedDiscriminatorPath.js +5 -2
- package/lib/helpers/schema/getPath.js +5 -2
- package/lib/helpers/update/castArrayFilters.js +7 -2
- package/lib/model.js +16 -2
- package/lib/schema/map.js +2 -2
- package/lib/schema.js +1 -1
- package/lib/types/buffer.js +17 -0
- package/lib/types/map.js +1 -1
- package/package.json +9 -9
- package/types/schemaoptions.d.ts +3 -2
|
@@ -81,6 +81,8 @@ function assignRawDocsToIdStructure(rawIds, resultDocs, resultOrder, options, re
|
|
|
81
81
|
if (id?.constructor?.name === 'Binary' && id.sub_type === 4 && typeof id.toUUID === 'function') {
|
|
82
82
|
// Workaround for gh-15315 because Mongoose UUIDs don't use BSON UUIDs yet.
|
|
83
83
|
sid = String(id.toUUID());
|
|
84
|
+
} else if (id?.constructor?.name === 'Buffer' && id._subtype === 4 && typeof id.toUUID === 'function') {
|
|
85
|
+
sid = String(id.toUUID());
|
|
84
86
|
} else {
|
|
85
87
|
sid = String(id);
|
|
86
88
|
}
|
|
@@ -17,7 +17,7 @@ const updatedPathsByArrayFilter = require('../update/updatedPathsByArrayFilter')
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
module.exports = function getEmbeddedDiscriminatorPath(schema, update, filter, path, options) {
|
|
20
|
-
const parts = path.split('.');
|
|
20
|
+
const parts = path.indexOf('.') === -1 ? [path] : path.split('.');
|
|
21
21
|
let schematype = null;
|
|
22
22
|
let type = 'adhocOrUndefined';
|
|
23
23
|
|
|
@@ -26,9 +26,10 @@ module.exports = function getEmbeddedDiscriminatorPath(schema, update, filter, p
|
|
|
26
26
|
const arrayFilters = options != null && Array.isArray(options.arrayFilters) ?
|
|
27
27
|
options.arrayFilters : [];
|
|
28
28
|
const updatedPathsByFilter = updatedPathsByArrayFilter(update);
|
|
29
|
+
let startIndex = 0;
|
|
29
30
|
|
|
30
31
|
for (let i = 0; i < parts.length; ++i) {
|
|
31
|
-
const originalSubpath = parts.slice(
|
|
32
|
+
const originalSubpath = parts.slice(startIndex, i + 1).join('.');
|
|
32
33
|
const subpath = cleanPositionalOperators(originalSubpath);
|
|
33
34
|
schematype = schema.path(subpath);
|
|
34
35
|
if (schematype == null) {
|
|
@@ -89,6 +90,8 @@ module.exports = function getEmbeddedDiscriminatorPath(schema, update, filter, p
|
|
|
89
90
|
|
|
90
91
|
const rest = parts.slice(i + 1).join('.');
|
|
91
92
|
schematype = discriminatorSchema.path(rest);
|
|
93
|
+
schema = discriminatorSchema;
|
|
94
|
+
startIndex = i + 1;
|
|
92
95
|
if (schematype != null) {
|
|
93
96
|
type = discriminatorSchema._getPathType(rest);
|
|
94
97
|
break;
|
|
@@ -8,7 +8,7 @@ const numberRE = /^\d+$/;
|
|
|
8
8
|
* @api private
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
module.exports = function getPath(schema, path) {
|
|
11
|
+
module.exports = function getPath(schema, path, discriminatorValueMap) {
|
|
12
12
|
let schematype = schema.path(path);
|
|
13
13
|
if (schematype != null) {
|
|
14
14
|
return schematype;
|
|
@@ -26,10 +26,13 @@ module.exports = function getPath(schema, path) {
|
|
|
26
26
|
schematype = schema.path(cur);
|
|
27
27
|
if (schematype != null && schematype.schema) {
|
|
28
28
|
schema = schematype.schema;
|
|
29
|
-
cur = '';
|
|
30
29
|
if (!isArray && schematype.$isMongooseDocumentArray) {
|
|
31
30
|
isArray = true;
|
|
32
31
|
}
|
|
32
|
+
if (discriminatorValueMap && discriminatorValueMap[cur]) {
|
|
33
|
+
schema = schema.discriminators[discriminatorValueMap[cur]] ?? schema;
|
|
34
|
+
}
|
|
35
|
+
cur = '';
|
|
33
36
|
}
|
|
34
37
|
}
|
|
35
38
|
|
|
@@ -33,6 +33,10 @@ function _castArrayFilters(arrayFilters, schema, strictQuery, updatedPathsByFilt
|
|
|
33
33
|
return;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
// Map to store discriminator values for embedded documents in the array filters.
|
|
37
|
+
// This is used to handle cases where array filters target specific embedded document types.
|
|
38
|
+
const discriminatorValueMap = {};
|
|
39
|
+
|
|
36
40
|
for (const filter of arrayFilters) {
|
|
37
41
|
if (filter == null) {
|
|
38
42
|
throw new Error(`Got null array filter in ${arrayFilters}`);
|
|
@@ -58,12 +62,13 @@ function _castArrayFilters(arrayFilters, schema, strictQuery, updatedPathsByFilt
|
|
|
58
62
|
updatedPathsByFilter[filterWildcardPath]
|
|
59
63
|
);
|
|
60
64
|
|
|
61
|
-
const baseSchematype = getPath(schema, baseFilterPath);
|
|
65
|
+
const baseSchematype = getPath(schema, baseFilterPath, discriminatorValueMap);
|
|
62
66
|
let filterBaseSchema = baseSchematype != null ? baseSchematype.schema : null;
|
|
63
67
|
if (filterBaseSchema != null &&
|
|
64
68
|
filterBaseSchema.discriminators != null &&
|
|
65
69
|
filter[filterWildcardPath + '.' + filterBaseSchema.options.discriminatorKey]) {
|
|
66
70
|
filterBaseSchema = filterBaseSchema.discriminators[filter[filterWildcardPath + '.' + filterBaseSchema.options.discriminatorKey]] || filterBaseSchema;
|
|
71
|
+
discriminatorValueMap[baseFilterPath] = filter[filterWildcardPath + '.' + filterBaseSchema.options.discriminatorKey];
|
|
67
72
|
}
|
|
68
73
|
|
|
69
74
|
for (const key of keys) {
|
|
@@ -83,7 +88,7 @@ function _castArrayFilters(arrayFilters, schema, strictQuery, updatedPathsByFilt
|
|
|
83
88
|
// If there are multiple array filters in the path being updated, make sure
|
|
84
89
|
// to replace them so we can get the schema path.
|
|
85
90
|
filterPathRelativeToBase = cleanPositionalOperators(filterPathRelativeToBase);
|
|
86
|
-
schematype = getPath(filterBaseSchema, filterPathRelativeToBase);
|
|
91
|
+
schematype = getPath(filterBaseSchema, filterPathRelativeToBase, discriminatorValueMap);
|
|
87
92
|
}
|
|
88
93
|
|
|
89
94
|
if (schematype == null) {
|
package/lib/model.js
CHANGED
|
@@ -4688,7 +4688,14 @@ function _assign(model, vals, mod, assignmentOpts) {
|
|
|
4688
4688
|
if (__val instanceof Document) {
|
|
4689
4689
|
__val = __val._doc._id;
|
|
4690
4690
|
}
|
|
4691
|
-
|
|
4691
|
+
if (__val?.constructor?.name === 'Binary' && __val.sub_type === 4 && typeof __val.toUUID === 'function') {
|
|
4692
|
+
// Workaround for gh-15315 because Mongoose UUIDs don't use BSON UUIDs yet.
|
|
4693
|
+
key = String(__val.toUUID());
|
|
4694
|
+
} else if (__val?.constructor?.name === 'Buffer' && __val._subtype === 4 && typeof __val.toUUID === 'function') {
|
|
4695
|
+
key = String(__val.toUUID());
|
|
4696
|
+
} else {
|
|
4697
|
+
key = String(__val);
|
|
4698
|
+
}
|
|
4692
4699
|
if (rawDocs[key]) {
|
|
4693
4700
|
if (Array.isArray(rawDocs[key])) {
|
|
4694
4701
|
rawDocs[key].push(val);
|
|
@@ -4711,7 +4718,14 @@ function _assign(model, vals, mod, assignmentOpts) {
|
|
|
4711
4718
|
if (_val instanceof Document) {
|
|
4712
4719
|
_val = _val._doc._id;
|
|
4713
4720
|
}
|
|
4714
|
-
|
|
4721
|
+
if (_val?.constructor?.name === 'Binary' && _val.sub_type === 4 && typeof _val.toUUID === 'function') {
|
|
4722
|
+
// Workaround for gh-15315 because Mongoose UUIDs don't use BSON UUIDs yet.
|
|
4723
|
+
key = String(_val.toUUID());
|
|
4724
|
+
} else if (_val?.constructor?.name === 'Buffer' && _val._subtype === 4 && typeof _val.toUUID === 'function') {
|
|
4725
|
+
key = String(_val.toUUID());
|
|
4726
|
+
} else {
|
|
4727
|
+
key = String(_val);
|
|
4728
|
+
}
|
|
4715
4729
|
if (rawDocs[key]) {
|
|
4716
4730
|
if (Array.isArray(rawDocs[key])) {
|
|
4717
4731
|
rawDocs[key].push(val);
|
package/lib/schema/map.js
CHANGED
|
@@ -23,12 +23,12 @@ class SchemaMap extends SchemaType {
|
|
|
23
23
|
return SchemaType.set(option, value);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
cast(val, doc, init) {
|
|
26
|
+
cast(val, doc, init, prev, options) {
|
|
27
27
|
if (val instanceof MongooseMap) {
|
|
28
28
|
return val;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
const path = this.path;
|
|
31
|
+
const path = options?.path ?? this.path;
|
|
32
32
|
|
|
33
33
|
if (init) {
|
|
34
34
|
const map = new MongooseMap({}, path, doc, this.$__schemaType);
|
package/lib/schema.js
CHANGED
|
@@ -77,7 +77,7 @@ const numberRE = /^\d+$/;
|
|
|
77
77
|
* - [validateBeforeSave](https://mongoosejs.com/docs/guide.html#validateBeforeSave) - bool - defaults to `true`
|
|
78
78
|
* - [validateModifiedOnly](https://mongoosejs.com/docs/api/document.html#Document.prototype.validate()) - bool - defaults to `false`
|
|
79
79
|
* - [versionKey](https://mongoosejs.com/docs/guide.html#versionKey): string or object - defaults to "__v"
|
|
80
|
-
* - [optimisticConcurrency](https://mongoosejs.com/docs/guide.html#optimisticConcurrency): bool - defaults to false. Set to true to enable [optimistic concurrency](https://thecodebarbarian.com/whats-new-in-mongoose-5-10-optimistic-concurrency.html).
|
|
80
|
+
* - [optimisticConcurrency](https://mongoosejs.com/docs/guide.html#optimisticConcurrency): bool or string[] or { exclude: string[] } - defaults to false. Set to true to enable [optimistic concurrency](https://thecodebarbarian.com/whats-new-in-mongoose-5-10-optimistic-concurrency.html). Set to string array to enable optimistic concurrency for only certain fields, or `{ exclude: string[] }` to define a list of fields to ignore for optimistic concurrency.
|
|
81
81
|
* - [collation](https://mongoosejs.com/docs/guide.html#collation): object - defaults to null (which means use no collation)
|
|
82
82
|
* - [timeseries](https://mongoosejs.com/docs/guide.html#timeseries): object - defaults to null (which means this schema's collection won't be a timeseries collection)
|
|
83
83
|
* - [selectPopulatedPaths](https://mongoosejs.com/docs/guide.html#selectPopulatedPaths): boolean - defaults to `true`
|
package/lib/types/buffer.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
'use strict';
|
|
6
6
|
|
|
7
7
|
const Binary = require('bson').Binary;
|
|
8
|
+
const UUID = require('bson').UUID;
|
|
8
9
|
const utils = require('../utils');
|
|
9
10
|
|
|
10
11
|
/**
|
|
@@ -207,6 +208,22 @@ MongooseBuffer.mixin.toBSON = function() {
|
|
|
207
208
|
return new Binary(this, this._subtype || 0);
|
|
208
209
|
};
|
|
209
210
|
|
|
211
|
+
/**
|
|
212
|
+
* Converts this buffer to a UUID. Throws an error if subtype is not 4.
|
|
213
|
+
*
|
|
214
|
+
* @return {UUID}
|
|
215
|
+
* @api public
|
|
216
|
+
* @method toUUID
|
|
217
|
+
* @memberOf MongooseBuffer
|
|
218
|
+
*/
|
|
219
|
+
|
|
220
|
+
MongooseBuffer.mixin.toUUID = function() {
|
|
221
|
+
if (this._subtype !== 4) {
|
|
222
|
+
throw new Error('Cannot convert a Buffer with subtype ' + this._subtype + ' to a UUID');
|
|
223
|
+
}
|
|
224
|
+
return new UUID(this);
|
|
225
|
+
};
|
|
226
|
+
|
|
210
227
|
/**
|
|
211
228
|
* Determines if this buffer is equals to `other` buffer
|
|
212
229
|
*
|
package/lib/types/map.js
CHANGED
|
@@ -136,7 +136,7 @@ class MongooseMap extends Map {
|
|
|
136
136
|
}
|
|
137
137
|
} else {
|
|
138
138
|
try {
|
|
139
|
-
const options = this.$__schemaType.$isMongooseDocumentArray || this.$__schemaType.$isSingleNested ?
|
|
139
|
+
const options = this.$__schemaType.$isMongooseDocumentArray || this.$__schemaType.$isSingleNested || this.$__schemaType.$isMongooseArray || this.$__schemaType.$isSchemaMap ?
|
|
140
140
|
{ path: fullPath.call(this) } :
|
|
141
141
|
null;
|
|
142
142
|
value = this.$__schemaType.applySetters(
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongoose",
|
|
3
3
|
"description": "Mongoose MongoDB ODM",
|
|
4
|
-
"version": "8.14.
|
|
4
|
+
"version": "8.14.2",
|
|
5
5
|
"author": "Guillermo Rauch <guillermo@learnboost.com>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mongodb",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"sift": "17.1.3"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@babel/core": "7.
|
|
33
|
-
"@babel/preset-env": "7.
|
|
32
|
+
"@babel/core": "7.27.1",
|
|
33
|
+
"@babel/preset-env": "7.27.1",
|
|
34
34
|
"@typescript-eslint/eslint-plugin": "^8.19.1",
|
|
35
35
|
"@typescript-eslint/parser": "^8.19.1",
|
|
36
36
|
"acquit": "1.3.0",
|
|
@@ -53,9 +53,9 @@
|
|
|
53
53
|
"lodash.isequal": "4.5.0",
|
|
54
54
|
"lodash.isequalwith": "4.4.0",
|
|
55
55
|
"markdownlint-cli2": "^0.17.1",
|
|
56
|
-
"marked": "15.0.
|
|
56
|
+
"marked": "15.0.11",
|
|
57
57
|
"mkdirp": "^3.0.1",
|
|
58
|
-
"mocha": "11.
|
|
58
|
+
"mocha": "11.2.2",
|
|
59
59
|
"moment": "2.30.1",
|
|
60
60
|
"mongodb-memory-server": "10.1.4",
|
|
61
61
|
"ncp": "^2.0.0",
|
|
@@ -64,10 +64,10 @@
|
|
|
64
64
|
"q": "1.5.1",
|
|
65
65
|
"sinon": "20.0.0",
|
|
66
66
|
"stream-browserify": "3.0.0",
|
|
67
|
-
"tsd": "0.
|
|
68
|
-
"typescript": "5.
|
|
67
|
+
"tsd": "0.32.0",
|
|
68
|
+
"typescript": "5.8.3",
|
|
69
69
|
"uuid": "11.1.0",
|
|
70
|
-
"webpack": "5.
|
|
70
|
+
"webpack": "5.99.7"
|
|
71
71
|
},
|
|
72
72
|
"directories": {
|
|
73
73
|
"lib": "./lib/mongoose"
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"mongo": "node ./tools/repl.js",
|
|
102
102
|
"publish-7x": "npm publish --tag 7x",
|
|
103
103
|
"test": "mocha --exit ./test/*.test.js",
|
|
104
|
-
"test-deno": "deno run --allow-env --allow-read --allow-net --allow-run --allow-sys --allow-write ./test/deno.
|
|
104
|
+
"test-deno": "deno run --allow-env --allow-read --allow-net --allow-run --allow-sys --allow-write ./test/deno.mjs",
|
|
105
105
|
"test-rs": "START_REPLICA_SET=1 mocha --timeout 30000 --exit ./test/*.test.js",
|
|
106
106
|
"test-tsd": "node ./test/types/check-types-filename && tsd",
|
|
107
107
|
"setup-test-encryption": "bash scripts/configure-cluster-with-encryption.sh",
|
package/types/schemaoptions.d.ts
CHANGED
|
@@ -107,9 +107,10 @@ declare module 'mongoose' {
|
|
|
107
107
|
/**
|
|
108
108
|
* Optimistic concurrency is a strategy to ensure the document you're updating didn't change between when you
|
|
109
109
|
* loaded it using find() or findOne(), and when you update it using save(). Set to `true` to enable
|
|
110
|
-
* optimistic concurrency.
|
|
110
|
+
* optimistic concurrency. Set to string array to enable optimistic concurrency for only certain fields,
|
|
111
|
+
* or `{ exclude: string[] }` to define a list of fields to ignore for optimistic concurrency.
|
|
111
112
|
*/
|
|
112
|
-
optimisticConcurrency?: boolean;
|
|
113
|
+
optimisticConcurrency?: boolean | string[] | { exclude: string[] };
|
|
113
114
|
/**
|
|
114
115
|
* If `plugin()` called with tags, Mongoose will only apply plugins to schemas that have
|
|
115
116
|
* a matching tag in `pluginTags`
|