UNPKG

@finnair/path

Version:
63 lines (62 loc) 2.11 kB
export function jsonClone(input, replacer) { return _jsonClone('', { '': input }, replacer); } function _jsonClone(key, holder, replacer) { const value = _replaceValue(key, holder, replacer); if (value && typeof value === 'object') { let clone; if (Array.isArray(value)) { clone = []; for (let i = 0; i < value.length; i++) { clone[i] = _jsonClone(i.toString(), value, replacer) ?? null; } } else { clone = {}; if (Array.isArray(replacer)) { const len = replacer.length; for (let i = 0; i < len; i++) { const nestedKey = replacer[i].toString(); const keyValue = _jsonClone(nestedKey, value, replacer); // undefined is not included in the result if (keyValue !== undefined) { clone[nestedKey] = keyValue; } } } else { for (const nestedKey in value) { const keyValue = _jsonClone(nestedKey, value, replacer); // undefined is not included in the result if (keyValue !== undefined) { clone[nestedKey] = keyValue; } } } } return clone; } else { switch (typeof value) { // ignore function and symbol case 'function': case 'symbol': return undefined; // BigInt is not supported by JSON.stringify case 'bigint': throw new TypeError("BigInt value can't be serialized in JSON"); default: return value; } } } function _replaceValue(key, holder, replacer) { let value = holder[key]; if (typeof value?.toJSON === 'function') { value = value.toJSON(key); } if (typeof replacer === 'function') { value = replacer.call(holder, key, value); } return value; }