1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- 'use strict';
- const Assert = require('./assert');
- const Clone = require('./clone');
- const Utils = require('./utils');
- const internals = {};
- module.exports = internals.merge = function (target, source, options) {
- Assert(target && typeof target === 'object', 'Invalid target value: must be an object');
- Assert(source === null || source === undefined || typeof source === 'object', 'Invalid source value: must be null, undefined, or an object');
- if (!source) {
- return target;
- }
- options = Object.assign({ nullOverride: true, mergeArrays: true }, options);
- if (Array.isArray(source)) {
- Assert(Array.isArray(target), 'Cannot merge array onto an object');
- if (!options.mergeArrays) {
- target.length = 0; // Must not change target assignment
- }
- for (let i = 0; i < source.length; ++i) {
- target.push(Clone(source[i], { symbols: options.symbols }));
- }
- return target;
- }
- const keys = Utils.keys(source, options);
- for (let i = 0; i < keys.length; ++i) {
- const key = keys[i];
- if (key === '__proto__' ||
- !Object.prototype.propertyIsEnumerable.call(source, key)) {
- continue;
- }
- const value = source[key];
- if (value &&
- typeof value === 'object') {
- if (!target[key] ||
- typeof target[key] !== 'object' ||
- (Array.isArray(target[key]) !== Array.isArray(value)) ||
- value instanceof Date ||
- (Buffer && Buffer.isBuffer(value)) || // $lab:coverage:ignore$
- value instanceof RegExp) {
- target[key] = Clone(value, { symbols: options.symbols });
- }
- else {
- internals.merge(target[key], value, options);
- }
- }
- else {
- if (value !== null &&
- value !== undefined) { // Explicit to preserve empty strings
- target[key] = value;
- }
- else if (options.nullOverride) {
- target[key] = value;
- }
- }
- }
- return target;
- };
|