UNPKG

deepmerge-plus

Version:

用於深度(遞迴)合併 JavaScript 物件的函式庫 / A library for deep (recursive) merging of JavaScript objects

1 lines 51.5 kB
{"version":3,"file":"index.umd.development.cjs","sources":["../src/index.ts"],"sourcesContent":["/**\n * 深度合併兩個 JavaScript 物件(可遞迴合併巢狀物件和陣列)\n * Deep (recursive) merge of two JavaScript objects\n *\n * @package deepmerge-plus\n * @version 3.0.2\n */\nimport isMergeableObject from 'is-mergeable-object';\nimport { ITSPickExtra, ITSWriteable, ITSToWriteableArray, ITSPropertyKey } from 'ts-type';\n\n/**\n * 建立空目標物件 / Create empty target object\n *\n * 根據輸入值類型回傳空陣列或空物件\n * 用於深度合併時建立目標的空白副本\n *\n * Returns empty array or object based on input value type\n * Used to create a blank copy of target during deep merge\n *\n * @param val - 輸入值 / Input value (array or object)\n * @returns 空陣列(若輸入為陣列)或空物件(若輸入為物件)/ Empty array (if input is array) or empty object (if input is object)\n *\n * @example\n * emptyTarget([1, 2, 3]) // 回傳 []\n * emptyTarget({ a: 1 }) // 回傳 {}\n */\nfunction emptyTarget(val)\n{\n\treturn Array.isArray(val) ? [] : {}\n}\n\n/**\n * 決定是否啟用深度複製功能\n * 預設為 true(啟用),除非選項明確設為 false\n *\n * Determine whether to enable deep cloning\n * Default is true (enabled), unless options explicitly set to false\n *\n * @note 注意事項 / Note:\n * 即使 `options.clone` 設為 `false`,在某些情況下仍可能會產生 clone。\n * 這是正常現象,因為深度合併需要確保輸出物件與輸入物件相互獨立,\n * 以避免意外修改原始資料。\n *\n * Even if `options.clone` is set to `false`, cloning may still occur\n * in certain situations. This is expected behavior because deep merge\n * needs to ensure the output object is independent from the input objects\n * to prevent accidental modification of original data.\n */\nexport function _shouldClone(optionsRuntime?: IOptions)\n{\n\t// do not change or remove this code logic\n\t// const clone = !optionsRuntime || optionsRuntime.clone !== false;\n\tconst clone = optionsRuntime?.clone !== false;\n\treturn clone;\n}\n\n/**\n * 檢查目標物件中該 key 的值是否為 undefined\n * Check if target key value is undefined\n */\nexport function _defaultCheckShouldNotUpsertValue(value, optionsRuntime: IOptions, tmpRuntimeTarget: ICache, tmpRuntimeData: ITmpRuntimeData)\n{\n\tconst targetValue = tmpRuntimeTarget.target?.[tmpRuntimeTarget.key];\n\tconst shouldNotUpsertValue = !_isUndefined(targetValue);\n\treturn shouldNotUpsertValue;\n}\n\n/**\n * 除非另有指定,否則複製值 / Clone value unless otherwise specified\n *\n * 決定是否需要深度複製輸入值:\n * 1. 檢查選項中的 clone 設定\n * 2. 判斷值是否為可合併物件\n * 3. 若需要合併則遞迴複製\n *\n * Determines whether to deep clone the input value:\n * 1. Check clone option in optionsArgument\n * 2. Check if value is mergeable object\n * 3. Recursively clone if mergeable\n *\n * @param value - 要複製的值 / Value to clone\n * @param optionsRuntime - 合併選項 / Merge options\n * @param tmpRuntimeTarget - 內部快取資訊 / Internal cache information\n * @returns 複製後的值或原始值 / Cloned value or original value\n */\nfunction cloneUnlessOtherwiseSpecified(value, optionsRuntime: IOptions, tmpRuntimeTarget: ICache, tmpRuntimeData: ITmpRuntimeData)\n{\n\t/**\n\t * 決定是否啟用深度複製功能\n\t * 預設為 true(啟用),除非選項明確設為 false\n\t *\n\t * Determine whether to enable deep cloning\n\t * Default is true (enabled), unless options explicitly set to false\n\t *\n\t * @note 即使 `options.clone` 設為 `false`,在某些情況下仍可能會產生 clone\n\t * @note Even if `options.clone` is set to `false`, cloning may still occur\n\t */\n\tconst clone = _shouldClone(optionsRuntime);\n\n\t/**\n\t * 判斷當前值是否需要進行深度複製\n\t * 條件:clone 為 true 且值為可合併物件\n\t * Determine if current value needs deep cloning\n\t * Condition: clone is true AND value is a mergeable object\n\t */\n\tconst bool = clone && _isMergeableObject(value, optionsRuntime, tmpRuntimeTarget, tmpRuntimeData);\n\n\t/**\n\t * 根據 bool 條件決定回傳值\n\t * 若需要複製:建立空目標並遞迴合併(深度複製)\n\t * 若不需要複製:直接回傳原始值\n\t * Return value based on bool condition\n\t * If needs cloning: create empty target and recursively merge (deep clone)\n\t * If not needs cloning: return original value directly\n\t */\n\tlet ret = (bool)\n\t\t? deepmerge(emptyTarget(value), value, optionsRuntime, tmpRuntimeData)\n\t\t: value;\n\n\t/**\n\t * keyValueOrMode 模式處理\n\t * 當啟用此模式且值不需要合併時,優先使用目標中已存在的值\n\t * 檢查順序:destination > target > source\n\t * keyValueOrMode mode handling\n\t * When enabled and value doesn't need merging, prefer existing values in target\n\t *\n\t * 由左至右的概念 / Left-to-right concept:\n\t * merge(target, source, options) 中:\n\t * - target 是「左側」(left)- 被合併的物件,代表現有值\n\t * - source 是「右側」(right)- 要合併進來的物件,代表新值\n\t * - 當 source 值為 falsy 時,使用「左側」的值作為回退\n\t *\n\t * In merge(target, source, options):\n\t * - target is \"left\" - the object being merged INTO, represents existing values\n\t * - source is \"right\" - the object being merged FROM, represents new values\n\t * - When source value is falsy, use \"left\" value as fallback\n\t *\n\t * Check order: destination > target > source\n\t */\n\tif (optionsRuntime?.keyValueOrMode && !bool && tmpRuntimeTarget && ('key' in tmpRuntimeTarget))\n\t{\n\t\t/** 檢查目的物件中是否有現有值 / Check if destination has existing value */\n\t\tif (tmpRuntimeTarget.destination)\n\t\t{\n\t\t\t//console.log('destination', tmpRuntimeTarget.destination[tmpRuntimeTarget.key], ret, tmpRuntimeTarget.key);\n\t\t\tret = tmpRuntimeTarget.destination[tmpRuntimeTarget.key] || ret;\n\t\t}\n\n\t\t/** 檢查目標物件中是否有現有值 / Check if target has existing value */\n\t\tif (tmpRuntimeTarget.target)\n\t\t{\n\t\t\t//console.log('target', tmpRuntimeTarget.target[tmpRuntimeTarget.key], ret, tmpRuntimeTarget.key);\n\t\t\tret = tmpRuntimeTarget.target[tmpRuntimeTarget.key] || ret;\n\t\t}\n\n\t\t/** 檢查來源物件中是否有現有值 / Check if source has existing value */\n\t\tif (tmpRuntimeTarget.source)\n\t\t{\n\t\t\t//console.log('source', tmpRuntimeTarget.source[tmpRuntimeTarget.key], ret, tmpRuntimeTarget.key);\n\t\t\tret = tmpRuntimeTarget.source[tmpRuntimeTarget.key] || ret;\n\t\t}\n\t}\n\n\t// console.dir({\n\t// \tvalue,\n\t// \tret,\n\t// \toptionsRuntime,\n\t// \ttmpRuntimeTarget,\n\t// \ttmpRuntimeData,\n\t// \ttargetValue: tmpRuntimeTarget.target?.[tmpRuntimeTarget.key],\n\t// \tbool,\n\t// }, { depth: 2 });\n\n\t/**\n\t * keyValueUpsertMode 模式處理\n\t * 當啟用此模式時,根據條件決定是否應該使用目標中的現有值\n\t * keyValueUpsertMode mode handling\n\t * When enabled, decides whether to use existing value in target based on condition\n\t *\n\t * 由左至右的概念 / Left-to-right concept:\n\t * merge(target, source, options) 中:\n\t * - target 是「左側」(left)- 被合併的物件,代表現有值\n\t * - source 是「右側」(right)- 要合併進來的物件,代表新值\n\t * - 合併結果會傾向保留「左側」的值(除非條件允許使用「右側」的值)\n\t *\n\t * In merge(target, source, options):\n\t * - target is \"left\" - the object being merged INTO, represents existing values\n\t * - source is \"right\" - the object being merged FROM, represents new values\n\t * - The merged result tends to preserve \"left\" values (unless conditions allow using \"right\" values)\n\t *\n\t * 為 true 時:只會在目標 key 的值為 undefined 時才使用目標的值\n\t * 為 function 時:只會在函式回傳 true 時使用目標的值\n\t *\n\t * When true: Only use target's value when target key value is undefined\n\t * When function: Only use target's value when function returns true\n\t */\n\tif (optionsRuntime?.keyValueUpsertMode && !bool && tmpRuntimeTarget && ('key' in tmpRuntimeTarget))\n\t{\n\t\t/** 檢查是否應該使用目標的值 / Check if should use target's value */\n\t\tlet shouldNotUpsertValue = false;\n\n\t\tif (typeof optionsRuntime.keyValueUpsertMode === 'function')\n\t\t{\n\t\t\t/** 使用自訂函式判斷 / Use custom function to determine */\n\t\t\tshouldNotUpsertValue = optionsRuntime.keyValueUpsertMode(value, optionsRuntime, tmpRuntimeTarget, tmpRuntimeData);\n\t\t}\n\t\telse if (optionsRuntime.keyValueUpsertMode === true)\n\t\t{\n\t\t\t/** 檢查目標物件中該 key 的值是否為 undefined / Check if target key value is undefined */\n\t\t\tconst targetValue = tmpRuntimeTarget.target?.[tmpRuntimeTarget.key];\n\t\t\tshouldNotUpsertValue = !_isUndefined(targetValue);\n\t\t}\n\n\t\t/** 若符合條件,則使用目標中的現有值 / If condition met, use existing value in target */\n\t\tif (shouldNotUpsertValue)\n\t\t{\n\t\t\tlet upsertValue: any;\n\n\t\t\t/** 檢查目的物件中是否有現有值 / Check if destination has existing value */\n\t\t\tif (tmpRuntimeTarget.destination)\n\t\t\t{\n\t\t\t\tupsertValue ??= tmpRuntimeTarget.destination[tmpRuntimeTarget.key];\n\t\t\t}\n\n\t\t\t/** 檢查目標物件中是否有現有值 / Check if target has existing value */\n\t\t\tif (tmpRuntimeTarget.target)\n\t\t\t{\n\t\t\t\tupsertValue ??= tmpRuntimeTarget.target[tmpRuntimeTarget.key];\n\t\t\t}\n\n\t\t\tret = upsertValue;\n\t\t}\n\n\t\t// console.dir({\n\t\t// \tshouldNotUpsertValue,\n\t\t// \tkey: tmpRuntimeTarget.key,\n\t\t// \tret,\n\t\t// \tvalue,\n\t\t// });\n\t}\n\n\treturn ret;\n}\n\nexport function _isUndefined(value: unknown): value is undefined\n{\n\treturn typeof value === 'undefined'\n}\n\nexport function _isNull(value: unknown): value is null\n{\n\treturn value === null\n}\n\nexport function _isNullOrUndefined(value: unknown): value is null\n{\n\treturn value === null || typeof value === 'undefined'\n}\n\n/**\n * 檢查值是否為可合併物件 / Check if value is a mergeable object\n *\n * 判斷邏輯:\n * 1. 先檢查選項中的自訂 isMergeableObject 函式\n * 2. 若無自訂函式,檢查 SYMBOL_IS_MERGEABLE 符號\n * 3. 若無符號,使用預設的 isMergeableObject 函式\n *\n * Decision logic:\n * 1. First check custom isMergeableObject function in options\n * 2. If no custom function, check SYMBOL_IS_MERGEABLE symbol\n * 3. If no symbol, use default isMergeableObject function\n *\n * @param value - 要檢查的值 / Value to check\n * @param optionsArgument - 合併選項 / Merge options\n * @param tmpRuntimeTarget - 內部快取資訊 / Internal cache information\n * @returns 是否可合併 / Whether mergeable\n */\nexport function _isMergeableObject(value, optionsArgument: IOptions, tmpRuntimeTarget: ICache, tmpRuntimeData: ITmpRuntimeData): boolean\n{\n\t/**\n\t * 步驟 1:嘗試使用自訂 isMergeableObject 函式(若存在)\n\t * Step 1: Try using custom isMergeableObject function (if exists)\n\t */\n\tlet ret = optionsArgument?.isMergeableObject?.(value, isMergeableObject, optionsArgument, tmpRuntimeTarget, tmpRuntimeData) as any;\n\n\t/**\n\t * 步驟 2:若自訂函式未回傳明確結果(null 或 undefined)\n\t * 檢查 SYMBOL_IS_MERGEABLE 符號\n\t * Step 2: If custom function doesn't return definite result (null or undefined)\n\t * Check SYMBOL_IS_MERGEABLE symbol\n\t */\n\tif (ret === null || typeof ret === 'undefined')\n\t{\n\t\t/** 檢查值是否帶有可合併標記符號 / Check if value has mergeable marker symbol */\n\t\tif ((typeof value?.[SYMBOL_IS_MERGEABLE] == 'boolean'))\n\t\t{\n\t\t\tret = value[SYMBOL_IS_MERGEABLE];\n\t\t}\n\t\t/** 若無符號,使用預設的 isMergeableObject 函式 / If no symbol, use default isMergeableObject function */\n\t\telse\n\t\t{\n\t\t\tret = isMergeableObject(value);\n\t\t}\n\t}\n\treturn ret\n}\n\n/**\n * 預設陣列合併函式 / Default array merge function\n *\n * 將來源陣列串接到目標陣列,並對每個元素進行深度複製\n * 這是 deepmerge 的預設陣列合併策略\n *\n * Concatenates source array to target array and deep clones each element\n * This is the default array merge strategy for deepmerge\n *\n * 處理邏輯 / Processing logic:\n * 1. 將來源陣列串接到目標陣列末尾\n * 2. 對每個元素進行條件性深度複製\n * 3. 確保合併後的陣列元素是獨立的副本\n *\n * @param target - 目標陣列(被合併的陣列)/ Target array (the array being merged into)\n * @param source - 來源陣列(要合併的陣列)/ Source array (the array to merge from)\n * @param optionsArgument - 合併選項 / Merge options\n * @returns 合併後的新陣列 / New merged array\n */\nfunction defaultArrayMerge<T extends any[]>(target: T, source: any[], optionsArgument?: IOptions, tmpRuntimeData?: ITmpRuntimeData<T>): T[];\nfunction defaultArrayMerge(target: any[], source: any[], optionsArgument?: IOptions, tmpRuntimeData?: ITmpRuntimeData): any[]\nfunction defaultArrayMerge(target: any[], source: any[], optionsArgument?: IOptions, tmpRuntimeData?: ITmpRuntimeData): any[]\n{\n\t// @ts-ignore\n\ttmpRuntimeData ??= _newTmpRuntimeData<any[]>([]);\n\n\tconst level = tmpRuntimeData.level + 1;\n\tconst root = tmpRuntimeData.root;\n\tconst parent = [] as any[];\n\n\t(tmpRuntimeData.parent as any)[tmpRuntimeData.key] = parent;\n\n\t/**\n\t * 1. 串接目標陣列和來源陣列\n\t * 2. 對每個元素進行深度複製(確保元素是獨立的副本)\n\t * 1. Concatenate target array and source array\n\t * 2. Deep clone each element (ensuring elements are independent copies)\n\t */\n\treturn target.concat(source as any).reduce((parent, element, index) => {\n\n\t\t/**\n\t\t * 對每個元素進行條件性複製\n\t\t * 若為可合併物件則深度複製,否則直接複製\n\t\t * Conditionally clone each element\n\t\t * Deep clone if mergeable, otherwise copy directly\n\t\t */\n\t\telement = cloneUnlessOtherwiseSpecified(element, optionsArgument, {\n\t\t\tkey: index,\n\t\t}, {\n\t\t\tlevel,\n\t\t\tpaths: [...tmpRuntimeData.paths, index],\n\t\t\troot,\n\t\t\tparent,\n\t\t\tkey: index,\n\t\t});\n\n\t\tparent[index] = element;\n\n\t\treturn parent;\n\t}, parent);\n}\n\n/**\n * 合併兩個物件 / Merge two objects\n *\n * 這是 deepmerge 處理物件合併的核心函式\n * 負責將來源物件的屬性合併到目標物件\n *\n * This is the core function for object merging in deepmerge\n * Responsible for merging source object properties into target object\n *\n * 由左至右的概念 / Left-to-right concept:\n * merge(target, source, options) 中:\n * - 第一個參數 target 是「左側」(left)- 被合併的物件,代表現有值\n * - 第二個參數 source 是「右側」(right)- 要合併進來的物件,代表新值\n * - 合併結果是將「右側」的值合併進「左側」\n *\n * In merge(target, source, options):\n * - First parameter target is \"left\" - the object being merged INTO, represents existing values\n * - Second parameter source is \"right\" - the object being merged FROM, represents new values\n * - The result merges \"right\" values INTO \"left\"\n *\n * 處理邏輯 / Processing logic:\n * 1. 建立目的物件(destination)用於存放合併結果\n * 2. 遍歷目標物件的所有鍵值:\n * - 複製到目的物件,進行深度複製\n * 3. 遍歷來源物件的所有鍵值:\n * - 若鍵不存在於目標 OR 來源值不可合併 → 直接複製\n * - 若鍵存在於目標 AND 來源值可合併 → 遞迴呼叫 deepmerge 進行深度合併\n *\n * @param target - 目標物件(被合併的物件)/ Target object (the object being merged into)\n * @param source - 來源物件(要合併的物件)/ Source object (the object to merge from)\n * @param optionsArgument - 合併選項 / Merge options\n * @returns 合併後的新物件 / New merged object\n */\nfunction mergeObject(target, source, optionsArgument: IOptions, tmpRuntimeData: ITmpRuntimeData)\n{\n\tlet destination = {};\n\n\tif (!tmpRuntimeData)\n\t{\n\t\ttmpRuntimeData = _newTmpRuntimeData(destination);\n\t}\n\n\t/**\n\t * 處理階段 1:遍歷目標物件的所有鍵值\n\t * 將目標物件的屬性複製到目的物件(進行深度複製)\n\t * Processing phase 1: Iterate all keys of target object\n\t * Copy target object properties to destination (deep clone)\n\t */\n\tif (_isMergeableObject(target, optionsArgument, void 0, tmpRuntimeData))\n\t{\n\t\tObject.keys(target).forEach(function (key)\n\t\t{\n\t\t\tdestination[key] = cloneUnlessOtherwiseSpecified(target[key], optionsArgument, {\n\t\t\t\tkey,\n\t\t\t\tsource,\n\t\t\t\ttarget,\n\t\t\t\tdestination,\n\t\t\t}, {\n\t\t\t\tlevel: tmpRuntimeData.level + 1,\n\t\t\t\tpaths: [...tmpRuntimeData.paths, key],\n\t\t\t\troot: tmpRuntimeData.root,\n\t\t\t\tparent: destination,\n\t\t\t\tkey: key\n\t\t\t})\n\t\t})\n\t}\n\t/**\n\t * 處理階段 2:遍歷來源物件的所有鍵值\n\t * 根據是否存在於目標中以及是否可合併來決定合併策略\n\t * Processing phase 2: Iterate all keys of source object\n\t * Decide merge strategy based on whether key exists in target and if mergeable\n\t */\n\tObject.keys(source).forEach(function (key)\n\t{\n\t\t/**\n\t\t * 判斷邏輯:\n\t\t * - 若來源值不可合併 OR 目標中沒有此鍵 → 直接複製\n\t\t * - 若來源值可合併且目標中也有此鍵 → 遞迴合併\n\t\t * Decision logic:\n\t\t * - If source value not mergeable OR key doesn't exist in target → copy directly\n\t\t * - If source value mergeable AND key exists in target → recursively merge\n\t\t */\n\t\tif (!_isMergeableObject(source[key], optionsArgument, {\n\t\t\t\tkey,\n\t\t\t\tsource,\n\t\t\t\ttarget,\n\t\t\t}, tmpRuntimeData) || !target[key])\n\t\t{\n\t\t\tdestination[key] = cloneUnlessOtherwiseSpecified(source[key], optionsArgument, {\n\t\t\t\tkey,\n\t\t\t\tsource,\n\t\t\t\ttarget,\n\t\t\t}, {\n\t\t\t\tlevel: tmpRuntimeData.level + 1,\n\t\t\t\tpaths: [...tmpRuntimeData.paths, key],\n\t\t\t\troot: tmpRuntimeData.root,\n\t\t\t\tparent: destination,\n\t\t\t\tkey: key\n\t\t\t})\n\t\t}\n\t\telse\n\t\t{\n\t\t\tdestination[key] = deepmerge(target[key], source[key], optionsArgument, {\n\t\t\t\tlevel: tmpRuntimeData.level + 1,\n\t\t\t\tpaths: [...tmpRuntimeData.paths, key],\n\t\t\t\troot: tmpRuntimeData.root,\n\t\t\t\tparent: destination,\n\t\t\t\tkey: key\n\t\t\t})\n\t\t}\n\t});\n\treturn destination\n}\n\n/**\n * 深度合併結果類型 / Deep merge result type\n *\n * 合併兩個物件後的類型,推斷規則如下:\n * 1. 取得 T2 中不在 T1 的鍵(新增的鍵)\n * 2. 與 T1 的鍵進行交集(保留 T1 的鍵)\n * 3. 確保結果為可寫入類型\n *\n * Type after merging two objects, inference rules:\n * 1. Get keys in T2 that are not in T1 (new keys)\n * 2. Intersect with keys in T1 (preserve T1's keys)\n * 3. Ensure result is writeable type\n *\n * @template T1 - 目標物件類型 / Target object type\n * @template T2 - 來源物件類型 / Source object type\n */\nexport type IDeepmergeResult<T1, T2> = ITSWriteable<ITSPickExtra<T2, Exclude<keyof T2, keyof T1>> & T1>;\n\n/**\n * 初始化選項\n * 若未提供則使用預設設定(使用預設陣列合併函式)\n *\n * Initialize options\n * Use default settings if not provided (use default array merge function)\n */\nexport function _handleOptions(optionsArgument?: IOptions): IOptions\n{\n\tconst options: IOptions = optionsArgument || {};\n\t// @ts-ignore\n\t// options.arrayMerge ??= defaultArrayMerge;\n\n\treturn options;\n}\n\n/**\n * 深度合併函式 / Deep merge function\n *\n * 主要的合併函式,處理物件和陣列的深度合併\n * Main merge function that handles deep merging of objects and arrays\n *\n * 處理邏輯 / Processing logic:\n * 1. 檢查來源和目標是否為陣列\n * 2. 檢查類型是否匹配(兩者都必須是陣列或都不是)\n * 3. 若類型不匹配,返回來源物件的克隆\n * 4. 若兩者都是陣列,使用 arrayMerge 函式合併\n * 5. 否則,使用 mergeObject 進行物件合併\n *\n * @param T1 - 目標物件類型 / Target object type\n * @param T2 - 來源物件類型 / Source object type\n * @param target - 目標物件 / Target object\n * @param source - 來源物件 / Source object\n * @param optionsArgument - 合併選項 / Merge options\n * @returns 合併後的物件 / Merged object\n */\nexport function deepmerge<T1 extends unknown[], T2 extends unknown[]>(x: T1, y: T2, options?: IOptions, tmpRuntimeData?: ITmpRuntimeData): [...T1, ...T2]\nexport function deepmerge<T1, T2>(x: T1[], y: T2[], options?: IOptions, tmpRuntimeData?: ITmpRuntimeData): (T2 | T1)[]\nexport function deepmerge<T1, T2>(x: T1, y: T2, options?: IOptions, tmpRuntimeData?: ITmpRuntimeData): IDeepmergeResult<T1, T2>\nexport function deepmerge<T>(x: Partial<NoInfer<T>>, y: Partial<NoInfer<T>>, options?: IOptions, tmpRuntimeData?: ITmpRuntimeData): ITSWriteable<T>\nexport function deepmerge(target, source, optionsArgument, tmpRuntimeData: ITmpRuntimeData)\n{\n\t/**\n\t * 步驟 1:類型檢測\n\t * 判斷來源和目標是否為陣列\n\t *\n\t * Step 1: Type detection\n\t * Check if source and target are arrays\n\t */\n\tconst sourceIsArray = Array.isArray(source);\n\tconst targetIsArray = Array.isArray(target);\n\n\t/**\n\t * 步驟 2:初始化選項\n\t * 若未提供則使用預設設定(使用預設陣列合併函式)\n\t *\n\t * Step 2: Initialize options\n\t * Use default settings if not provided (use default array merge function)\n\t */\n\tconst options = _handleOptions(optionsArgument);\n\n\t/**\n\t * 步驟 3:類型匹配檢查\n\t * 確保兩者都是陣列或都不是陣列\n\t *\n\t * Step 3: Type matching check\n\t * Ensure both are arrays or both are not arrays\n\t */\n\tconst sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;\n\n\t/**\n\t * 情境 1:類型不匹配(陣列 vs 物件)\n\t * 回傳來源物件的克隆,不進行合併\n\t *\n\t * Scenario 1: Type mismatch (array vs object)\n\t * Return clone of source object, no merging\n\t *\n\t * 範例 / Example:\n\t * deepmerge([], {}) // 回傳 {} 的克隆 / returns clone of {}\n\t * deepmerge({}, []) // 回傳 [] 的克隆 / returns clone of []\n\t */\n\tif (!sourceAndTargetTypesMatch)\n\t{\n\t\treturn cloneUnlessOtherwiseSpecified(source, optionsArgument, {\n\t\t\ttarget,\n\t\t\tsource,\n\t\t}, tmpRuntimeData);\n\t}\n\t/**\n\t * 情境 2:兩者都是陣列\n\t * 使用 arrayMerge 函式進行合併(預設為串接)\n\t *\n\t * Scenario 2: Both are arrays\n\t * Use arrayMerge function to merge (default is concatenation)\n\t *\n\t * 範例 / Example:\n\t * deepmerge([1, 2], [3, 4])\n\t * // 回傳 / returns [1, 2, 3, 4](預設行為)/ (default behavior)\n\t */\n\telse if (sourceIsArray)\n\t{\n\t\treturn (options?.arrayMerge ?? defaultArrayMerge)(target, source, optionsArgument, tmpRuntimeData);\n\t}\n\t/**\n\t * 情境 3:兩者都是物件\n\t * 使用 mergeObject 進行物件屬性合併\n\t *\n\t * Scenario 3: Both are objects\n\t * Use mergeObject to merge object properties\n\t *\n\t * 範例 / Example:\n\t * deepmerge({ a: 1 }, { b: 2 })\n\t * // 回傳 / returns { a: 1, b: 2 }\n\t */\n\telse\n\t{\n\t\treturn mergeObject(target, source, optionsArgument, tmpRuntimeData);\n\t}\n}\n\n/**\n * 內部快取介面 / Internal cache interface\n *\n * 用於在合併過程中傳遞上下文資訊\n * 這些資訊在遞迴合併時用於維持物件間的引用關係\n *\n * 與 ITmpRuntimeData 的差異:\n * - ICache: 追蹤 source、target、destination 的引用關係\n * - ITmpRuntimeData: 追蹤遞迴路徑和深度資訊\n *\n * Used to pass context information during merge operations\n * This information is used during recursive merge to maintain object references\n *\n * Difference from ITmpRuntimeData:\n * - ICache: Tracks source, target, destination reference relationships\n * - ITmpRuntimeData: Tracks recursion path and depth information\n *\n * @example\n * {\n * key: 'user', // 目前處理的鍵名\n * source: { ... }, // 來源物件\n * target: { ... }, // 目標物件\n * destination: { ... } // 目的物件(目前合併結果)\n * }\n *\n * `tmpRuntimeTarget: ICache`\n */\nexport interface ICache\n{\n\t/** 鍵名 / Key name */\n\tkey?\n\t/** 來源物件 / Source object */\n\tsource?\n\t/** 目標物件 / Target object */\n\ttarget?\n\t/** 目的物件 / Destination object */\n\tdestination?\n}\n\nexport type IAnyRecord = Record<ITSPropertyKey | number, any>;\n\n/**\n * 執行時資料介面 / Runtime data interface\n *\n * 用於在 deepmerge 遞迴呼叫過程中傳遞上下文資訊\n * 追蹤目前在合併樹中的位置和路徑\n *\n * Used to pass context information during deepmerge recursive calls\n * Tracks current position and path in the merge tree\n *\n * 屬性說明 / Properties Description:\n * - level: 目前的遞迴深度(根為 0,每遞迴一次 +1)\n * - paths: 從根到目前位置的路徑陣列(可用於 _.get(root, paths))\n * - root: 最頂層的 destination 物件(永遠不變)\n * - parent: 目前層級的父物件\n * - key: 目前正在處理的鍵名\n *\n * 遞迴流程範例 / Recursive Flow Example:\n * 合併 { a: { b: 1 } } 和 { a: { c: 2 } } 時:\n * - 根層級: level=0, paths=[], root={}, parent={}, key=undefined\n * - level1: level=1, paths=['a'], root={}, parent={}, key='a'\n * - level2: level=2, paths=['a','b'], root={}, parent={a:{}}, key='b'\n *\n * @template T - parent 物件的類型(通常與 root 相同或為其子物件)\n * @template R - root 物件的類型\n */\nexport interface ITmpRuntimeData<T extends IAnyRecord = IAnyRecord, R extends IAnyRecord = IAnyRecord>\n{\n\t/** 遞迴深度計數(根為 0)/ Recursion depth count (root is 0) */\n\treadonly level: number;\n\n\t/** 從根到目前位置的路徑陣列 / Path array from root to current position */\n\treadonly paths: (keyof R | keyof T | ITSPropertyKey | number)[];\n\n\t/** 最頂層的 destination 物件(永遠不變)/ Top-level destination object (always unchanged) */\n\treadonly root: R;\n\n\t/** 目前層級的父物件 / Parent object at current level */\n\treadonly parent: T;\n\n\t/** 目前正在處理的鍵名 / Key currently being processed */\n\treadonly key: keyof T;\n}\n\n/**\n * 合併選項介面 / Merge options interface\n *\n * 定義 deepmerge 函式的可選配置參數\n * Allows customization of merge behavior\n *\n * Defines optional configuration parameters for deepmerge function\n */\nexport interface IOptions\n{\n\t/**\n\t * 決定是否啟用深度複製功能\n\t * 預設為 true(啟用),除非選項明確設為 false\n\t *\n\t * Determine whether to enable deep cloning\n\t * Default is true (enabled), unless options explicitly set to false\n\t *\n\t * @note 注意事項 / Note:\n\t * - 即使設為 `false`,在部分狀況下仍可能會忽略此設定並產生 clone\n\t * - 此行為為正常現象,因為深度合併需要確保輸出物件與輸入物件相互獨立\n\t *\n\t * - Even if set to `false`, cloning may still occur in certain situations\n\t * - This is expected behavior because deep merge needs to ensure the output\n\t * object is independent from the input objects\n\t *\n\t * @default true\n\t */\n\tclone?: boolean;\n\n\t/**\n\t * 自訂陣列合併函式\n\t * Custom array merge function\n\t *\n\t * 允許自訂陣列的合併行為\n\t * 預設行為是串接兩個陣列\n\t *\n\t * Allows customization of array merge behavior\n\t * Default behavior is to concatenate two arrays\n\t *\n\t * @param destination - 目標陣列 / Destination array\n\t * @param source - 來源陣列 / Source array\n\t * @param options - 合併選項 / Merge options\n\t * @returns 合併後的陣列 / Merged array\n\t */\n\tarrayMerge?<T extends any[]>(target: T, source: any[], options?: IOptions, tmpRuntimeData?: ITmpRuntimeData<T>): T[];\n\tarrayMerge?(target: any[], source: any[], options?: IOptions, tmpRuntimeData?: ITmpRuntimeData): any[];\n\n\t/**\n\t * 自訂可合併物件判斷函式\n\t * Custom mergeable object check function\n\t *\n\t * 允許自訂哪些物件可以被合併\n\t * 可用於支援自訂類型(如 Map、Set 等)\n\t *\n\t * Allows customizing which objects can be merged\n\t * Can be used to support custom types (like Map, Set, etc.)\n\t *\n\t * @param value - 要檢查的值 / Value to check\n\t * @param isMergeableObject - 預設的判斷函式 / Default check function\n\t * @param optionsArgument - 合併選項 / Merge options\n\t * @param tmpRuntimeData - 執行時資料 / Runtime data\n\t */\n\tisMergeableObject?(value, isMergeableObject: typeof isMergeable, optionsArgument?: IOptions,\n\t\ttmpRuntimeTarget?: ICache, tmpRuntimeData?: ITmpRuntimeData): void;\n\tisMergeableObject?(value, isMergeableObject: typeof isMergeable, optionsArgument?: IOptions,\n\t\ttmpRuntimeTarget?: ICache,\n\t\ttmpRuntimeData?: ITmpRuntimeData): boolean;\n\n\t/**\n\t * (val = old || new) 模式\n\t * (val = old || new) mode\n\t *\n\t * 啟用時會保留目標中已存在的值\n\t * 當來源物件和目標物件都有相同鍵時,優先使用目標的值\n\t *\n\t * When enabled, preserves values that already exist in target\n\t * When both source and target have the same key, priority is given to target's value\n\t *\n\t * @deprecated 棄用,建議使用 `keyValueUpsertMode` 取代\n\t * @deprecated Deprecated, use `keyValueUpsertMode` instead\n\t *\n\t * @note 注意事項 / Note:\n\t * 此選項保留為相容性用途,不建議在新程式碼中使用。\n\t * 若有需要自訂合併邏輯,建議使用 `keyValueUpsertMode` 選項。\n\t *\n\t * This option is kept for backward compatibility and is not recommended for new code.\n\t * For custom merge logic, use the `keyValueUpsertMode` option instead.\n\t *\n\t * @example\n\t * const target = { name: 'Alice', age: 25 };\n\t * const source = { name: 'Bob', city: 'Taipei' };\n\t * // keyValueOrMode: true 時 / when keyValueOrMode: true\n\t * // 結果: { name: 'Alice', age: 25, city: 'Taipei' }\n\t * // name 保留目標的值,age 來自目標,city 來自來源\n\t */\n\tkeyValueOrMode?: boolean,\n\n\t/**\n\t * Upsert 模式(選擇性更新)\n\t * Upsert mode (selective update)\n\t *\n\t * 控制何時應該更新目標中的值\n\t * 為 true 時:保留原有值(不取代),只在目標 key 的值為 undefined 時才使用來源的值\n\t * 為 function 時:只在函式回傳 true 時保留原有值(不取代)\n\t *\n\t * Control when to update values in target\n\t * When true: Preserve existing values (don't replace), only use source's value when target key value is undefined\n\t * When function: Only preserve existing values (don't replace) when function returns true\n\t *\n\t * @note 重要說明 / Important Note:\n\t * 當 keyValueUpsertMode 為 true 時,表示「不取代」模式:\n\t * - 如果目標值不是 undefined,則保留目標的原始值\n\t * - 只有當目標值是 undefined 時,才會使用來源的值\n\t * 這包括 null、0、false、空字串等 falsy 值,都會被保留\n\t *\n\t * When keyValueUpsertMode is true, it means \"don't replace\" mode:\n\t * - If target value is not undefined, preserve the original target value\n\t * - Only use source's value when target value is undefined\n\t * This includes falsy values like null, 0, false, empty string, which are all preserved\n\t *\n\t * @note 升級說明 / Upgrade Note:\n\t * 此選項為 `keyValueOrMode` 的升級版本,解決了以下問題:\n\t * - 使用 `??` 取代 `||` 運算子,避免 falsy 值(如 `0`、`''`、`false`)被錯誤處理\n\t * - 支援自訂函式,可根據條件靈活決定是否保留目標的值\n\t * - 行為更直觀,true 時明確表示「保留原有值」\n\t *\n\t * This option is an upgraded version of `keyValueOrMode`, solving the following issues:\n\t * - Uses `??` instead of `||` operator to avoid incorrect handling of falsy values (like `0`, `''`, `false`)\n\t * - Supports custom functions for flexible conditional logic\n\t * - More intuitive behavior, true clearly means \"preserve existing values\"\n\t *\n\t * @example\n\t * const target = { name: 'Alice', age: undefined, count: 0, email: null };\n\t * const source = { name: 'Bob', age: 30, count: 5, email: 'bob@example.com' };\n\t * // keyValueUpsertMode: true 時 / when keyValueUpsertMode: true\n\t * // 結果: { name: 'Alice', age: 30, count: 0, email: null }\n\t * // name: 保留目標值 'Alice'(不是 undefined)\n\t * // age: 使用來源值 30(目標值是 undefined)\n\t * // count: 保留目標值 0(不是 undefined)\n\t * // email: 保留目標值 null(不是 undefined)\n\t *\n\t * @example\n\t * // 使用自訂函式 / Using custom function\n\t * keyValueUpsertMode: (value, options, tmpRuntimeTarget, tmpRuntimeData) => {\n\t * return tmpRuntimeTarget.target?.[tmpRuntimeTarget.key] !== undefined;\n\t * }\n\t */\n\tkeyValueUpsertMode?:\n\t\t| boolean\n\t\t| ((value: unknown, optionsRuntime?: IOptions, tmpRuntimeTarget?: ICache, tmpRuntimeData?: ITmpRuntimeData) => boolean);\n}\n\n/**\n * 檢查值是否為可合併物件 / Check if value is a mergeable object\n *\n * 這是一個便捷函式,包裝了 is-mergeable-object 模組\n * 用於快速判斷給定的值是否可以被 deepmerge 合併\n *\n * This is a convenience function that wraps the is-mergeable-object module\n * Used to quickly determine if a given value can be merged by deepmerge\n *\n * 可合併的類型通常包括:\n * - 普通物件(plain objects)\n * - 陣列(arrays)\n * - 不可合併的類型(如原始類型、函式、Date 等)會回傳 false\n *\n * Mergeable types typically include:\n * - Plain objects\n * - Arrays\n * - Non-mergeable types (such as primitives, functions, Date, etc.) return false\n *\n * @param value - 要檢查的值 / Value to check\n * @returns 是否可合併(true 表示可以進行深度合併)/ Whether mergeable (true means deep merge can be performed)\n *\n * @example\n * isMergeable({}) // 回傳 / returns true\n * isMergeable([]) // 回傳 / returns true\n * isMergeable('string') // 回傳 / returns false\n * isMergeable(123) // 回傳 / returns false\n * isMergeable(new Date()) // 回傳 / returns false\n */\nexport function isMergeable(value: any): boolean\n{\n\treturn isMergeableObject(value)\n}\n\n/**\n * 可合併物件標記符號 / Mergeable object marker symbol\n *\n * 全域符號,用於在物件上標記是否為可合併物件\n * 這是一個全域可共享的 Symbol,可跨模組使用\n *\n * Global symbol used to mark whether an object is mergeable\n * This is a globally shareable Symbol that can be used across modules\n *\n * 用法 / Usage:\n * ```typescript\n * const obj = { name: 'test' };\n * obj[SYMBOL_IS_MERGEABLE] = true; // 標記為可合併 / Mark as mergeable\n * obj[SYMBOL_IS_MERGEABLE] = false; // 標記為不可合併 / Mark as not mergeable\n * ```\n *\n * 優勢 / Advantages:\n * - 可以自訂物件的可合併性\n * - 可以自訂物件的可合併性\n * - 避免與物件原有屬性衝突\n * - Avoid conflicts with object's original properties\n */\nconst SYMBOL_IS_MERGEABLE = Symbol.for('SYMBOL_IS_MERGEABLE');\n\nexport { SYMBOL_IS_MERGEABLE }\n\n/**\n * 建立新的執行時資料 / Create new runtime data\n *\n * 在開始新的合併操作時呼叫此函式建立初始的 tmpRuntimeData\n * 初始狀態為根層級,level 為 0,paths 為空陣列\n *\n * Called when starting a new merge operation to create initial tmpRuntimeData\n * Initial state is root level, level is 0, paths is empty array\n *\n * @template R - root 物件的類型\n * @template T - parent 物件的類型(預設與 R 相同)\n * @param root - 初始的 destination 物件(將作為 root 傳遞)\n * @returns 初始化的 tmpRuntimeData\n *\n * @example\n * const data = _newTmpRuntimeData({});\n * // data.level === 0\n * // data.paths === []\n * // data.root === {}\n * // data.parent === {}\n * // data.key === undefined\n */\nexport function _newTmpRuntimeData<R extends ITmpRuntimeData[\"root\"], T extends IAnyRecord = R>(root: R)\n{\n\tconst tmpRuntimeData = {\n\t\tlevel: 0,\n\t\tpaths: [],\n\t\troot: root,\n\t\tparent: root,\n\t\tkey: undefined,\n\t}\n\treturn tmpRuntimeData as any as ITmpRuntimeData<T, R>;\n}\n\n/**\n * 合併多個物件 / Merge multiple objects\n *\n * 將陣列中的所有物件依序合併成單一物件\n * 這是 deepmerge 的陣列版本,適用於合併多個物件\n *\n * Merges all objects in the array into a single object sequentially\n * This is the array version of deepmerge, suitable for merging multiple objects\n *\n * 處理邏輯 / Processing logic:\n * 1. 驗證輸入參數是否為陣列\n * 2. 使用 reduce 依序合併所有物件\n * 3. 初始值為空物件,每次迭代都會與下一個物件合併\n *\n * @param array - 要合併的物件陣列 / Array of objects to merge\n * @param optionsArgument - 合併選項 / Merge options\n * @returns 合併後的物件 / Merged object\n * @throws 若第一個參數不是陣列,則拋出錯誤 / Throws error if first argument is not an array\n *\n * @example\n * deepmergeAll([{ a: 1 }, { b: 2 }, { c: 3 }])\n * // 回傳 / returns { a: 1, b: 2, c: 3 }\n */\nexport function deepmergeAll<T1, T2 = any>(array: [T1, ...T2[]], optionsArgument?: IOptions): IDeepmergeResult<T1, T2>\nexport function deepmergeAll<T1>(array: T1[], optionsArgument?: IOptions): T1\nexport function deepmergeAll<T>(array: any[], optionsArgument?: IOptions): T\n{\n\t/**\n\t * 驗證輸入參數是否為陣列\n\t * 若不是陣列則拋出錯誤\n\t * Validate input parameter is an array\n\t * Throw error if not an array\n\t */\n\tif (!Array.isArray(array))\n\t{\n\t\tthrow new Error('first argument should be an array')\n\t}\n\n\t/**\n\t * 使用 reduce 依序合併所有物件\n\t * 初始值為空物件,每次迭代都會與下一個物件合併\n\t * Use reduce to sequentially merge all objects\n\t * Initial value is empty object, each iteration merges with next object\n\t */\n\t// @ts-ignore\n\treturn array.reduce(function (prev, next)\n\t{\n\t\treturn deepmerge(prev, next, optionsArgument)\n\t}, {})\n}\n\nexport { deepmergeAll as all }\n\nexport default deepmerge\n\n/**\n * CommonJS 環境兼容性設定\n * CommonJS environment compatibility settings\n *\n * 為非 ESM 環境添加必要的屬性:\n * - __esModule: 標記為 ES 模組\n * - deepmerge: 指向 deepmerge 函式本身\n * - default: 指向預設匯出的 deepmerge\n * - isMergeable: 便捷函式\n * - SYMBOL_IS_MERGEABLE: 符號匯出\n * - deepmergeAll: 所有物件合併函式\n * - all: deepmergeAll 的別名\n * - _isMergeableObject: 內部可合併判斷函式\n *\n * Adds necessary properties for non-ESM environments:\n * - __esModule: Mark as ES module\n * - deepmerge: Point to deepmerge function itself\n * - default: Point to default exported deepmerge\n * - isMergeable: Convenience function\n * - SYMBOL_IS_MERGEABLE: Symbol export\n * - deepmergeAll: All objects merge function\n * - all: Alias for deepmergeAll\n * - _isMergeableObject: Internal mergeable check function\n */\n// @ts-ignore\nif (process.env.TSDX_FORMAT !== 'esm')\n{\n\t/**\n\t * CommonJS 環境兼容性處理\n\t * 為模組添加必要的屬性以支援 CommonJS 匯入方式\n\t * CommonJS environment compatibility handling\n\t * Add necessary properties to support CommonJS import methods\n\t *\n\t * 例如:const deepmerge = require('deepmerge-plus')\n\t * 或 :import * as deepmerge from 'deepmerge-plus'\n\t */\n\n\t/** 標記為 ES 模組 / Mark as ES module */\n\tObject.defineProperty(deepmerge, \"__esModule\", { value: true });\n\n\t/** 匯出 deepmerge 函式 / Export deepmerge function */\n\tObject.defineProperty(deepmerge, 'deepmerge', { value: deepmerge });\n\n\t/** 設定預設匯出 / Set default export */\n\tObject.defineProperty(deepmerge, 'default', { value: deepmerge });\n\n\t/** 匯出便捷函式 isMergeable / Export convenience function isMergeable */\n\tObject.defineProperty(deepmerge, 'isMergeable', { value: isMergeable });\n\n\t/** 匯出可合併物件標記符號 / Export mergeable object marker symbol */\n\tObject.defineProperty(deepmerge, 'SYMBOL_IS_MERGEABLE', { value: SYMBOL_IS_MERGEABLE });\n\n\t/** 匯出 deepmergeAll 函式 / Export deepmergeAll function */\n\tObject.defineProperty(deepmerge, 'deepmergeAll', { value: deepmergeAll });\n\n\t/** 匯出 all 別名 / Export all alias */\n\tObject.defineProperty(deepmerge, 'all', { value: deepmergeAll });\n\n\t/** 匯出內部函式 _isMergeableObject / Export internal function _isMergeableObject */\n\tObject.defineProperty(deepmerge, '_isMergeableObject', { value: _isMergeableObject });\n}\n"],"names":["emptyTarget","val","Array","isArray","_shouldClone","optionsRuntime","clone","_defaultCheckShouldNotUpsertValue","value","tmpRuntimeTarget","tmpRuntimeData","_tmpRuntimeTarget$tar","targetValue","target","key","shouldNotUpsertValue","_isUndefined","cloneUnlessOtherwiseSpecified","bool","_isMergeableObject","ret","deepmerge","keyValueOrMode","destination","source","keyValueUpsertMode","_tmpRuntimeTarget$tar2","upsertValue","_isNull","_isNullOrUndefined","optionsArgument","_optionsArgument$isMe","isMergeableObject","call","SYMBOL_IS_MERGEABLE","defaultArrayMerge","_newTmpRuntimeData","level","root","parent","concat","reduce","element","index","paths","mergeObject","Object","keys","forEach","_handleOptions","options","sourceIsArray","targetIsArray","sourceAndTargetTypesMatch","_options$arrayMerge","arrayMerge","isMergeable","Symbol","for","undefined","deepmergeAll","array","Error","prev","next","defineProperty"],"mappings":"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"}