fix(core): Do not mark duplicates as circular references in jsonStringify (#5789)

* fix(core): jsonStringify should not mark duplicates as circular references

* not mark duplicates as circular references in the code node as well
This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™
2023-03-27 16:22:59 +02:00
committed by GitHub
parent f15f4bdcf2
commit 18efaf397a
3 changed files with 22 additions and 19 deletions

View File

@@ -64,27 +64,24 @@ export const jsonParse = <T>(jsonString: string, options?: JSONParseOptions<T>):
type JSONStringifyOptions = {
replaceCircularRefs?: boolean;
circularRefReplacement?: string;
};
const getReplaceCircularReferencesFn = (options: JSONStringifyOptions) => {
const knownObjects = new WeakSet();
return (key: any, value: any) => {
if (typeof value === 'object' && value !== null) {
if (knownObjects.has(value)) {
return options?.circularRefReplacement ?? '[Circular Reference]';
}
knownObjects.add(value);
const replaceCircularReferences = <T>(value: T, knownObjects = new WeakSet()): T => {
if (value && typeof value === 'object') {
if (knownObjects.has(value)) return '[Circular Reference]' as T;
knownObjects.add(value);
const copy = (Array.isArray(value) ? [] : {}) as T;
for (const key in value) {
copy[key] = replaceCircularReferences(value[key], knownObjects);
}
return value;
};
knownObjects.delete(value);
return copy;
}
return value;
};
export const jsonStringify = (obj: unknown, options: JSONStringifyOptions = {}): string => {
const replacer = options?.replaceCircularRefs
? getReplaceCircularReferencesFn(options)
: undefined;
return JSON.stringify(obj, replacer);
return JSON.stringify(options?.replaceCircularRefs ? replaceCircularReferences(obj) : obj);
};
export const sleep = async (ms: number): Promise<void> =>

View File

@@ -30,6 +30,14 @@ describe('jsonStringify', () => {
'{"a":1,"b":2,"c":"[Circular Reference]"}',
);
});
it('should not detect duplicates as circular references', () => {
const y = { z: 5 };
const x = [y, y, { y }];
expect(jsonStringify(x, { replaceCircularRefs: true })).toEqual(
'[{"z":5},{"z":5},{"y":{"z":5}}]',
);
});
});
describe('deepCopy', () => {