mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-21 01:07:46 +00:00
Sync upstream Gemini-CLI v0.8.2 (#838)
This commit is contained in:
90
packages/cli/src/utils/deepMerge.ts
Normal file
90
packages/cli/src/utils/deepMerge.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { MergeStrategy } from '../config/settingsSchema.js';
|
||||
|
||||
export type Mergeable =
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null
|
||||
| undefined
|
||||
| object
|
||||
| Mergeable[];
|
||||
|
||||
export type MergeableObject = Record<string, Mergeable>;
|
||||
|
||||
function isPlainObject(item: unknown): item is MergeableObject {
|
||||
return !!item && typeof item === 'object' && !Array.isArray(item);
|
||||
}
|
||||
|
||||
function mergeRecursively(
|
||||
target: MergeableObject,
|
||||
source: MergeableObject,
|
||||
getMergeStrategyForPath: (path: string[]) => MergeStrategy | undefined,
|
||||
path: string[] = [],
|
||||
) {
|
||||
for (const key of Object.keys(source)) {
|
||||
if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
|
||||
continue;
|
||||
}
|
||||
const newPath = [...path, key];
|
||||
const srcValue = source[key];
|
||||
const objValue = target[key];
|
||||
const mergeStrategy = getMergeStrategyForPath(newPath);
|
||||
|
||||
if (mergeStrategy === MergeStrategy.SHALLOW_MERGE && objValue && srcValue) {
|
||||
const obj1 =
|
||||
typeof objValue === 'object' && objValue !== null ? objValue : {};
|
||||
const obj2 =
|
||||
typeof srcValue === 'object' && srcValue !== null ? srcValue : {};
|
||||
target[key] = { ...obj1, ...obj2 };
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Array.isArray(objValue)) {
|
||||
const srcArray = Array.isArray(srcValue) ? srcValue : [srcValue];
|
||||
if (mergeStrategy === MergeStrategy.CONCAT) {
|
||||
target[key] = objValue.concat(srcArray);
|
||||
continue;
|
||||
}
|
||||
if (mergeStrategy === MergeStrategy.UNION) {
|
||||
target[key] = [...new Set(objValue.concat(srcArray))];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (isPlainObject(objValue) && isPlainObject(srcValue)) {
|
||||
mergeRecursively(objValue, srcValue, getMergeStrategyForPath, newPath);
|
||||
} else if (isPlainObject(srcValue)) {
|
||||
target[key] = {};
|
||||
mergeRecursively(
|
||||
target[key] as MergeableObject,
|
||||
srcValue,
|
||||
getMergeStrategyForPath,
|
||||
newPath,
|
||||
);
|
||||
} else {
|
||||
target[key] = srcValue;
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
export function customDeepMerge(
|
||||
getMergeStrategyForPath: (path: string[]) => MergeStrategy | undefined,
|
||||
...sources: MergeableObject[]
|
||||
): MergeableObject {
|
||||
const result: MergeableObject = {};
|
||||
|
||||
for (const source of sources) {
|
||||
if (source) {
|
||||
mergeRecursively(result, source, getMergeStrategyForPath);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
Reference in New Issue
Block a user