refactor(cli): fix settings merging so that settings using the new json format take priority over ones using the old format (#15116)

This commit is contained in:
Jacob Richman
2025-12-15 19:59:24 -08:00
committed by GitHub
parent 2995af6a21
commit 5ea5107d05
5 changed files with 276 additions and 3 deletions

View File

@@ -199,4 +199,28 @@ describe('customDeepMerge', () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
expect((result as any)['hooks']['disabled']).toEqual(['hook-a', 'hook-b']);
});
it('should overwrite primitive with object', () => {
const target = { a: 1 };
const source = { a: { b: 2 } };
const getMergeStrategy = () => undefined;
const result = customDeepMerge(getMergeStrategy, target, source);
expect(result).toEqual({ a: { b: 2 } });
});
it('should overwrite object with primitive', () => {
const target = { a: { b: 2 } };
const source = { a: 1 };
const getMergeStrategy = () => undefined;
const result = customDeepMerge(getMergeStrategy, target, source);
expect(result).toEqual({ a: 1 });
});
it('should not overwrite with undefined', () => {
const target = { a: 1 };
const source = { a: undefined };
const getMergeStrategy = () => undefined;
const result = customDeepMerge(getMergeStrategy, target, source);
expect(result).toEqual({ a: 1 });
});
});

View File

@@ -28,11 +28,16 @@ function mergeRecursively(
path: string[] = [],
) {
for (const key of Object.keys(source)) {
if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
// JSON.parse can create objects with __proto__ as an own property.
// We must skip it to prevent prototype pollution.
if (key === '__proto__') {
continue;
}
const srcValue = source[key];
if (srcValue === undefined) {
continue;
}
const newPath = [...path, key];
const srcValue = source[key];
const objValue = target[key];
const mergeStrategy = getMergeStrategyForPath(newPath);