lib/differ.js
function diffObjects(container, pathPrefix, objOld, objNew, patchSpec) {

	// keep track of processed properties
	const unrecognizedPropNames = new Set(Object.keys(objNew));

	// diff main properties
	diffObjectProps(
		container, pathPrefix,
		objOld, objNew,
		unrecognizedPropNames, patchSpec);	

	// check if polymorphic object and check the subtype properties
	if (container.isPolymorphObject()) {

		// type property is recognized
		unrecognizedPropNames.delete(container.typePropertyName);

		// match the subtype
		const subtype = objOld[container.typePropertyName];
		if (objNew[container.typePropertyName] !== subtype)
			throw new common.X2SyntaxError(
				'Polymorphic object type does not match.');

		// go over the subtype properties
		const subtypeDesc = container.getPropertyDesc(subtype);
		diffObjectProps(
			subtypeDesc.nestedProperties, `${pathPrefix}${subtype}:`,
			objOld, objNew,
			unrecognizedPropNames, patchSpec);
	}

	// any unrecognized properties?
	if (unrecognizedPropNames.size > 0)
		throw new common.X2SyntaxError(
			`Unrecognized properties for ${container.recordTypeName}` +
			` at ${pathPrefix}:` + Array.from(unrecognizedPropNames).join(', '));
}
function diffObjects(container, pathPrefix, objOld, objNew, patchSpec) {

	// keep track of processed properties
	const unrecognizedPropNames = new Set(Object.keys(objNew));

	// diff main properties
	diffObjectProps(
		container, pathPrefix,
		objOld, objNew,
		unrecognizedPropNames, patchSpec);	

	// check if polymorphic object and check the subtype properties
	if (container.isPolymorphObject()) {

		// type property is recognized
		unrecognizedPropNames.delete(container.typePropertyName);

		// match the subtype
		const subtype = objOld[container.typePropertyName];
		if (objNew[container.typePropertyName] !== subtype)
			throw new common.X2SyntaxError(
				'Polymorphic object type does not match.');

		// go over the subtype properties
		const subtypeDesc = container.getPropertyDesc(subtype);
		diffObjectProps(
			subtypeDesc.nestedProperties, `${pathPrefix}${subtype}:`,
			objOld, objNew,
			unrecognizedPropNames, patchSpec);
	}

	// any unrecognized properties?
	if (unrecognizedPropNames.size > 0)
		throw new common.X2SyntaxError(
			`Unrecognized properties for ${container.recordTypeName}` +
			` at ${pathPrefix}:` + Array.from(unrecognizedPropNames).join(', '));
}
function diffObjects ( container , pathPrefix , objOld , objNew , patchSpec ) { // keep track of processed properties const unrecognizedPropNames = new Set ( Object . keys ( objNew ) ) ; // diff main properties diffObjectProps ( container , pathPrefix , objOld , objNew , unrecognizedPropNames , patchSpec ) ; // check if polymorphic object and check the subtype properties if ( container . isPolymorphObject ( ) ) { // type property is recognized unrecognizedPropNames . delete ( container . typePropertyName ) ; // match the subtype const subtype = objOld [ container . typePropertyName ] ; if ( objNew [ container . typePropertyName ] !== subtype ) throw new common . X2SyntaxError ( 'Polymorphic object type does not match.' ) ; // go over the subtype properties const subtypeDesc = container . getPropertyDesc ( subtype ) ; diffObjectProps ( subtypeDesc . nestedProperties , ` ${ pathPrefix } ${ subtype } ` , objOld , objNew , unrecognizedPropNames , patchSpec ) ; } // any unrecognized properties? if ( unrecognizedPropNames . size > 0 ) throw new common . X2SyntaxError ( ` ${ container . recordTypeName } ` + ` ${ pathPrefix } ` + Array . from ( unrecognizedPropNames ) . join ( ', ' ) ) ; }
Recursively diff two objects and generate corresponding patch operations.

@private
@param {module:x2node-records~PropertiesContainer} container The container
that describes the object (record or nested object property).
@param {string} pathPrefix Prefix to add to contained property names to form
corresponding JSON pointers.
@param {Object} objOld Original object.
@param {Object} objNew New object.
@param {Array.<Object>} patchSpec The patch specification, to which to add
generated operations.
Recursively diff two objects and generate corresponding patch operations .