mongoose 9.1.2 → 9.1.3

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.
@@ -51,15 +51,24 @@ module.exports = function setupTimestamps(schema, timestamps) {
51
51
  setDocumentTimestamps(this, timestampOption, currentTime, createdAt, updatedAt);
52
52
  });
53
53
 
54
- schema.methods.initializeTimestamps = function() {
54
+ schema.methods.initializeTimestamps = function(timestampsOptions) {
55
+ if (timestampsOptions === false) {
56
+ return this;
57
+ }
55
58
  const ts = currentTime != null ?
56
59
  currentTime() : this.constructor.base.now();
57
60
 
61
+ const initTimestampsCreatedAt = timestampsOptions != null ?
62
+ handleTimestampOption(timestampsOptions, 'createdAt') :
63
+ createdAt;
64
+ const initTimestampsUpdatedAt = timestampsOptions != null ?
65
+ handleTimestampOption(timestampsOptions, 'updatedAt') :
66
+ updatedAt;
58
67
 
59
- if (createdAt && !this.get(createdAt)) {
68
+ if (initTimestampsCreatedAt && !this.get(initTimestampsCreatedAt)) {
60
69
  this.$set(createdAt, ts);
61
70
  }
62
- if (updatedAt && !this.get(updatedAt)) {
71
+ if (initTimestampsUpdatedAt && !this.get(initTimestampsUpdatedAt)) {
63
72
  this.$set(updatedAt, ts);
64
73
  }
65
74
  if (this.$isSubdocument) {
@@ -69,7 +78,7 @@ module.exports = function setupTimestamps(schema, timestamps) {
69
78
  const subdocs = this.$getAllSubdocs();
70
79
  for (const subdoc of subdocs) {
71
80
  if (subdoc.initializeTimestamps) {
72
- subdoc.initializeTimestamps();
81
+ subdoc.initializeTimestamps(timestampsOptions);
73
82
  }
74
83
  }
75
84
 
package/lib/model.js CHANGED
@@ -3029,9 +3029,9 @@ Model.insertMany = async function insertMany(arr, options) {
3029
3029
  if (doc.$__schema.options.versionKey) {
3030
3030
  doc[doc.$__schema.options.versionKey] = 0;
3031
3031
  }
3032
- const shouldSetTimestamps = (!options || options.timestamps !== false) && doc.initializeTimestamps && (!doc.$__ || doc.$__.timestamps !== false);
3032
+ const shouldSetTimestamps = options?.timestamps !== false && doc.initializeTimestamps && (!doc.$__ || doc.$__.timestamps !== false);
3033
3033
  if (shouldSetTimestamps) {
3034
- doc.initializeTimestamps();
3034
+ doc.initializeTimestamps(options?.timestamps);
3035
3035
  }
3036
3036
  if (doc.$__hasOnlyPrimitiveValues()) {
3037
3037
  return doc.$__toObjectShallow();
package/lib/query.js CHANGED
@@ -4025,7 +4025,7 @@ Query.prototype._mergeUpdate = function(update) {
4025
4025
 
4026
4026
  if (update instanceof Query) {
4027
4027
  if (Array.isArray(this._update)) {
4028
- throw new MongooseError('Cannot mix array and object updates');
4028
+ throw new MongooseError(`Cannot mix array and object updates (current: ${_previewUpdate(this._update)}, incoming: ${_previewUpdate(update._update)})`);
4029
4029
  }
4030
4030
  if (update._update) {
4031
4031
  utils.mergeClone(this._update, update._update);
@@ -4037,18 +4037,33 @@ Query.prototype._mergeUpdate = function(update) {
4037
4037
  if (this._update == null || utils.isEmptyObject(this._update)) {
4038
4038
  this._update = [];
4039
4039
  } else {
4040
- throw new MongooseError('Cannot mix array and object updates');
4040
+ throw new MongooseError(`Cannot mix array and object updates (current: ${_previewUpdate(this._update)}, incoming: ${_previewUpdate(update)})`);
4041
4041
  }
4042
4042
  }
4043
4043
  this._update = this._update.concat(update);
4044
4044
  } else {
4045
4045
  if (Array.isArray(this._update)) {
4046
- throw new MongooseError('Cannot mix array and object updates');
4046
+ throw new MongooseError(`Cannot mix array and object updates (current: ${_previewUpdate(this._update)}, incoming: ${_previewUpdate(update)})`);
4047
4047
  }
4048
4048
  utils.mergeClone(this._update, update);
4049
4049
  }
4050
4050
  };
4051
4051
 
4052
+ function _previewUpdate(update) {
4053
+ const preview = util.inspect(update, {
4054
+ depth: 2,
4055
+ maxArrayLength: 5,
4056
+ breakLength: 80,
4057
+ compact: true
4058
+ });
4059
+
4060
+ if (preview.length > 200) {
4061
+ return `${preview.slice(0, 197)}...`;
4062
+ }
4063
+
4064
+ return preview;
4065
+ }
4066
+
4052
4067
  /*!
4053
4068
  * ignore
4054
4069
  */
@@ -155,7 +155,7 @@ SchemaArray.defaultOptions = {};
155
155
  * #### Example:
156
156
  *
157
157
  * // Make all Array instances have `required` of true by default.
158
- * mongoose.Schema.Array.set('required', true);
158
+ * mongoose.Schema.Types.Array.set('required', true);
159
159
  *
160
160
  * const User = mongoose.model('User', new Schema({ test: Array }));
161
161
  * new User({ }).validateSync().errors.test.message; // Path `test` is required.
@@ -52,7 +52,7 @@ SchemaBigInt._cast = castBigInt;
52
52
  * #### Example:
53
53
  *
54
54
  * // Make all bigints required by default
55
- * mongoose.Schema.BigInt.set('required', true);
55
+ * mongoose.Schema.Types.BigInt.set('required', true);
56
56
  *
57
57
  * @param {String} option The option you'd like to set the value for
58
58
  * @param {Any} value value for option
@@ -72,7 +72,7 @@ SchemaBigInt.setters = [];
72
72
  * #### Example:
73
73
  *
74
74
  * // Convert bigints to numbers
75
- * mongoose.Schema.BigInt.get(v => v == null ? v : Number(v));
75
+ * mongoose.Schema.Types.BigInt.get(v => v == null ? v : Number(v));
76
76
  *
77
77
  * @param {Function} getter
78
78
  * @return {this}
@@ -90,7 +90,7 @@ SchemaBigInt.get = SchemaType.get;
90
90
  *
91
91
  * // Make Mongoose cast empty string '' to false.
92
92
  * const original = mongoose.Schema.Types.BigInt.cast();
93
- * mongoose.Schema.BigInt.cast(v => {
93
+ * mongoose.Schema.Types.BigInt.cast(v => {
94
94
  * if (v === '') {
95
95
  * return false;
96
96
  * }
@@ -98,7 +98,7 @@ SchemaBigInt.get = SchemaType.get;
98
98
  * });
99
99
  *
100
100
  * // Or disable casting entirely
101
- * mongoose.Schema.BigInt.cast(false);
101
+ * mongoose.Schema.Types.BigInt.cast(false);
102
102
  *
103
103
  * @param {Function} caster
104
104
  * @return {Function}
@@ -52,7 +52,7 @@ SchemaBoolean._cast = castBoolean;
52
52
  * #### Example:
53
53
  *
54
54
  * // Make all booleans have `default` of false.
55
- * mongoose.Schema.Boolean.set('default', false);
55
+ * mongoose.Schema.Types.Boolean.set('default', false);
56
56
  *
57
57
  * const Order = mongoose.model('Order', new Schema({ isPaid: Boolean }));
58
58
  * new Order({ }).isPaid; // false
@@ -74,7 +74,7 @@ SchemaBoolean.setters = [];
74
74
  *
75
75
  * #### Example:
76
76
  *
77
- * mongoose.Schema.Boolean.get(v => v === true ? 'yes' : 'no');
77
+ * mongoose.Schema.Types.Boolean.get(v => v === true ? 'yes' : 'no');
78
78
  *
79
79
  * const Order = mongoose.model('Order', new Schema({ isPaid: Boolean }));
80
80
  * new Order({ isPaid: false }).isPaid; // 'no'
@@ -94,8 +94,8 @@ SchemaBoolean.get = SchemaType.get;
94
94
  * #### Example:
95
95
  *
96
96
  * // Make Mongoose cast empty string '' to false.
97
- * const original = mongoose.Schema.Boolean.cast();
98
- * mongoose.Schema.Boolean.cast(v => {
97
+ * const original = mongoose.Schema.Types.Boolean.cast();
98
+ * mongoose.Schema.Types.Boolean.cast(v => {
99
99
  * if (v === '') {
100
100
  * return false;
101
101
  * }
@@ -103,7 +103,7 @@ SchemaBoolean.get = SchemaType.get;
103
103
  * });
104
104
  *
105
105
  * // Or disable casting entirely
106
- * mongoose.Schema.Boolean.cast(false);
106
+ * mongoose.Schema.Types.Boolean.cast(false);
107
107
  *
108
108
  * @param {Function} caster
109
109
  * @return {Function}
@@ -175,7 +175,7 @@ SchemaBoolean.prototype.checkRequired = function(value) {
175
175
  *
176
176
  * const M = mongoose.model('Test', new Schema({ b: Boolean }));
177
177
  * new M({ b: 'affirmative' }).b; // undefined
178
- * mongoose.Schema.Boolean.convertToTrue.add('affirmative');
178
+ * mongoose.Schema.Types.Boolean.convertToTrue.add('affirmative');
179
179
  * new M({ b: 'affirmative' }).b; // true
180
180
  *
181
181
  * @property convertToTrue
@@ -58,7 +58,7 @@ SchemaBuffer._checkRequired = v => !!v?.length;
58
58
  * #### Example:
59
59
  *
60
60
  * // Make all buffers have `required` of true by default.
61
- * mongoose.Schema.Buffer.set('required', true);
61
+ * mongoose.Schema.Types.Buffer.set('required', true);
62
62
  *
63
63
  * const User = mongoose.model('User', new Schema({ test: Buffer }));
64
64
  * new User({ }).validateSync().errors.test.message; // Path `test` is required.
@@ -58,7 +58,7 @@ SchemaDate._cast = castDate;
58
58
  * #### Example:
59
59
  *
60
60
  * // Make all dates have `required` of true by default.
61
- * mongoose.Schema.Date.set('required', true);
61
+ * mongoose.Schema.Types.Date.set('required', true);
62
62
  *
63
63
  * const User = mongoose.model('User', new Schema({ test: Date }));
64
64
  * new User({ }).validateSync().errors.test.message; // Path `test` is required.
@@ -81,7 +81,7 @@ SchemaDate.setters = [];
81
81
  * #### Example:
82
82
  *
83
83
  * // Always convert Dates to string
84
- * mongoose.Date.get(v => v.toString());
84
+ * mongoose.Schema.Types.Date.get(v => v.toString());
85
85
  *
86
86
  * const Model = mongoose.model('Test', new Schema({ date: { type: Date, default: () => new Date() } }));
87
87
  * typeof (new Model({}).date); // 'string'
@@ -53,7 +53,7 @@ SchemaDecimal128._cast = castDecimal128;
53
53
  * #### Example:
54
54
  *
55
55
  * // Make all decimal 128s have `required` of true by default.
56
- * mongoose.Schema.Decimal128.set('required', true);
56
+ * mongoose.Schema.Types.Decimal128.set('required', true);
57
57
  *
58
58
  * const User = mongoose.model('User', new Schema({ test: mongoose.Decimal128 }));
59
59
  * new User({ }).validateSync().errors.test.message; // Path `test` is required.
@@ -76,7 +76,7 @@ SchemaDecimal128.setters = [];
76
76
  * #### Example:
77
77
  *
78
78
  * // Automatically convert Decimal128s to Numbers
79
- * mongoose.Schema.Decimal128.get(v => v == null ? v : Number(v));
79
+ * mongoose.Schema.Types.Decimal128.get(v => v == null ? v : Number(v));
80
80
  *
81
81
  * @param {Function} getter
82
82
  * @return {this}
@@ -574,8 +574,8 @@ SchemaDocumentArray.defaultOptions = {};
574
574
  *
575
575
  * #### Example:
576
576
  *
577
- * // Make all numbers have option `min` equal to 0.
578
- * mongoose.Schema.DocumentArray.set('_id', false);
577
+ * // Make all document arrays not have `_id` by default.
578
+ * mongoose.Schema.Types.DocumentArray.set('_id', false);
579
579
  *
580
580
  * @param {String} option The name of the option you'd like to set (e.g. trim, lowercase, etc...)
581
581
  * @param {Any} value The value of the option you'd like to set.
@@ -49,6 +49,36 @@ SchemaDocumentArrayElement.schemaName = 'DocumentArrayElement';
49
49
 
50
50
  SchemaDocumentArrayElement.defaultOptions = {};
51
51
 
52
+ /**
53
+ * Sets a default option for all SchemaDocumentArrayElement instances.
54
+ *
55
+ * #### Example:
56
+ *
57
+ * // Make all document array elements have option `_id` equal to false.
58
+ * mongoose.Schema.Types.DocumentArrayElement.set('_id', false);
59
+ *
60
+ * @param {String} option The name of the option you'd like to set
61
+ * @param {Any} value The value of the option you'd like to set.
62
+ * @return {void}
63
+ * @function set
64
+ * @static
65
+ * @api public
66
+ */
67
+
68
+ SchemaDocumentArrayElement.set = SchemaType.set;
69
+
70
+ /**
71
+ * Attaches a getter for all DocumentArrayElement instances
72
+ *
73
+ * @param {Function} getter
74
+ * @return {this}
75
+ * @function get
76
+ * @static
77
+ * @api public
78
+ */
79
+
80
+ SchemaDocumentArrayElement.get = SchemaType.get;
81
+
52
82
  /*!
53
83
  * Inherits from SchemaType.
54
84
  */
@@ -52,7 +52,7 @@ SchemaDouble._cast = castDouble;
52
52
  * #### Example:
53
53
  *
54
54
  * // Make all Double fields required by default
55
- * mongoose.Schema.Double.set('required', true);
55
+ * mongoose.Schema.Types.Double.set('required', true);
56
56
  *
57
57
  * @param {String} option The option you'd like to set the value for
58
58
  * @param {Any} value value for option
@@ -72,7 +72,7 @@ SchemaDouble.setters = [];
72
72
  * #### Example:
73
73
  *
74
74
  * // Converts Double to be a represent milliseconds upon access
75
- * mongoose.Schema.Double.get(v => v == null ? '0.000 ms' : v.toString() + ' ms');
75
+ * mongoose.Schema.Types.Double.get(v => v == null ? '0.000 ms' : v.toString() + ' ms');
76
76
  *
77
77
  * @param {Function} getter
78
78
  * @return {this}
@@ -112,7 +112,7 @@ SchemaDouble._defaultCaster = v => {
112
112
  * });
113
113
  *
114
114
  * // Or disable casting for Doubles entirely (only JS numbers are permitted)
115
- * mongoose.Schema.Double.cast(false);
115
+ * mongoose.Schema.Types.Double.cast(false);
116
116
  *
117
117
  *
118
118
  * @param {Function} caster
@@ -12,6 +12,7 @@ exports.Buffer = require('./buffer');
12
12
  exports.Date = require('./date');
13
13
  exports.Decimal128 = exports.Decimal = require('./decimal128');
14
14
  exports.DocumentArray = require('./documentArray');
15
+ exports.DocumentArrayElement = require('./documentArrayElement');
15
16
  exports.Double = require('./double');
16
17
  exports.Int32 = require('./int32');
17
18
  exports.Map = require('./map');
@@ -53,7 +53,7 @@ SchemaInt32._cast = castInt32;
53
53
  * #### Example:
54
54
  *
55
55
  * // Make all Int32 fields required by default
56
- * mongoose.Schema.Int32.set('required', true);
56
+ * mongoose.Schema.Types.Int32.set('required', true);
57
57
  *
58
58
  * @param {String} option The option you'd like to set the value for
59
59
  * @param {Any} value value for option
@@ -73,7 +73,7 @@ SchemaInt32.setters = [];
73
73
  * #### Example:
74
74
  *
75
75
  * // Converts int32 to be a represent milliseconds upon access
76
- * mongoose.Schema.Int32.get(v => v == null ? '0 ms' : v.toString() + ' ms');
76
+ * mongoose.Schema.Types.Int32.get(v => v == null ? '0 ms' : v.toString() + ' ms');
77
77
  *
78
78
  * @param {Function} getter
79
79
  * @return {this}
@@ -116,7 +116,7 @@ SchemaInt32._defaultCaster = v => {
116
116
  * });
117
117
  *
118
118
  * // Or disable casting for Int32s entirely (only JS numbers within 32-bit integer bounds and null-ish values are permitted)
119
- * mongoose.Schema.Int32.cast(false);
119
+ * mongoose.Schema.Types.Int32.cast(false);
120
120
  *
121
121
  *
122
122
  * @param {Function} caster
@@ -61,7 +61,7 @@ SchemaMixed.prototype.constructor = SchemaMixed;
61
61
  * #### Example:
62
62
  *
63
63
  * // Hide the 'hidden' path
64
- * mongoose.Schema.Mixed.get(v => Object.assign({}, v, { hidden: null }));
64
+ * mongoose.Schema.Types.Mixed.get(v => Object.assign({}, v, { hidden: null }));
65
65
  *
66
66
  * const Model = mongoose.model('Test', new Schema({ test: {} }));
67
67
  * new Model({ test: { hidden: 'Secret!' } }).test.hidden; // null
@@ -81,7 +81,7 @@ SchemaMixed.get = SchemaType.get;
81
81
  * #### Example:
82
82
  *
83
83
  * // Make all mixed instances have `required` of true by default.
84
- * mongoose.Schema.Mixed.set('required', true);
84
+ * mongoose.Schema.Types.Mixed.set('required', true);
85
85
  *
86
86
  * const User = mongoose.model('User', new Schema({ test: mongoose.Mixed }));
87
87
  * new User({ }).validateSync().errors.test.message; // Path `test` is required.
@@ -56,7 +56,7 @@ SchemaNumber.get = SchemaType.get;
56
56
  * #### Example:
57
57
  *
58
58
  * // Make all numbers have option `min` equal to 0.
59
- * mongoose.Schema.Number.set('min', 0);
59
+ * mongoose.Schema.Types.Number.set('min', 0);
60
60
  *
61
61
  * const Order = mongoose.model('Order', new Schema({ amount: Number }));
62
62
  * new Order({ amount: -10 }).validateSync().errors.amount.message; // Path `amount` must be larger than 0.
@@ -33,7 +33,7 @@ function SchemaObjectId(key, options, _schemaOptions, parentSchema) {
33
33
  if ((isKeyHexStr || typeof key === 'undefined') && !suppressWarning) {
34
34
  utils.warn('mongoose: To create a new ObjectId please try ' +
35
35
  '`Mongoose.Types.ObjectId` instead of using ' +
36
- '`Mongoose.Schema.ObjectId`. Set the `suppressWarning` option if ' +
36
+ '`Mongoose.Schema.Types.ObjectId`. Set the `suppressWarning` option if ' +
37
37
  'you\'re trying to create a hex char path in your schema.');
38
38
  }
39
39
  SchemaType.call(this, key, options, 'ObjectId', parentSchema);
@@ -82,7 +82,7 @@ SchemaObjectId.get = SchemaType.get;
82
82
  * #### Example:
83
83
  *
84
84
  * // Make all object ids have option `required` equal to true.
85
- * mongoose.Schema.ObjectId.set('required', true);
85
+ * mongoose.Schema.Types.ObjectId.set('required', true);
86
86
  *
87
87
  * const Order = mongoose.model('Order', new Schema({ userId: ObjectId }));
88
88
  * new Order({ }).validateSync().errors.userId.message; // Path `userId` is required.
@@ -111,7 +111,7 @@ SchemaString._defaultCaster = v => {
111
111
  * #### Example:
112
112
  *
113
113
  * // Make all numbers round down
114
- * mongoose.Schema.String.get(v => v.toLowerCase());
114
+ * mongoose.Schema.Types.String.get(v => v.toLowerCase());
115
115
  *
116
116
  * const Model = mongoose.model('Test', new Schema({ test: String }));
117
117
  * new Model({ test: 'FOO' }).test; // 'foo'
@@ -131,7 +131,7 @@ SchemaString.get = SchemaType.get;
131
131
  * #### Example:
132
132
  *
133
133
  * // Make all strings have option `trim` equal to true.
134
- * mongoose.Schema.String.set('trim', true);
134
+ * mongoose.Schema.Types.String.set('trim', true);
135
135
  *
136
136
  * const User = mongoose.model('User', new Schema({ name: String }));
137
137
  * new User({ name: ' John Doe ' }).name; // 'John Doe'
@@ -364,8 +364,8 @@ SchemaSubdocument.defaultOptions = {};
364
364
  *
365
365
  * #### Example:
366
366
  *
367
- * // Make all numbers have option `min` equal to 0.
368
- * mongoose.Schema.Subdocument.set('required', true);
367
+ * // Make all subdocuments required by default.
368
+ * mongoose.Schema.Types.Subdocument.set('required', true);
369
369
  *
370
370
  * @param {String} option The option you'd like to set the value for
371
371
  * @param {Any} value value for option
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mongoose",
3
3
  "description": "Mongoose MongoDB ODM",
4
- "version": "9.1.2",
4
+ "version": "9.1.3",
5
5
  "author": "Guillermo Rauch <guillermo@learnboost.com>",
6
6
  "keywords": [
7
7
  "mongodb",
package/types/models.d.ts CHANGED
@@ -71,6 +71,7 @@ declare module 'mongoose' {
71
71
  ordered?: boolean;
72
72
  lean?: boolean;
73
73
  throwOnValidationError?: boolean;
74
+ timestamps?: boolean | QueryTimestampsConfig;
74
75
  }
75
76
 
76
77
  interface InsertManyResult<T> extends mongodb.InsertManyResult<T> {
@@ -237,7 +238,11 @@ declare module 'mongoose' {
237
238
  ? (Record<KeyType, ValueType> | Array<[KeyType, ValueType]> | T[K])
238
239
  : NonNullable<T[K]> extends Types.DocumentArray<infer RawSubdocType>
239
240
  ? RawSubdocType[] | T[K]
240
- : QueryTypeCasting<T[K]>;
241
+ : NonNullable<T[K]> extends Document<any, any, infer RawSubdocType>
242
+ ? ApplyBasicCreateCasting<RawSubdocType> | T[K]
243
+ : NonNullable<T[K]> extends Record<string, any>
244
+ ? ApplyBasicCreateCasting<T[K]> | T[K]
245
+ : QueryTypeCasting<T[K]>;
241
246
  };
242
247
 
243
248
  type HasLeanOption<TSchema> = 'lean' extends keyof ObtainSchemaGeneric<TSchema, 'TSchemaOptions'> ?
@@ -513,6 +513,15 @@ declare module 'mongoose' {
513
513
  static defaultOptions: Record<string, any>;
514
514
  }
515
515
 
516
+ class DocumentArrayElement extends SchemaType {
517
+ /** This schema type's name, to defend against minifiers that mangle function names. */
518
+ static schemaName: 'DocumentArrayElement';
519
+ readonly schemaName: 'DocumentArrayElement';
520
+
521
+ /** Default options for this SchemaType */
522
+ static defaultOptions: Record<string, any>;
523
+ }
524
+
516
525
  class Map extends SchemaType {
517
526
  /** This schema type's name, to defend against minifiers that mangle function names. */
518
527
  static schemaName: 'Map';
@@ -15,7 +15,7 @@ declare module 'mongoose' {
15
15
  // If not a document, then return the type. Otherwise, get the DocType.
16
16
  ? NonNullable<T[P]>
17
17
  : Extract<NonNullable<T[P]>, Document> extends Document<any, any, infer DocType, any>
18
- ? DocType
18
+ ? DocType | Exclude<NonNullable<T[P]>, Document>
19
19
  : never
20
20
  // Handle nested paths
21
21
  : P extends `${infer Key}.${infer Rest}`