UNPKG

circ-json

Version:
88 lines (84 loc) 2.76 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); // This is a port of json-decycle. It has a few bug fixes and is in ts. const isObject = (value) => typeof value === 'object' && value != null && !(value instanceof Boolean) && !(value instanceof Date) && !(value instanceof Number) && !(value instanceof RegExp) && !(value instanceof String); const toPointer = (parts) => '#' + parts.map(part => String(part).replace(/~/g, '~0').replace(/\//g, '~1')).join('/'); const sym = Symbol('$ref'); function decycle() { const paths = new WeakMap(); return function replacer(key, value) { if (key === '$ref' && (typeof value === "string" || (value instanceof String && !value[sym])) && value.startsWith("#")) return "#" + value; if (isObject(value)) { const seen = paths.has(value); if (seen) { const $ref = new String(toPointer(paths.get(value))); $ref[sym] = true; return { $ref }; } else { paths.set(value, [...paths.get(this) ?? [], key]); } } return value; }; } function retrocycle() { const parents = new WeakMap(); const keys = new WeakMap(); const refs = new Set(); /** * @param {{ $ref: string }} ref * @this object */ function dereference(ref) { const parts = ref.$ref.slice(1).split('/'); let key, parent, value = this; for (var i = 0; i < parts.length; i++) { key = parts[i].replace(/~1/g, '/').replace(/~0/g, '~'); value = value[key]; } parent = parents.get(ref); parent[keys.get(ref)] = value; } return function reviver(key, value) { if (key === '$ref' && typeof value === "string") { if (value.startsWith("##")) return value.slice(1); else if (value.startsWith("#")) { refs.add(this); return value; } } if (isObject(value)) { var isRoot = key === '' && Object.keys(this).length === 1; if (isRoot) { refs.forEach(dereference, this); } else { parents.set(value, this); keys.set(value, key); } } return value; }; } function parse(str) { if (str === undefined) return undefined; return JSON.parse(str, retrocycle()); } function stringify(obj, space) { return JSON.stringify(obj, decycle(), space); } exports.decycle = decycle; exports.parse = parse; exports.retrocycle = retrocycle; exports.stringify = stringify; //# sourceMappingURL=circJson.js.map