mongoose 9.0.2 → 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.
Files changed (88) hide show
  1. package/lib/aggregate.js +1 -1
  2. package/lib/cast/string.js +1 -1
  3. package/lib/cast.js +7 -15
  4. package/lib/collection.js +2 -2
  5. package/lib/connection.js +20 -14
  6. package/lib/cursor/changeStream.js +5 -5
  7. package/lib/document.js +117 -77
  8. package/lib/drivers/node-mongodb-native/collection.js +5 -17
  9. package/lib/drivers/node-mongodb-native/connection.js +8 -23
  10. package/lib/error/cast.js +1 -1
  11. package/lib/helpers/aggregate/prepareDiscriminatorPipeline.js +4 -4
  12. package/lib/helpers/clone.js +8 -8
  13. package/lib/helpers/common.js +4 -4
  14. package/lib/helpers/cursor/eachAsync.js +1 -1
  15. package/lib/helpers/discriminator/getConstructor.js +1 -1
  16. package/lib/helpers/discriminator/getSchemaDiscriminatorByValue.js +1 -1
  17. package/lib/helpers/discriminator/mergeDiscriminatorSchema.js +2 -2
  18. package/lib/helpers/document/applyDefaults.js +1 -1
  19. package/lib/helpers/document/applyTimestamps.js +2 -1
  20. package/lib/helpers/document/applyVirtuals.js +4 -3
  21. package/lib/helpers/document/cleanModifiedSubpaths.js +1 -1
  22. package/lib/helpers/document/compile.js +4 -4
  23. package/lib/helpers/document/getDeepestSubdocumentForPath.js +1 -1
  24. package/lib/helpers/indexes/decorateDiscriminatorIndexOptions.js +1 -1
  25. package/lib/helpers/indexes/getRelatedIndexes.js +3 -3
  26. package/lib/helpers/model/castBulkWrite.js +5 -9
  27. package/lib/helpers/model/discriminator.js +1 -1
  28. package/lib/helpers/populate/assignRawDocsToIdStructure.js +1 -1
  29. package/lib/helpers/populate/assignVals.js +4 -4
  30. package/lib/helpers/populate/getModelsMapForPopulate.js +25 -23
  31. package/lib/helpers/populate/getSchemaTypes.js +6 -7
  32. package/lib/helpers/printJestWarning.js +1 -1
  33. package/lib/helpers/processConnectionOptions.js +1 -1
  34. package/lib/helpers/query/castUpdate.js +12 -12
  35. package/lib/helpers/query/getEmbeddedDiscriminatorPath.js +2 -2
  36. package/lib/helpers/query/handleImmutable.js +2 -2
  37. package/lib/helpers/query/sanitizeFilter.js +1 -1
  38. package/lib/helpers/schema/applyPlugins.js +1 -1
  39. package/lib/helpers/schema/applyReadConcern.js +1 -1
  40. package/lib/helpers/schema/applyWriteConcern.js +4 -2
  41. package/lib/helpers/schema/getIndexes.js +3 -3
  42. package/lib/helpers/schema/getSubdocumentStrictValue.js +1 -1
  43. package/lib/helpers/schema/handleIdOption.js +1 -1
  44. package/lib/helpers/schema/idGetter.js +1 -1
  45. package/lib/helpers/schematype/handleImmutable.js +1 -1
  46. package/lib/helpers/setDefaultsOnInsert.js +2 -5
  47. package/lib/helpers/timestamps/setDocumentTimestamps.js +2 -2
  48. package/lib/helpers/timestamps/setupTimestamps.js +2 -2
  49. package/lib/helpers/update/applyTimestampsToUpdate.js +10 -9
  50. package/lib/helpers/update/castArrayFilters.js +4 -4
  51. package/lib/helpers/update/decorateUpdateWithVersionKey.js +1 -1
  52. package/lib/helpers/updateValidators.js +4 -4
  53. package/lib/model.js +33 -44
  54. package/lib/mongoose.js +5 -5
  55. package/lib/options/virtualOptions.js +1 -1
  56. package/lib/plugins/saveSubdocs.js +2 -2
  57. package/lib/plugins/trackTransaction.js +3 -4
  58. package/lib/query.js +62 -59
  59. package/lib/queryHelpers.js +9 -12
  60. package/lib/schema/array.js +10 -12
  61. package/lib/schema/buffer.js +6 -6
  62. package/lib/schema/documentArray.js +15 -23
  63. package/lib/schema/documentArrayElement.js +3 -3
  64. package/lib/schema/map.js +1 -1
  65. package/lib/schema/mixed.js +2 -2
  66. package/lib/schema/number.js +22 -4
  67. package/lib/schema/objectId.js +1 -1
  68. package/lib/schema/operators/exists.js +1 -1
  69. package/lib/schema/operators/geospatial.js +1 -1
  70. package/lib/schema/string.js +2 -2
  71. package/lib/schema/subdocument.js +9 -12
  72. package/lib/schema/union.js +1 -1
  73. package/lib/schema.js +27 -28
  74. package/lib/schemaType.js +11 -11
  75. package/lib/types/array/index.js +2 -2
  76. package/lib/types/array/methods/index.js +38 -8
  77. package/lib/types/arraySubdocument.js +12 -2
  78. package/lib/types/buffer.js +1 -1
  79. package/lib/types/documentArray/index.js +2 -2
  80. package/lib/types/documentArray/methods/index.js +5 -5
  81. package/lib/types/map.js +8 -8
  82. package/lib/types/subdocument.js +15 -5
  83. package/lib/utils.js +23 -7
  84. package/package.json +2 -2
  85. package/types/index.d.ts +15 -5
  86. package/types/middlewares.d.ts +11 -0
  87. package/types/models.d.ts +15 -5
  88. package/types/schemaoptions.d.ts +4 -2
@@ -91,15 +91,8 @@ function iter(i) {
91
91
  const collection = this._getCollection();
92
92
  const args = Array.from(arguments);
93
93
  const _this = this;
94
- const globalDebug = _this &&
95
- _this.conn &&
96
- _this.conn.base &&
97
- _this.conn.base.options &&
98
- _this.conn.base.options.debug;
99
- const connectionDebug = _this &&
100
- _this.conn &&
101
- _this.conn.options &&
102
- _this.conn.options.debug;
94
+ const globalDebug = _this?.conn?.base?.options?.debug;
95
+ const connectionDebug = _this?.conn?.options?.debug;
103
96
  const debug = connectionDebug == null ? globalDebug : connectionDebug;
104
97
  const opId = new ObjectId();
105
98
 
@@ -180,7 +173,7 @@ function iter(i) {
180
173
  }
181
174
 
182
175
  const ret = collection[i].apply(collection, args);
183
- if (ret != null && typeof ret.then === 'function') {
176
+ if (typeof ret?.then === 'function') {
184
177
  return ret.then(
185
178
  result => {
186
179
  if (timeout != null) {
@@ -312,7 +305,7 @@ function formatDate(x, key, shell) {
312
305
  }
313
306
  }
314
307
  function format(obj, sub, color, shell) {
315
- if (obj && typeof obj.toBSON === 'function') {
308
+ if (typeof obj?.toBSON === 'function') {
316
309
  obj = obj.toBSON();
317
310
  }
318
311
  if (obj == null) {
@@ -362,12 +355,7 @@ function format(obj, sub, color, shell) {
362
355
  formatDate(x, key, shell);
363
356
  } else if (_constructorName === 'ClientSession') {
364
357
  x[key] = inspectable('ClientSession("' +
365
- (
366
- x[key] &&
367
- x[key].id &&
368
- x[key].id.id &&
369
- x[key].id.id.buffer || ''
370
- ).toString('hex') + '")');
358
+ (x[key]?.id?.id?.buffer || '').toString('hex') + '")');
371
359
  } else if (Array.isArray(x[key])) {
372
360
  x[key] = x[key].map(map);
373
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 && options.useCache) {
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 && options.config.autoIndex != null ?
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 ((Object.keys(schemaMap).length > 0 || Object.keys(encryptedFieldsMap).length) && !options.autoEncryption) {
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 (Object.keys(schemaMap).length > 0) {
321
+ if (utils.hasOwnKeys(schemaMap)) {
324
322
  options.autoEncryption.schemaMap = schemaMap;
325
323
  }
326
324
 
327
- if (Object.keys(encryptedFieldsMap).length > 0) {
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
- client.s &&
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 && schemaType._castErrorMessage || null;
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 && schema.discriminatorMapping;
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] != null && originalPipeline[0].$geoNear) {
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] != null && originalPipeline[0].$search) {
26
- if (originalPipeline[1] && originalPipeline[1].$match != null) {
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 = {};
@@ -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.$__parent = obj.$__parent;
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 && options.json && typeof obj.toJSON === 'function') {
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 && options.flattenObjectIds) {
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 && options.flattenDecimals) {
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 && options.bson && typeof obj.toBSON === 'function') {
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 && options.minimize;
135
- const omitUndefined = options && options.omitUndefined;
136
- const seen = options && options._seen;
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
 
@@ -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 && schema.path && schema.path(path + key);
39
- const isNested = schema && schema.nested && schema.nested[path + key];
40
- if (keySchema && keySchema.instance === 'Mixed') continue;
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 && options.skipArrays && Array.isArray(val)) {
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 (maybePromise && typeof maybePromise.then === 'function') {
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 = (value != null && value[discriminatorKey]);
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 == null || schema.discriminators == null) {
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 != null && from.instanceOfSchema) {
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 != null && from.instanceOfSchema) {
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 && options.skipParentChangeTracking;
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 && Object.keys(schema.discriminators).length > 0) {
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 && virtuals.length && !attachedVirtuals) {
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 && Object.keys(schema.discriminators).length > 0) {
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 && (virtualType.options.ref || virtualType.options.refPath);
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 && schemaType.$isMongooseDocumentArray) {
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
- Object.keys(limb).length > 0 &&
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 && this.schema && this.schema.options && this.schema.options.toObject && this.schema.options.toObject.virtuals || null
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 && this.schema && this.schema.options && this.schema.options.toJSON && this.schema.options.toJSON.virtuals || null
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 != null && v.$__isNested) {
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 && curSchemaType.schema) {
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 && schema.discriminatorMapping.value;
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 && discriminatorMapping.key;
35
- const discriminatorValue = discriminatorMapping && discriminatorMapping.value;
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 && options.partialFilterExpression;
60
+ return options?.partialFilterExpression;
61
61
  }
62
62
  return index.partialFilterExpression;
63
63
  }
@@ -107,7 +107,7 @@ module.exports.castUpdateOne = function castUpdateOne(originalModel, updateOne,
107
107
 
108
108
  const model = decideModelByObject(originalModel, updateOne['filter']);
109
109
  const schema = model.schema;
110
- const strict = options.strict != null ? options.strict : model.schema.options.strict;
110
+ const strict = options.strict ?? model.schema.options.strict;
111
111
 
112
112
  const update = clone(updateOne['update']);
113
113
 
@@ -129,9 +129,7 @@ module.exports.castUpdateOne = function castUpdateOne(originalModel, updateOne,
129
129
  }
130
130
 
131
131
  const globalSetDefaultsOnInsert = originalModel.base.options.setDefaultsOnInsert;
132
- const shouldSetDefaultsOnInsert = updateOne.setDefaultsOnInsert == null ?
133
- globalSetDefaultsOnInsert :
134
- updateOne.setDefaultsOnInsert;
132
+ const shouldSetDefaultsOnInsert = updateOne.setDefaultsOnInsert ?? globalSetDefaultsOnInsert;
135
133
  if (shouldSetDefaultsOnInsert !== false) {
136
134
  setDefaultsOnInsert(updateOne['filter'], model.schema, update, {
137
135
  setDefaultsOnInsert: true,
@@ -170,12 +168,10 @@ module.exports.castUpdateMany = function castUpdateMany(originalModel, updateMan
170
168
 
171
169
  const model = decideModelByObject(originalModel, updateMany['filter']);
172
170
  const schema = model.schema;
173
- const strict = options.strict != null ? options.strict : model.schema.options.strict;
171
+ const strict = options.strict ?? model.schema.options.strict;
174
172
 
175
173
  const globalSetDefaultsOnInsert = originalModel.base.options.setDefaultsOnInsert;
176
- const shouldSetDefaultsOnInsert = updateMany.setDefaultsOnInsert == null ?
177
- globalSetDefaultsOnInsert :
178
- updateMany.setDefaultsOnInsert;
174
+ const shouldSetDefaultsOnInsert = updateMany.setDefaultsOnInsert ?? globalSetDefaultsOnInsert;
179
175
 
180
176
  if (shouldSetDefaultsOnInsert !== false) {
181
177
  setDefaultsOnInsert(updateMany['filter'], model.schema, updateMany['update'], {
@@ -223,7 +219,7 @@ module.exports.castUpdateMany = function castUpdateMany(originalModel, updateMan
223
219
  module.exports.castReplaceOne = async function castReplaceOne(originalModel, replaceOne, options) {
224
220
  const model = decideModelByObject(originalModel, replaceOne['filter']);
225
221
  const schema = model.schema;
226
- const strict = options.strict != null ? options.strict : model.schema.options.strict;
222
+ const strict = options.strict ?? model.schema.options.strict;
227
223
 
228
224
  _addDiscriminatorToObject(schema, replaceOne['filter']);
229
225
  replaceOne['filter'] = cast(model.schema, replaceOne['filter'], {
@@ -68,7 +68,7 @@ function validateDiscriminatorSchemasForEncryption(parentSchema, childSchema) {
68
68
  */
69
69
 
70
70
  module.exports = function discriminator(model, name, schema, tiedValue, applyPlugins, mergeHooks, overwriteExisting) {
71
- if (!(schema && schema.instanceOfSchema)) {
71
+ if (!schema?.instanceOfSchema) {
72
72
  throw new Error('You must pass a valid discriminator Schema');
73
73
  }
74
74
 
@@ -104,7 +104,7 @@ function assignRawDocsToIdStructure(rawIds, resultDocs, resultOrder, options, re
104
104
  } else {
105
105
  newOrder.push(doc);
106
106
  }
107
- } else if (id != null && id[modelSymbol] != null) {
107
+ } else if (id?.[modelSymbol] != null) {
108
108
  newOrder.push(id);
109
109
  } else {
110
110
  newOrder.push(options.retainNullValues || nullIfNotFound ? null : id);
@@ -129,11 +129,11 @@ module.exports = function assignVals(o) {
129
129
 
130
130
  if (isDoc && Array.isArray(valueToSet)) {
131
131
  for (const val of valueToSet) {
132
- if (val != null && val.$__ != null) {
132
+ if (val?.$__ != null) {
133
133
  val.$__.parent = docs[i];
134
134
  }
135
135
  }
136
- } else if (isDoc && valueToSet != null && valueToSet.$__ != null) {
136
+ } else if (isDoc && valueToSet?.$__ != null) {
137
137
  valueToSet.$__.parent = docs[i];
138
138
  }
139
139
 
@@ -184,7 +184,7 @@ module.exports = function assignVals(o) {
184
184
  // See gh-8342, gh-8455
185
185
  const curPath = parts.slice(0, j + 1).join('.');
186
186
  const schematype = originalSchema._getSchema(curPath);
187
- if (valueToSet == null && schematype != null && schematype.$isMongooseArray) {
187
+ if (valueToSet == null && schematype?.$isMongooseArray) {
188
188
  break;
189
189
  }
190
190
  cur[parts[j]] = {};
@@ -200,7 +200,7 @@ module.exports = function assignVals(o) {
200
200
  o.allOptions.options[populateModelSymbol] = o.allOptions.model;
201
201
  docs[i].$populated(_path, o.unpopulatedValues[i], o.allOptions.options);
202
202
 
203
- if (valueToSet != null && valueToSet.$__ != null) {
203
+ if (valueToSet?.$__ != null) {
204
204
  valueToSet.$__.wasPopulated = { value: o.unpopulatedValues[i] };
205
205
  }
206
206