Skip to content

Commit 21e4565

Browse files
authored
fix(fast-html): ensure plain object properties are properly merged (#7233)
* fix: ensure plain object properties are deep merged * Change files
1 parent ad7e166 commit 21e4565

File tree

2 files changed

+36
-13
lines changed

2 files changed

+36
-13
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "prerelease",
3+
"comment": "fix: ensure plain object properties are deep merged",
4+
"packageName": "@microsoft/fast-html",
5+
"email": "863023+radium-v@users.noreply.github.com",
6+
"dependentChangeType": "none"
7+
}

packages/fast-html/src/components/utilities.ts

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1622,15 +1622,26 @@ export function deepEqual(obj1: any, obj2: any): boolean {
16221622
return true;
16231623
}
16241624

1625+
/**
1626+
* Checks if a value is a plain object (not an array, null, or other type).
1627+
*
1628+
* @param value - The value to check
1629+
* @returns True if the value is a plain object, false otherwise
1630+
*/
1631+
export function isPlainObject(value: any): value is Record<string, any> {
1632+
return !!value && typeof value === "object" && !Array.isArray(value);
1633+
}
1634+
16251635
/**
16261636
* Deeply merges the source object into the target object.
16271637
*
16281638
* @param target - The target object to merge into
16291639
* @param source - The source object to merge from
1630-
* @returns void
1640+
* @returns boolean indicating whether changes were made
16311641
*/
1632-
export function deepMerge(target: any, source: any): void {
1642+
export function deepMerge(target: any, source: any): boolean {
16331643
const hasOwn = Object.prototype.hasOwnProperty;
1644+
let hasChanges = false;
16341645

16351646
for (const key in source as any) {
16361647
if (!hasOwn.call(source, key)) {
@@ -1649,12 +1660,12 @@ export function deepMerge(target: any, source: any): void {
16491660
continue;
16501661
}
16511662

1652-
const isSourceArray = Array.isArray(sourceValue);
1663+
hasChanges = true;
16531664

1654-
if (isSourceArray) {
1665+
if (Array.isArray(sourceValue)) {
16551666
const isTargetArray = Array.isArray(targetValue);
16561667
const clonedItems = sourceValue.map((item: unknown) =>
1657-
item && typeof item === "object" ? { ...item } : item
1668+
isPlainObject(item) ? { ...item } : item
16581669
);
16591670

16601671
if (isTargetArray) {
@@ -1667,19 +1678,24 @@ export function deepMerge(target: any, source: any): void {
16671678
continue;
16681679
}
16691680

1670-
if (sourceValue && typeof sourceValue === "object") {
1671-
if (
1672-
!targetValue ||
1673-
typeof targetValue !== "object" ||
1674-
Array.isArray(targetValue)
1675-
) {
1676-
target[key] = {};
1681+
if (isPlainObject(sourceValue)) {
1682+
const targetIsObject = isPlainObject(targetValue);
1683+
const nextTarget = targetIsObject ? { ...targetValue } : {};
1684+
const nestedChanged = deepMerge(nextTarget, sourceValue);
1685+
1686+
if (!targetIsObject) {
1687+
target[key] = nextTarget;
1688+
continue;
16771689
}
16781690

1679-
deepMerge(target[key], sourceValue);
1691+
if (nestedChanged) {
1692+
target[key] = nextTarget;
1693+
}
16801694
continue;
16811695
}
16821696

16831697
target[key] = sourceValue;
16841698
}
1699+
1700+
return hasChanges;
16851701
}

0 commit comments

Comments
 (0)