@finnair/path
Version:
Simple object path as array of strings and numbers
63 lines (62 loc) • 2.11 kB
JavaScript
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;
}