mongoose 9.0.1 → 9.1.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/lib/aggregate.js +1 -1
- package/lib/cast/string.js +1 -1
- package/lib/cast.js +7 -15
- package/lib/collection.js +2 -2
- package/lib/connection.js +20 -14
- package/lib/cursor/changeStream.js +5 -5
- package/lib/document.js +126 -79
- package/lib/drivers/node-mongodb-native/collection.js +33 -126
- package/lib/drivers/node-mongodb-native/connection.js +8 -23
- package/lib/error/cast.js +1 -1
- package/lib/helpers/aggregate/prepareDiscriminatorPipeline.js +4 -4
- package/lib/helpers/clone.js +8 -8
- package/lib/helpers/common.js +4 -4
- package/lib/helpers/cursor/eachAsync.js +1 -1
- package/lib/helpers/discriminator/getConstructor.js +1 -1
- package/lib/helpers/discriminator/getSchemaDiscriminatorByValue.js +1 -1
- package/lib/helpers/discriminator/mergeDiscriminatorSchema.js +2 -2
- package/lib/helpers/document/applyDefaults.js +1 -1
- package/lib/helpers/document/applyTimestamps.js +2 -1
- package/lib/helpers/document/applyVirtuals.js +4 -3
- package/lib/helpers/document/cleanModifiedSubpaths.js +1 -1
- package/lib/helpers/document/compile.js +4 -4
- package/lib/helpers/document/getDeepestSubdocumentForPath.js +1 -1
- package/lib/helpers/indexes/decorateDiscriminatorIndexOptions.js +1 -1
- package/lib/helpers/indexes/getRelatedIndexes.js +3 -3
- package/lib/helpers/model/castBulkWrite.js +5 -9
- package/lib/helpers/model/discriminator.js +1 -1
- package/lib/helpers/populate/assignRawDocsToIdStructure.js +1 -1
- package/lib/helpers/populate/assignVals.js +4 -4
- package/lib/helpers/populate/getModelsMapForPopulate.js +25 -23
- package/lib/helpers/populate/getSchemaTypes.js +6 -7
- package/lib/helpers/printJestWarning.js +1 -1
- package/lib/helpers/processConnectionOptions.js +1 -1
- package/lib/helpers/query/castUpdate.js +12 -12
- package/lib/helpers/query/getEmbeddedDiscriminatorPath.js +2 -2
- package/lib/helpers/query/handleImmutable.js +2 -2
- package/lib/helpers/query/sanitizeFilter.js +1 -1
- package/lib/helpers/schema/applyPlugins.js +1 -1
- package/lib/helpers/schema/applyReadConcern.js +1 -1
- package/lib/helpers/schema/applyWriteConcern.js +4 -2
- package/lib/helpers/schema/getIndexes.js +3 -3
- package/lib/helpers/schema/getSubdocumentStrictValue.js +1 -1
- package/lib/helpers/schema/handleIdOption.js +1 -1
- package/lib/helpers/schema/idGetter.js +1 -1
- package/lib/helpers/schematype/handleImmutable.js +1 -1
- package/lib/helpers/setDefaultsOnInsert.js +2 -5
- package/lib/helpers/timestamps/setDocumentTimestamps.js +2 -2
- package/lib/helpers/timestamps/setupTimestamps.js +2 -2
- package/lib/helpers/update/applyTimestampsToUpdate.js +10 -9
- package/lib/helpers/update/castArrayFilters.js +4 -4
- package/lib/helpers/update/decorateUpdateWithVersionKey.js +1 -1
- package/lib/helpers/updateValidators.js +4 -4
- package/lib/model.js +42 -48
- package/lib/mongoose.js +5 -5
- package/lib/options/virtualOptions.js +1 -1
- package/lib/plugins/saveSubdocs.js +2 -2
- package/lib/plugins/trackTransaction.js +3 -4
- package/lib/query.js +62 -59
- package/lib/queryHelpers.js +9 -12
- package/lib/schema/array.js +10 -12
- package/lib/schema/buffer.js +6 -6
- package/lib/schema/documentArray.js +15 -23
- package/lib/schema/documentArrayElement.js +3 -3
- package/lib/schema/map.js +1 -1
- package/lib/schema/mixed.js +2 -2
- package/lib/schema/number.js +22 -4
- package/lib/schema/objectId.js +1 -1
- package/lib/schema/operators/exists.js +1 -1
- package/lib/schema/operators/geospatial.js +1 -1
- package/lib/schema/string.js +2 -2
- package/lib/schema/subdocument.js +9 -12
- package/lib/schema/union.js +1 -1
- package/lib/schema.js +27 -28
- package/lib/schemaType.js +11 -11
- package/lib/types/array/index.js +2 -2
- package/lib/types/array/methods/index.js +38 -8
- package/lib/types/arraySubdocument.js +12 -2
- package/lib/types/buffer.js +1 -1
- package/lib/types/documentArray/index.js +2 -2
- package/lib/types/documentArray/methods/index.js +5 -5
- package/lib/types/map.js +8 -8
- package/lib/types/subdocument.js +15 -5
- package/lib/utils.js +23 -7
- package/package.json +3 -2
- package/types/index.d.ts +26 -9
- package/types/inferrawdoctype.d.ts +9 -3
- package/types/inferschematype.d.ts +20 -27
- package/types/middlewares.d.ts +11 -0
- package/types/models.d.ts +15 -5
- package/types/query.d.ts +1 -1
- package/types/schemaoptions.d.ts +4 -2
- package/types/utility.d.ts +1 -1
- package/types/virtuals.d.ts +3 -3
|
@@ -80,12 +80,6 @@ NativeCollection.prototype._getCollection = function _getCollection() {
|
|
|
80
80
|
return null;
|
|
81
81
|
};
|
|
82
82
|
|
|
83
|
-
/*!
|
|
84
|
-
* ignore
|
|
85
|
-
*/
|
|
86
|
-
|
|
87
|
-
const syncCollectionMethods = { watch: true, find: true, aggregate: true };
|
|
88
|
-
|
|
89
83
|
/**
|
|
90
84
|
* Copy the collection methods and make them subject to queues
|
|
91
85
|
* @param {Number|String} I
|
|
@@ -97,17 +91,9 @@ function iter(i) {
|
|
|
97
91
|
const collection = this._getCollection();
|
|
98
92
|
const args = Array.from(arguments);
|
|
99
93
|
const _this = this;
|
|
100
|
-
const globalDebug = _this
|
|
101
|
-
|
|
102
|
-
_this.conn.base &&
|
|
103
|
-
_this.conn.base.options &&
|
|
104
|
-
_this.conn.base.options.debug;
|
|
105
|
-
const connectionDebug = _this &&
|
|
106
|
-
_this.conn &&
|
|
107
|
-
_this.conn.options &&
|
|
108
|
-
_this.conn.options.debug;
|
|
94
|
+
const globalDebug = _this?.conn?.base?.options?.debug;
|
|
95
|
+
const connectionDebug = _this?.conn?.options?.debug;
|
|
109
96
|
const debug = connectionDebug == null ? globalDebug : connectionDebug;
|
|
110
|
-
const lastArg = arguments[arguments.length - 1];
|
|
111
97
|
const opId = new ObjectId();
|
|
112
98
|
|
|
113
99
|
// If user force closed, queueing will hang forever. See #5664
|
|
@@ -122,9 +108,8 @@ function iter(i) {
|
|
|
122
108
|
}
|
|
123
109
|
}
|
|
124
110
|
|
|
125
|
-
let _args = args;
|
|
126
|
-
let callback = null;
|
|
127
111
|
let timeout = null;
|
|
112
|
+
let waitForBufferPromise = null;
|
|
128
113
|
if (this._shouldBufferCommands() && this.buffer) {
|
|
129
114
|
this.conn.emit('buffer', {
|
|
130
115
|
_id: opId,
|
|
@@ -134,78 +119,28 @@ function iter(i) {
|
|
|
134
119
|
args: args
|
|
135
120
|
});
|
|
136
121
|
|
|
137
|
-
let callback;
|
|
138
|
-
let _args = args;
|
|
139
|
-
let promise = null;
|
|
140
|
-
if (syncCollectionMethods[i] && typeof lastArg === 'function') {
|
|
141
|
-
this.addQueue(i, _args);
|
|
142
|
-
callback = lastArg;
|
|
143
|
-
} else if (syncCollectionMethods[i]) {
|
|
144
|
-
promise = new this.Promise((resolve, reject) => {
|
|
145
|
-
callback = function collectionOperationCallback(err, res) {
|
|
146
|
-
if (timeout != null) {
|
|
147
|
-
clearTimeout(timeout);
|
|
148
|
-
}
|
|
149
|
-
if (err != null) {
|
|
150
|
-
return reject(err);
|
|
151
|
-
}
|
|
152
|
-
resolve(res);
|
|
153
|
-
};
|
|
154
|
-
_args = args.concat([callback]);
|
|
155
|
-
this.addQueue(i, _args);
|
|
156
|
-
});
|
|
157
|
-
} else if (typeof lastArg === 'function') {
|
|
158
|
-
callback = function collectionOperationCallback() {
|
|
159
|
-
if (timeout != null) {
|
|
160
|
-
clearTimeout(timeout);
|
|
161
|
-
}
|
|
162
|
-
return lastArg.apply(this, arguments);
|
|
163
|
-
};
|
|
164
|
-
_args = args.slice(0, args.length - 1).concat([callback]);
|
|
165
|
-
} else {
|
|
166
|
-
promise = new Promise((resolve, reject) => {
|
|
167
|
-
callback = function collectionOperationCallback(err, res) {
|
|
168
|
-
if (timeout != null) {
|
|
169
|
-
clearTimeout(timeout);
|
|
170
|
-
}
|
|
171
|
-
if (err != null) {
|
|
172
|
-
return reject(err);
|
|
173
|
-
}
|
|
174
|
-
resolve(res);
|
|
175
|
-
};
|
|
176
|
-
_args = args.concat([callback]);
|
|
177
|
-
this.addQueue(i, _args);
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
|
|
181
122
|
const bufferTimeoutMS = this._getBufferTimeoutMS();
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
}
|
|
123
|
+
waitForBufferPromise = new Promise((resolve, reject) => {
|
|
124
|
+
this.addQueue(resolve);
|
|
125
|
+
|
|
126
|
+
timeout = setTimeout(() => {
|
|
127
|
+
const removed = this.removeQueue(resolve);
|
|
128
|
+
if (removed) {
|
|
129
|
+
const message = 'Operation `' + this.name + '.' + i + '()` buffering timed out after ' +
|
|
130
|
+
bufferTimeoutMS + 'ms';
|
|
131
|
+
const err = new MongooseError(message);
|
|
132
|
+
this.conn.emit('buffer-end', { _id: opId, modelName: _this.modelName, collectionName: _this.name, method: i, error: err });
|
|
133
|
+
reject(err);
|
|
134
|
+
}
|
|
135
|
+
}, bufferTimeoutMS);
|
|
136
|
+
});
|
|
197
137
|
|
|
198
|
-
return
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
if (err != null) {
|
|
202
|
-
_this.conn.emit('operation-end', { _id: opId, modelName: _this.modelName, collectionName: _this.name, method: i, error: err });
|
|
203
|
-
} else {
|
|
204
|
-
_this.conn.emit('operation-end', { _id: opId, modelName: _this.modelName, collectionName: _this.name, method: i, result: res });
|
|
138
|
+
return waitForBufferPromise.then(() => {
|
|
139
|
+
if (timeout) {
|
|
140
|
+
clearTimeout(timeout);
|
|
205
141
|
}
|
|
206
|
-
return
|
|
207
|
-
};
|
|
208
|
-
_args = args.slice(0, args.length - 1).concat([callback]);
|
|
142
|
+
return this[i].apply(this, args);
|
|
143
|
+
});
|
|
209
144
|
}
|
|
210
145
|
|
|
211
146
|
if (debug) {
|
|
@@ -227,7 +162,7 @@ function iter(i) {
|
|
|
227
162
|
}
|
|
228
163
|
}
|
|
229
164
|
|
|
230
|
-
this.conn.emit('operation-start', { _id: opId, modelName: _this.modelName, collectionName: this.name, method: i, params:
|
|
165
|
+
this.conn.emit('operation-start', { _id: opId, modelName: _this.modelName, collectionName: this.name, method: i, params: args });
|
|
231
166
|
|
|
232
167
|
try {
|
|
233
168
|
if (collection == null) {
|
|
@@ -237,60 +172,37 @@ function iter(i) {
|
|
|
237
172
|
throw new MongooseError(message);
|
|
238
173
|
}
|
|
239
174
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
if (timeout != null) {
|
|
243
|
-
clearTimeout(timeout);
|
|
244
|
-
}
|
|
245
|
-
this.conn.emit('operation-end', { _id: opId, modelName: _this.modelName, collectionName: this.name, method: i, result });
|
|
246
|
-
return lastArg.call(this, null, result);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
const ret = collection[i].apply(collection, _args);
|
|
250
|
-
if (ret != null && typeof ret.then === 'function') {
|
|
175
|
+
const ret = collection[i].apply(collection, args);
|
|
176
|
+
if (typeof ret?.then === 'function') {
|
|
251
177
|
return ret.then(
|
|
252
178
|
result => {
|
|
253
179
|
if (timeout != null) {
|
|
254
180
|
clearTimeout(timeout);
|
|
255
181
|
}
|
|
256
|
-
|
|
257
|
-
lastArg(null, result);
|
|
258
|
-
} else {
|
|
259
|
-
this.conn.emit('operation-end', { _id: opId, modelName: _this.modelName, collectionName: this.name, method: i, result });
|
|
260
|
-
}
|
|
182
|
+
this.conn.emit('operation-end', { _id: opId, modelName: _this.modelName, collectionName: this.name, method: i, result });
|
|
261
183
|
return result;
|
|
262
184
|
},
|
|
263
185
|
error => {
|
|
264
186
|
if (timeout != null) {
|
|
265
187
|
clearTimeout(timeout);
|
|
266
188
|
}
|
|
267
|
-
|
|
268
|
-
lastArg(error);
|
|
269
|
-
return;
|
|
270
|
-
} else {
|
|
271
|
-
this.conn.emit('operation-end', { _id: opId, modelName: _this.modelName, collectionName: this.name, method: i, error });
|
|
272
|
-
}
|
|
189
|
+
this.conn.emit('operation-end', { _id: opId, modelName: _this.modelName, collectionName: this.name, method: i, error });
|
|
273
190
|
throw error;
|
|
274
191
|
}
|
|
275
192
|
);
|
|
276
193
|
}
|
|
194
|
+
|
|
195
|
+
this.conn.emit('operation-end', { _id: opId, modelName: _this.modelName, collectionName: this.name, method: i, result: ret });
|
|
277
196
|
if (timeout != null) {
|
|
278
197
|
clearTimeout(timeout);
|
|
279
198
|
}
|
|
280
199
|
return ret;
|
|
281
200
|
} catch (error) {
|
|
282
|
-
// Collection operation may throw because of max bson size, catch it here
|
|
283
|
-
// See gh-3906
|
|
284
201
|
if (timeout != null) {
|
|
285
202
|
clearTimeout(timeout);
|
|
286
203
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
} else {
|
|
290
|
-
this.conn.emit('operation-end', { _id: opId, modelName: _this.modelName, collectionName: this.name, method: i, error: error });
|
|
291
|
-
|
|
292
|
-
throw error;
|
|
293
|
-
}
|
|
204
|
+
this.conn.emit('operation-end', { _id: opId, modelName: _this.modelName, collectionName: this.name, method: i, error: error });
|
|
205
|
+
throw error;
|
|
294
206
|
}
|
|
295
207
|
};
|
|
296
208
|
}
|
|
@@ -393,7 +305,7 @@ function formatDate(x, key, shell) {
|
|
|
393
305
|
}
|
|
394
306
|
}
|
|
395
307
|
function format(obj, sub, color, shell) {
|
|
396
|
-
if (
|
|
308
|
+
if (typeof obj?.toBSON === 'function') {
|
|
397
309
|
obj = obj.toBSON();
|
|
398
310
|
}
|
|
399
311
|
if (obj == null) {
|
|
@@ -443,12 +355,7 @@ function format(obj, sub, color, shell) {
|
|
|
443
355
|
formatDate(x, key, shell);
|
|
444
356
|
} else if (_constructorName === 'ClientSession') {
|
|
445
357
|
x[key] = inspectable('ClientSession("' +
|
|
446
|
-
(
|
|
447
|
-
x[key] &&
|
|
448
|
-
x[key].id &&
|
|
449
|
-
x[key].id.id &&
|
|
450
|
-
x[key].id.id.buffer || ''
|
|
451
|
-
).toString('hex') + '")');
|
|
358
|
+
(x[key]?.id?.id?.buffer || '').toString('hex') + '")');
|
|
452
359
|
} else if (Array.isArray(x[key])) {
|
|
453
360
|
x[key] = x[key].map(map);
|
|
454
361
|
} else if (error != null) {
|
|
@@ -118,7 +118,7 @@ NativeConnection.prototype.useDb = function(name, options) {
|
|
|
118
118
|
newConn.otherDbs.push(this);
|
|
119
119
|
|
|
120
120
|
// push onto the relatedDbs cache, this is used when state changes
|
|
121
|
-
if (options
|
|
121
|
+
if (options?.useCache) {
|
|
122
122
|
this.relatedDbs[newConn.name] = newConn;
|
|
123
123
|
newConn.relatedDbs = this.relatedDbs;
|
|
124
124
|
}
|
|
@@ -251,9 +251,7 @@ NativeConnection.prototype.createClient = async function createClient(uri, optio
|
|
|
251
251
|
|
|
252
252
|
if (options) {
|
|
253
253
|
|
|
254
|
-
const autoIndex = options.config
|
|
255
|
-
options.config.autoIndex :
|
|
256
|
-
options.autoIndex;
|
|
254
|
+
const autoIndex = options.config?.autoIndex ?? options.autoIndex;
|
|
257
255
|
if (autoIndex != null) {
|
|
258
256
|
this.config.autoIndex = autoIndex !== false;
|
|
259
257
|
delete options.config;
|
|
@@ -316,15 +314,15 @@ NativeConnection.prototype.createClient = async function createClient(uri, optio
|
|
|
316
314
|
|
|
317
315
|
const { schemaMap, encryptedFieldsMap } = this._buildEncryptionSchemas();
|
|
318
316
|
|
|
319
|
-
if ((
|
|
317
|
+
if ((utils.hasOwnKeys(schemaMap) || utils.hasOwnKeys(encryptedFieldsMap)) && !options.autoEncryption) {
|
|
320
318
|
throw new Error('Must provide `autoEncryption` when connecting with encrypted schemas.');
|
|
321
319
|
}
|
|
322
320
|
|
|
323
|
-
if (
|
|
321
|
+
if (utils.hasOwnKeys(schemaMap)) {
|
|
324
322
|
options.autoEncryption.schemaMap = schemaMap;
|
|
325
323
|
}
|
|
326
324
|
|
|
327
|
-
if (
|
|
325
|
+
if (utils.hasOwnKeys(encryptedFieldsMap)) {
|
|
328
326
|
options.autoEncryption.encryptedFieldsMap = encryptedFieldsMap;
|
|
329
327
|
}
|
|
330
328
|
|
|
@@ -435,18 +433,8 @@ function _setClient(conn, client, options, dbName) {
|
|
|
435
433
|
const db = dbName != null ? client.db(dbName) : client.db();
|
|
436
434
|
conn.db = db;
|
|
437
435
|
conn.client = client;
|
|
438
|
-
conn.host = client
|
|
439
|
-
|
|
440
|
-
client.s.options &&
|
|
441
|
-
client.s.options.hosts &&
|
|
442
|
-
client.s.options.hosts[0] &&
|
|
443
|
-
client.s.options.hosts[0].host || void 0;
|
|
444
|
-
conn.port = client &&
|
|
445
|
-
client.s &&
|
|
446
|
-
client.s.options &&
|
|
447
|
-
client.s.options.hosts &&
|
|
448
|
-
client.s.options.hosts[0] &&
|
|
449
|
-
client.s.options.hosts[0].port || void 0;
|
|
436
|
+
conn.host = client?.s?.options?.hosts?.[0]?.host;
|
|
437
|
+
conn.port = client?.s?.options?.hosts?.[0]?.port;
|
|
450
438
|
conn.name = dbName != null ? dbName : db.databaseName;
|
|
451
439
|
conn._closeCalled = client._closeCalled;
|
|
452
440
|
|
|
@@ -463,10 +451,7 @@ function _setClient(conn, client, options, dbName) {
|
|
|
463
451
|
}
|
|
464
452
|
};
|
|
465
453
|
|
|
466
|
-
const type = client
|
|
467
|
-
client.topology &&
|
|
468
|
-
client.topology.description &&
|
|
469
|
-
client.topology.description.type || '';
|
|
454
|
+
const type = client?.topology?.description?.type || '';
|
|
470
455
|
|
|
471
456
|
if (type === 'Single') {
|
|
472
457
|
client.on('serverDescriptionChanged', ev => {
|
package/lib/error/cast.js
CHANGED
|
@@ -109,7 +109,7 @@ function getValueType(value) {
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
function getMessageFormat(schemaType) {
|
|
112
|
-
const messageFormat = schemaType
|
|
112
|
+
const messageFormat = schemaType?._castErrorMessage || null;
|
|
113
113
|
if (typeof messageFormat === 'string' || typeof messageFormat === 'function') {
|
|
114
114
|
return messageFormat;
|
|
115
115
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
module.exports = function prepareDiscriminatorPipeline(pipeline, schema, prefix) {
|
|
4
|
-
const discriminatorMapping = schema
|
|
4
|
+
const discriminatorMapping = schema?.discriminatorMapping;
|
|
5
5
|
prefix = prefix || '';
|
|
6
6
|
|
|
7
7
|
if (discriminatorMapping && !discriminatorMapping.isRoot) {
|
|
@@ -18,12 +18,12 @@ module.exports = function prepareDiscriminatorPipeline(pipeline, schema, prefix)
|
|
|
18
18
|
originalPipeline[0].$match[filterKey] = discriminatorValue;
|
|
19
19
|
// `originalPipeline` is a ref, so there's no need for
|
|
20
20
|
// aggregate._pipeline = originalPipeline
|
|
21
|
-
} else if (originalPipeline[0]
|
|
21
|
+
} else if (originalPipeline[0]?.$geoNear) {
|
|
22
22
|
originalPipeline[0].$geoNear.query =
|
|
23
23
|
originalPipeline[0].$geoNear.query || {};
|
|
24
24
|
originalPipeline[0].$geoNear.query[filterKey] = discriminatorValue;
|
|
25
|
-
} else if (originalPipeline[0]
|
|
26
|
-
if (originalPipeline[1]
|
|
25
|
+
} else if (originalPipeline[0]?.$search) {
|
|
26
|
+
if (originalPipeline[1]?.$match != null) {
|
|
27
27
|
originalPipeline[1].$match[filterKey] = originalPipeline[1].$match[filterKey] || discriminatorValue;
|
|
28
28
|
} else {
|
|
29
29
|
const match = {};
|
package/lib/helpers/clone.js
CHANGED
|
@@ -53,7 +53,7 @@ function clone(obj, options, isArrayChild) {
|
|
|
53
53
|
if (obj.__parentArray != null) {
|
|
54
54
|
clonedDoc.__parentArray = obj.__parentArray;
|
|
55
55
|
}
|
|
56
|
-
clonedDoc.$
|
|
56
|
+
clonedDoc.$__setParent(options.parentDoc ?? obj.$__parent);
|
|
57
57
|
return clonedDoc;
|
|
58
58
|
}
|
|
59
59
|
}
|
|
@@ -63,7 +63,7 @@ function clone(obj, options, isArrayChild) {
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
let ret;
|
|
66
|
-
if (options
|
|
66
|
+
if (options?.json && typeof obj.toJSON === 'function') {
|
|
67
67
|
ret = obj.toJSON(options);
|
|
68
68
|
} else {
|
|
69
69
|
ret = obj.toObject(options);
|
|
@@ -89,14 +89,14 @@ function clone(obj, options, isArrayChild) {
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
if (isBsonType(obj, 'ObjectId')) {
|
|
92
|
-
if (options
|
|
92
|
+
if (options?.flattenObjectIds) {
|
|
93
93
|
return obj.toJSON();
|
|
94
94
|
}
|
|
95
95
|
return new ObjectId(obj.id);
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
if (isBsonType(obj, 'Decimal128')) {
|
|
99
|
-
if (options
|
|
99
|
+
if (options?.flattenDecimals) {
|
|
100
100
|
return obj.toJSON();
|
|
101
101
|
}
|
|
102
102
|
return Decimal.fromString(obj.toString());
|
|
@@ -114,7 +114,7 @@ function clone(obj, options, isArrayChild) {
|
|
|
114
114
|
// If we're cloning this object to go into a MongoDB command,
|
|
115
115
|
// and there's a `toBSON()` function, assume this object will be
|
|
116
116
|
// stored as a primitive in MongoDB and doesn't need to be cloned.
|
|
117
|
-
if (options
|
|
117
|
+
if (options?.bson && typeof obj.toBSON === 'function') {
|
|
118
118
|
return obj;
|
|
119
119
|
}
|
|
120
120
|
|
|
@@ -131,9 +131,9 @@ module.exports = clone;
|
|
|
131
131
|
*/
|
|
132
132
|
|
|
133
133
|
function cloneObject(obj, options, isArrayChild) {
|
|
134
|
-
const minimize = options
|
|
135
|
-
const omitUndefined = options
|
|
136
|
-
const seen = options
|
|
134
|
+
const minimize = options?.minimize;
|
|
135
|
+
const omitUndefined = options?.omitUndefined;
|
|
136
|
+
const seen = options?._seen;
|
|
137
137
|
const ret = {};
|
|
138
138
|
let hasKeys;
|
|
139
139
|
|
package/lib/helpers/common.js
CHANGED
|
@@ -35,12 +35,12 @@ function flatten(update, path, options, schema) {
|
|
|
35
35
|
result[path + key] = val;
|
|
36
36
|
|
|
37
37
|
// Avoid going into mixed paths if schema is specified
|
|
38
|
-
const keySchema = schema
|
|
39
|
-
const isNested = schema
|
|
40
|
-
if (keySchema
|
|
38
|
+
const keySchema = schema?.path?.(path + key);
|
|
39
|
+
const isNested = schema?.nested?.[path + key];
|
|
40
|
+
if (keySchema?.instance === 'Mixed') continue;
|
|
41
41
|
|
|
42
42
|
if (shouldFlatten(val)) {
|
|
43
|
-
if (options
|
|
43
|
+
if (options?.skipArrays && Array.isArray(val)) {
|
|
44
44
|
continue;
|
|
45
45
|
}
|
|
46
46
|
const flat = flatten(val, path + key, options, schema);
|
|
@@ -174,7 +174,7 @@ module.exports = async function eachAsync(next, fn, options) {
|
|
|
174
174
|
} catch (err) {
|
|
175
175
|
return callback(err);
|
|
176
176
|
}
|
|
177
|
-
if (
|
|
177
|
+
if (typeof maybePromise?.then === 'function') {
|
|
178
178
|
maybePromise.then(
|
|
179
179
|
function() { callback(null); },
|
|
180
180
|
function(error) {
|
|
@@ -9,7 +9,7 @@ const getDiscriminatorByValue = require('./getDiscriminatorByValue');
|
|
|
9
9
|
|
|
10
10
|
module.exports = function getConstructor(Constructor, value, defaultDiscriminatorValue) {
|
|
11
11
|
const discriminatorKey = Constructor.schema.options.discriminatorKey;
|
|
12
|
-
let discriminatorValue =
|
|
12
|
+
let discriminatorValue = value?.[discriminatorKey];
|
|
13
13
|
if (discriminatorValue == null) {
|
|
14
14
|
discriminatorValue = defaultDiscriminatorValue;
|
|
15
15
|
}
|
|
@@ -11,7 +11,7 @@ const areDiscriminatorValuesEqual = require('./areDiscriminatorValuesEqual');
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
module.exports = function getSchemaDiscriminatorByValue(schema, value) {
|
|
14
|
-
if (schema
|
|
14
|
+
if (schema?.discriminators == null) {
|
|
15
15
|
return null;
|
|
16
16
|
}
|
|
17
17
|
for (const key of Object.keys(schema.discriminators)) {
|
|
@@ -40,7 +40,7 @@ module.exports = function mergeDiscriminatorSchema(to, from, path, seen) {
|
|
|
40
40
|
continue;
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
-
if (path === 'tree' && from
|
|
43
|
+
if (path === 'tree' && from?.instanceOfSchema) {
|
|
44
44
|
continue;
|
|
45
45
|
}
|
|
46
46
|
if (specialProperties.has(key)) {
|
|
@@ -85,7 +85,7 @@ module.exports = function mergeDiscriminatorSchema(to, from, path, seen) {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
if (from
|
|
88
|
+
if (from?.instanceOfSchema) {
|
|
89
89
|
to.tree = Object.assign({}, from.tree, to.tree);
|
|
90
90
|
}
|
|
91
91
|
};
|
|
@@ -5,7 +5,7 @@ const isNestedProjection = require('../projection/isNestedProjection');
|
|
|
5
5
|
module.exports = function applyDefaults(doc, fields, exclude, hasIncludedChildren, isBeforeSetters, pathsToSkip, options) {
|
|
6
6
|
const paths = Object.keys(doc.$__schema.paths);
|
|
7
7
|
const plen = paths.length;
|
|
8
|
-
const skipParentChangeTracking = options
|
|
8
|
+
const skipParentChangeTracking = options?.skipParentChangeTracking;
|
|
9
9
|
|
|
10
10
|
for (let i = 0; i < plen; ++i) {
|
|
11
11
|
let def;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const handleTimestampOption = require('../schema/handleTimestampOption');
|
|
4
4
|
const mpath = require('mpath');
|
|
5
|
+
const utils = require('../../utils');
|
|
5
6
|
|
|
6
7
|
module.exports = applyTimestamps;
|
|
7
8
|
|
|
@@ -71,7 +72,7 @@ function applyTimestampsToDoc(schema, obj, options) {
|
|
|
71
72
|
return;
|
|
72
73
|
}
|
|
73
74
|
|
|
74
|
-
if (schema.discriminators &&
|
|
75
|
+
if (schema.discriminators && utils.hasOwnKeys(schema.discriminators)) {
|
|
75
76
|
for (const discriminatorKey of Object.keys(schema.discriminators)) {
|
|
76
77
|
const discriminator = schema.discriminators[discriminatorKey];
|
|
77
78
|
const key = discriminator.discriminatorMapping.key;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const mpath = require('mpath');
|
|
4
|
+
const utils = require('../../utils');
|
|
4
5
|
|
|
5
6
|
module.exports = applyVirtuals;
|
|
6
7
|
|
|
@@ -76,7 +77,7 @@ function applyVirtualsToChildren(schema, res, virtuals) {
|
|
|
76
77
|
attachedVirtuals = true;
|
|
77
78
|
}
|
|
78
79
|
|
|
79
|
-
if (virtuals
|
|
80
|
+
if (virtuals?.length && !attachedVirtuals) {
|
|
80
81
|
applyVirtualsToDoc(schema, res, virtuals);
|
|
81
82
|
}
|
|
82
83
|
}
|
|
@@ -101,7 +102,7 @@ function applyVirtualsToDoc(schema, obj, virtuals) {
|
|
|
101
102
|
return;
|
|
102
103
|
}
|
|
103
104
|
|
|
104
|
-
if (schema.discriminators &&
|
|
105
|
+
if (schema.discriminators && utils.hasOwnKeys(schema.discriminators)) {
|
|
105
106
|
for (const discriminatorKey of Object.keys(schema.discriminators)) {
|
|
106
107
|
const discriminator = schema.discriminators[discriminatorKey];
|
|
107
108
|
const key = discriminator.discriminatorMapping.key;
|
|
@@ -133,7 +134,7 @@ function applyVirtualsToDoc(schema, obj, virtuals) {
|
|
|
133
134
|
}
|
|
134
135
|
let val = virtualType.applyGetters(cur[sp[sp.length - 1]], obj);
|
|
135
136
|
const isPopulateVirtual =
|
|
136
|
-
virtualType.options
|
|
137
|
+
virtualType.options?.ref || virtualType.options?.refPath;
|
|
137
138
|
if (isPopulateVirtual && val === undefined) {
|
|
138
139
|
if (virtualType.options.justOne) {
|
|
139
140
|
val = null;
|
|
@@ -16,7 +16,7 @@ module.exports = function cleanModifiedSubpaths(doc, path, options) {
|
|
|
16
16
|
for (const modifiedPath of Object.keys(doc.$__.activePaths.getStatePaths('modify'))) {
|
|
17
17
|
if (skipDocArrays) {
|
|
18
18
|
const schemaType = doc.$__schema.path(modifiedPath);
|
|
19
|
-
if (schemaType
|
|
19
|
+
if (schemaType?.$isMongooseDocumentArray) {
|
|
20
20
|
continue;
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -46,7 +46,7 @@ function compile(tree, proto, prefix, options) {
|
|
|
46
46
|
const limb = tree[key];
|
|
47
47
|
|
|
48
48
|
const hasSubprops = isPOJO(limb) &&
|
|
49
|
-
|
|
49
|
+
utils.hasOwnKeys(limb) &&
|
|
50
50
|
(!limb[typeKey] || (typeKey === 'type' && isPOJO(limb.type) && limb.type.type));
|
|
51
51
|
const subprops = hasSubprops ? limb : null;
|
|
52
52
|
|
|
@@ -132,7 +132,7 @@ function defineKey({ prop, subprops, prototype, prefix, options }) {
|
|
|
132
132
|
writable: false,
|
|
133
133
|
value: function() {
|
|
134
134
|
return _this.get(path, null, {
|
|
135
|
-
virtuals: this
|
|
135
|
+
virtuals: this?.schema?.options?.toObject?.virtuals || null
|
|
136
136
|
});
|
|
137
137
|
}
|
|
138
138
|
});
|
|
@@ -143,7 +143,7 @@ function defineKey({ prop, subprops, prototype, prefix, options }) {
|
|
|
143
143
|
writable: false,
|
|
144
144
|
value: function() {
|
|
145
145
|
return _this.get(path, null, {
|
|
146
|
-
virtuals: this
|
|
146
|
+
virtuals: this?.schema?.options?.toJSON?.virtuals || null
|
|
147
147
|
});
|
|
148
148
|
}
|
|
149
149
|
});
|
|
@@ -178,7 +178,7 @@ function defineKey({ prop, subprops, prototype, prefix, options }) {
|
|
|
178
178
|
return this.$__.getters[path];
|
|
179
179
|
},
|
|
180
180
|
set: function(v) {
|
|
181
|
-
if (v
|
|
181
|
+
if (v?.$__isNested) {
|
|
182
182
|
// Convert top-level to POJO, but leave subdocs hydrated so `$set`
|
|
183
183
|
// can handle them. See gh-9293.
|
|
184
184
|
v = v.$__get();
|
|
@@ -17,7 +17,7 @@ module.exports = function getDeepestSubdocumentForPath(doc, parts, schema) {
|
|
|
17
17
|
let subdoc = doc;
|
|
18
18
|
for (let i = 0; i < parts.length - 1; ++i) {
|
|
19
19
|
const curSchemaType = curSchema.path(curPath);
|
|
20
|
-
if (curSchemaType
|
|
20
|
+
if (curSchemaType?.schema) {
|
|
21
21
|
let newSubdoc = subdoc.get(curPath);
|
|
22
22
|
curSchema = curSchemaType.schema;
|
|
23
23
|
curPath = parts[i + 1];
|
|
@@ -4,7 +4,7 @@ module.exports = function decorateDiscriminatorIndexOptions(schema, indexOptions
|
|
|
4
4
|
// If the model is a discriminator and has an index, add a
|
|
5
5
|
// partialFilterExpression by default so the index will only apply
|
|
6
6
|
// to that discriminator.
|
|
7
|
-
const discriminatorName = schema.discriminatorMapping
|
|
7
|
+
const discriminatorName = schema.discriminatorMapping?.value;
|
|
8
8
|
if (discriminatorName && !('sparse' in indexOptions)) {
|
|
9
9
|
const discriminatorKey = schema.options.discriminatorKey;
|
|
10
10
|
indexOptions.partialFilterExpression = indexOptions.partialFilterExpression || {};
|
|
@@ -31,8 +31,8 @@ function getRelatedIndexes({
|
|
|
31
31
|
indexes,
|
|
32
32
|
indexesType
|
|
33
33
|
}) {
|
|
34
|
-
const discriminatorKey = discriminatorMapping
|
|
35
|
-
const discriminatorValue = discriminatorMapping
|
|
34
|
+
const discriminatorKey = discriminatorMapping?.key;
|
|
35
|
+
const discriminatorValue = discriminatorMapping?.value;
|
|
36
36
|
|
|
37
37
|
if (!discriminatorKey) {
|
|
38
38
|
return indexes;
|
|
@@ -57,7 +57,7 @@ function getRelatedIndexes({
|
|
|
57
57
|
function getPartialFilterExpression(index, indexesType) {
|
|
58
58
|
if (indexesType === 'schema') {
|
|
59
59
|
const options = index[1];
|
|
60
|
-
return options
|
|
60
|
+
return options?.partialFilterExpression;
|
|
61
61
|
}
|
|
62
62
|
return index.partialFilterExpression;
|
|
63
63
|
}
|