Skip to content

Commit fd105f4

Browse files
ardatantheguild-botgithub-actions[bot]
authored
fix(mergeDeep): handle undefined sources correctly (#7012)
* chore(release): update monorepo packages versions (#6826) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * fix(mergeDeep): handle `undefined` sources correctly * Fix * Major * .. --------- Co-authored-by: TheGuildBot <[email protected]> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 3f52824 commit fd105f4

File tree

3 files changed

+35
-3
lines changed

3 files changed

+35
-3
lines changed

.changeset/chilly-icons-guess.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
'@graphql-tools/utils': patch
3+
---
4+
5+
Fix the bug in `mergeDeep`;
6+
7+
The following inputs and outputs are corrected;
8+
9+
- `mergeDeep([{a:2}, undefined])` - Any nullish values should be ignored so it should return `{a:2}`
10+
- `mergeDeep([])` - no sources should return `undefined`
11+
- `mergeDeep([undefined])` - no sources should return `undefined`

packages/utils/src/mergeDeep.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ export function mergeDeep<S extends any[]>(
1212
respectArrays = false,
1313
respectArrayLength = false,
1414
): UnboxIntersection<UnionToIntersection<BoxedTupleTypes<S>>> & any {
15+
if (sources.length === 0) {
16+
return;
17+
}
18+
if (sources.length === 1) {
19+
return sources[0];
20+
}
1521
let expectedLength: number | undefined;
1622
let allArrays = true;
1723
const areArraysInTheSameLength = sources.every(source => {
@@ -46,14 +52,17 @@ export function mergeDeep<S extends any[]>(
4652
let firstObjectSource: any;
4753
if (respectPrototype) {
4854
firstObjectSource = sources.find(source => isObject(source));
49-
if (output == null) {
50-
output = {};
51-
}
5255
if (firstObjectSource) {
56+
if (output == null) {
57+
output = {};
58+
}
5359
Object.setPrototypeOf(output, Object.create(Object.getPrototypeOf(firstObjectSource)));
5460
}
5561
}
5662
for (const source of sources) {
63+
if (source == null) {
64+
continue;
65+
}
5766
if (isObject(source)) {
5867
if (firstObjectSource) {
5968
const outputPrototype = Object.getPrototypeOf(output);

packages/utils/tests/mergeDeep.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,16 @@ describe('mergeDeep', () => {
7272
const b = { options: ['$A', '$B'] };
7373
expect(mergeDeep([a, b], undefined, true, true)).toEqual({ options: ['$A', '$B'] });
7474
});
75+
76+
it('filters nullish values', () => {
77+
expect(mergeDeep([{ a: 'dsa' }, { a: 'dd', b: 1 }, undefined])).toEqual({ a: 'dd', b: 1 });
78+
});
79+
80+
it('respects empty objects', () => {
81+
expect(mergeDeep([{}])).toEqual({});
82+
});
83+
84+
it('returns undefined when an empty sources array passed', () => {
85+
expect(mergeDeep([])).toEqual(undefined);
86+
});
7587
});

0 commit comments

Comments
 (0)