fix(core): Handle Date and RegExp objects in AugmentObject (#5809)

This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™
2023-03-29 21:36:56 +02:00
committed by GitHub
parent 4f91525022
commit 6c35ffa82c
2 changed files with 34 additions and 27 deletions

View File

@@ -1,6 +1,24 @@
import type { IDataObject } from './Interfaces'; import type { IDataObject } from './Interfaces';
import util from 'util'; import util from 'util';
function augment<T>(value: T): T {
if (
typeof value !== 'object' ||
value === null ||
util.types.isProxy(value) ||
value instanceof RegExp
)
return value;
if (value instanceof Date) return new Date(value.valueOf()) as T;
// eslint-disable-next-line @typescript-eslint/no-use-before-define
if (Array.isArray(value)) return augmentArray(value) as T;
// eslint-disable-next-line @typescript-eslint/no-use-before-define
return augmentObject(value) as T;
}
export function augmentArray<T>(data: T[]): T[] { export function augmentArray<T>(data: T[]): T[] {
let newData: unknown[] | undefined = undefined; let newData: unknown[] | undefined = undefined;
@@ -17,24 +35,12 @@ export function augmentArray<T>(data: T[]): T[] {
}, },
get(target, key: string, receiver): unknown { get(target, key: string, receiver): unknown {
const value = Reflect.get(newData !== undefined ? newData : target, key, receiver) as unknown; const value = Reflect.get(newData !== undefined ? newData : target, key, receiver) as unknown;
const newValue = augment(value);
if (typeof value === 'object') { if (newValue !== value) {
if (value === null || util.types.isProxy(value)) {
return value;
}
newData = getData(); newData = getData();
Reflect.set(newData, key, newValue);
if (Array.isArray(value)) { return newValue;
Reflect.set(newData, key, augmentArray(value));
} else {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
Reflect.set(newData, key, augmentObject(value as IDataObject));
}
return Reflect.get(newData, key);
} }
return value; return value;
}, },
getOwnPropertyDescriptor(target, key) { getOwnPropertyDescriptor(target, key) {
@@ -83,18 +89,13 @@ export function augmentObject<T extends object>(data: T): T {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const value = Reflect.get(target, key, receiver); const value = Reflect.get(target, key, receiver);
const newValue = augment(value);
if (value !== null && typeof value === 'object') { if (newValue !== value) {
if (Array.isArray(value)) { Object.assign(newData, { [key]: newValue });
newData[key] = augmentArray(value); return newValue;
} else {
newData[key] = augmentObject(value as IDataObject);
}
return newData[key];
} }
return value as string; return value;
}, },
deleteProperty(target, key: string) { deleteProperty(target, key: string) {
if (key in newData) { if (key in newData) {

View File

@@ -193,11 +193,15 @@ describe('AugmentObject', () => {
describe('augmentObject', () => { describe('augmentObject', () => {
test('should work with simple values on first level', () => { test('should work with simple values on first level', () => {
const date = new Date(1680089084200);
const regexp = new RegExp('^test$', 'ig');
const originalObject: IDataObject = { const originalObject: IDataObject = {
1: 11, 1: 11,
2: '22', 2: '22',
a: 111, a: 111,
b: '222', b: '222',
d: date,
r: regexp,
}; };
const copyOriginal = JSON.parse(JSON.stringify(originalObject)); const copyOriginal = JSON.parse(JSON.stringify(originalObject));
@@ -221,7 +225,7 @@ describe('AugmentObject', () => {
augmentedObject.c = 3; augmentedObject.c = 3;
expect(originalObject).toEqual(copyOriginal); expect({ ...originalObject, d: date.toJSON(), r: {} }).toEqual(copyOriginal);
expect(augmentedObject).toEqual({ expect(augmentedObject).toEqual({
1: 911, 1: 911,
@@ -229,6 +233,8 @@ describe('AugmentObject', () => {
a: 9111, a: 9111,
b: '9222', b: '9222',
c: 3, c: 3,
d: date,
r: regexp,
}); });
}); });