lib/model/compiler.js
function compileDeserializer( attributes ) {
	if ( !attributes || typeof attributes !== "object" || Array.isArray( attributes ) ) {
		throw new TypeError( "definition of attributes must be object" );
	}

	const attributeNames = Object.keys( attributes );
	const numAttributes = attributeNames.length;
	const deserialization = new Array( 2 * numAttributes );

	let write = 0;
	for ( let ai = 0; ai < numAttributes; ai++ ) {
		const attributeName = attributeNames[ai];
		const attribute = attributes[attributeName];

		const handler = Types.selectByName( attribute.type );
		let sourceName;

		// append deserialize() method of current attribute's type handler
		{
			const { args, body } = extractBody( handler.deserialize );
			if ( args.length < 1 ) {
				throw new TypeError( `deserialize() of ModelType for handling ${attribute.type} values must accept one argument` );
			}

			if ( body.replace( ptnTrailingReturn, "" ).trim().length ) {
				sourceName = "$$d";
				deserialization[write++] = `
{
	let ${args[0]} = $$s["${attributeName}"];

	{
		${body.replace( ptnTrailingReturn, ( all, term ) => `$$d["${attributeName}"] = ${term.trim()};` )}
	}
}
		`;
			} else {
				sourceName = "$$s";
			}
		}

		// append coerce() method of current attribute's type handler
		{
			const { args, body } = extractBody( handler.coerce );
			if ( args.length < 2 ) {
				throw new TypeError( `coerce() of ModelType for handling ${attribute.type} values must accept two arguments` );
			}

			deserialization[write++] = `
{
	let ${args[0]} = ${sourceName}["${attributeName}"];
	const ${args[1]} = $$attrs["${attributeName}"];

	{
		${body.replace( ptnTrailingReturn, ( all, term ) => `$$d["${attributeName}"] = ${term.trim()};` )}
	}
}
		`;
		}
	}

	deserialization.splice( write );

	// eslint-disable-next-line no-new-func
	return new Function( "$$input", "$$attrs", `
if ( !$$attrs || typeof $$attrs !== "object" ) {
	throw new TypeError( "missing definition of attributes required for deserialization" );
}

const $$s = $$input && typeof $$input === "object" ? $$input : {};
const $$d = {};

${deserialization.join( "" )}

return $$d;
` );
}
function compileDeserializer( attributes ) {
	if ( !attributes || typeof attributes !== "object" || Array.isArray( attributes ) ) {
		throw new TypeError( "definition of attributes must be object" );
	}

	const attributeNames = Object.keys( attributes );
	const numAttributes = attributeNames.length;
	const deserialization = new Array( 2 * numAttributes );

	let write = 0;
	for ( let ai = 0; ai < numAttributes; ai++ ) {
		const attributeName = attributeNames[ai];
		const attribute = attributes[attributeName];

		const handler = Types.selectByName( attribute.type );
		let sourceName;

		// append deserialize() method of current attribute's type handler
		{
			const { args, body } = extractBody( handler.deserialize );
			if ( args.length < 1 ) {
				throw new TypeError( `deserialize() of ModelType for handling ${attribute.type} values must accept one argument` );
			}

			if ( body.replace( ptnTrailingReturn, "" ).trim().length ) {
				sourceName = "$$d";
				deserialization[write++] = `
{
	let ${args[0]} = $$s["${attributeName}"];

	{
		${body.replace( ptnTrailingReturn, ( all, term ) => `$$d["${attributeName}"] = ${term.trim()};` )}
	}
}
		`;
			} else {
				sourceName = "$$s";
			}
		}

		// append coerce() method of current attribute's type handler
		{
			const { args, body } = extractBody( handler.coerce );
			if ( args.length < 2 ) {
				throw new TypeError( `coerce() of ModelType for handling ${attribute.type} values must accept two arguments` );
			}

			deserialization[write++] = `
{
	let ${args[0]} = ${sourceName}["${attributeName}"];
	const ${args[1]} = $$attrs["${attributeName}"];

	{
		${body.replace( ptnTrailingReturn, ( all, term ) => `$$d["${attributeName}"] = ${term.trim()};` )}
	}
}
		`;
		}
	}

	deserialization.splice( write );

	// eslint-disable-next-line no-new-func
	return new Function( "$$input", "$$attrs", `
if ( !$$attrs || typeof $$attrs !== "object" ) {
	throw new TypeError( "missing definition of attributes required for deserialization" );
}

const $$s = $$input && typeof $$input === "object" ? $$input : {};
const $$d = {};

${deserialization.join( "" )}

return $$d;
` );
}
function compileDeserializer ( attributes ) { if ( ! attributes || typeof attributes !== "object" || Array . isArray ( attributes ) ) { throw new TypeError ( "definition of attributes must be object" ) ; } const attributeNames = Object . keys ( attributes ) ; const numAttributes = attributeNames . length ; const deserialization = new Array ( 2 * numAttributes ) ; let write = 0 ; for ( let ai = 0 ; ai < numAttributes ; ai ++ ) { const attributeName = attributeNames [ ai ] ; const attribute = attributes [ attributeName ] ; const handler = Types . selectByName ( attribute . type ) ; let sourceName ; // append deserialize() method of current attribute's type handler { const { args , body } = extractBody ( handler . deserialize ) ; if ( args . length < 1 ) { throw new TypeError ( ` ${ attribute . type } ` ) ; } if ( body . replace ( ptnTrailingReturn , "" ) . trim ( ) . length ) { sourceName = "$$d" ; deserialization [ write ++ ] = ` ${ args [ 0 ] } ${ attributeName } ${ body . replace ( ptnTrailingReturn , ( all , term ) => ` ${ attributeName } ${ term . trim ( ) } ` ) } ` ; } else { sourceName = "$$s" ; } } // append coerce() method of current attribute's type handler { const { args , body } = extractBody ( handler . coerce ) ; if ( args . length < 2 ) { throw new TypeError ( ` ${ attribute . type } ` ) ; } deserialization [ write ++ ] = ` ${ args [ 0 ] } ${ sourceName } ${ attributeName } ${ args [ 1 ] } ${ attributeName } ${ body . replace ( ptnTrailingReturn , ( all , term ) => ` ${ attributeName } ${ term . trim ( ) } ` ) } ` ; } } deserialization . splice ( write ) ; // eslint-disable-next-line no-new-func return new Function ( "$$input" , "$$attrs" , ` ${ deserialization . join ( "" ) } ` ) ; }
Creates function de-serializing and coercing all attributes in a provided
record.

This method is creating function resulting from concatenating methods
`deserialize()` and `coerce()` of every attribute's type handler.

@param {object<string,object>} attributes definition of essential attributes
@returns {function(object):object} function mapping some provided record into record of de-serialized attribute values
Creates function de - serializing and coercing all attributes in a provided record .