Skip to content

Commit 8061a20

Browse files
authored
Merge pull request #15741 from Automattic/8.20
8.20
2 parents c0aa391 + 34b9fc9 commit 8061a20

27 files changed

+279
-125
lines changed

lib/cast.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ module.exports = function cast(schema, obj, options, context) {
210210
}
211211

212212
if (geo) {
213-
const numbertype = new Types.Number('__QueryCasting__');
213+
const numbertype = new Types.Number('__QueryCasting__', null, null, schema);
214214
let value = val[geo];
215215

216216
if (val.$maxDistance != null) {

lib/helpers/discriminator/mergeDiscriminatorSchema.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const schemaMerge = require('../schema/merge');
33
const specialProperties = require('../../helpers/specialProperties');
44
const isBsonType = require('../../helpers/isBsonType');
55
const ObjectId = require('../../types/objectid');
6+
const SchemaType = require('../../schemaType');
67
const isObject = require('../../helpers/isObject');
78
/**
89
* Merges `from` into `to` without overwriting existing properties.
@@ -69,6 +70,15 @@ module.exports = function mergeDiscriminatorSchema(to, from, path, seen) {
6970
} else if (isBsonType(from[key], 'ObjectId')) {
7071
to[key] = new ObjectId(from[key]);
7172
continue;
73+
} else if (from[key] instanceof SchemaType) {
74+
if (to[key] == null) {
75+
to[key] = from[key].clone();
76+
}
77+
// For container types with nested schemas, we need to continue to the
78+
// recursive merge below to properly merge the nested schemas
79+
if (!from[key].$isMongooseDocumentArray && !from[key].$isSingleNested) {
80+
continue;
81+
}
7282
}
7383
}
7484
mergeDiscriminatorSchema(to[key], from[key], path ? path + '.' + key : key, seen);

lib/helpers/query/castUpdate.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ function walkUpdatePath(schema, obj, op, options, context, filter, prefix) {
428428
if (obj[key] == null) {
429429
throw new CastError('String', obj[key], `${prefix}${key}.$rename`);
430430
}
431-
const schematype = new SchemaString(`${prefix}${key}.$rename`);
431+
const schematype = new SchemaString(`${prefix}${key}.$rename`, null, null, schema);
432432
obj[key] = schematype.castForQuery(null, obj[key], context);
433433
continue;
434434
}

lib/schema.js

Lines changed: 10 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1572,7 +1572,7 @@ Schema.prototype.interpretAsType = function(path, obj, options) {
15721572
let name;
15731573

15741574
if (utils.isPOJO(type) || type === 'mixed') {
1575-
return new MongooseTypes.Mixed(path, obj);
1575+
return new MongooseTypes.Mixed(path, obj, null, this);
15761576
}
15771577

15781578
if (Array.isArray(type) || type === Array || type === 'array' || type === MongooseTypes.Array) {
@@ -1595,7 +1595,7 @@ Schema.prototype.interpretAsType = function(path, obj, options) {
15951595
`${path}: new Schema(...)`);
15961596
}
15971597
}
1598-
return new MongooseTypes.DocumentArray(path, cast, obj);
1598+
return new MongooseTypes.DocumentArray(path, cast, obj, null, this);
15991599
}
16001600
if (cast &&
16011601
cast[options.typeKey] &&
@@ -1612,14 +1612,14 @@ Schema.prototype.interpretAsType = function(path, obj, options) {
16121612
`${path}: new Schema(...)`);
16131613
}
16141614
}
1615-
return new MongooseTypes.DocumentArray(path, cast[options.typeKey], obj, cast);
1615+
return new MongooseTypes.DocumentArray(path, cast[options.typeKey], obj, cast, this);
16161616
}
16171617
if (typeof cast !== 'undefined') {
16181618
if (Array.isArray(cast) || cast.type === Array || cast.type == 'Array') {
16191619
if (cast && cast.type == 'Array') {
16201620
cast.type = Array;
16211621
}
1622-
return new MongooseTypes.Array(path, this.interpretAsType(path, cast, options), obj);
1622+
return new MongooseTypes.Array(path, this.interpretAsType(path, cast, options), obj, null, this);
16231623
}
16241624
}
16251625

@@ -1660,10 +1660,10 @@ Schema.prototype.interpretAsType = function(path, obj, options) {
16601660

16611661
const childSchema = new Schema(castFromTypeKey, childSchemaOptions);
16621662
childSchema.$implicitlyCreated = true;
1663-
return new MongooseTypes.DocumentArray(path, childSchema, obj);
1663+
return new MongooseTypes.DocumentArray(path, childSchema, obj, null, this);
16641664
} else {
16651665
// Special case: empty object becomes mixed
1666-
return new MongooseTypes.Array(path, MongooseTypes.Mixed, obj);
1666+
return new MongooseTypes.Array(path, MongooseTypes.Mixed, obj, null, this);
16671667
}
16681668
}
16691669

@@ -1672,7 +1672,7 @@ Schema.prototype.interpretAsType = function(path, obj, options) {
16721672
? cast[options.typeKey]
16731673
: cast;
16741674
if (Array.isArray(type)) {
1675-
return new MongooseTypes.Array(path, this.interpretAsType(path, type, options), obj);
1675+
return new MongooseTypes.Array(path, this.interpretAsType(path, type, options), obj, null, this);
16761676
}
16771677

16781678
name = typeof type === 'string'
@@ -1700,11 +1700,11 @@ Schema.prototype.interpretAsType = function(path, obj, options) {
17001700
}
17011701
}
17021702

1703-
return new MongooseTypes.Array(path, cast || MongooseTypes.Mixed, obj, options);
1703+
return new MongooseTypes.Array(path, cast || MongooseTypes.Mixed, obj, options, this);
17041704
}
17051705

17061706
if (type && type.instanceOfSchema) {
1707-
return new MongooseTypes.Subdocument(type, path, obj);
1707+
return new MongooseTypes.Subdocument(type, path, obj, this);
17081708
}
17091709

17101710
if (Buffer.isBuffer(type)) {
@@ -1743,53 +1743,11 @@ Schema.prototype.interpretAsType = function(path, obj, options) {
17431743
'https://bit.ly/mongoose-schematypes for a list of valid schema types.');
17441744
}
17451745

1746-
if (name === 'Union') {
1747-
obj.parentSchema = this;
1748-
}
1749-
const schemaType = new MongooseTypes[name](path, obj, options);
1750-
1751-
if (schemaType.$isSchemaMap) {
1752-
createMapNestedSchemaType(this, schemaType, path, obj, options);
1753-
}
1746+
const schemaType = new MongooseTypes[name](path, obj, options, this);
17541747

17551748
return schemaType;
17561749
};
17571750

1758-
/*!
1759-
* ignore
1760-
*/
1761-
1762-
function createMapNestedSchemaType(schema, schemaType, path, obj, options) {
1763-
const mapPath = path + '.$*';
1764-
let _mapType = { type: {} };
1765-
if (utils.hasUserDefinedProperty(obj, 'of')) {
1766-
const isInlineSchema = utils.isPOJO(obj.of) &&
1767-
Object.keys(obj.of).length > 0 &&
1768-
!utils.hasUserDefinedProperty(obj.of, schema.options.typeKey);
1769-
if (isInlineSchema) {
1770-
_mapType = { [schema.options.typeKey]: new Schema(obj.of) };
1771-
} else if (utils.isPOJO(obj.of)) {
1772-
_mapType = Object.assign({}, obj.of);
1773-
} else {
1774-
_mapType = { [schema.options.typeKey]: obj.of };
1775-
}
1776-
1777-
if (_mapType[schema.options.typeKey] && _mapType[schema.options.typeKey].instanceOfSchema) {
1778-
const subdocumentSchema = _mapType[schema.options.typeKey];
1779-
subdocumentSchema.eachPath((subpath, type) => {
1780-
if (type.options.select === true || type.options.select === false) {
1781-
throw new MongooseError('Cannot use schema-level projections (`select: true` or `select: false`) within maps at path "' + path + '.' + subpath + '"');
1782-
}
1783-
});
1784-
}
1785-
1786-
if (utils.hasUserDefinedProperty(obj, 'ref')) {
1787-
_mapType.ref = obj.ref;
1788-
}
1789-
}
1790-
schemaType.$__schemaType = schema.interpretAsType(mapPath, _mapType, options);
1791-
}
1792-
17931751
/**
17941752
* Iterates the schemas paths similar to Array#forEach.
17951753
*

lib/schema/array.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,12 @@ const emptyOpts = Object.freeze({});
3838
* @param {SchemaType} cast
3939
* @param {Object} options
4040
* @param {Object} schemaOptions
41+
* @param {Schema} parentSchema
4142
* @inherits SchemaType
4243
* @api public
4344
*/
4445

45-
function SchemaArray(key, cast, options, schemaOptions) {
46+
function SchemaArray(key, cast, options, schemaOptions, parentSchema) {
4647
// lazy load
4748
EmbeddedDoc || (EmbeddedDoc = require('../types').Embedded);
4849

@@ -92,7 +93,11 @@ function SchemaArray(key, cast, options, schemaOptions) {
9293
!caster.$isArraySubdocument &&
9394
!caster.$isSchemaMap) {
9495
const path = this.caster instanceof EmbeddedDoc ? null : key;
95-
this.caster = new caster(path, castOptions);
96+
if (caster === SchemaArray) {
97+
this.caster = new caster(path, castOptions, schemaOptions, null, parentSchema);
98+
} else {
99+
this.caster = new caster(path, castOptions, schemaOptions, parentSchema);
100+
}
96101
} else {
97102
this.caster = caster;
98103
if (!(this.caster instanceof EmbeddedDoc)) {
@@ -105,7 +110,7 @@ function SchemaArray(key, cast, options, schemaOptions) {
105110

106111
this.$isMongooseArray = true;
107112

108-
SchemaType.call(this, key, options, 'Array');
113+
SchemaType.call(this, key, options, 'Array', parentSchema);
109114

110115
let defaultArr;
111116
let fn;
@@ -494,7 +499,7 @@ SchemaArray.prototype.discriminator = function(...args) {
494499

495500
SchemaArray.prototype.clone = function() {
496501
const options = Object.assign({}, this.options);
497-
const schematype = new this.constructor(this.path, this.caster, options, this.schemaOptions);
502+
const schematype = new this.constructor(this.path, this.caster, options, this.schemaOptions, this.parentSchema);
498503
schematype.validators = this.validators.slice();
499504
if (this.requiredValidator !== undefined) {
500505
schematype.requiredValidator = this.requiredValidator;

lib/schema/bigint.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ const createJSONSchemaTypeDefinition = require('../helpers/createJSONSchemaTypeD
1414
*
1515
* @param {String} path
1616
* @param {Object} options
17+
* @param {Object} schemaOptions
18+
* @param {Schema} parentSchema
1719
* @inherits SchemaType
1820
* @api public
1921
*/
2022

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);
2325
}
2426

2527
/**

lib/schema/boolean.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ const createJSONSchemaTypeDefinition = require('../helpers/createJSONSchemaTypeD
1414
*
1515
* @param {String} path
1616
* @param {Object} options
17+
* @param {Object} schemaOptions
18+
* @param {Schema} parentSchema
1719
* @inherits SchemaType
1820
* @api public
1921
*/
2022

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);
2325
}
2426

2527
/**

lib/schema/buffer.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@ const CastError = SchemaType.CastError;
1919
*
2020
* @param {String} key
2121
* @param {Object} options
22+
* @param {Object} schemaOptions
23+
* @param {Schema} parentSchema
2224
* @inherits SchemaType
2325
* @api public
2426
*/
2527

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);
2830
}
2931

3032
/**

lib/schema/date.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@ const CastError = SchemaType.CastError;
1919
*
2020
* @param {String} key
2121
* @param {Object} options
22+
* @param {Object} schemaOptions
23+
* @param {Schema} parentSchema
2224
* @inherits SchemaType
2325
* @api public
2426
*/
2527

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);
2830
}
2931

3032
/**

lib/schema/decimal128.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ const isBsonType = require('../helpers/isBsonType');
1515
*
1616
* @param {String} key
1717
* @param {Object} options
18+
* @param {Object} schemaOptions
19+
* @param {Schema} parentSchema
1820
* @inherits SchemaType
1921
* @api public
2022
*/
2123

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);
2426
}
2527

2628
/**

0 commit comments

Comments
 (0)