mongoose 6.2.7 → 6.2.8

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.
@@ -17,6 +17,7 @@ const isObject = require('./helpers/isObject');
17
17
  * Document constructor.
18
18
  *
19
19
  * @param {Object} obj the values to set
20
+ * @param {Object} schema
20
21
  * @param {Object} [fields] optional object containing the fields which were selected in the query returning this document and any populated paths data
21
22
  * @param {Boolean} [skipId] bool, should we auto create an ObjectId _id
22
23
  * @inherits NodeJS EventEmitter https://nodejs.org/api/events.html#events_class_events_eventemitter
@@ -26,7 +26,6 @@ const util = require('util');
26
26
  * Use [`Aggregate#cursor()`](/docs/api.html#aggregate_Aggregate-cursor) instead.
27
27
  *
28
28
  * @param {Aggregate} agg
29
- * @param {Object} options
30
29
  * @inherits Readable
31
30
  * @event `cursor`: Emitted when the cursor is created
32
31
  * @event `error`: Emitted when an error occurred
package/lib/document.js CHANGED
@@ -801,7 +801,7 @@ function init(self, obj, doc, opts, prefix) {
801
801
  init(self, obj[i], doc[i], opts, path + '.');
802
802
  } else if (!schemaType) {
803
803
  doc[i] = obj[i];
804
- if (!strict) {
804
+ if (!strict && !prefix) {
805
805
  self[i] = obj[i];
806
806
  }
807
807
  } else {
@@ -2472,7 +2472,6 @@ function _getPathsToValidate(doc) {
2472
2472
  return true;
2473
2473
  }));
2474
2474
 
2475
-
2476
2475
  Object.keys(doc.$__.activePaths.states.init).forEach(addToPaths);
2477
2476
  Object.keys(doc.$__.activePaths.states.modify).forEach(addToPaths);
2478
2477
  Object.keys(doc.$__.activePaths.states.default).forEach(addToPaths);
@@ -2484,18 +2483,23 @@ function _getPathsToValidate(doc) {
2484
2483
  if (subdoc.$basePath) {
2485
2484
  // Remove child paths for now, because we'll be validating the whole
2486
2485
  // subdoc
2486
+ if (!subdoc.$__.fullPath) {
2487
+ subdoc.ownerDocument();
2488
+ }
2489
+ const fullPathToSubdoc = subdoc.$__.fullPath;
2490
+
2487
2491
  for (const p of paths) {
2488
- if (p === null || p.startsWith(subdoc.$basePath + '.')) {
2492
+ if (p === null || p.startsWith(fullPathToSubdoc + '.')) {
2489
2493
  paths.delete(p);
2490
2494
  }
2491
2495
  }
2492
2496
 
2493
- if (doc.$isModified(subdoc.$basePath, modifiedPaths) &&
2494
- !doc.isDirectModified(subdoc.$basePath) &&
2495
- !doc.$isDefault(subdoc.$basePath)) {
2496
- paths.add(subdoc.$basePath);
2497
+ if (doc.$isModified(fullPathToSubdoc, modifiedPaths) &&
2498
+ !doc.isDirectModified(fullPathToSubdoc) &&
2499
+ !doc.$isDefault(fullPathToSubdoc)) {
2500
+ paths.add(fullPathToSubdoc);
2497
2501
 
2498
- skipSchemaValidators[subdoc.$basePath] = true;
2502
+ skipSchemaValidators[fullPathToSubdoc] = true;
2499
2503
  }
2500
2504
  }
2501
2505
  }
@@ -2658,6 +2662,7 @@ Document.prototype.$__validate = function(pathsToValidate, options, callback) {
2658
2662
  } else if (pathsToSkip) {
2659
2663
  paths = _handlePathsToSkip(paths, pathsToSkip);
2660
2664
  }
2665
+
2661
2666
  if (paths.length === 0) {
2662
2667
  return immediate(function() {
2663
2668
  const error = _complete();
@@ -2,14 +2,32 @@
2
2
 
3
3
  const utils = require('../../utils');
4
4
 
5
+ const keysToSkip = new Set(['__index', '__parentArray', '_doc']);
6
+
5
7
  /**
6
8
  * Using spread operator on a Mongoose document gives you a
7
9
  * POJO that has a tendency to cause infinite recursion. So
8
10
  * we use this function on `set()` to prevent that.
9
11
  */
10
12
 
11
- module.exports = function handleSpreadDoc(v) {
13
+ module.exports = function handleSpreadDoc(v, includeExtraKeys) {
12
14
  if (utils.isPOJO(v) && v.$__ != null && v._doc != null) {
15
+ if (includeExtraKeys) {
16
+ const extraKeys = {};
17
+ for (const key of Object.keys(v)) {
18
+ if (typeof key === 'symbol') {
19
+ continue;
20
+ }
21
+ if (key[0] === '$') {
22
+ continue;
23
+ }
24
+ if (keysToSkip.has(key)) {
25
+ continue;
26
+ }
27
+ extraKeys[key] = v[key];
28
+ }
29
+ return { ...v._doc, ...extraKeys };
30
+ }
13
31
  return v._doc;
14
32
  }
15
33
 
@@ -41,7 +41,6 @@ module.exports = function castFilterPath(query, schematype, val) {
41
41
  }
42
42
  continue;
43
43
  }
44
- // cast(schematype.caster ? schematype.caster.schema : schema, nested, options, context);
45
44
  } else {
46
45
  val[$cond] = schematype.castForQueryWrapper({
47
46
  $conditional: $cond,
package/lib/model.js CHANGED
@@ -1885,7 +1885,7 @@ Model.discriminators;
1885
1885
  * ####Note:
1886
1886
  * Only translate arguments of object type anything else is returned raw
1887
1887
  *
1888
- * @param {Object} raw fields/conditions that may contain aliased keys
1888
+ * @param {Object} fields fields/conditions that may contain aliased keys
1889
1889
  * @return {Object} the translated 'pure' fields/conditions
1890
1890
  */
1891
1891
  Model.translateAliases = function translateAliases(fields) {
@@ -26,7 +26,7 @@ module.exports = SubdocumentPath;
26
26
  * Single nested subdocument SchemaType constructor.
27
27
  *
28
28
  * @param {Schema} schema
29
- * @param {String} key
29
+ * @param {String} path
30
30
  * @param {Object} options
31
31
  * @inherits SchemaType
32
32
  * @api public
@@ -243,6 +243,9 @@ SubdocumentPath.prototype.doValidate = function(value, fn, scope, options) {
243
243
  }
244
244
 
245
245
  if (options && options.skipSchemaValidators) {
246
+ if (!value) {
247
+ return fn(null);
248
+ }
246
249
  return value.validate(fn);
247
250
  }
248
251
 
@@ -32,6 +32,7 @@ const emptyOpts = Object.freeze({});
32
32
  * @param {String} key
33
33
  * @param {SchemaType} cast
34
34
  * @param {Object} options
35
+ * @param {Object} schemaOptions
35
36
  * @inherits SchemaType
36
37
  * @api public
37
38
  */
@@ -12,6 +12,7 @@ const SchemaDocumentArrayOptions =
12
12
  const SchemaType = require('../schematype');
13
13
  const discriminator = require('../helpers/model/discriminator');
14
14
  const handleIdOption = require('../helpers/schema/handleIdOption');
15
+ const handleSpreadDoc = require('../helpers/document/handleSpreadDoc');
15
16
  const util = require('util');
16
17
  const utils = require('../utils');
17
18
  const getConstructor = require('../helpers/discriminator/getConstructor');
@@ -29,6 +30,7 @@ let Subdocument;
29
30
  * @param {String} key
30
31
  * @param {Schema} schema
31
32
  * @param {Object} options
33
+ * @param {Object} schemaOptions
32
34
  * @inherits SchemaArray
33
35
  * @api public
34
36
  */
@@ -427,13 +429,18 @@ DocumentArrayPath.prototype.cast = function(value, doc, init, prev, options) {
427
429
  const Constructor = getConstructor(this.casterConstructor, rawArray[i]);
428
430
 
429
431
  // Check if the document has a different schema (re gh-3701)
430
- if (rawArray[i].$__ && !(rawArray[i] instanceof Constructor)) {
431
- rawArray[i] = rawArray[i].toObject({
432
- transform: false,
433
- // Special case: if different model, but same schema, apply virtuals
434
- // re: gh-7898
435
- virtuals: rawArray[i].schema === Constructor.schema
436
- });
432
+ if (rawArray[i].$__ != null && !(rawArray[i] instanceof Constructor)) {
433
+ const spreadDoc = handleSpreadDoc(rawArray[i], true);
434
+ if (rawArray[i] !== spreadDoc) {
435
+ rawArray[i] = spreadDoc;
436
+ } else {
437
+ rawArray[i] = rawArray[i].toObject({
438
+ transform: false,
439
+ // Special case: if different model, but same schema, apply virtuals
440
+ // re: gh-7898
441
+ virtuals: rawArray[i].schema === Constructor.schema
442
+ });
443
+ }
437
444
  }
438
445
 
439
446
  if (rawArray[i] instanceof Subdocument) {
@@ -445,6 +445,7 @@ const methods = {
445
445
  * Return whether or not the `obj` is included in the array.
446
446
  *
447
447
  * @param {Object} obj the item to check
448
+ * @param {Number} fromIndex
448
449
  * @return {Boolean}
449
450
  * @api public
450
451
  * @method includes
@@ -460,6 +461,7 @@ const methods = {
460
461
  * Return the index of `obj` or `-1` if not found.
461
462
  *
462
463
  * @param {Object} obj the item to look for
464
+ * @param {Number} fromIndex
463
465
  * @return {Number}
464
466
  * @api public
465
467
  * @method indexOf
@@ -24,6 +24,7 @@ const utils = require('./utils');
24
24
  * @param {Number} [options.skip=null] add a default `skip` to the `populate()` query
25
25
  * @param {Number} [options.perDocumentLimit=null] For legacy reasons, `limit` with `populate()` may give incorrect results because it only executes a single query for every document being populated. If you set `perDocumentLimit`, Mongoose will ensure correct `limit` per document by executing a separate query for each document to `populate()`. For example, `.find().populate({ path: 'test', perDocumentLimit: 2 })` will execute 2 additional queries if `.find()` returns 2 documents.
26
26
  * @param {Object} [options.options=null] Additional options like `limit` and `lean`.
27
+ * @param {string} name
27
28
  * @api public
28
29
  */
29
30
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mongoose",
3
3
  "description": "Mongoose MongoDB ODM",
4
- "version": "6.2.7",
4
+ "version": "6.2.8",
5
5
  "author": "Guillermo Rauch <guillermo@learnboost.com>",
6
6
  "keywords": [
7
7
  "mongodb",
@@ -35,6 +35,7 @@
35
35
  "acquit": "1.x",
36
36
  "acquit-ignore": "0.2.x",
37
37
  "acquit-require": "0.1.x",
38
+ "axios": "0.26.1",
38
39
  "babel-loader": "8.2.3",
39
40
  "benchmark": "2.1.4",
40
41
  "bluebird": "3.7.2",
@@ -116,4 +117,4 @@
116
117
  "target": "ES2017"
117
118
  }
118
119
  }
119
- }
120
+ }
@@ -169,6 +169,9 @@ declare module 'mongoose' {
169
169
  /** The name of the model */
170
170
  modelName: string;
171
171
 
172
+ /** Returns the model with the given name on this document's associated connection. */
173
+ model<ModelType = Model<unknown>>(name: string): ModelType;
174
+
172
175
  /**
173
176
  * Overwrite all values in this document with the values of `obj`, except
174
177
  * for immutable properties. Behaves similarly to `set()`, except for it
package/types/index.d.ts CHANGED
@@ -709,6 +709,8 @@ declare module 'mongoose' {
709
709
  model?: string | Model<any>;
710
710
  /** optional query options like sort, limit, etc */
711
711
  options?: any;
712
+ /** optional boolean, set to `false` to allow populating paths that aren't in the schema */
713
+ strictPopulate?: boolean;
712
714
  /** deep populate */
713
715
  populate?: string | PopulateOptions | (string | PopulateOptions)[];
714
716
  /**
@@ -757,7 +759,7 @@ declare module 'mongoose' {
757
759
  export type PostMiddlewareFunction<ThisType = any, ResType = any> = (this: ThisType, res: ResType, next: CallbackWithoutResultAndOptionalError) => void | Promise<void>;
758
760
  export type ErrorHandlingMiddlewareFunction<ThisType = any, ResType = any> = (this: ThisType, err: NativeError, res: ResType, next: CallbackWithoutResultAndOptionalError) => void;
759
761
 
760
- class Schema<DocType = any, M = Model<DocType, any, any, any>, TInstanceMethods = any, TQueryHelpers = any> extends events.EventEmitter {
762
+ class Schema<DocType = any, M = Model<DocType, any, any, any>, TInstanceMethods = {}, TQueryHelpers = {}> extends events.EventEmitter {
761
763
  /**
762
764
  * Create a new schema
763
765
  */
@@ -811,7 +813,7 @@ declare module 'mongoose' {
811
813
  method(obj: Partial<TInstanceMethods>): this;
812
814
 
813
815
  /** Object of currently defined methods on this schema. */
814
- methods: { [F in keyof TInstanceMethods]: TInstanceMethods[F] };
816
+ methods: { [F in keyof TInstanceMethods]: TInstanceMethods[F] } & AnyObject;
815
817
 
816
818
  /** The original object passed to the schema constructor */
817
819
  obj: SchemaDefinition<SchemaDefinitionType<DocType>>;
@@ -933,6 +935,8 @@ declare module 'mongoose' {
933
935
  type AnyArray<T> = T[] | ReadonlyArray<T>;
934
936
  type SchemaValidator<T> = RegExp | [RegExp, string] | Function | [Function, string] | ValidateOpts<T> | ValidateOpts<T>[];
935
937
 
938
+ type ExtractMongooseArray<T> = T extends Types.Array<any> ? AnyArray<Unpacked<T>> : T;
939
+
936
940
  export class SchemaTypeOptions<T> {
937
941
  type?:
938
942
  T extends string ? StringSchemaDefinition :
@@ -970,7 +974,7 @@ declare module 'mongoose' {
970
974
  * The default value for this path. If a function, Mongoose executes the function
971
975
  * and uses the return value as the default.
972
976
  */
973
- default?: T | ((this: any, doc: any) => Partial<T>);
977
+ default?: ExtractMongooseArray<T> | ((this: any, doc: any) => Partial<ExtractMongooseArray<T>>);
974
978
 
975
979
  /**
976
980
  * The model that `populate()` should use if populating this path.