-
-
Notifications
You must be signed in to change notification settings - Fork 29
/
jsonpointer.js
105 lines (90 loc) · 2.49 KB
/
jsonpointer.js
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*
This file is copied from https://github.com/janl/node-jsonpointer
because I was not able to use it directly from the jsonpointer package.
*/
var hasExcape = /~/;
var escapeMatcher = /~[01]/g;
function escapeReplacer(m) {
switch (m) {
case "~1":
return "/";
case "~0":
return "~";
}
throw new Error("Invalid tilde escape: " + m);
}
function untilde(str) {
if (!hasExcape.test(str)) return str;
return str.replace(escapeMatcher, escapeReplacer);
}
function setter(obj, pointer, value) {
var part;
var hasNextPart;
for (var p = 1, len = pointer.length; p < len; ) {
part = untilde(pointer[p++]);
hasNextPart = len > p;
if (typeof obj[part] === "undefined") {
// support setting of /-
if (Array.isArray(obj) && part === "-") {
part = obj.length;
}
// support nested objects/array when setting values
if (hasNextPart) {
if ((pointer[p] !== "" && pointer[p] < Infinity) || pointer[p] === "-")
obj[part] = [];
else obj[part] = {};
}
}
if (!hasNextPart) break;
obj = obj[part];
}
var oldValue = obj[part];
if (value === undefined) delete obj[part];
else obj[part] = value;
return oldValue;
}
function compilePointer(pointer) {
if (typeof pointer === "string") {
pointer = pointer.split("/");
if (pointer[0] === "") return pointer;
throw new Error("Invalid JSON pointer.");
} else if (Array.isArray(pointer)) {
return pointer;
}
throw new Error("Invalid JSON pointer.");
}
function get(obj, pointer) {
if (typeof obj !== "object") throw new Error("Invalid input object.");
pointer = compilePointer(pointer);
var len = pointer.length;
if (len === 1) return obj;
for (var p = 1; p < len; ) {
obj = obj[untilde(pointer[p++])];
if (len === p) return obj;
if (typeof obj !== "object") return undefined;
}
}
function set(obj, pointer, value) {
if (typeof obj !== "object") throw new Error("Invalid input object.");
pointer = compilePointer(pointer);
if (pointer.length === 0) throw new Error("Invalid JSON pointer for set.");
return setter(obj, pointer, value);
}
function compile(pointer) {
var compiled = compilePointer(pointer);
return {
get: function (object) {
return get(object, compiled);
},
set: function (object, value) {
return set(object, compiled, value);
}
};
}
if (typeof window === "undefined" || navigator.userAgent.includes("jsdom")) {
module.exports = {
get,
set,
compile
};
}