/** * 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; }