mongoose 8.19.4 → 9.0.0-rc0

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 (105) hide show
  1. package/eslint.config.mjs +198 -0
  2. package/lib/aggregate.js +17 -73
  3. package/lib/cast/bigint.js +1 -1
  4. package/lib/cast/double.js +1 -1
  5. package/lib/cast/uuid.js +5 -48
  6. package/lib/cast.js +3 -3
  7. package/lib/connection.js +0 -1
  8. package/lib/cursor/aggregationCursor.js +14 -24
  9. package/lib/cursor/queryCursor.js +7 -14
  10. package/lib/document.js +125 -121
  11. package/lib/drivers/node-mongodb-native/connection.js +3 -10
  12. package/lib/error/divergentArray.js +2 -2
  13. package/lib/error/objectParameter.js +1 -2
  14. package/lib/error/validation.js +0 -8
  15. package/lib/helpers/clone.js +1 -1
  16. package/lib/helpers/common.js +1 -1
  17. package/lib/helpers/discriminator/mergeDiscriminatorSchema.js +10 -0
  18. package/lib/helpers/indexes/isIndexEqual.js +0 -1
  19. package/lib/helpers/model/applyDefaultsToPOJO.js +2 -2
  20. package/lib/helpers/model/applyHooks.js +43 -53
  21. package/lib/helpers/model/applyMethods.js +2 -2
  22. package/lib/helpers/model/applyStaticHooks.js +1 -48
  23. package/lib/helpers/model/castBulkWrite.js +1 -1
  24. package/lib/helpers/parallelLimit.js +18 -36
  25. package/lib/helpers/pluralize.js +3 -3
  26. package/lib/helpers/populate/assignRawDocsToIdStructure.js +1 -8
  27. package/lib/helpers/populate/createPopulateQueryFilter.js +1 -1
  28. package/lib/helpers/populate/getModelsMapForPopulate.js +17 -9
  29. package/lib/helpers/populate/getSchemaTypes.js +5 -5
  30. package/lib/helpers/query/cast$expr.js +8 -10
  31. package/lib/helpers/query/castFilterPath.js +1 -1
  32. package/lib/helpers/query/castUpdate.js +15 -13
  33. package/lib/helpers/query/getEmbeddedDiscriminatorPath.js +1 -1
  34. package/lib/helpers/schema/applyPlugins.js +1 -1
  35. package/lib/helpers/schema/getIndexes.js +1 -7
  36. package/lib/helpers/timestamps/setupTimestamps.js +3 -6
  37. package/lib/helpers/updateValidators.js +57 -111
  38. package/lib/model.js +419 -607
  39. package/lib/mongoose.js +41 -13
  40. package/lib/plugins/saveSubdocs.js +24 -51
  41. package/lib/plugins/sharding.js +5 -4
  42. package/lib/plugins/validateBeforeSave.js +3 -13
  43. package/lib/query.js +101 -145
  44. package/lib/queryHelpers.js +2 -2
  45. package/lib/schema/array.js +46 -84
  46. package/lib/schema/bigint.js +4 -2
  47. package/lib/schema/boolean.js +4 -2
  48. package/lib/schema/buffer.js +4 -2
  49. package/lib/schema/date.js +4 -2
  50. package/lib/schema/decimal128.js +4 -2
  51. package/lib/schema/documentArray.js +66 -91
  52. package/lib/schema/documentArrayElement.js +18 -11
  53. package/lib/schema/double.js +4 -2
  54. package/lib/schema/int32.js +4 -2
  55. package/lib/schema/map.js +87 -6
  56. package/lib/schema/mixed.js +4 -2
  57. package/lib/schema/number.js +4 -2
  58. package/lib/schema/objectId.js +4 -2
  59. package/lib/schema/string.js +5 -3
  60. package/lib/schema/subdocument.js +27 -31
  61. package/lib/schema/union.js +11 -3
  62. package/lib/schema/uuid.js +4 -23
  63. package/lib/schema.js +91 -91
  64. package/lib/schemaType.js +67 -59
  65. package/lib/types/array/index.js +2 -2
  66. package/lib/types/array/methods/index.js +4 -4
  67. package/lib/types/arraySubdocument.js +1 -1
  68. package/lib/types/buffer.js +10 -10
  69. package/lib/types/decimal128.js +1 -1
  70. package/lib/types/documentArray/index.js +1 -1
  71. package/lib/types/documentArray/methods/index.js +32 -18
  72. package/lib/types/double.js +1 -1
  73. package/lib/types/map.js +1 -2
  74. package/lib/types/objectid.js +1 -1
  75. package/lib/types/subdocument.js +15 -43
  76. package/lib/types/uuid.js +1 -1
  77. package/lib/utils.js +1 -8
  78. package/lib/validOptions.js +3 -3
  79. package/package.json +11 -24
  80. package/types/connection.d.ts +20 -11
  81. package/types/document.d.ts +96 -27
  82. package/types/index.d.ts +143 -39
  83. package/types/inferhydrateddoctype.d.ts +115 -0
  84. package/types/inferrawdoctype.d.ts +99 -75
  85. package/types/inferschematype.d.ts +17 -3
  86. package/types/middlewares.d.ts +0 -2
  87. package/types/models.d.ts +131 -199
  88. package/types/mongooseoptions.d.ts +6 -5
  89. package/types/pipelinestage.d.ts +1 -1
  90. package/types/query.d.ts +71 -139
  91. package/types/schemaoptions.d.ts +1 -1
  92. package/types/schematypes.d.ts +14 -10
  93. package/types/types.d.ts +3 -4
  94. package/types/utility.d.ts +68 -48
  95. package/types/validation.d.ts +18 -14
  96. package/browser.js +0 -8
  97. package/dist/browser.umd.js +0 -2
  98. package/lib/browser.js +0 -141
  99. package/lib/browserDocument.js +0 -101
  100. package/lib/documentProvider.js +0 -30
  101. package/lib/drivers/browser/binary.js +0 -14
  102. package/lib/drivers/browser/decimal128.js +0 -7
  103. package/lib/drivers/browser/index.js +0 -13
  104. package/lib/drivers/browser/objectid.js +0 -29
  105. package/lib/helpers/promiseOrCallback.js +0 -54
@@ -10,24 +10,33 @@ const SchemaSubdocument = require('./subdocument');
10
10
  const getConstructor = require('../helpers/discriminator/getConstructor');
11
11
 
12
12
  /**
13
- * DocumentArrayElement SchemaType constructor.
13
+ * DocumentArrayElement SchemaType constructor. Mongoose calls this internally when you define a new document array in your schema.
14
+ *
15
+ * #### Example:
16
+ * const schema = new Schema({ users: [{ name: String }] });
17
+ * schema.path('users.$'); // SchemaDocumentArrayElement with schema `new Schema({ name: String })`
14
18
  *
15
19
  * @param {String} path
20
+ * @param {Schema} schema
21
+ * @param {Object} options
16
22
  * @param {Object} options
23
+ * @param {Schema} parentSchema
17
24
  * @inherits SchemaType
18
25
  * @api public
19
26
  */
20
27
 
21
- function SchemaDocumentArrayElement(path, options) {
28
+ function SchemaDocumentArrayElement(path, schema, options, parentSchema) {
22
29
  this.$parentSchemaType = options && options.$parentSchemaType;
23
30
  if (!this.$parentSchemaType) {
24
31
  throw new MongooseError('Cannot create DocumentArrayElement schematype without a parent');
25
32
  }
26
33
  delete options.$parentSchemaType;
27
34
 
28
- SchemaType.call(this, path, options, 'DocumentArrayElement');
35
+ SchemaType.call(this, path, options, 'DocumentArrayElement', parentSchema);
29
36
 
30
37
  this.$isMongooseDocumentArrayElement = true;
38
+ this.Constructor = options && options.Constructor;
39
+ this.schema = schema;
31
40
  }
32
41
 
33
42
  /**
@@ -58,21 +67,19 @@ SchemaDocumentArrayElement.prototype.cast = function(...args) {
58
67
  };
59
68
 
60
69
  /**
61
- * Casts contents for queries.
70
+ * Async validation on this individual array element
62
71
  *
63
- * @param {String} $cond
64
- * @param {any} [val]
65
- * @api private
72
+ * @api public
66
73
  */
67
74
 
68
- SchemaDocumentArrayElement.prototype.doValidate = function(value, fn, scope, options) {
69
- const Constructor = getConstructor(this.caster, value);
75
+ SchemaDocumentArrayElement.prototype.doValidate = async function doValidate(value, scope, options) {
76
+ const Constructor = getConstructor(this.Constructor, value);
70
77
 
71
78
  if (value && !(value instanceof Constructor)) {
72
79
  value = new Constructor(value, scope, null, null, options && options.index != null ? options.index : null);
73
80
  }
74
81
 
75
- return SchemaSubdocument.prototype.doValidate.call(this, value, fn, scope, options);
82
+ return SchemaSubdocument.prototype.doValidate.call(this, value, scope, options);
76
83
  };
77
84
 
78
85
  /**
@@ -87,7 +94,7 @@ SchemaDocumentArrayElement.prototype.clone = function() {
87
94
  const ret = SchemaType.prototype.clone.apply(this, arguments);
88
95
  delete this.options.$parentSchemaType;
89
96
 
90
- ret.caster = this.caster;
97
+ ret.Constructor = this.Constructor;
91
98
  ret.schema = this.schema;
92
99
 
93
100
  return ret;
@@ -14,12 +14,14 @@ const createJSONSchemaTypeDefinition = require('../helpers/createJSONSchemaTypeD
14
14
  *
15
15
  * @param {String} path
16
16
  * @param {Object} options
17
+ * @param {Object} schemaOptions
18
+ * @param {Schema} parentSchema
17
19
  * @inherits SchemaType
18
20
  * @api public
19
21
  */
20
22
 
21
- function SchemaDouble(path, options) {
22
- SchemaType.call(this, path, options, 'Double');
23
+ function SchemaDouble(path, options, _schemaOptions, parentSchema) {
24
+ SchemaType.call(this, path, options, 'Double', parentSchema);
23
25
  }
24
26
 
25
27
  /**
@@ -15,12 +15,14 @@ const handleBitwiseOperator = require('./operators/bitwise');
15
15
  *
16
16
  * @param {String} path
17
17
  * @param {Object} options
18
+ * @param {Object} schemaOptions
19
+ * @param {Schema} parentSchema
18
20
  * @inherits SchemaType
19
21
  * @api public
20
22
  */
21
23
 
22
- function SchemaInt32(path, options) {
23
- SchemaType.call(this, path, options, 'Int32');
24
+ function SchemaInt32(path, options, _schemaOptions, parentSchema) {
25
+ SchemaType.call(this, path, options, 'Int32', parentSchema);
24
26
  }
25
27
 
26
28
  /**
package/lib/schema/map.js CHANGED
@@ -8,21 +8,51 @@ const MongooseMap = require('../types/map');
8
8
  const SchemaMapOptions = require('../options/schemaMapOptions');
9
9
  const SchemaType = require('../schemaType');
10
10
  const createJSONSchemaTypeDefinition = require('../helpers/createJSONSchemaTypeDefinition');
11
-
12
- /*!
13
- * ignore
14
- */
11
+ const MongooseError = require('../error/mongooseError');
12
+ const Schema = require('../schema');
13
+ const utils = require('../utils');
15
14
 
16
15
  class SchemaMap extends SchemaType {
17
- constructor(key, options) {
18
- super(key, options, 'Map');
16
+ /**
17
+ * Map SchemaType constructor.
18
+ *
19
+ * @param {String} path
20
+ * @param {Object} options
21
+ * @param {Object} schemaOptions
22
+ * @param {Schema} parentSchema
23
+ * @inherits SchemaType
24
+ * @api public
25
+ */
26
+
27
+ constructor(key, options, schemaOptions, parentSchema) {
28
+ super(key, options, 'Map', parentSchema);
19
29
  this.$isSchemaMap = true;
30
+ // Create the nested schema type for the map values
31
+ this._createNestedSchemaType(parentSchema, key, options, schemaOptions);
20
32
  }
21
33
 
34
+ /**
35
+ * Sets a default option for all Map instances.
36
+ *
37
+ * @param {String} option The option you'd like to set the value for
38
+ * @param {Any} value value for option
39
+ * @return {undefined}
40
+ * @function set
41
+ * @api public
42
+ */
43
+
22
44
  set(option, value) {
23
45
  return SchemaType.set(option, value);
24
46
  }
25
47
 
48
+ /**
49
+ * Casts to Map
50
+ *
51
+ * @param {Object} value
52
+ * @param {Object} model this value is optional
53
+ * @api private
54
+ */
55
+
26
56
  cast(val, doc, init, prev, options) {
27
57
  if (val instanceof MongooseMap) {
28
58
  return val;
@@ -65,6 +95,12 @@ class SchemaMap extends SchemaType {
65
95
  return new MongooseMap(val, path, doc, this.$__schemaType, options);
66
96
  }
67
97
 
98
+ /**
99
+ * Creates a copy of this map schema type.
100
+ *
101
+ * @api private
102
+ */
103
+
68
104
  clone() {
69
105
  const schematype = super.clone();
70
106
 
@@ -76,7 +112,10 @@ class SchemaMap extends SchemaType {
76
112
 
77
113
  /**
78
114
  * Returns the embedded schema type (i.e. the `.$*` path)
115
+ *
116
+ * @api public
79
117
  */
118
+
80
119
  getEmbeddedSchemaType() {
81
120
  return this.$__schemaType;
82
121
  }
@@ -100,6 +139,12 @@ class SchemaMap extends SchemaType {
100
139
  return result;
101
140
  }
102
141
 
142
+ /**
143
+ * Returns the auto encryption type for this schema type.
144
+ *
145
+ * @api public
146
+ */
147
+
103
148
  autoEncryptionType() {
104
149
  return 'object';
105
150
  }
@@ -111,10 +156,46 @@ class SchemaMap extends SchemaType {
111
156
  *
112
157
  * @api public
113
158
  */
159
+
114
160
  SchemaMap.schemaName = 'Map';
115
161
 
116
162
  SchemaMap.prototype.OptionsConstructor = SchemaMapOptions;
117
163
 
118
164
  SchemaMap.defaultOptions = {};
119
165
 
166
+ /*!
167
+ * ignore
168
+ */
169
+
170
+ SchemaMap.prototype._createNestedSchemaType = function _createNestedSchemaType(schema, path, obj, options) {
171
+ const mapPath = path + '.$*';
172
+ let _mapType = { type: {} };
173
+ if (utils.hasUserDefinedProperty(obj, 'of')) {
174
+ const isInlineSchema = utils.isPOJO(obj.of) &&
175
+ Object.keys(obj.of).length > 0 &&
176
+ !utils.hasUserDefinedProperty(obj.of, schema.options.typeKey);
177
+ if (isInlineSchema) {
178
+ _mapType = { [schema.options.typeKey]: new Schema(obj.of) };
179
+ } else if (utils.isPOJO(obj.of)) {
180
+ _mapType = Object.assign({}, obj.of);
181
+ } else {
182
+ _mapType = { [schema.options.typeKey]: obj.of };
183
+ }
184
+
185
+ if (_mapType[schema.options.typeKey] && _mapType[schema.options.typeKey].instanceOfSchema) {
186
+ const subdocumentSchema = _mapType[schema.options.typeKey];
187
+ subdocumentSchema.eachPath((subpath, type) => {
188
+ if (type.options.select === true || type.options.select === false) {
189
+ throw new MongooseError('Cannot use schema-level projections (`select: true` or `select: false`) within maps at path "' + path + '.' + subpath + '"');
190
+ }
191
+ });
192
+ }
193
+
194
+ if (utils.hasUserDefinedProperty(obj, 'ref')) {
195
+ _mapType.ref = obj.ref;
196
+ }
197
+ }
198
+ this.$__schemaType = schema.interpretAsType(mapPath, _mapType, options);
199
+ };
200
+
120
201
  module.exports = SchemaMap;
@@ -14,11 +14,13 @@ const utils = require('../utils');
14
14
  *
15
15
  * @param {String} path
16
16
  * @param {Object} options
17
+ * @param {Object} _schemaOptions
18
+ * @param {Schema} parentSchema
17
19
  * @inherits SchemaType
18
20
  * @api public
19
21
  */
20
22
 
21
- function SchemaMixed(path, options) {
23
+ function SchemaMixed(path, options, _schemaOptions, parentSchema) {
22
24
  if (options && options.default) {
23
25
  const def = options.default;
24
26
  if (Array.isArray(def) && def.length === 0) {
@@ -32,7 +34,7 @@ function SchemaMixed(path, options) {
32
34
  }
33
35
  }
34
36
 
35
- SchemaType.call(this, path, options, 'Mixed');
37
+ SchemaType.call(this, path, options, 'Mixed', parentSchema);
36
38
 
37
39
  this[symbols.schemaMixedSymbol] = true;
38
40
  }
@@ -19,12 +19,14 @@ const CastError = SchemaType.CastError;
19
19
  *
20
20
  * @param {String} key
21
21
  * @param {Object} options
22
+ * @param {Object} schemaOptions
23
+ * @param {Schema} parentSchema
22
24
  * @inherits SchemaType
23
25
  * @api public
24
26
  */
25
27
 
26
- function SchemaNumber(key, options) {
27
- SchemaType.call(this, key, options, 'Number');
28
+ function SchemaNumber(key, options, _schemaOptions, parentSchema) {
29
+ SchemaType.call(this, key, options, 'Number', parentSchema);
28
30
  }
29
31
 
30
32
  /**
@@ -21,11 +21,13 @@ let Document;
21
21
  *
22
22
  * @param {String} key
23
23
  * @param {Object} options
24
+ * @param {Object} schemaOptions
25
+ * @param {Schema} parentSchema
24
26
  * @inherits SchemaType
25
27
  * @api public
26
28
  */
27
29
 
28
- function SchemaObjectId(key, options) {
30
+ function SchemaObjectId(key, options, _schemaOptions, parentSchema) {
29
31
  const isKeyHexStr = typeof key === 'string' && key.length === 24 && /^[a-f0-9]+$/i.test(key);
30
32
  const suppressWarning = options && options.suppressWarning;
31
33
  if ((isKeyHexStr || typeof key === 'undefined') && !suppressWarning) {
@@ -34,7 +36,7 @@ function SchemaObjectId(key, options) {
34
36
  '`Mongoose.Schema.ObjectId`. Set the `suppressWarning` option if ' +
35
37
  'you\'re trying to create a hex char path in your schema.');
36
38
  }
37
- SchemaType.call(this, key, options, 'ObjectId');
39
+ SchemaType.call(this, key, options, 'ObjectId', parentSchema);
38
40
  }
39
41
 
40
42
  /**
@@ -19,14 +19,16 @@ const CastError = SchemaType.CastError;
19
19
  *
20
20
  * @param {String} key
21
21
  * @param {Object} options
22
+ * @param {Object} schemaOptions
23
+ * @param {Schema} parentSchema
22
24
  * @inherits SchemaType
23
25
  * @api public
24
26
  */
25
27
 
26
- function SchemaString(key, options) {
28
+ function SchemaString(key, options, _schemaOptions, parentSchema) {
27
29
  this.enumValues = [];
28
30
  this.regExp = null;
29
- SchemaType.call(this, key, options, 'String');
31
+ SchemaType.call(this, key, options, 'String', parentSchema);
30
32
  }
31
33
 
32
34
  /**
@@ -603,7 +605,7 @@ SchemaString.prototype.cast = function(value, doc, init, prev, options) {
603
605
 
604
606
  try {
605
607
  return castString(value);
606
- } catch (error) {
608
+ } catch {
607
609
  throw new CastError('string', value, this.path, null, this);
608
610
  }
609
611
  };
@@ -32,11 +32,12 @@ module.exports = SchemaSubdocument;
32
32
  * @param {Schema} schema
33
33
  * @param {String} path
34
34
  * @param {Object} options
35
+ * @param {Schema} parentSchema
35
36
  * @inherits SchemaType
36
37
  * @api public
37
38
  */
38
39
 
39
- function SchemaSubdocument(schema, path, options) {
40
+ function SchemaSubdocument(schema, path, options, parentSchema) {
40
41
  if (schema.options.timeseries) {
41
42
  throw new InvalidSchemaOptionError(path, 'timeseries');
42
43
  }
@@ -49,13 +50,13 @@ function SchemaSubdocument(schema, path, options) {
49
50
 
50
51
  schema = handleIdOption(schema, options);
51
52
 
52
- this.caster = _createConstructor(schema, null, options);
53
- this.caster.path = path;
54
- this.caster.prototype.$basePath = path;
53
+ this.Constructor = _createConstructor(schema, null, options);
54
+ this.Constructor.path = path;
55
+ this.Constructor.prototype.$basePath = path;
55
56
  this.schema = schema;
56
57
  this.$isSingleNested = true;
57
58
  this.base = schema.base;
58
- SchemaType.call(this, path, options, 'Embedded');
59
+ SchemaType.call(this, path, options, 'Embedded', parentSchema);
59
60
  }
60
61
 
61
62
  /*!
@@ -180,13 +181,13 @@ SchemaSubdocument.prototype.cast = function(val, doc, init, priorVal, options) {
180
181
  return val;
181
182
  }
182
183
 
183
- if (val != null && (typeof val !== 'object' || Array.isArray(val))) {
184
+ if (!init && val != null && (typeof val !== 'object' || Array.isArray(val))) {
184
185
  throw new ObjectExpectedError(this.path, val);
185
186
  }
186
187
 
187
188
  const discriminatorKeyPath = this.schema.path(this.schema.options.discriminatorKey);
188
189
  const defaultDiscriminatorValue = discriminatorKeyPath == null ? null : discriminatorKeyPath.getDefault(doc);
189
- const Constructor = getConstructor(this.caster, val, defaultDiscriminatorValue);
190
+ const Constructor = getConstructor(this.Constructor, val, defaultDiscriminatorValue);
190
191
 
191
192
  let subdoc;
192
193
 
@@ -201,7 +202,7 @@ SchemaSubdocument.prototype.cast = function(val, doc, init, priorVal, options) {
201
202
  return obj;
202
203
  }, null);
203
204
  if (init) {
204
- subdoc = new Constructor(void 0, selected, doc, false, { defaults: false });
205
+ subdoc = new Constructor(void 0, selected, doc, { defaults: false });
205
206
  delete subdoc.$__.defaults;
206
207
  // Don't pass `path` to $init - it's only for the subdocument itself, not its fields.
207
208
  // For change tracking, subdocuments use relative paths internally.
@@ -216,10 +217,10 @@ SchemaSubdocument.prototype.cast = function(val, doc, init, priorVal, options) {
216
217
  } else {
217
218
  options = Object.assign({}, options, { priorDoc: priorVal });
218
219
  if (Object.keys(val).length === 0) {
219
- return new Constructor({}, selected, doc, undefined, options);
220
+ return new Constructor({}, selected, doc, options);
220
221
  }
221
222
 
222
- return new Constructor(val, selected, doc, undefined, options);
223
+ return new Constructor(val, selected, doc, options);
223
224
  }
224
225
 
225
226
  return subdoc;
@@ -246,7 +247,7 @@ SchemaSubdocument.prototype.castForQuery = function($conditional, val, context,
246
247
  return val;
247
248
  }
248
249
 
249
- const Constructor = getConstructor(this.caster, val);
250
+ const Constructor = getConstructor(this.Constructor, val);
250
251
  if (val instanceof Constructor) {
251
252
  return val;
252
253
  }
@@ -274,11 +275,11 @@ SchemaSubdocument.prototype.castForQuery = function($conditional, val, context,
274
275
  /**
275
276
  * Async validation on this single nested doc.
276
277
  *
277
- * @api private
278
+ * @api public
278
279
  */
279
280
 
280
- SchemaSubdocument.prototype.doValidate = function(value, fn, scope, options) {
281
- const Constructor = getConstructor(this.caster, value);
281
+ SchemaSubdocument.prototype.doValidate = async function doValidate(value, scope, options) {
282
+ const Constructor = getConstructor(this.Constructor, value);
282
283
 
283
284
  if (value && !(value instanceof Constructor)) {
284
285
  value = new Constructor(value, null, (scope != null && scope.$__ != null) ? scope : null);
@@ -286,21 +287,15 @@ SchemaSubdocument.prototype.doValidate = function(value, fn, scope, options) {
286
287
 
287
288
  if (options && options.skipSchemaValidators) {
288
289
  if (!value) {
289
- return fn(null);
290
+ return;
290
291
  }
291
- return value.validate().then(() => fn(null), err => fn(err));
292
+ return value.validate();
292
293
  }
293
294
 
294
- SchemaType.prototype.doValidate.call(this, value, function(error) {
295
- if (error) {
296
- return fn(error);
297
- }
298
- if (!value) {
299
- return fn(null);
300
- }
301
-
302
- value.validate().then(() => fn(null), err => fn(err));
303
- }, scope, options);
295
+ await SchemaType.prototype.doValidate.call(this, value, scope, options);
296
+ if (value != null) {
297
+ await value.validate();
298
+ }
304
299
  };
305
300
 
306
301
  /**
@@ -354,11 +349,11 @@ SchemaSubdocument.prototype.discriminator = function(name, schema, options) {
354
349
  schema = schema.clone();
355
350
  }
356
351
 
357
- schema = discriminator(this.caster, name, schema, value, null, null, options.overwriteExisting);
352
+ schema = discriminator(this.Constructor, name, schema, value, null, null, options.overwriteExisting);
358
353
 
359
- this.caster.discriminators[name] = _createConstructor(schema, this.caster);
354
+ this.Constructor.discriminators[name] = _createConstructor(schema, this.Constructor);
360
355
 
361
- return this.caster.discriminators[name];
356
+ return this.Constructor.discriminators[name];
362
357
  };
363
358
 
364
359
  /*!
@@ -415,13 +410,14 @@ SchemaSubdocument.prototype.clone = function() {
415
410
  const schematype = new this.constructor(
416
411
  this.schema,
417
412
  this.path,
418
- { ...this.options, _skipApplyDiscriminators: true }
413
+ { ...this.options, _skipApplyDiscriminators: true },
414
+ this.parentSchema
419
415
  );
420
416
  schematype.validators = this.validators.slice();
421
417
  if (this.requiredValidator !== undefined) {
422
418
  schematype.requiredValidator = this.requiredValidator;
423
419
  }
424
- schematype.caster.discriminators = Object.assign({}, this.caster.discriminators);
420
+ schematype.Constructor.discriminators = Object.assign({}, this.Constructor.discriminators);
425
421
  schematype._appliedDiscriminators = this._appliedDiscriminators;
426
422
  return schematype;
427
423
  };
@@ -14,12 +14,20 @@ const firstValueSymbol = Symbol('firstValue');
14
14
  */
15
15
 
16
16
  class Union extends SchemaType {
17
- constructor(key, options, schemaOptions = {}) {
18
- super(key, options, 'Union');
17
+ /**
18
+ * Create a Union schema type.
19
+ *
20
+ * @param {String} key the path in the schema for this schema type
21
+ * @param {Object} options SchemaType-specific options (must have 'of' as array)
22
+ * @param {Object} schemaOptions additional options from the schema this schematype belongs to
23
+ * @param {Schema} parentSchema the schema this schematype belongs to
24
+ */
25
+ constructor(key, options, schemaOptions, parentSchema) {
26
+ super(key, options, 'Union', parentSchema);
19
27
  if (!options || !Array.isArray(options.of) || options.of.length === 0) {
20
28
  throw new Error('Union schema type requires an array of types');
21
29
  }
22
- this.schemaTypes = options.of.map(obj => options.parentSchema.interpretAsType(key, obj, schemaOptions));
30
+ this.schemaTypes = options.of.map(obj => parentSchema.interpretAsType(key, obj, schemaOptions));
23
31
  }
24
32
 
25
33
  cast(val, doc, init, prev, options) {
@@ -4,7 +4,6 @@
4
4
 
5
5
  'use strict';
6
6
 
7
- const MongooseBuffer = require('../types/buffer');
8
7
  const SchemaType = require('../schemaType');
9
8
  const CastError = SchemaType.CastError;
10
9
  const castUUID = require('../cast/uuid');
@@ -13,7 +12,6 @@ const utils = require('../utils');
13
12
  const handleBitwiseOperator = require('./operators/bitwise');
14
13
 
15
14
  const UUID_FORMAT = castUUID.UUID_FORMAT;
16
- const Binary = MongooseBuffer.Binary;
17
15
 
18
16
  /**
19
17
  * Convert binary to a uuid string
@@ -37,27 +35,14 @@ function binaryToString(uuidBin) {
37
35
  *
38
36
  * @param {String} key
39
37
  * @param {Object} options
38
+ * @param {Object} _schemaOptions
39
+ * @param {Schema} parentSchema
40
40
  * @inherits SchemaType
41
41
  * @api public
42
42
  */
43
43
 
44
- function SchemaUUID(key, options) {
45
- SchemaType.call(this, key, options, 'UUID');
46
- this.getters.push(function(value) {
47
- // For populated
48
- if (value != null && value.$__ != null) {
49
- return value;
50
- }
51
- if (Buffer.isBuffer(value)) {
52
- return binaryToString(value);
53
- } else if (value instanceof Binary) {
54
- return binaryToString(value.buffer);
55
- } else if (utils.isPOJO(value) && value.type === 'Buffer' && Array.isArray(value.data)) {
56
- // Cloned buffers look like `{ type: 'Buffer', data: [5, 224, ...] }`
57
- return binaryToString(Buffer.from(value.data));
58
- }
59
- return value;
60
- });
44
+ function SchemaUUID(key, options, _schemaOptions, parentSchema) {
45
+ SchemaType.call(this, key, options, 'UUID', parentSchema);
61
46
  }
62
47
 
63
48
  /**
@@ -249,11 +234,7 @@ const $conditionalHandlers = {
249
234
  $bitsAllSet: handleBitwiseOperator,
250
235
  $bitsAnySet: handleBitwiseOperator,
251
236
  $all: handleArray,
252
- $gt: handleSingle,
253
- $gte: handleSingle,
254
237
  $in: handleArray,
255
- $lt: handleSingle,
256
- $lte: handleSingle,
257
238
  $ne: handleSingle,
258
239
  $nin: handleArray
259
240
  };