/**
 * Copyright 2021 Opstrace, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */ interface IIsObject { ( item ) : boolean ; } interface IObject { [ key ] : any ; } interface IDeepMerge { ( target , ... sources ) : IObject ; } description param item return { Boolean } item const isObject = ( item ) : boolean => { return item === Object ( item ) && ! Array . isArray ( item ) ; } ; description param { Object } target sources param { Array < Object > } sources target return { Object } export const deepMerge = ( target , ... sources ) : IObject => { if ( ! sources . length ) { return target ; } const result = target ; if ( isObject ( result ) ) { const len = sources . length ; for ( let i = 0 ; i < len ; i += 1 ) { const elm = sources [ i ] ; if ( isObject ( elm ) ) { for ( const key in elm ) { if ( elm . hasOwnProperty ( key ) ) { if ( isObject ( elm [ key ] ) ) { if ( ! result [ key ] || ! isObject ( result [ key ] ) ) { result [ key ] = { } ; } deepMerge ( result [ key ] , elm [ key ] ) ; } else { if ( Array . isArray ( result [ key ] ) && Array . isArray ( elm [ key ] ) ) { result [ key ] = Array . from ( new Set ( result [ key ] . concat ( elm [ key ] ) ) ) ; } else { result [ key ] = elm [ key ] ; } } } } } } } return result ; } ;