"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Config_1 = require("./Config");
var ArrayStrategy_1 = require("./Constants/ArrayStrategy");
var handleMergeError_1 = require("./handleMergeError");
var Messages = require("./Messages");
function merge(target, source, options) {
if (options === void 0) { options = {}; }
var sourceKeys = [];
var config;
if (options instanceof Config_1.default) {
config = options;
}
else {
config = new Config_1.default();
}
if (typeof options === 'boolean' && options === true) {
config.deep = true;
}
else if (options && typeof options === 'object') {
Object.assign(config, options);
}
if (!target || typeof target !== 'object') {
throw new TypeError(Messages.TYPE_ERROR_TARGET(target));
}
if (!source || typeof source !== 'object') {
throw new TypeError(Messages.TYPE_ERROR_SOURCE(source));
}
if (Array.isArray(source)) {
if (config.arrayStrategy === ArrayStrategy_1.default.PUSH) {
// Merge arrays via push()
target.push.apply(target, source);
return target;
}
for (var i = 0; i < source.length; i++) {
sourceKeys.push(i.toString());
}
}
else if (source) {
sourceKeys = Object.getOwnPropertyNames(source);
}
for (var _i = 0, sourceKeys_1 = sourceKeys; _i < sourceKeys_1.length; _i++) {
var key = sourceKeys_1[_i];
var descriptor = Object.getOwnPropertyDescriptor(source, key);
// Skip read-only properties
if (typeof descriptor.get === 'function' && !descriptor.set && !config.includeReadOnly)
continue;
// Skip non-enumerable properties
if (!descriptor.enumerable && !config.includeNonEmurable)
continue;
if (!config.deep ||
typeof source[key] !== 'object' ||
source[key] === null ||
(Array.isArray(source[key]) && config.useReferenceIfArray) ||
(!target[key] && config.useReferenceIfTargetUnset)) {
// If:
// - Shallow merge
// - All non-object primatives
// - Null pointers
// - Arrays, if `useReferenceIfArray` set
// - Target prop null or undefined and `useRererenceIfTargetUnset` set
try {
target[key] = source[key];
}
catch (err) {
handleMergeError_1.default(err, target, key, config.errorMessage);
}
}
else {
// Deep merge objects/arrays
if (!Object.prototype.hasOwnProperty.call(target, key) || target[key] === null) {
// If property does not exist on target, instantiate an empty
// object or array to merge into
target[key] = Array.isArray(source[key]) ? [] : {};
}
// Recursively deep copy objects or arrays
merge(target[key], source[key], config);
}
}
return target;
}
exports.default = merge;
//# sourceMappingURL=merge.js.map |