mongoose 6.3.6 → 6.3.7

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/document.js CHANGED
@@ -79,7 +79,6 @@ function Document(obj, fields, skipId, options) {
79
79
  options = skipId;
80
80
  skipId = options.skipId;
81
81
  }
82
- options = Object.assign({}, options);
83
82
 
84
83
  // Support `browserDocument.js` syntax
85
84
  if (this.$__schema == null) {
@@ -93,9 +92,9 @@ function Document(obj, fields, skipId, options) {
93
92
  }
94
93
 
95
94
  this.$__ = new InternalCache();
96
- this.$isNew = 'isNew' in options ? options.isNew : true;
95
+ this.$isNew = options && options.isNew != null ? options.isNew : true;
97
96
 
98
- if (options.priorDoc != null) {
97
+ if (options && options.priorDoc != null) {
99
98
  this.$__.priorDoc = options.priorDoc;
100
99
  }
101
100
 
@@ -108,18 +107,20 @@ function Document(obj, fields, skipId, options) {
108
107
  }
109
108
 
110
109
  let defaults = true;
111
- if (options.defaults !== undefined) {
110
+ if (options && options.defaults !== undefined) {
112
111
  this.$__.defaults = options.defaults;
113
112
  defaults = options.defaults;
114
113
  }
115
114
 
116
115
  const schema = this.$__schema;
117
116
 
117
+ let strict;
118
118
  if (typeof fields === 'boolean' || fields === 'throw') {
119
119
  this.$__.strictMode = fields;
120
+ strict = fields;
120
121
  fields = undefined;
121
122
  } else {
122
- this.$__.strictMode = schema.options.strict;
123
+ strict = schema.options.strict;
123
124
  if (fields != null) {
124
125
  this.$__.selected = fields;
125
126
  }
@@ -136,7 +137,6 @@ function Document(obj, fields, skipId, options) {
136
137
  // excluded fields
137
138
  if (utils.isPOJO(fields)) {
138
139
  exclude = isExclusive(fields);
139
-
140
140
  this.$__.fields = fields;
141
141
  this.$__.exclude = exclude;
142
142
  }
@@ -170,15 +170,15 @@ function Document(obj, fields, skipId, options) {
170
170
  // Function defaults get applied **after** setting initial values so they
171
171
  // see the full doc rather than an empty one, unless they opt out.
172
172
  // Re: gh-3781, gh-6155
173
- if (options.willInit && defaults) {
173
+ if (options && options.willInit && defaults) {
174
174
  if (options.skipDefaults) {
175
175
  this.$__.skipDefaults = options.skipDefaults;
176
176
  }
177
177
  } else if (defaults) {
178
- $__applyDefaults(this, fields, exclude, hasIncludedChildren, false, options.skipDefaults);
178
+ $__applyDefaults(this, fields, exclude, hasIncludedChildren, false, options && options.skipDefaults);
179
179
  }
180
180
 
181
- if (!this.$__.strictMode && obj) {
181
+ if (!strict && obj) {
182
182
  const _this = this;
183
183
  const keys = Object.keys(this._doc);
184
184
 
@@ -641,7 +641,11 @@ Document.prototype.$__buildDoc = function(obj, fields, skipId, exclude, hasInclu
641
641
  for (let i = 0; i < len; ++i) {
642
642
  const piece = path[i];
643
643
 
644
- curPath += (!curPath.length ? '' : '.') + piece;
644
+ if (!curPath.length) {
645
+ curPath = piece;
646
+ } else {
647
+ curPath += '.' + piece;
648
+ }
645
649
 
646
650
  // support excluding intermediary levels
647
651
  if (exclude === true) {
@@ -1045,8 +1049,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
1045
1049
  type = undefined;
1046
1050
  }
1047
1051
 
1048
- options = options || {};
1049
- const merge = options.merge;
1052
+ const merge = options && options.merge;
1050
1053
  const adhoc = type && type !== true;
1051
1054
  const constructing = type === true;
1052
1055
  let adhocs;
@@ -1056,7 +1059,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
1056
1059
  let key;
1057
1060
  let prefix;
1058
1061
 
1059
- const strict = 'strict' in options
1062
+ const strict = options && 'strict' in options
1060
1063
  ? options.strict
1061
1064
  : this.$__.strictMode;
1062
1065
 
@@ -1087,7 +1090,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
1087
1090
 
1088
1091
  // `_skipMinimizeTopLevel` is because we may have deleted the top-level
1089
1092
  // nested key to ensure key order.
1090
- const _skipMinimizeTopLevel = options._skipMinimizeTopLevel || false;
1093
+ const _skipMinimizeTopLevel = options && options._skipMinimizeTopLevel || false;
1091
1094
  if (len === 0 && _skipMinimizeTopLevel) {
1092
1095
  delete options._skipMinimizeTopLevel;
1093
1096
  if (val) {
@@ -1565,7 +1568,7 @@ Document.prototype.set = Document.prototype.$set;
1565
1568
  */
1566
1569
 
1567
1570
  Document.prototype.$__shouldModify = function(pathToMark, path, options, constructing, parts, schema, val, priorVal) {
1568
- if (options._skipMarkModified) {
1571
+ if (options && options._skipMarkModified) {
1569
1572
  return false;
1570
1573
  }
1571
1574
  if (this.$isNew) {
@@ -3929,12 +3932,19 @@ function applySchemaTypeTransforms(self, json) {
3929
3932
  const schematype = schema.paths[path];
3930
3933
  if (typeof schematype.options.transform === 'function') {
3931
3934
  const val = self.$get(path);
3935
+ if (val === undefined) {
3936
+ continue;
3937
+ }
3932
3938
  const transformedValue = schematype.options.transform.call(self, val);
3933
3939
  throwErrorIfPromise(path, transformedValue);
3934
3940
  utils.setValue(path, transformedValue, json);
3935
3941
  } else if (schematype.$embeddedSchemaType != null &&
3936
3942
  typeof schematype.$embeddedSchemaType.options.transform === 'function') {
3937
- const vals = [].concat(self.$get(path));
3943
+ const val = self.$get(path);
3944
+ if (val === undefined) {
3945
+ continue;
3946
+ }
3947
+ const vals = [].concat(val);
3938
3948
  const transform = schematype.$embeddedSchemaType.options.transform;
3939
3949
  for (let i = 0; i < vals.length; ++i) {
3940
3950
  const transformedValue = transform.call(self, vals[i]);
@@ -40,7 +40,8 @@ function createImmutableSetter(path, immutable) {
40
40
  const _value = this.$__.priorDoc != null ?
41
41
  this.$__.priorDoc.$__getValue(path) :
42
42
  this.$__getValue(path);
43
- if (this.$__.strictMode === 'throw' && v !== _value) {
43
+ const strict = this.$__.strictMode == null ? this.$__schema.options.strict : this.$__.strictMode;
44
+ if (strict === 'throw' && v !== _value) {
44
45
  throw new StrictModeError(path, 'Path `' + path + '` is immutable ' +
45
46
  'and strict mode is set to throw.', true);
46
47
  }
@@ -15,6 +15,9 @@ module.exports = function castArrayFilters(query) {
15
15
  if (query._mongooseOptions.strict != null) {
16
16
  strictQuery = query._mongooseOptions.strict;
17
17
  }
18
+ if (query.model && query.model.base.options.strictQuery != null) {
19
+ strictQuery = query.model.base.options.strictQuery;
20
+ }
18
21
  if (schema._userProvidedOptions.strictQuery != null) {
19
22
  strictQuery = schema._userProvidedOptions.strictQuery;
20
23
  }
@@ -119,6 +119,19 @@ Object.defineProperty(SchemaTypeOptions.prototype, 'default', opts);
119
119
 
120
120
  Object.defineProperty(SchemaTypeOptions.prototype, 'ref', opts);
121
121
 
122
+ /**
123
+ * The path in the document that `populate()` should use to find the model
124
+ * to use.
125
+ *
126
+ * @api public
127
+ * @property ref
128
+ * @memberOf SchemaTypeOptions
129
+ * @type Function|String
130
+ * @instance
131
+ */
132
+
133
+ Object.defineProperty(SchemaTypeOptions.prototype, 'refPath', opts);
134
+
122
135
  /**
123
136
  * Whether to include or exclude this path by default when loading documents
124
137
  * using `find()`, `findOne()`, etc.
@@ -33,6 +33,13 @@ module.exports = SubdocumentPath;
33
33
  */
34
34
 
35
35
  function SubdocumentPath(schema, path, options) {
36
+ const schemaTypeIdOption = SubdocumentPath.defaultOptions &&
37
+ SubdocumentPath.defaultOptions._id;
38
+ if (schemaTypeIdOption != null) {
39
+ options = options || {};
40
+ options._id = schemaTypeIdOption;
41
+ }
42
+
36
43
  schema = handleIdOption(schema, options);
37
44
 
38
45
  this.caster = _createConstructor(schema);
@@ -160,7 +167,7 @@ SubdocumentPath.prototype.cast = function(val, doc, init, priorVal, options) {
160
167
  }
161
168
  return obj;
162
169
  }, null);
163
- options = Object.assign({}, options, { priorDoc: priorVal });
170
+ options = priorVal != null ? Object.assign({}, options, { priorDoc: priorVal }) : options;
164
171
  if (init) {
165
172
  subdoc = new Constructor(void 0, selected, doc);
166
173
  subdoc.$init(val);
@@ -391,8 +391,6 @@ DocumentArrayPath.prototype.cast = function(value, doc, init, prev, options) {
391
391
  let selected;
392
392
  let subdoc;
393
393
 
394
- options = options || {};
395
-
396
394
  if (!Array.isArray(value)) {
397
395
  if (!init && !DocumentArrayPath.options.castNonArrays) {
398
396
  throw new CastError('DocumentArray', value, this.path, null, this);
@@ -407,7 +405,7 @@ DocumentArrayPath.prototype.cast = function(value, doc, init, prev, options) {
407
405
 
408
406
  // We need to create a new array, otherwise change tracking will
409
407
  // update the old doc (gh-4449)
410
- if (!options.skipDocumentArrayCast || utils.isMongooseDocumentArray(value)) {
408
+ if (!options || !options.skipDocumentArrayCast || utils.isMongooseDocumentArray(value)) {
411
409
  value = new MongooseDocumentArray(value, this.path, doc);
412
410
  }
413
411
 
@@ -415,7 +413,7 @@ DocumentArrayPath.prototype.cast = function(value, doc, init, prev, options) {
415
413
  value[arrayAtomicsSymbol] = prev[arrayAtomicsSymbol] || {};
416
414
  }
417
415
 
418
- if (options.arrayPathIndex != null) {
416
+ if (options && options.arrayPathIndex != null) {
419
417
  value[arrayPathSymbol] = this.path + '.' + options.arrayPathIndex;
420
418
  }
421
419
 
package/lib/schema.js CHANGED
@@ -1202,6 +1202,7 @@ Schema.prototype.interpretAsType = function(path, obj, options) {
1202
1202
  }
1203
1203
 
1204
1204
  if (type && type.instanceOfSchema) {
1205
+
1205
1206
  return new MongooseTypes.Subdocument(type, path, obj);
1206
1207
  }
1207
1208
 
package/lib/schematype.js CHANGED
@@ -1181,6 +1181,7 @@ SchemaType.prototype._castNullish = function _castNullish(v) {
1181
1181
 
1182
1182
  SchemaType.prototype.applySetters = function(value, scope, init, priorVal, options) {
1183
1183
  let v = this._applySetters(value, scope, init, priorVal, options);
1184
+
1184
1185
  if (v == null) {
1185
1186
  return this._castNullish(v);
1186
1187
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mongoose",
3
3
  "description": "Mongoose MongoDB ODM",
4
- "version": "6.3.6",
4
+ "version": "6.3.7",
5
5
  "author": "Guillermo Rauch <guillermo@learnboost.com>",
6
6
  "keywords": [
7
7
  "mongodb",
@@ -96,7 +96,7 @@
96
96
  "test": "mocha --exit ./test/*.test.js",
97
97
  "test-rs": "START_REPLICA_SET=1 mocha --timeout 30000 --exit ./test/*.test.js",
98
98
  "test-tsd": "node ./test/types/check-types-filename && tsd",
99
- "tdd": "mocha ./test/*.test.js ./test/typescript/main.test.js --inspect --watch --recursive --watch-files ./**/*.js",
99
+ "tdd": "mocha ./test/*.test.js --inspect --watch --recursive --watch-files ./**/*.{js,ts}",
100
100
  "test-coverage": "nyc --reporter=html --reporter=text npm test",
101
101
  "ts-benchmark": "ts-benchmark -p ./benchmarks/typescript/simple -f 17 18 29 32",
102
102
  "ts-benchmark-watch": "ts-benchmark -p ./benchmarks/typescript/simple -w ./types -i -s -f 17 18 29 32 -b master"
@@ -145,4 +145,4 @@
145
145
  "target": "ES2017"
146
146
  }
147
147
  }
148
- }
148
+ }
@@ -20,14 +20,13 @@ declare module 'mongoose' {
20
20
  * of an ObjectId.
21
21
  */
22
22
  function isObjectIdOrHexString(v: mongodb.ObjectId): true;
23
- function isObjectIdOrHexString(v: string): boolean;
23
+ function isObjectIdOrHexString(v: mongodb.ObjectId | string): boolean;
24
24
  function isObjectIdOrHexString(v: any): false;
25
25
 
26
26
  /**
27
27
  * Returns true if Mongoose can cast the given value to an ObjectId, or
28
28
  * false otherwise.
29
29
  */
30
- function isValidObjectId(v: mongodb.ObjectId): true;
31
- function isValidObjectId(v: Types.ObjectId): true;
30
+ function isValidObjectId(v: mongodb.ObjectId | Types.ObjectId): true;
32
31
  function isValidObjectId(v: any): boolean;
33
- }
32
+ }
package/types/models.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  declare module 'mongoose' {
2
2
  import mongodb = require('mongodb');
3
3
 
4
- export interface AcceptsDiscriminator<B> {
4
+ export interface AcceptsDiscriminator {
5
5
  /** Adds a discriminator type. */
6
- discriminator<D>(name: string | number, schema: Schema<D>, value?: string | number | ObjectId): Model<Omit<B, keyof D> & D>;
6
+ discriminator<D>(name: string | number, schema: Schema, value?: string | number | ObjectId): Model<D>;
7
7
  discriminator<T, U>(name: string | number, schema: Schema<T, U>, value?: string | number | ObjectId): U;
8
8
  }
9
9
 
@@ -116,7 +116,7 @@ declare module 'mongoose' {
116
116
  const Model: Model<any>;
117
117
  interface Model<T, TQueryHelpers = {}, TMethodsAndOverrides = {}, TVirtuals = {}> extends
118
118
  NodeJS.EventEmitter,
119
- AcceptsDiscriminator<T>,
119
+ AcceptsDiscriminator,
120
120
  IndexManager,
121
121
  SessionStarter {
122
122
  new <DocType = AnyKeys<T> & AnyObject>(doc?: DocType, fields?: any | null, options?: boolean | AnyObject): HydratedDocument<T, TMethodsAndOverrides, TVirtuals>;
@@ -416,4 +416,4 @@ declare module 'mongoose' {
416
416
  where<ResultDoc = HydratedDocument<T, TMethodsAndOverrides, TVirtuals>>(obj: object): QueryWithHelpers<Array<ResultDoc>, ResultDoc, TQueryHelpers, T>;
417
417
  where<ResultDoc = HydratedDocument<T, TMethodsAndOverrides, TVirtuals>>(): QueryWithHelpers<Array<ResultDoc>, ResultDoc, TQueryHelpers, T>;
418
418
  }
419
- }
419
+ }
@@ -37,6 +37,8 @@ declare module 'mongoose' {
37
37
  /** The various Mongoose SchemaTypes. */
38
38
  const SchemaTypes: typeof Schema.Types;
39
39
 
40
+ type DefaultType<T> = T extends Schema.Types.Mixed ? any : Partial<ExtractMongooseArray<T>>;
41
+
40
42
  class SchemaTypeOptions<T> {
41
43
  type?:
42
44
  T extends string ? StringSchemaDefinition :
@@ -74,13 +76,20 @@ declare module 'mongoose' {
74
76
  * The default value for this path. If a function, Mongoose executes the function
75
77
  * and uses the return value as the default.
76
78
  */
77
- default?: T extends Schema.Types.Mixed ? ({} | ((this: any, doc: any) => any)) : (ExtractMongooseArray<T> | ((this: any, doc: any) => Partial<ExtractMongooseArray<T>>));
79
+ default?: DefaultType<T> | ((this: any, doc: any) => DefaultType<T>) | null;
78
80
 
79
81
  /**
80
82
  * The model that `populate()` should use if populating this path.
81
83
  */
82
84
  ref?: string | Model<any> | ((this: any, doc: any) => string | Model<any>);
83
85
 
86
+ /**
87
+ * The path in the document that `populate()` should use to find the model
88
+ * to use.
89
+ */
90
+
91
+ refPath?: string | ((this: any, doc: any) => string);
92
+
84
93
  /**
85
94
  * Whether to include or exclude this path by default when loading documents
86
95
  * using `find()`, `findOne()`, etc.
@@ -269,17 +278,17 @@ declare module 'mongoose' {
269
278
 
270
279
  namespace Schema {
271
280
  namespace Types {
272
- class Array<B = any> extends SchemaType<B> implements AcceptsDiscriminator<B> {
281
+ class Array extends SchemaType implements AcceptsDiscriminator {
273
282
  /** This schema type's name, to defend against minifiers that mangle function names. */
274
283
  static schemaName: 'Array';
275
284
 
276
285
  static options: { castNonArrays: boolean; };
277
286
 
278
287
  discriminator<T, U>(name: string | number, schema: Schema<T, U>, value?: string): U;
279
- discriminator<D>(name: string | number, schema: Schema<D>, value?: string | number | ObjectId): Model<Omit<B, keyof D> & D>;
288
+ discriminator<D>(name: string | number, schema: Schema, value?: string): Model<D>;
280
289
 
281
290
  /** The schematype embedded in this array */
282
- caster?: SchemaType<B>;
291
+ caster?: SchemaType;
283
292
 
284
293
  /**
285
294
  * Adds an enum validator if this is an array of strings or numbers. Equivalent to
@@ -329,17 +338,17 @@ declare module 'mongoose' {
329
338
  static schemaName: 'Decimal128';
330
339
  }
331
340
 
332
- class DocumentArray<B = any> extends SchemaType<B> implements AcceptsDiscriminator<B> {
341
+ class DocumentArray extends SchemaType implements AcceptsDiscriminator {
333
342
  /** This schema type's name, to defend against minifiers that mangle function names. */
334
343
  static schemaName: 'DocumentArray';
335
344
 
336
345
  static options: { castNonArrays: boolean; };
337
346
 
338
- discriminator<D>(name: string | number, schema: Schema<D>, value?: string | number | ObjectId): Model<Omit<B, keyof D> & D>;
347
+ discriminator<D>(name: string | number, schema: Schema, value?: string): Model<D>;
339
348
  discriminator<T, U>(name: string | number, schema: Schema<T, U>, value?: string): U;
340
349
 
341
350
  /** The schema used for documents in this array */
342
- schema: Schema<B>;
351
+ schema: Schema;
343
352
 
344
353
  /** The constructor used for subdocuments in this array */
345
354
  caster?: typeof Types.Subdocument;
@@ -377,15 +386,15 @@ declare module 'mongoose' {
377
386
  auto(turnOn: boolean): this;
378
387
  }
379
388
 
380
- class Subdocument<B = any> extends SchemaType<B> implements AcceptsDiscriminator<B> {
389
+ class Subdocument extends SchemaType implements AcceptsDiscriminator {
381
390
  /** This schema type's name, to defend against minifiers that mangle function names. */
382
391
  static schemaName: string;
383
392
 
384
393
  /** The document's schema */
385
- schema: Schema<B>;
394
+ schema: Schema;
386
395
 
387
396
  discriminator<T, U>(name: string | number, schema: Schema<T, U>, value?: string): U;
388
- discriminator<D>(name: string | number, schema: Schema<D>, value?: string | number | ObjectId): Model<Omit<B, keyof D> & D>;
397
+ discriminator<D>(name: string | number, schema: Schema, value?: string): Model<D>;
389
398
  }
390
399
 
391
400
  class String extends SchemaType {