Skip to content
Snippets Groups Projects
Select Git revision
  • 1180a55b638b86bbe7035838261a92b306a94117
  • master default protected
2 results

duplex-browser.js

Blame
  • extend.mjs 2.24 KiB
    /**
     * Copyright © schukai GmbH and all contributing authors, {{copyRightYear}}. All rights reserved.
     * Node module: @schukai/monster
     *
     * This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
     * The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
     *
     * For those who do not wish to adhere to the AGPLv3, a commercial license is available.
     * Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
     * For more information about purchasing a commercial license, please contact schukai GmbH.
     *
     * SPDX-License-Identifier: AGPL-3.0
     */
    
    import { isArray, isObject } from "../types/is.mjs";
    import { typeOf } from "../types/typeof.mjs";
    
    export { extend };
    
    /**
     * Extend copies all enumerable own properties from one or
     * more source objects to a target object. It returns the modified target object.
     *
     * @return {object}
     * @license AGPLv3
     * @since 1.10.0
     * @copyright schukai GmbH
     * @throws {Error} unsupported argument
     * @throws {Error} type mismatch
     * @throws {Error} unsupported argument
     * @param args
     */
    function extend(...args) {
    	let o;
    	let i;
    
    	if (typeof args !== "object" || args[0] === null) {
    		throw new Error(`unsupported argument ${JSON.stringify(args[0])}`);
    	}
    
    	for (i = 0; i < args.length; i++) {
    		const a = args[i];
    
    		if (!(isObject(a) || isArray(a))) {
    			throw new Error(`unsupported argument ${JSON.stringify(a)}`);
    		}
    
    		if (o === undefined) {
    			o = a;
    			continue;
    		}
    
    		for (const k in a) {
    			const v = a?.[k];
    
    			if (k in o && v === o?.[k]) {
    				// k in o is for the case of undefined
    				continue;
    			}
    
    			if ((isObject(v) && typeOf(v) === "object") || isArray(v)) {
    				if (o[k] === undefined) {
    					if (isArray(v)) {
    						o[k] = [];
    					} else {
    						o[k] = {};
    					}
    				} else {
    					if (typeOf(o[k]) !== typeOf(v)) {
    						throw new Error(
    							`type mismatch: ${JSON.stringify(o[k])}(${typeOf(
    								o[k],
    							)}) != ${JSON.stringify(v)}(${typeOf(v)})`,
    						);
    					}
    				}
    
    				if (isArray(o[k])) {
    					o[k] = [];
    					o[k].push(...v);
    					continue;
    				}
    
    				o[k] = extend(o[k], v);
    			} else {
    				if (isArray(o)) {
    					o.push(v);
    					continue;
    				}
    				o[k] = v;
    			}
    		}
    	}
    
    	return o;
    }