-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathjson-filter.js
More file actions
58 lines (50 loc) · 1.63 KB
/
json-filter.js
File metadata and controls
58 lines (50 loc) · 1.63 KB
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
52
53
54
55
56
57
58
import * as ptr from "json-ptr";
function arrayOrObject(ob, arrayFunc, obFunc) {
if (Array.isArray(ob)) {
// ob is an array
// perform the operation for each array element and return the array
return ob.map(arrayFunc);
}
// ob is not array, perform operation once on the object
return obFunc();
}
function performOp(ob, op) {
// if ob is undefined return ob
if (!ob) return ob;
const { $ref } = op;
if ($ref) {
// existance of $ref implies that we have to return the value in that path directly
// perform different operations depending on ob being array or object
return arrayOrObject(
ob,
(el) => $ref === '#/' ? el : ptr.JsonPointer.get(el, $ref),
() => $ref === '#/' ? ob : ptr.JsonPointer.get(ob, $ref)
);
} else {
// have to return object
function returnNewOb(ob) {
const newOb = {};
Object.keys(op).forEach((key) => {
const $ref = op[key].$ref || {};
// calculate actual prop
let prop = "";
if (key.charAt(0) === "#") {
// if key starts with #, then it's a relative path to the field containing the actual key
prop = key === "#/" ? ob : ptr.JsonPointer.get(ob, key);
} else prop = key;
// assign new prop value
newOb[prop] = $ref === "#/" ? ob : ptr.JsonPointer.get(ob, $ref);
});
return newOb;
}
// perform different operations depending on ob being array or object
return arrayOrObject(
ob,
(el) => returnNewOb(el),
() => returnNewOb(ob)
);
}
}
export default function (jsonOb, op) {
return op.reduce((ac, cr) => performOp(ac, cr), jsonOb);
}