aboutsummaryrefslogtreecommitdiff
path: root/src/decycler/decycler.js
blob: 7fb8a45c7c0a0c255d4b636820008d22134f0391 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
///
///  this is a modified copy of the npm project: https://www.npmjs.com/package/json-decycle
///  the original code is used as replacer when stringifying JSON objects that have cycles.
///  However, we want an additional replacer that stringifies Dash Fields and Docs in a custom way.
///  So this modified code allows for a custom replacer to be added to this object that will run before this replacer
///

const g = e => typeof e === 'object' && e != null && !(e instanceof Boolean) && !(e instanceof Date) && !(e instanceof Number) && !(e instanceof RegExp) && !(e instanceof String);
const b = e => String('#') + e.map(t => String(t).replace(/~/g, '~0').replace(/\//g, '~1')).join('/');
// eslint-disable-next-line node/no-unsupported-features/es-syntax
export function decycle(replacer) {
    const e = new WeakMap();
    return function (n, rr) {
        const r = replacer(n, rr);
        if (n !== '$ref' && g(r)) {
            if (e.has(r)) return { $ref: b(e.get(r)) };
            e.set(r, [...(e.get(this) === undefined ? [] : e.get(this)), n]);
        }
        return r;
    };
}
// eslint-disable-next-line node/no-unsupported-features/es-syntax
export function retrocycle() {
    const e = new WeakMap();
    const t = new WeakMap();
    const n = new Set();
    function r(o) {
        const c = o.$ref.slice(1).split('/');
        let s;
        let a = this;
        // eslint-disable-next-line no-plusplus
        for (let p = 0; p < c.length; p++) {
            s = c[p].replace(/~1/g, '/').replace(/~0/g, '~');
            a = a[s];
        }
        const f = e.get(o);
        f[t.get(o)] = a;
    }
    return function (c, s) {
        if (c === '$ref') n.add(this);
        else if (g(s)) {
            const f = c === '' && Object.keys(this).length === 1;
            if (f) n.forEach(r, this);
            else {
                e.set(s, this);
                t.set(s, c);
            }
        }
        return s;
    };
}