aboutsummaryrefslogtreecommitdiff
path: root/src/decycler/decycler.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/decycler/decycler.js')
-rw-r--r--src/decycler/decycler.js51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/decycler/decycler.js b/src/decycler/decycler.js
new file mode 100644
index 000000000..7fb8a45c7
--- /dev/null
+++ b/src/decycler/decycler.js
@@ -0,0 +1,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;
+ };
+}