fix(core): AugmentObject should check for own propeties correctly (#12534)

This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™ 2025-01-09 13:47:42 +01:00 committed by GitHub
parent 5f1adefca7
commit 0cdf393743
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 29 additions and 7 deletions

View file

@ -2,6 +2,9 @@ import type { IDataObject } from './Interfaces';
const defaultPropertyDescriptor = Object.freeze({ enumerable: true, configurable: true }); const defaultPropertyDescriptor = Object.freeze({ enumerable: true, configurable: true });
// eslint-disable-next-line @typescript-eslint/unbound-method
const { hasOwnProperty } = Object.prototype;
const augmentedObjects = new WeakSet<object>(); const augmentedObjects = new WeakSet<object>();
function augment<T>(value: T): T { function augment<T>(value: T): T {
@ -84,7 +87,7 @@ export function augmentObject<T extends object>(data: T): T {
return undefined; return undefined;
} }
if (newData[key] !== undefined) { if (hasOwnProperty.call(newData, key)) {
return newData[key]; return newData[key];
} }
@ -102,11 +105,11 @@ export function augmentObject<T extends object>(data: T): T {
return value; return value;
}, },
deleteProperty(target, key: string) { deleteProperty(_target, key: string) {
if (key in newData) { if (hasOwnProperty.call(newData, key)) {
delete newData[key]; delete newData[key];
} }
if (key in target) { if (hasOwnProperty.call(data, key)) {
deletedProperties.add(key); deletedProperties.add(key);
} }
@ -131,9 +134,10 @@ export function augmentObject<T extends object>(data: T): T {
return true; return true;
}, },
has(target, key) { has(_target, key) {
if (deletedProperties.has(key)) return false; if (deletedProperties.has(key)) return false;
return Reflect.has(newData, key) || Reflect.has(target, key); const target = hasOwnProperty.call(newData, key) ? newData : data;
return Reflect.has(target, key);
}, },
ownKeys(target) { ownKeys(target) {
const originalKeys = Reflect.ownKeys(target); const originalKeys = Reflect.ownKeys(target);
@ -145,7 +149,8 @@ export function augmentObject<T extends object>(data: T): T {
getOwnPropertyDescriptor(_target, key) { getOwnPropertyDescriptor(_target, key) {
if (deletedProperties.has(key)) return undefined; if (deletedProperties.has(key)) return undefined;
return Object.getOwnPropertyDescriptor(key in newData ? newData : data, key); const target = hasOwnProperty.call(newData, key) ? newData : data;
return Object.getOwnPropertyDescriptor(target, key);
}, },
}); });

View file

@ -572,5 +572,22 @@ describe('AugmentObject', () => {
expect('z' in augmentedObject.x).toBe(true); expect('z' in augmentedObject.x).toBe(true);
expect('y' in augmentedObject.x).toBe(true); expect('y' in augmentedObject.x).toBe(true);
}); });
test('should ignore non-enumerable keys', () => {
const originalObject: { toString?: string } = { toString: '123' };
const augmentedObject = augmentObject(originalObject);
expect('toString' in augmentedObject).toBe(true);
expect(Object.keys(augmentedObject)).toEqual(['toString']);
expect(Object.getOwnPropertyDescriptor(augmentedObject, 'toString')?.value).toEqual(
originalObject.toString,
);
expect(augmentedObject.toString).toEqual(originalObject.toString);
augmentedObject.toString = '456';
expect(augmentedObject.toString).toBe('456');
delete augmentedObject.toString;
expect(augmentedObject.toString).toBeUndefined();
});
}); });
}); });