Skip to content

Commit 3924cd9

Browse files
committed
Merge pull request #7 from hildjj/master
Modify to support draft-ietf-appsawg-json-pointer-08
2 parents c7ff6b0 + b1befb1 commit 3924cd9

4 files changed

Lines changed: 87 additions & 14 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# JSON Pointer for nodejs
22

3-
This is an implementation of [JSON Pointer](http://tools.ietf.org/html/draft-pbryan-zyp-json-pointer-00).
3+
This is an implementation of [JSON Pointer](http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-08).
44

55
## Usage
66

jsonpointer.js

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
11
var console = require("console");
22

3+
var untilde = function(str) {
4+
return str.replace(/~./g, function(m) {
5+
switch (m) {
6+
case "~0":
7+
return "~";
8+
case "~1":
9+
return "/";
10+
}
11+
throw("Invalid tilde escape: " + m);
12+
});
13+
}
14+
315
var traverse = function(obj, pointer, value) {
416
// assert(isArray(pointer))
5-
var part = unescape(pointer.shift());
17+
var part = untilde(pointer.shift());
618
if(typeof obj[part] === "undefined") {
719
throw("Value for pointer '" + pointer + "' not found.");
820
return;
921
}
10-
if(pointer.length != 0) { // keep traversin!
22+
if(pointer.length !== 0) { // keep traversin!
1123
return traverse(obj[part], pointer, value);
1224
}
1325
// we're done
@@ -30,26 +42,36 @@ var validate_input = function(obj, pointer) {
3042
throw("Invalid input object.");
3143
}
3244

45+
if(pointer === "") {
46+
return [];
47+
}
48+
3349
if(!pointer) {
3450
throw("Invalid JSON pointer.");
3551
}
52+
53+
pointer = pointer.split("/");
54+
var first = pointer.shift();
55+
if (first !== "") {
56+
throw("Invalid JSON pointer.");
57+
}
58+
59+
return pointer;
3660
}
3761

3862
var get = function(obj, pointer) {
39-
validate_input(obj, pointer);
40-
if (pointer === "/") {
63+
pointer = validate_input(obj, pointer);
64+
if (pointer.length === 0) {
4165
return obj;
4266
}
43-
pointer = pointer.split("/").slice(1);
4467
return traverse(obj, pointer);
4568
}
4669

4770
var set = function(obj, pointer, value) {
48-
validate_input(obj, pointer);
49-
if (pointer === "/") {
50-
return obj;
71+
pointer = validate_input(obj, pointer);
72+
if (pointer.length === 0) {
73+
throw("Invalid JSON pointer for set.")
5174
}
52-
pointer = pointer.split("/").slice(1);
5375
return traverse(obj, pointer, value);
5476
}
5577

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
, "tags" : ["util", "simple", "util", "utility"]
44
, "version" : "1.0.1"
55
, "author" : "Jan Lehnardt <jan@apache.org>"
6+
, "contributors":
7+
["Joe Hildebrand <joe-github@cursive.net>"]
68
, "repository" :
79
{ "type" : "git"
810
, "url" : "http://github.com/janl/node-jsonpointer.git"

test.js

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,70 @@ assert.equal(jsonpointer.get(obj, "/d/e/0/a"), 4);
3131
assert.equal(jsonpointer.get(obj, "/d/e/1/b"), 5);
3232
assert.equal(jsonpointer.get(obj, "/d/e/2/c"), 6);
3333

34-
assert.equal(jsonpointer.get(obj, "/"), obj);
34+
assert.equal(jsonpointer.get(obj, ""), obj);
35+
assert.throws(function() {
36+
assert.equal(jsonpointer.get(obj, "a"), 3);
37+
});
3538

3639
var complexKeys = {
3740
"a/b": {
3841
c: 1
3942
},
4043
d: {
4144
"e/f": 2
42-
}
45+
},
46+
"~1": 3,
47+
"01": 4
4348
}
4449

45-
assert.equal(jsonpointer.get(complexKeys, "/a%2Fb/c"), 1);
46-
assert.equal(jsonpointer.get(complexKeys, "/d/e%2Ff"), 2);
50+
assert.equal(jsonpointer.get(complexKeys, "/a~1b/c"), 1);
51+
assert.equal(jsonpointer.get(complexKeys, "/d/e~1f"), 2);
52+
assert.equal(jsonpointer.get(complexKeys, "/~01"), 3);
53+
assert.equal(jsonpointer.get(complexKeys, "/01"), 4);
4754
assert.throws(function() {
4855
assert.equal(jsonpointer.get(complexKeys, "/a/b/c"), 1);
4956
});
57+
assert.throws(function() {
58+
assert.equal(jsonpointer.get(complexKeys, "/~1"), 3);
59+
});
60+
61+
// draft-ietf-appsawg-json-pointer-08 has special array rules
62+
var ary = [ "zero", "one", "two" ];
63+
64+
assert.throws(function() {
65+
assert.equal(jsonpointer.get(ary, "/01"), "one");
66+
});
67+
//assert.equal(jsonpointer.set(ary, "/-", "three"), null);
68+
//assert.equal(ary[3], "three");
69+
70+
// Examples from the draft:
71+
var example = {
72+
"foo": ["bar", "baz"],
73+
"": 0,
74+
"a/b": 1,
75+
"c%d": 2,
76+
"e^f": 3,
77+
"g|h": 4,
78+
"i\\j": 5,
79+
"k\"l": 6,
80+
" ": 7,
81+
"m~n": 8
82+
};
83+
84+
assert.equal(jsonpointer.get(example, ""), example);
85+
var ans = jsonpointer.get(example, "/foo");
86+
assert.equal(ans.length, 2);
87+
assert.equal(ans[0], "bar");
88+
assert.equal(ans[1], "baz");
89+
assert.equal(jsonpointer.get(example, "/foo/0"), "bar");
90+
assert.equal(jsonpointer.get(example, "/"), 0);
91+
assert.equal(jsonpointer.get(example, "/a~1b"), 1);
92+
assert.equal(jsonpointer.get(example, "/c%d"), 2);
93+
assert.equal(jsonpointer.get(example, "/e^f"), 3);
94+
assert.equal(jsonpointer.get(example, "/g|h"), 4);
95+
assert.equal(jsonpointer.get(example, "/i\\j"), 5);
96+
assert.equal(jsonpointer.get(example, "/k\"l"), 6);
97+
assert.equal(jsonpointer.get(example, "/ "), 7);
98+
assert.equal(jsonpointer.get(example, "/m~0n"), 8);
5099

51100
console.log("All tests pass.");

0 commit comments

Comments
 (0)