/*! assimilate 0.4.0 Original author Alan Plum . Released into the Public Domain under the UNLICENSE. @preserve */ var slice = Array.prototype.slice; function bind(fn, self) { var args = slice.call(arguments, 2); if (typeof Function.prototype.bind === 'function') { return Function.prototype.bind.apply(fn, [self].concat(args)); } return function() { return fn.apply(self, args.concat(slice.call(arguments, 0))); }; } function simpleCopy(target, name, source) { target[name] = source[name]; } function properCopy(target, name, source) { var descriptor = Object.getOwnPropertyDescriptor(source, name); Object.defineProperty(target, name, descriptor); } function ownProperties(obj) { return Object.getOwnPropertyNames(obj); } function allKeys(obj) { var keys = []; for (var name in obj) { keys.push(name); } return keys; } function ownKeys(obj) { var keys = []; for (var name in obj) { if (obj.hasOwnProperty(name)) { keys.push(name); } } return keys; } function assimilateWithStrategy(target) { var strategy = this, sources = slice.call(arguments, 1), i, source, names, j, name; if (target === undefined || target === null) { target = {}; } for (i = 0; i < sources.length; i++) { source = sources[i]; names = strategy.keysFn(source); for (j = 0; j < names.length; j++) { name = names[j]; strategy.copyFn(target, name, source); } } return target; } var strategies = { DEFAULT: { keysFn: ownKeys, copyFn: simpleCopy }, PROPER: { keysFn: ownProperties, copyFn: properCopy }, INHERITED: { keysFn: allKeys, copyFn: simpleCopy }, DEEP: { keysFn: ownKeys, copyFn: function recursiveCopy(target, name, source) { var val = source[name]; var old = target[name]; if (typeof val === 'object' && typeof old === 'object') { assimilateWithStrategy.call(strategies.DEEP, old, val); } else { simpleCopy(target, name, source); } } }, STRICT: { keysFn: ownKeys, copyFn: function strictCopy(target, name, source) { if (source[name] !== undefined) { simpleCopy(target, name, source); } } }, FALLBACK: { keysFn: function fallbackCopy(target, name, source) { if (target[name] === undefined) { simpleCopy(target, name, source); } }, copyFn: simpleCopy } }; var assimilate = bind(assimilateWithStrategy, strategies.DEFAULT); assimilate.strategies = strategies; assimilate.withStrategy = function withStrategy(strategy) { if (typeof strategy === 'string') { strategy = strategies[strategy.toUpperCase()]; } if (!strategy) { throw new Error('Unknwon or invalid strategy:' + strategy); } if (typeof strategy.copyFn !== 'function') { throw new Error('Strategy missing copy function:' + strategy); } if (typeof strategy.keysFn !== 'function') { throw new Error('Strategy missing keys function:' + strategy); } return bind(assimilateWithStrategy, strategy); }; module.exports = assimilate;