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.
- package/eslint.config.mjs +198 -0
- package/lib/aggregate.js +17 -73
- package/lib/cast/bigint.js +1 -1
- package/lib/cast/double.js +1 -1
- package/lib/cast/uuid.js +5 -48
- package/lib/cast.js +3 -3
- package/lib/connection.js +0 -1
- package/lib/cursor/aggregationCursor.js +14 -24
- package/lib/cursor/queryCursor.js +7 -14
- package/lib/document.js +125 -121
- package/lib/drivers/node-mongodb-native/connection.js +3 -10
- package/lib/error/divergentArray.js +2 -2
- package/lib/error/objectParameter.js +1 -2
- package/lib/error/validation.js +0 -8
- package/lib/helpers/clone.js +1 -1
- package/lib/helpers/common.js +1 -1
- package/lib/helpers/discriminator/mergeDiscriminatorSchema.js +10 -0
- package/lib/helpers/indexes/isIndexEqual.js +0 -1
- package/lib/helpers/model/applyDefaultsToPOJO.js +2 -2
- package/lib/helpers/model/applyHooks.js +43 -53
- package/lib/helpers/model/applyMethods.js +2 -2
- package/lib/helpers/model/applyStaticHooks.js +1 -48
- package/lib/helpers/model/castBulkWrite.js +1 -1
- package/lib/helpers/parallelLimit.js +18 -36
- package/lib/helpers/pluralize.js +3 -3
- package/lib/helpers/populate/assignRawDocsToIdStructure.js +1 -8
- package/lib/helpers/populate/createPopulateQueryFilter.js +1 -1
- package/lib/helpers/populate/getModelsMapForPopulate.js +17 -9
- package/lib/helpers/populate/getSchemaTypes.js +5 -5
- package/lib/helpers/query/cast$expr.js +8 -10
- package/lib/helpers/query/castFilterPath.js +1 -1
- package/lib/helpers/query/castUpdate.js +15 -13
- package/lib/helpers/query/getEmbeddedDiscriminatorPath.js +1 -1
- package/lib/helpers/schema/applyPlugins.js +1 -1
- package/lib/helpers/schema/getIndexes.js +1 -7
- package/lib/helpers/timestamps/setupTimestamps.js +3 -6
- package/lib/helpers/updateValidators.js +57 -111
- package/lib/model.js +419 -607
- package/lib/mongoose.js +41 -13
- package/lib/plugins/saveSubdocs.js +24 -51
- package/lib/plugins/sharding.js +5 -4
- package/lib/plugins/validateBeforeSave.js +3 -13
- package/lib/query.js +101 -145
- package/lib/queryHelpers.js +2 -2
- package/lib/schema/array.js +46 -84
- package/lib/schema/bigint.js +4 -2
- package/lib/schema/boolean.js +4 -2
- package/lib/schema/buffer.js +4 -2
- package/lib/schema/date.js +4 -2
- package/lib/schema/decimal128.js +4 -2
- package/lib/schema/documentArray.js +66 -91
- package/lib/schema/documentArrayElement.js +18 -11
- package/lib/schema/double.js +4 -2
- package/lib/schema/int32.js +4 -2
- package/lib/schema/map.js +87 -6
- package/lib/schema/mixed.js +4 -2
- package/lib/schema/number.js +4 -2
- package/lib/schema/objectId.js +4 -2
- package/lib/schema/string.js +5 -3
- package/lib/schema/subdocument.js +27 -31
- package/lib/schema/union.js +11 -3
- package/lib/schema/uuid.js +4 -23
- package/lib/schema.js +91 -91
- package/lib/schemaType.js +67 -59
- package/lib/types/array/index.js +2 -2
- package/lib/types/array/methods/index.js +4 -4
- package/lib/types/arraySubdocument.js +1 -1
- package/lib/types/buffer.js +10 -10
- package/lib/types/decimal128.js +1 -1
- package/lib/types/documentArray/index.js +1 -1
- package/lib/types/documentArray/methods/index.js +32 -18
- package/lib/types/double.js +1 -1
- package/lib/types/map.js +1 -2
- package/lib/types/objectid.js +1 -1
- package/lib/types/subdocument.js +15 -43
- package/lib/types/uuid.js +1 -1
- package/lib/utils.js +1 -8
- package/lib/validOptions.js +3 -3
- package/package.json +11 -24
- package/types/connection.d.ts +20 -11
- package/types/document.d.ts +96 -27
- package/types/index.d.ts +143 -39
- package/types/inferhydrateddoctype.d.ts +115 -0
- package/types/inferrawdoctype.d.ts +99 -75
- package/types/inferschematype.d.ts +17 -3
- package/types/middlewares.d.ts +0 -2
- package/types/models.d.ts +131 -199
- package/types/mongooseoptions.d.ts +6 -5
- package/types/pipelinestage.d.ts +1 -1
- package/types/query.d.ts +71 -139
- package/types/schemaoptions.d.ts +1 -1
- package/types/schematypes.d.ts +14 -10
- package/types/types.d.ts +3 -4
- package/types/utility.d.ts +68 -48
- package/types/validation.d.ts +18 -14
- package/browser.js +0 -8
- package/dist/browser.umd.js +0 -2
- package/lib/browser.js +0 -141
- package/lib/browserDocument.js +0 -101
- package/lib/documentProvider.js +0 -30
- package/lib/drivers/browser/binary.js +0 -14
- package/lib/drivers/browser/decimal128.js +0 -7
- package/lib/drivers/browser/index.js +0 -13
- package/lib/drivers/browser/objectid.js +0 -29
- package/lib/helpers/promiseOrCallback.js +0 -54
package/lib/schema/array.js
CHANGED
|
@@ -28,7 +28,6 @@ const getDiscriminatorByValue = require('../helpers/discriminator/getDiscriminat
|
|
|
28
28
|
let MongooseArray;
|
|
29
29
|
let EmbeddedDoc;
|
|
30
30
|
|
|
31
|
-
const isNestedArraySymbol = Symbol('mongoose#isNestedArray');
|
|
32
31
|
const emptyOpts = Object.freeze({});
|
|
33
32
|
|
|
34
33
|
/**
|
|
@@ -38,11 +37,12 @@ const emptyOpts = Object.freeze({});
|
|
|
38
37
|
* @param {SchemaType} cast
|
|
39
38
|
* @param {Object} options
|
|
40
39
|
* @param {Object} schemaOptions
|
|
40
|
+
* @param {Schema} parentSchema
|
|
41
41
|
* @inherits SchemaType
|
|
42
42
|
* @api public
|
|
43
43
|
*/
|
|
44
44
|
|
|
45
|
-
function SchemaArray(key, cast, options, schemaOptions) {
|
|
45
|
+
function SchemaArray(key, cast, options, schemaOptions, parentSchema) {
|
|
46
46
|
// lazy load
|
|
47
47
|
EmbeddedDoc || (EmbeddedDoc = require('../types').Embedded);
|
|
48
48
|
|
|
@@ -80,32 +80,26 @@ function SchemaArray(key, cast, options, schemaOptions) {
|
|
|
80
80
|
: utils.getFunctionName(cast);
|
|
81
81
|
|
|
82
82
|
const Types = require('./index.js');
|
|
83
|
-
const
|
|
83
|
+
const schemaTypeDefinition = Types.hasOwnProperty(name) ? Types[name] : cast;
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
this.caster = new caster(path, castOptions);
|
|
96
|
-
} else {
|
|
97
|
-
this.caster = caster;
|
|
98
|
-
if (!(this.caster instanceof EmbeddedDoc)) {
|
|
99
|
-
this.caster.path = key;
|
|
85
|
+
if (typeof schemaTypeDefinition === 'function') {
|
|
86
|
+
if (schemaTypeDefinition === SchemaArray) {
|
|
87
|
+
this.embeddedSchemaType = new schemaTypeDefinition(key, castOptions, schemaOptions, null, parentSchema);
|
|
88
|
+
} else {
|
|
89
|
+
this.embeddedSchemaType = new schemaTypeDefinition(key, castOptions, schemaOptions, parentSchema);
|
|
90
|
+
}
|
|
91
|
+
} else if (schemaTypeDefinition instanceof SchemaType) {
|
|
92
|
+
this.embeddedSchemaType = schemaTypeDefinition;
|
|
93
|
+
if (!(this.embeddedSchemaType instanceof EmbeddedDoc)) {
|
|
94
|
+
this.embeddedSchemaType.path = key;
|
|
100
95
|
}
|
|
101
96
|
}
|
|
102
97
|
|
|
103
|
-
this.$embeddedSchemaType = this.caster;
|
|
104
98
|
}
|
|
105
99
|
|
|
106
100
|
this.$isMongooseArray = true;
|
|
107
101
|
|
|
108
|
-
SchemaType.call(this, key, options, 'Array');
|
|
102
|
+
SchemaType.call(this, key, options, 'Array', parentSchema);
|
|
109
103
|
|
|
110
104
|
let defaultArr;
|
|
111
105
|
let fn;
|
|
@@ -262,10 +256,10 @@ SchemaArray.prototype.enum = function() {
|
|
|
262
256
|
let arr = this;
|
|
263
257
|
while (true) {
|
|
264
258
|
const instance = arr &&
|
|
265
|
-
arr.
|
|
266
|
-
arr.
|
|
259
|
+
arr.embeddedSchemaType &&
|
|
260
|
+
arr.embeddedSchemaType.instance;
|
|
267
261
|
if (instance === 'Array') {
|
|
268
|
-
arr = arr.
|
|
262
|
+
arr = arr.embeddedSchemaType;
|
|
269
263
|
continue;
|
|
270
264
|
}
|
|
271
265
|
if (instance !== 'String' && instance !== 'Number') {
|
|
@@ -280,7 +274,7 @@ SchemaArray.prototype.enum = function() {
|
|
|
280
274
|
enumArray = utils.object.vals(enumArray);
|
|
281
275
|
}
|
|
282
276
|
|
|
283
|
-
arr.
|
|
277
|
+
arr.embeddedSchemaType.enum.apply(arr.embeddedSchemaType, enumArray);
|
|
284
278
|
return this;
|
|
285
279
|
};
|
|
286
280
|
|
|
@@ -303,9 +297,8 @@ SchemaArray.prototype.applyGetters = function(value, scope) {
|
|
|
303
297
|
};
|
|
304
298
|
|
|
305
299
|
SchemaArray.prototype._applySetters = function(value, scope, init, priorVal) {
|
|
306
|
-
if (this.
|
|
307
|
-
SchemaArray.options.castNonArrays
|
|
308
|
-
!this[isNestedArraySymbol]) {
|
|
300
|
+
if (this.embeddedSchemaType.$isMongooseArray &&
|
|
301
|
+
SchemaArray.options.castNonArrays) {
|
|
309
302
|
// Check nesting levels and wrap in array if necessary
|
|
310
303
|
let depth = 0;
|
|
311
304
|
let arr = this;
|
|
@@ -313,7 +306,7 @@ SchemaArray.prototype._applySetters = function(value, scope, init, priorVal) {
|
|
|
313
306
|
arr.$isMongooseArray &&
|
|
314
307
|
!arr.$isMongooseDocumentArray) {
|
|
315
308
|
++depth;
|
|
316
|
-
arr = arr.
|
|
309
|
+
arr = arr.embeddedSchemaType;
|
|
317
310
|
}
|
|
318
311
|
|
|
319
312
|
// No need to wrap empty arrays
|
|
@@ -387,9 +380,9 @@ SchemaArray.prototype.cast = function(value, doc, init, prev, options) {
|
|
|
387
380
|
return value;
|
|
388
381
|
}
|
|
389
382
|
|
|
390
|
-
const caster = this.
|
|
383
|
+
const caster = this.embeddedSchemaType;
|
|
391
384
|
const isMongooseArray = caster.$isMongooseArray;
|
|
392
|
-
if (caster && this.
|
|
385
|
+
if (caster && this.embeddedSchemaType.constructor !== Mixed) {
|
|
393
386
|
try {
|
|
394
387
|
const len = rawValue.length;
|
|
395
388
|
for (i = 0; i < len; i++) {
|
|
@@ -444,19 +437,18 @@ SchemaArray.prototype._castForPopulate = function _castForPopulate(value, doc) {
|
|
|
444
437
|
const rawValue = value.__array ? value.__array : value;
|
|
445
438
|
const len = rawValue.length;
|
|
446
439
|
|
|
447
|
-
|
|
448
|
-
if (caster && this.casterConstructor !== Mixed) {
|
|
440
|
+
if (this.embeddedSchemaType && this.embeddedSchemaType.constructor !== Mixed) {
|
|
449
441
|
try {
|
|
450
442
|
for (i = 0; i < len; i++) {
|
|
451
443
|
const opts = {};
|
|
452
444
|
// Perf: creating `arrayPath` is expensive for large arrays.
|
|
453
445
|
// We only need `arrayPath` if this is a nested array, so
|
|
454
446
|
// skip if possible.
|
|
455
|
-
if (
|
|
447
|
+
if (this.embeddedSchemaType.$isMongooseArray && this.embeddedSchemaType._arrayParentPath != null) {
|
|
456
448
|
opts.arrayPathIndex = i;
|
|
457
449
|
}
|
|
458
450
|
|
|
459
|
-
rawValue[i] =
|
|
451
|
+
rawValue[i] = this.embeddedSchemaType.cast(rawValue[i], doc, false, void 0, opts);
|
|
460
452
|
}
|
|
461
453
|
} catch (e) {
|
|
462
454
|
// rethrow
|
|
@@ -479,11 +471,10 @@ SchemaArray.prototype.$toObject = SchemaArray.prototype.toObject;
|
|
|
479
471
|
SchemaArray.prototype.discriminator = function(...args) {
|
|
480
472
|
let arr = this;
|
|
481
473
|
while (arr.$isMongooseArray && !arr.$isMongooseDocumentArray) {
|
|
482
|
-
arr = arr.
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
}
|
|
474
|
+
arr = arr.embeddedSchemaType;
|
|
475
|
+
}
|
|
476
|
+
if (!arr.$isMongooseDocumentArray) {
|
|
477
|
+
throw new MongooseError('You can only add an embedded discriminator on a document array, ' + this.path + ' is a plain array');
|
|
487
478
|
}
|
|
488
479
|
return arr.discriminator(...args);
|
|
489
480
|
};
|
|
@@ -494,7 +485,7 @@ SchemaArray.prototype.discriminator = function(...args) {
|
|
|
494
485
|
|
|
495
486
|
SchemaArray.prototype.clone = function() {
|
|
496
487
|
const options = Object.assign({}, this.options);
|
|
497
|
-
const schematype = new this.constructor(this.path, this.
|
|
488
|
+
const schematype = new this.constructor(this.path, this.embeddedSchemaType, options, this.schemaOptions, this.parentSchema);
|
|
498
489
|
schematype.validators = this.validators.slice();
|
|
499
490
|
if (this.requiredValidator !== undefined) {
|
|
500
491
|
schematype.requiredValidator = this.requiredValidator;
|
|
@@ -503,30 +494,21 @@ SchemaArray.prototype.clone = function() {
|
|
|
503
494
|
};
|
|
504
495
|
|
|
505
496
|
SchemaArray.prototype._castForQuery = function(val, context) {
|
|
506
|
-
let
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
if (typeof val[Constructor.schema.options.discriminatorKey] === 'string' &&
|
|
514
|
-
Constructor.discriminators[val[Constructor.schema.options.discriminatorKey]]) {
|
|
515
|
-
Constructor = Constructor.discriminators[val[Constructor.schema.options.discriminatorKey]];
|
|
497
|
+
let embeddedSchemaType = this.embeddedSchemaType;
|
|
498
|
+
const discriminatorKey = embeddedSchemaType?.schema?.options?.discriminatorKey;
|
|
499
|
+
const discriminators = embeddedSchemaType?.discriminators;
|
|
500
|
+
|
|
501
|
+
if (val && discriminators && typeof discriminatorKey === 'string') {
|
|
502
|
+
if (discriminators[val[discriminatorKey]]) {
|
|
503
|
+
embeddedSchemaType = discriminators[val[discriminatorKey]];
|
|
516
504
|
} else {
|
|
517
|
-
const constructorByValue = getDiscriminatorByValue(
|
|
505
|
+
const constructorByValue = getDiscriminatorByValue(discriminators, val[discriminatorKey]);
|
|
518
506
|
if (constructorByValue) {
|
|
519
|
-
|
|
507
|
+
embeddedSchemaType = constructorByValue;
|
|
520
508
|
}
|
|
521
509
|
}
|
|
522
510
|
}
|
|
523
511
|
|
|
524
|
-
const proto = this.casterConstructor.prototype;
|
|
525
|
-
const protoCastForQuery = proto && proto.castForQuery;
|
|
526
|
-
const protoCast = proto && proto.cast;
|
|
527
|
-
const constructorCastForQuery = Constructor.castForQuery;
|
|
528
|
-
const caster = this.caster;
|
|
529
|
-
|
|
530
512
|
if (Array.isArray(val)) {
|
|
531
513
|
this.setters.reverse().forEach(setter => {
|
|
532
514
|
val = setter.call(this, val, this);
|
|
@@ -535,30 +517,10 @@ SchemaArray.prototype._castForQuery = function(val, context) {
|
|
|
535
517
|
if (utils.isObject(v) && v.$elemMatch) {
|
|
536
518
|
return v;
|
|
537
519
|
}
|
|
538
|
-
|
|
539
|
-
v = protoCastForQuery.call(caster, null, v, context);
|
|
540
|
-
return v;
|
|
541
|
-
} else if (protoCast) {
|
|
542
|
-
v = protoCast.call(caster, v);
|
|
543
|
-
return v;
|
|
544
|
-
} else if (constructorCastForQuery) {
|
|
545
|
-
v = constructorCastForQuery.call(caster, null, v, context);
|
|
546
|
-
return v;
|
|
547
|
-
}
|
|
548
|
-
if (v != null) {
|
|
549
|
-
v = new Constructor(v);
|
|
550
|
-
return v;
|
|
551
|
-
}
|
|
552
|
-
return v;
|
|
520
|
+
return embeddedSchemaType.castForQuery(null, v, context);
|
|
553
521
|
});
|
|
554
|
-
} else
|
|
555
|
-
val =
|
|
556
|
-
} else if (protoCast) {
|
|
557
|
-
val = protoCast.call(caster, val);
|
|
558
|
-
} else if (constructorCastForQuery) {
|
|
559
|
-
val = constructorCastForQuery.call(caster, null, val, context);
|
|
560
|
-
} else if (val != null) {
|
|
561
|
-
val = new Constructor(val);
|
|
522
|
+
} else {
|
|
523
|
+
val = embeddedSchemaType.castForQuery(null, val, context);
|
|
562
524
|
}
|
|
563
525
|
|
|
564
526
|
return val;
|
|
@@ -624,12 +586,12 @@ function cast$all(val, context) {
|
|
|
624
586
|
return v;
|
|
625
587
|
}
|
|
626
588
|
if (v.$elemMatch != null) {
|
|
627
|
-
return { $elemMatch: cast(this.
|
|
589
|
+
return { $elemMatch: cast(this.embeddedSchemaType.schema, v.$elemMatch, null, this && this.$$context) };
|
|
628
590
|
}
|
|
629
591
|
|
|
630
592
|
const o = {};
|
|
631
593
|
o[this.path] = v;
|
|
632
|
-
return cast(this.
|
|
594
|
+
return cast(this.embeddedSchemaType.schema, o, null, this && this.$$context)[this.path];
|
|
633
595
|
}, this);
|
|
634
596
|
|
|
635
597
|
return this.castForQuery(null, val, context);
|
|
@@ -677,7 +639,7 @@ function createLogicalQueryOperatorHandler(op) {
|
|
|
677
639
|
|
|
678
640
|
const ret = [];
|
|
679
641
|
for (const obj of val) {
|
|
680
|
-
ret.push(cast(this.
|
|
642
|
+
ret.push(cast(this.embeddedSchemaType.schema ?? context.schema, obj, null, this && this.$$context));
|
|
681
643
|
}
|
|
682
644
|
|
|
683
645
|
return ret;
|
package/lib/schema/bigint.js
CHANGED
|
@@ -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 SchemaBigInt(path, options) {
|
|
22
|
-
SchemaType.call(this, path, options, 'BigInt');
|
|
23
|
+
function SchemaBigInt(path, options, _schemaOptions, parentSchema) {
|
|
24
|
+
SchemaType.call(this, path, options, 'BigInt', parentSchema);
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
/**
|
package/lib/schema/boolean.js
CHANGED
|
@@ -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 SchemaBoolean(path, options) {
|
|
22
|
-
SchemaType.call(this, path, options, 'Boolean');
|
|
23
|
+
function SchemaBoolean(path, options, _schemaOptions, parentSchema) {
|
|
24
|
+
SchemaType.call(this, path, options, 'Boolean', parentSchema);
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
/**
|
package/lib/schema/buffer.js
CHANGED
|
@@ -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 SchemaBuffer(key, options) {
|
|
27
|
-
SchemaType.call(this, key, options, 'Buffer');
|
|
28
|
+
function SchemaBuffer(key, options, _schemaOptions, parentSchema) {
|
|
29
|
+
SchemaType.call(this, key, options, 'Buffer', parentSchema);
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
/**
|
package/lib/schema/date.js
CHANGED
|
@@ -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 SchemaDate(key, options) {
|
|
27
|
-
SchemaType.call(this, key, options, 'Date');
|
|
28
|
+
function SchemaDate(key, options, _schemaOptions, parentSchema) {
|
|
29
|
+
SchemaType.call(this, key, options, 'Date', parentSchema);
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
/**
|
package/lib/schema/decimal128.js
CHANGED
|
@@ -15,12 +15,14 @@ const isBsonType = require('../helpers/isBsonType');
|
|
|
15
15
|
*
|
|
16
16
|
* @param {String} key
|
|
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 SchemaDecimal128(key, options) {
|
|
23
|
-
SchemaType.call(this, key, options, 'Decimal128');
|
|
24
|
+
function SchemaDecimal128(key, options, _schemaOptions, parentSchema) {
|
|
25
|
+
SchemaType.call(this, key, options, 'Decimal128', parentSchema);
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
/**
|
|
@@ -35,11 +35,12 @@ let Subdocument;
|
|
|
35
35
|
* @param {Schema} schema
|
|
36
36
|
* @param {Object} options
|
|
37
37
|
* @param {Object} schemaOptions
|
|
38
|
+
* @param {Schema} parentSchema
|
|
38
39
|
* @inherits SchemaArray
|
|
39
40
|
* @api public
|
|
40
41
|
*/
|
|
41
42
|
|
|
42
|
-
function SchemaDocumentArray(key, schema, options, schemaOptions) {
|
|
43
|
+
function SchemaDocumentArray(key, schema, options, schemaOptions, parentSchema) {
|
|
43
44
|
if (schema.options && schema.options.timeseries) {
|
|
44
45
|
throw new InvalidSchemaOptionError(key, 'timeseries');
|
|
45
46
|
}
|
|
@@ -56,18 +57,26 @@ function SchemaDocumentArray(key, schema, options, schemaOptions) {
|
|
|
56
57
|
schema = handleIdOption(schema, options);
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
const
|
|
60
|
-
|
|
60
|
+
const Constructor = _createConstructor(schema, options);
|
|
61
|
+
Constructor.prototype.$basePath = key;
|
|
62
|
+
Constructor.path = key;
|
|
61
63
|
|
|
62
|
-
|
|
64
|
+
const $parentSchemaType = this;
|
|
65
|
+
const embeddedSchemaType = new DocumentArrayElement(key + '.$', schema, {
|
|
66
|
+
...(schemaOptions || {}),
|
|
67
|
+
$parentSchemaType,
|
|
68
|
+
Constructor
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
SchemaArray.call(this, key, embeddedSchemaType, options, null, parentSchema);
|
|
63
72
|
|
|
64
73
|
this.schema = schema;
|
|
65
74
|
// EmbeddedDocument schematype options
|
|
66
75
|
this.schemaOptions = schemaOptions || {};
|
|
67
76
|
this.$isMongooseDocumentArray = true;
|
|
68
|
-
this.Constructor =
|
|
77
|
+
this.Constructor = Constructor;
|
|
69
78
|
|
|
70
|
-
|
|
79
|
+
Constructor.base = schema.base;
|
|
71
80
|
|
|
72
81
|
const fn = this.defaultValue;
|
|
73
82
|
|
|
@@ -81,15 +90,6 @@ function SchemaDocumentArray(key, schema, options, schemaOptions) {
|
|
|
81
90
|
return arr;
|
|
82
91
|
});
|
|
83
92
|
}
|
|
84
|
-
|
|
85
|
-
const $parentSchemaType = this;
|
|
86
|
-
this.$embeddedSchemaType = new DocumentArrayElement(key + '.$', {
|
|
87
|
-
...(schemaOptions || {}),
|
|
88
|
-
$parentSchemaType
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
this.$embeddedSchemaType.caster = this.Constructor;
|
|
92
|
-
this.$embeddedSchemaType.schema = this.schema;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
/**
|
|
@@ -212,93 +212,62 @@ SchemaDocumentArray.prototype.discriminator = function(name, schema, options) {
|
|
|
212
212
|
schema = schema.clone();
|
|
213
213
|
}
|
|
214
214
|
|
|
215
|
-
schema = discriminator(this.
|
|
215
|
+
schema = discriminator(this.Constructor, name, schema, tiedValue, null, null, options?.overwriteExisting);
|
|
216
216
|
|
|
217
|
-
const EmbeddedDocument = _createConstructor(schema, null, this.
|
|
218
|
-
EmbeddedDocument.baseCasterConstructor = this.
|
|
217
|
+
const EmbeddedDocument = _createConstructor(schema, null, this.Constructor);
|
|
218
|
+
EmbeddedDocument.baseCasterConstructor = this.Constructor;
|
|
219
219
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
});
|
|
224
|
-
} catch (error) {
|
|
225
|
-
// Ignore error, only happens on old versions of node
|
|
226
|
-
}
|
|
220
|
+
Object.defineProperty(EmbeddedDocument, 'name', {
|
|
221
|
+
value: name
|
|
222
|
+
});
|
|
227
223
|
|
|
228
|
-
this.
|
|
224
|
+
this.Constructor.discriminators[name] = EmbeddedDocument;
|
|
229
225
|
|
|
230
|
-
return this.
|
|
226
|
+
return this.Constructor.discriminators[name];
|
|
231
227
|
};
|
|
232
228
|
|
|
233
229
|
/**
|
|
234
230
|
* Performs local validations first, then validations on each embedded doc
|
|
235
231
|
*
|
|
236
|
-
* @api
|
|
232
|
+
* @api public
|
|
237
233
|
*/
|
|
238
234
|
|
|
239
|
-
SchemaDocumentArray.prototype.doValidate = function(array,
|
|
235
|
+
SchemaDocumentArray.prototype.doValidate = async function doValidate(array, scope, options) {
|
|
240
236
|
// lazy load
|
|
241
237
|
MongooseDocumentArray || (MongooseDocumentArray = require('../types/documentArray'));
|
|
242
238
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
}
|
|
247
|
-
|
|
239
|
+
await SchemaType.prototype.doValidate.call(this, array, scope);
|
|
240
|
+
if (options?.updateValidator) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
if (!utils.isMongooseDocumentArray(array)) {
|
|
244
|
+
array = new MongooseDocumentArray(array, this.path, scope);
|
|
248
245
|
}
|
|
249
246
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
return fn(err);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
let count = array && array.length;
|
|
256
|
-
let error;
|
|
257
|
-
|
|
258
|
-
if (!count) {
|
|
259
|
-
return fn();
|
|
260
|
-
}
|
|
261
|
-
if (options && options.updateValidator) {
|
|
262
|
-
return fn();
|
|
263
|
-
}
|
|
264
|
-
if (!utils.isMongooseDocumentArray(array)) {
|
|
265
|
-
array = new MongooseDocumentArray(array, _this.path, scope);
|
|
266
|
-
}
|
|
267
|
-
|
|
247
|
+
const promises = [];
|
|
248
|
+
for (let i = 0; i < array.length; ++i) {
|
|
268
249
|
// handle sparse arrays, do not use array.forEach which does not
|
|
269
250
|
// iterate over sparse elements yet reports array.length including
|
|
270
251
|
// them :(
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
252
|
+
let doc = array[i];
|
|
253
|
+
if (doc == null) {
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
// If you set the array index directly, the doc might not yet be
|
|
257
|
+
// a full fledged mongoose subdoc, so make it into one.
|
|
258
|
+
if (!(doc instanceof Subdocument)) {
|
|
259
|
+
const Constructor = getConstructor(this.Constructor, array[i]);
|
|
260
|
+
doc = array[i] = new Constructor(doc, array, undefined, undefined, i);
|
|
277
261
|
}
|
|
278
262
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
let doc = array[i];
|
|
282
|
-
if (doc == null) {
|
|
283
|
-
--count || fn(error);
|
|
284
|
-
continue;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// If you set the array index directly, the doc might not yet be
|
|
288
|
-
// a full fledged mongoose subdoc, so make it into one.
|
|
289
|
-
if (!(doc instanceof Subdocument)) {
|
|
290
|
-
const Constructor = getConstructor(_this.casterConstructor, array[i]);
|
|
291
|
-
doc = array[i] = new Constructor(doc, array, undefined, undefined, i);
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
if (options != null && options.validateModifiedOnly && !doc.$isModified()) {
|
|
295
|
-
--count || fn(error);
|
|
296
|
-
continue;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
doc.$__validate(null, options, callback);
|
|
263
|
+
if (options != null && options.validateModifiedOnly && !doc.$isModified()) {
|
|
264
|
+
continue;
|
|
300
265
|
}
|
|
266
|
+
|
|
267
|
+
promises.push(doc.$__validate(null, options));
|
|
301
268
|
}
|
|
269
|
+
|
|
270
|
+
await Promise.all(promises);
|
|
302
271
|
};
|
|
303
272
|
|
|
304
273
|
/**
|
|
@@ -339,7 +308,7 @@ SchemaDocumentArray.prototype.doValidateSync = function(array, scope, options) {
|
|
|
339
308
|
// If you set the array index directly, the doc might not yet be
|
|
340
309
|
// a full fledged mongoose subdoc, so make it into one.
|
|
341
310
|
if (!(doc instanceof Subdocument)) {
|
|
342
|
-
const Constructor = getConstructor(this.
|
|
311
|
+
const Constructor = getConstructor(this.Constructor, array[i]);
|
|
343
312
|
doc = array[i] = new Constructor(doc, array, undefined, undefined, i);
|
|
344
313
|
}
|
|
345
314
|
|
|
@@ -384,7 +353,7 @@ SchemaDocumentArray.prototype.getDefault = function(scope, init, options) {
|
|
|
384
353
|
ret = new MongooseDocumentArray(ret, this.path, scope);
|
|
385
354
|
|
|
386
355
|
for (let i = 0; i < ret.length; ++i) {
|
|
387
|
-
const Constructor = getConstructor(this.
|
|
356
|
+
const Constructor = getConstructor(this.Constructor, ret[i]);
|
|
388
357
|
const _subdoc = new Constructor({}, ret, undefined,
|
|
389
358
|
undefined, i);
|
|
390
359
|
_subdoc.$init(ret[i]);
|
|
@@ -462,7 +431,7 @@ SchemaDocumentArray.prototype.cast = function(value, doc, init, prev, options) {
|
|
|
462
431
|
continue;
|
|
463
432
|
}
|
|
464
433
|
|
|
465
|
-
const Constructor = getConstructor(this.
|
|
434
|
+
const Constructor = getConstructor(this.Constructor, rawArray[i]);
|
|
466
435
|
|
|
467
436
|
const spreadDoc = handleSpreadDoc(rawArray[i], true);
|
|
468
437
|
if (rawArray[i] !== spreadDoc) {
|
|
@@ -529,7 +498,13 @@ SchemaDocumentArray.prototype.cast = function(value, doc, init, prev, options) {
|
|
|
529
498
|
|
|
530
499
|
SchemaDocumentArray.prototype.clone = function() {
|
|
531
500
|
const options = Object.assign({}, this.options);
|
|
532
|
-
const schematype = new this.constructor(
|
|
501
|
+
const schematype = new this.constructor(
|
|
502
|
+
this.path,
|
|
503
|
+
this.schema,
|
|
504
|
+
options,
|
|
505
|
+
this.schemaOptions,
|
|
506
|
+
this.parentSchema
|
|
507
|
+
);
|
|
533
508
|
schematype.validators = this.validators.slice();
|
|
534
509
|
if (this.requiredValidator !== undefined) {
|
|
535
510
|
schematype.requiredValidator = this.requiredValidator;
|
|
@@ -647,21 +622,21 @@ function cast$elemMatch(val, context) {
|
|
|
647
622
|
// Is this an embedded discriminator and is the discriminator key set?
|
|
648
623
|
// If so, use the discriminator schema. See gh-7449
|
|
649
624
|
const discriminatorKey = this &&
|
|
650
|
-
this.
|
|
651
|
-
this.
|
|
652
|
-
this.
|
|
653
|
-
this.
|
|
625
|
+
this.Constructor &&
|
|
626
|
+
this.Constructor.schema &&
|
|
627
|
+
this.Constructor.schema.options &&
|
|
628
|
+
this.Constructor.schema.options.discriminatorKey;
|
|
654
629
|
const discriminators = this &&
|
|
655
|
-
this.
|
|
656
|
-
this.
|
|
657
|
-
this.
|
|
630
|
+
this.Constructor &&
|
|
631
|
+
this.Constructor.schema &&
|
|
632
|
+
this.Constructor.schema.discriminators || {};
|
|
658
633
|
if (discriminatorKey != null &&
|
|
659
634
|
val[discriminatorKey] != null &&
|
|
660
635
|
discriminators[val[discriminatorKey]] != null) {
|
|
661
636
|
return cast(discriminators[val[discriminatorKey]], val, null, this && this.$$context);
|
|
662
637
|
}
|
|
663
638
|
|
|
664
|
-
const schema = this.
|
|
639
|
+
const schema = this.Constructor.schema ?? context.schema;
|
|
665
640
|
return cast(schema, val, null, this && this.$$context);
|
|
666
641
|
}
|
|
667
642
|
|