mongoose 8.5.3 → 8.5.5

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/cast.js CHANGED
@@ -8,6 +8,7 @@ const CastError = require('./error/cast');
8
8
  const StrictModeError = require('./error/strict');
9
9
  const Types = require('./schema/index');
10
10
  const cast$expr = require('./helpers/query/cast$expr');
11
+ const castString = require('./cast/string');
11
12
  const castTextSearch = require('./schema/operators/text');
12
13
  const get = require('./helpers/get');
13
14
  const getSchemaDiscriminatorByValue = require('./helpers/discriminator/getSchemaDiscriminatorByValue');
@@ -95,6 +96,9 @@ module.exports = function cast(schema, obj, options, context) {
95
96
  val = cast(schema, val, options, context);
96
97
  } else if (path === '$text') {
97
98
  val = castTextSearch(val, path);
99
+ } else if (path === '$comment' && !schema.paths.hasOwnProperty('$comment')) {
100
+ val = castString(val, path);
101
+ obj[path] = val;
98
102
  } else {
99
103
  if (!schema) {
100
104
  // no casting for Mixed types
package/lib/document.js CHANGED
@@ -842,7 +842,7 @@ function init(self, obj, doc, opts, prefix) {
842
842
  */
843
843
 
844
844
  Document.prototype.updateOne = function updateOne(doc, options, callback) {
845
- const query = this.constructor.updateOne({ _id: this._id }, doc, options);
845
+ const query = this.constructor.updateOne({ _id: this._doc._id }, doc, options);
846
846
  const self = this;
847
847
  query.pre(function queryPreUpdateOne(cb) {
848
848
  self.constructor._middleware.execPre('updateOne', self, [self], cb);
@@ -883,7 +883,7 @@ Document.prototype.updateOne = function updateOne(doc, options, callback) {
883
883
 
884
884
  Document.prototype.replaceOne = function replaceOne() {
885
885
  const args = [...arguments];
886
- args.unshift({ _id: this._id });
886
+ args.unshift({ _id: this._doc._id });
887
887
  return this.constructor.replaceOne.apply(this.constructor, args);
888
888
  };
889
889
 
@@ -3050,7 +3050,7 @@ Document.prototype.$__validate = function(pathsToValidate, options, callback) {
3050
3050
  } else if (val != null && val.$__ != null && val.$__.wasPopulated) {
3051
3051
  // Array paths, like `somearray.1`, do not show up as populated with `$populated()`,
3052
3052
  // so in that case pull out the document's id
3053
- val = val._id;
3053
+ val = val._doc._id;
3054
3054
  }
3055
3055
  const scope = _this.$__.pathsToScopes != null && path in _this.$__.pathsToScopes ?
3056
3056
  _this.$__.pathsToScopes[path] :
@@ -15,7 +15,7 @@ class ParallelSaveError extends MongooseError {
15
15
  */
16
16
  constructor(doc) {
17
17
  const msg = 'Can\'t save() the same doc multiple times in parallel. Document: ';
18
- super(msg + doc._id);
18
+ super(msg + doc._doc._id);
19
19
  }
20
20
  }
21
21
 
@@ -16,7 +16,7 @@ class ParallelValidateError extends MongooseError {
16
16
  */
17
17
  constructor(doc) {
18
18
  const msg = 'Can\'t validate() the same doc multiple times in parallel. Document: ';
19
- super(msg + doc._id);
19
+ super(msg + doc._doc._id);
20
20
  }
21
21
  }
22
22
 
@@ -17,7 +17,7 @@ class VersionError extends MongooseError {
17
17
  */
18
18
  constructor(doc, currentVersion, modifiedPaths) {
19
19
  const modifiedPathsStr = modifiedPaths.join(', ');
20
- super('No matching document found for id "' + doc._id +
20
+ super('No matching document found for id "' + doc._doc._id +
21
21
  '" version ' + currentVersion + ' modifiedPaths "' + modifiedPathsStr + '"');
22
22
  this.version = currentVersion;
23
23
  this.modifiedPaths = modifiedPaths;
@@ -115,6 +115,9 @@ module.exports = function discriminator(model, name, schema, tiedValue, applyPlu
115
115
  }
116
116
  }
117
117
 
118
+ // Shallow clone `obj` so we can add additional properties without modifying original
119
+ // schema. `Schema.prototype.clone()` copies `obj` by reference, no cloning.
120
+ schema.obj = { ...schema.obj };
118
121
  mergeDiscriminatorSchema(schema, baseSchema);
119
122
 
120
123
  // Clean up conflicting paths _after_ merging re: gh-6076
@@ -626,7 +626,7 @@ function _getLocalFieldValues(doc, localField, model, options, virtual, schema)
626
626
 
627
627
  function convertTo_id(val, schema) {
628
628
  if (val != null && val.$__ != null) {
629
- return val._id;
629
+ return val._doc._id;
630
630
  }
631
631
  if (val != null && val._id != null && (schema == null || !schema.$isSchemaMap)) {
632
632
  return val._id;
@@ -636,7 +636,7 @@ function convertTo_id(val, schema) {
636
636
  const rawVal = val.__array != null ? val.__array : val;
637
637
  for (let i = 0; i < rawVal.length; ++i) {
638
638
  if (rawVal[i] != null && rawVal[i].$__ != null) {
639
- rawVal[i] = rawVal[i]._id;
639
+ rawVal[i] = rawVal[i]._doc._id;
640
640
  }
641
641
  }
642
642
  if (utils.isMongooseArray(val) && val.$schema()) {
@@ -17,11 +17,11 @@ const utils = require('../../utils');
17
17
  */
18
18
 
19
19
  module.exports = function markArraySubdocsPopulated(doc, populated) {
20
- if (doc._id == null || populated == null || populated.length === 0) {
20
+ if (doc._doc._id == null || populated == null || populated.length === 0) {
21
21
  return;
22
22
  }
23
23
 
24
- const id = String(doc._id);
24
+ const id = String(doc._doc._id);
25
25
  for (const item of populated) {
26
26
  if (item.isVirtual) {
27
27
  continue;
package/lib/model.js CHANGED
@@ -10,6 +10,7 @@ const Document = require('./document');
10
10
  const DocumentNotFoundError = require('./error/notFound');
11
11
  const EventEmitter = require('events').EventEmitter;
12
12
  const Kareem = require('kareem');
13
+ const MongooseBulkWriteError = require('./error/bulkWriteError');
13
14
  const MongooseError = require('./error/index');
14
15
  const ObjectParameterError = require('./error/objectParameter');
15
16
  const OverwriteModelError = require('./error/overwriteModel');
@@ -62,7 +63,6 @@ const setDottedPath = require('./helpers/path/setDottedPath');
62
63
  const STATES = require('./connectionState');
63
64
  const util = require('util');
64
65
  const utils = require('./utils');
65
- const MongooseBulkWriteError = require('./error/bulkWriteError');
66
66
  const minimize = require('./helpers/minimize');
67
67
 
68
68
  const modelCollectionSymbol = Symbol('mongoose#Model#collection');
@@ -2345,7 +2345,7 @@ Model.findByIdAndUpdate = function(id, update, options) {
2345
2345
 
2346
2346
  // if a model is passed in instead of an id
2347
2347
  if (id instanceof Document) {
2348
- id = id._id;
2348
+ id = id._doc._id;
2349
2349
  }
2350
2350
 
2351
2351
  return this.findOneAndUpdate.call(this, { _id: id }, update, options);
@@ -3202,8 +3202,8 @@ function _setIsNew(doc, val) {
3202
3202
  * @param {Boolean} [options.j=true] If false, disable [journal acknowledgement](https://www.mongodb.com/docs/manual/reference/write-concern/#j-option)
3203
3203
  * @param {Boolean} [options.skipValidation=false] Set to true to skip Mongoose schema validation on bulk write operations. Mongoose currently runs validation on `insertOne` and `replaceOne` operations by default.
3204
3204
  * @param {Boolean} [options.bypassDocumentValidation=false] If true, disable [MongoDB server-side schema validation](https://www.mongodb.com/docs/manual/core/schema-validation/) for all writes in this bulk.
3205
- * @param {Boolean} [options.throwOnValidationError=false] If true and `ordered: false`, throw an error if one of the operations failed validation, but all valid operations completed successfully.
3206
- * @param {Boolean} [options.strict=null] Overwrites the [`strict` option](https://mongoosejs.com/docs/guide.html#strict) on schema. If false, allows filtering and writing fields not defined in the schema for all writes in this bulk.
3205
+ * @param {Boolean} [options.throwOnValidationError=false] If true and `ordered: false`, throw an error if one of the operations failed validation, but all valid operations completed successfully. Note that Mongoose will still send all valid operations to the MongoDB server.
3206
+ * @param {Boolean|"throw"} [options.strict=null] Overwrites the [`strict` option](https://mongoosejs.com/docs/guide.html#strict) on schema. If false, allows filtering and writing fields not defined in the schema for all writes in this bulk.
3207
3207
  * @return {Promise} resolves to a [`BulkWriteOpResult`](https://mongodb.github.io/node-mongodb-native/4.9/classes/BulkWriteResult.html) if the operation succeeds
3208
3208
  * @api public
3209
3209
  */
@@ -3408,7 +3408,7 @@ Model.bulkSave = async function bulkSave(documents, options) {
3408
3408
  documents.map(async(document) => {
3409
3409
  const documentError = bulkWriteError && bulkWriteError.writeErrors.find(writeError => {
3410
3410
  const writeErrorDocumentId = writeError.err.op._id || writeError.err.op.q._id;
3411
- return writeErrorDocumentId.toString() === document._id.toString();
3411
+ return writeErrorDocumentId.toString() === document._doc._id.toString();
3412
3412
  });
3413
3413
 
3414
3414
  if (documentError == null) {
@@ -4436,7 +4436,7 @@ function _assign(model, vals, mod, assignmentOpts) {
4436
4436
 
4437
4437
  for (let __val of _val) {
4438
4438
  if (__val instanceof Document) {
4439
- __val = __val._id;
4439
+ __val = __val._doc._id;
4440
4440
  }
4441
4441
  key = String(__val);
4442
4442
  if (rawDocs[key]) {
package/lib/mongoose.js CHANGED
@@ -358,7 +358,7 @@ Mongoose.prototype.get = Mongoose.prototype.set;
358
358
  *
359
359
  * // initialize now, connect later
360
360
  * db = mongoose.createConnection();
361
- * db.openUri('127.0.0.1', 'database', port, [opts]);
361
+ * await db.openUri('mongodb://127.0.0.1:27017/database');
362
362
  *
363
363
  * @param {String} uri mongodb URI to connect to
364
364
  * @param {Object} [options] passed down to the [MongoDB driver's `connect()` function](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/MongoClientOptions.html), except for 4 mongoose-specific options explained below.
@@ -406,11 +406,10 @@ Mongoose.prototype.createConnection = function(uri, options) {
406
406
  * // with options
407
407
  * mongoose.connect(uri, options);
408
408
  *
409
- * // optional callback that gets fired when initial connection completed
409
+ * // Using `await` throws "MongooseServerSelectionError: Server selection timed out after 30000 ms"
410
+ * // if Mongoose can't connect.
410
411
  * const uri = 'mongodb://nonexistent.domain:27000';
411
- * mongoose.connect(uri, function(error) {
412
- * // if error is truthy, the initial connection failed.
413
- * })
412
+ * await mongoose.connect(uri);
414
413
  *
415
414
  * @param {String} uri mongodb URI to connect to
416
415
  * @param {Object} [options] passed down to the [MongoDB driver's `connect()` function](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/MongoClientOptions.html), except for 4 mongoose-specific options explained below.
package/lib/query.js CHANGED
@@ -2446,19 +2446,23 @@ Query.prototype.merge = function(source) {
2446
2446
  }
2447
2447
 
2448
2448
  opts.omit = {};
2449
- if (source.$and) {
2449
+ if (Array.isArray(source.$and)) {
2450
2450
  opts.omit['$and'] = true;
2451
2451
  if (!this._conditions) {
2452
2452
  this._conditions = {};
2453
2453
  }
2454
- this._conditions.$and = (this._conditions.$and || []).concat(source.$and);
2454
+ this._conditions.$and = (this._conditions.$and || []).concat(
2455
+ source.$and.map(el => utils.isPOJO(el) ? utils.merge({}, el) : el)
2456
+ );
2455
2457
  }
2456
- if (source.$or) {
2458
+ if (Array.isArray(source.$or)) {
2457
2459
  opts.omit['$or'] = true;
2458
2460
  if (!this._conditions) {
2459
2461
  this._conditions = {};
2460
2462
  }
2461
- this._conditions.$or = (this._conditions.$or || []).concat(source.$or);
2463
+ this._conditions.$or = (this._conditions.$or || []).concat(
2464
+ source.$or.map(el => utils.isPOJO(el) ? utils.merge({}, el) : el)
2465
+ );
2462
2466
  }
2463
2467
 
2464
2468
  // plain object
@@ -3376,9 +3380,9 @@ Query.prototype._findOneAndUpdate = async function _findOneAndUpdate() {
3376
3380
  if (!this._update || Object.keys(this._update).length === 0) {
3377
3381
  if (options.upsert) {
3378
3382
  // still need to do the upsert to empty doc
3379
- const doc = clone(this._update);
3380
- delete doc._id;
3381
- this._update = { $set: doc };
3383
+ const $set = clone(this._update);
3384
+ delete $set._id;
3385
+ this._update = { $set };
3382
3386
  } else {
3383
3387
  this._executionStack = null;
3384
3388
  const res = await this._findOne();
@@ -15,7 +15,7 @@ const castString = require('../../cast/string');
15
15
  * @api private
16
16
  */
17
17
 
18
- module.exports = function(val, path) {
18
+ module.exports = function castTextSearch(val, path) {
19
19
  if (val == null || typeof val !== 'object') {
20
20
  throw new CastError('$text', val, path);
21
21
  }
package/lib/utils.js CHANGED
@@ -53,6 +53,12 @@ exports.toCollectionName = function(name, pluralize) {
53
53
  return name;
54
54
  }
55
55
  if (typeof pluralize === 'function') {
56
+ if (typeof name !== 'string') {
57
+ throw new TypeError('Collection name must be a string');
58
+ }
59
+ if (name.length === 0) {
60
+ throw new TypeError('Collection name cannot be empty');
61
+ }
56
62
  return pluralize(name);
57
63
  }
58
64
  return name;
@@ -301,6 +307,8 @@ exports.merge = function merge(to, from, options, path) {
301
307
  to[key] = from[key];
302
308
  }
303
309
  }
310
+
311
+ return to;
304
312
  };
305
313
 
306
314
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mongoose",
3
3
  "description": "Mongoose MongoDB ODM",
4
- "version": "8.5.3",
4
+ "version": "8.5.5",
5
5
  "author": "Guillermo Rauch <guillermo@learnboost.com>",
6
6
  "keywords": [
7
7
  "mongodb",
@@ -53,7 +53,7 @@
53
53
  "lodash.isequal": "4.5.0",
54
54
  "lodash.isequalwith": "4.4.0",
55
55
  "markdownlint-cli2": "^0.13.0",
56
- "marked": "4.3.0",
56
+ "marked": "14.0.0",
57
57
  "mkdirp": "^3.0.1",
58
58
  "mocha": "10.7.0",
59
59
  "moment": "2.30.1",
@@ -87,8 +87,8 @@ declare module 'mongoose' {
87
87
  'createdAt' | 'updatedAt'
88
88
  > as TimestampOptions[K] extends true
89
89
  ? K
90
- : TimestampOptions[K] extends string
91
- ? TimestampOptions[K]
90
+ : TimestampOptions[K] extends `${infer TimestampValue}`
91
+ ? TimestampValue
92
92
  : never]: NativeDate;
93
93
  } & T
94
94
  : T
package/types/query.d.ts CHANGED
@@ -431,7 +431,7 @@ declare module 'mongoose' {
431
431
  ): QueryWithHelpers<DocType | null, DocType, THelpers, RawDocType, 'findOne', TInstanceMethods>;
432
432
  findOne(
433
433
  filter?: FilterQuery<RawDocType>
434
- ): QueryWithHelpers<DocType | null, RawDocType, THelpers, RawDocType, 'findOne', TInstanceMethods>;
434
+ ): QueryWithHelpers<DocType | null, DocType, THelpers, RawDocType, 'findOne', TInstanceMethods>;
435
435
 
436
436
  /** Creates a `findOneAndDelete` query: atomically finds the given document, deletes it, and returns the document as it was before deletion. */
437
437
  findOneAndDelete(