API Docs for: 0.0.0
Show:

File: src/__subject/private/assign.js

/* jshint ignore:start */
if (typeof define !== 'function') { var define = require('amdefine')(module) }
/* jshint ignore:end */

define(function (require, exports, module) {
	'use strict';


	var _ = require('lodash');

		// descriptor for both accessor and data
	var defaultDescriptor = {
			configurable: true,
			enumerable:   true,
		},
		// descriptor for data only.
		defaultDataDescriptor = _.extend({
			writable:     true,
		}, defaultDescriptor);



	/**
	 * Defines properties using accessor descriptor
	 *
	 * @method assignAccessor
	 * @param  {[type]} obj        [description]
	 * @param  {[type]} properties [description]
	 * @param  {[type]} descriptor [description]
	 * @return {[type]}            [description]
	 */
	function assignAccessor(obj, properties, descriptor) {

		// when the descriptor DOES NOT HAVE
		// neither 'get' nor 'set'
		// set defaults for configurable, enumerable and writable.
		_.defaults(descriptor, defaultDescriptor);

		if (_.isArray(properties)) {

			_.each(properties, function (property) {

				// partialize get and set
				// using the property name as first argument.
				var desc = _.extend({}, descriptor);
				if (desc.get) {
					desc.get = _.partial(desc.get, property);
				}

				if (desc.set) {
					desc.set = _.partial(desc.set, property);
				}

				// run defineProperty
				Object.defineProperty(obj, property, desc);
			});

		} else {

			// TODO
			throw new Error('Currently subject.assign does not accept non-array properties for accessor assignment.');
		}
	}

	/**
	 * Defines properties using data descriptors.
	 *
	 * @method assignData
	 * @param  {[type]} obj        [description]
	 * @param  {[type]} data [description]
	 * @param  {[type]} descriptor [description]
	 * @return {[type]}            [description]
	 */
	function assignData(obj, data, descriptor) {

		// when the descriptor HAS
		// either 'get' or 'set'
		// set defaults only for configurable, enumerable
		_.defaults(descriptor, defaultDataDescriptor);


		_.each(data, function (value, property) {

			// set value on descriptor
			var desc = _.assign({ value: value }, descriptor);

			// run defineProperty
			Object.defineProperty(obj, property, desc);
		});
	}

	/**
	 *
	 *
	 * @method assign
	 * @private
	 * @param obj
	 * @param data
	 * @param [descriptor]
	 */
	module.exports = function assign(obj, data, descriptor) {

		if (!descriptor) {
			// simple assigning.
			_.assign(obj, data);

		} else {
			// use defineProperty to assign.

			if (descriptor.get || descriptor.set) {
				// ACCESSOR DESCRIPTOR

				assignAccessor(obj, data, descriptor);

			} else {
				//
				assignData(obj, data, descriptor);
			}
		}

		return obj;
	};

});