lib/record-patch-builder.js
function isValidObjectValue(recordTypes, val, objectPropDesc, forUpdate) {

	const container = objectPropDesc.nestedProperties;
	for (let propName of container.allPropertyNames) {
		const propDesc = container.getPropertyDesc(propName);
		if (propDesc.isView() || propDesc.isCalculated())
			continue;
		const propVal = val[propName];
		if ((propVal === undefined) || (propVal === null)) {
			if (!propDesc.optional && (!forUpdate || !propDesc.isGenerated()))
				return false;
		} else if (propDesc.isArray()) {
			if (!Array.isArray(propVal))
				return false;
			if (!propDesc.optional && (propVal.length === 0))
				return false;
			if (propVal.some(
				v => isInvalidScalarValueType(
					recordTypes, v, propDesc, forUpdate)))
				return false;
		} else if (propDesc.isMap()) {
			if ((typeof propVal) !== 'object')
				return false;
			const keys = Object.keys(propVal);
			if (!propDesc.optional && (keys.length === 0))
				return false;
			if (keys.some(
				k => isInvalidScalarValueType(
					recordTypes, propVal[k], propDesc, forUpdate)))
				return false;
		} else {
			if (isInvalidScalarValueType(
				recordTypes, propVal, propDesc, forUpdate))
				return false;
		}
	}

	return true;
}
function isValidObjectValue(recordTypes, val, objectPropDesc, forUpdate) {

	const container = objectPropDesc.nestedProperties;
	for (let propName of container.allPropertyNames) {
		const propDesc = container.getPropertyDesc(propName);
		if (propDesc.isView() || propDesc.isCalculated())
			continue;
		const propVal = val[propName];
		if ((propVal === undefined) || (propVal === null)) {
			if (!propDesc.optional && (!forUpdate || !propDesc.isGenerated()))
				return false;
		} else if (propDesc.isArray()) {
			if (!Array.isArray(propVal))
				return false;
			if (!propDesc.optional && (propVal.length === 0))
				return false;
			if (propVal.some(
				v => isInvalidScalarValueType(
					recordTypes, v, propDesc, forUpdate)))
				return false;
		} else if (propDesc.isMap()) {
			if ((typeof propVal) !== 'object')
				return false;
			const keys = Object.keys(propVal);
			if (!propDesc.optional && (keys.length === 0))
				return false;
			if (keys.some(
				k => isInvalidScalarValueType(
					recordTypes, propVal[k], propDesc, forUpdate)))
				return false;
		} else {
			if (isInvalidScalarValueType(
				recordTypes, propVal, propDesc, forUpdate))
				return false;
		}
	}

	return true;
}
function isValidObjectValue ( recordTypes , val , objectPropDesc , forUpdate ) { const container = objectPropDesc . nestedProperties ; for ( let propName of container . allPropertyNames ) { const propDesc = container . getPropertyDesc ( propName ) ; if ( propDesc . isView ( ) || propDesc . isCalculated ( ) ) continue ; const propVal = val [ propName ] ; if ( ( propVal === undefined ) || ( propVal === null ) ) { if ( ! propDesc . optional && ( ! forUpdate || ! propDesc . isGenerated ( ) ) ) return false ; } else if ( propDesc . isArray ( ) ) { if ( ! Array . isArray ( propVal ) ) return false ; if ( ! propDesc . optional && ( propVal . length === 0 ) ) return false ; if ( propVal . some ( v => isInvalidScalarValueType ( recordTypes , v , propDesc , forUpdate ) ) ) return false ; } else if ( propDesc . isMap ( ) ) { if ( ( typeof propVal ) !== 'object' ) return false ; const keys = Object . keys ( propVal ) ; if ( ! propDesc . optional && ( keys . length === 0 ) ) return false ; if ( keys . some ( k => isInvalidScalarValueType ( recordTypes , propVal [ k ] , propDesc , forUpdate ) ) ) return false ; } else { if ( isInvalidScalarValueType ( recordTypes , propVal , propDesc , forUpdate ) ) return false ; } } return true ; }
Tell if the specified object is suitable to be a value for the specified
nested object property.

@private
@param {module:x2node-records~RecordTypesLibrary} recordTypes Record types
library.
@param {Object} val The object to test. May not be <code>null</code> nor
<code>undefined</code>.
@param {module:x2node-records~PropertyDescriptor} objectPropDesc Nested object
property descriptor (either scalar or not).
@param {boolean} forUpdate <code>true</code> if the object is intended as a
new value for the property, or <code>false</code> if only used to test the
current property value.
@returns {boolean} <code>true</code> if valid.
Tell if the specified object is suitable to be a value for the specified nested object property .