Skip to content

Commit 7e9d053

Browse files
committed
Merge pull request #19 from marcbachmann/set-improvement
Support /- and nested properties
2 parents e0d2d41 + 6232e8d commit 7e9d053

File tree

2 files changed

+57
-23
lines changed

2 files changed

+57
-23
lines changed

jsonpointer.js

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,34 +11,51 @@ var untilde = function(str) {
1111
}
1212

1313
var traverse = function(obj, pointer, value) {
14-
// assert(isArray(pointer))
1514
var part = untilde(pointer.shift());
16-
if(!obj.hasOwnProperty(part)) {
17-
return null;
15+
var isJustReading = arguments.length === 2;
16+
17+
if (obj[part] == null) {
18+
if (isJustReading) return null;
19+
20+
// support setting of /-
21+
if (part === '-' && obj instanceof Array) {
22+
part = obj.length;
23+
}
24+
25+
// support nested objects/array when setting values
26+
var nextPart = pointer[0];
27+
if (nextPart === '-' || !isNaN(nextPart)) {
28+
obj[part] = [];
29+
} else if (nextPart) {
30+
obj[part] = {};
31+
}
1832
}
19-
if(pointer.length !== 0) { // keep traversin!
20-
return traverse(obj[part], pointer, value);
33+
34+
// keep traversing
35+
if (pointer.length !== 0) {
36+
if (isJustReading) {
37+
return traverse(obj[part], pointer);
38+
} else {
39+
return traverse(obj[part], pointer, value);
40+
}
2141
}
42+
2243
// we're done
23-
if(typeof value === "undefined") {
24-
// just reading
44+
if (isJustReading) {
2545
return obj[part];
2646
}
47+
2748
// set new value, return old value
28-
var old_value = obj[part];
29-
if(value === null) {
49+
var oldValue = obj[part];
50+
if (value === null) {
3051
delete obj[part];
3152
} else {
3253
obj[part] = value;
3354
}
34-
return old_value;
55+
return oldValue;
3556
}
3657

37-
var validate_input = function(obj, pointer) {
38-
if(typeof obj !== "object") {
39-
throw new Error("Invalid input object.");
40-
}
41-
58+
var compilePointer = function(pointer) {
4259
if(pointer === "") {
4360
return [];
4461
}
@@ -47,15 +64,22 @@ var validate_input = function(obj, pointer) {
4764
throw new Error("Invalid JSON pointer.");
4865
}
4966

50-
pointer = pointer.split("/");
51-
var first = pointer.shift();
52-
if (first !== "") {
53-
throw new Error("Invalid JSON pointer.");
67+
if (!(pointer instanceof Array)) {
68+
pointer = pointer.split("/");
69+
if (pointer.shift() !== "") throw new Error("Invalid JSON pointer.")
5470
}
5571

5672
return pointer;
5773
}
5874

75+
var validate_input = function(obj, pointer) {
76+
if(typeof obj !== "object") {
77+
throw new Error("Invalid input object.");
78+
}
79+
80+
return compilePointer(pointer);
81+
}
82+
5983
var get = function(obj, pointer) {
6084
pointer = validate_input(obj, pointer);
6185
if (pointer.length === 0) {

test.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
var assert = require("assert");
2-
var jsonpointer = require("./jsonpointer");
1+
var assert = require('assert');
2+
var jsonpointer = require('./jsonpointer');
33

44
var obj = {
55
a: 1,
@@ -24,6 +24,16 @@ assert.equal(jsonpointer.set(obj, "/d/e/0/a", 4), 3);
2424
assert.equal(jsonpointer.set(obj, "/d/e/1/b", 5), 4);
2525
assert.equal(jsonpointer.set(obj, "/d/e/2/c", 6), 5);
2626

27+
// set nested properties
28+
assert.equal(jsonpointer.set(obj, "/f/g/h/i", 6), undefined);
29+
assert.equal(jsonpointer.get(obj, "/f/g/h/i"), 6);
30+
31+
// set an array
32+
assert.equal(jsonpointer.set(obj, "/f/g/h/foo/-", 'test'), undefined);
33+
arr = jsonpointer.get(obj, "/f/g/h/foo")
34+
assert(Array.isArray(arr), 'set /- creates an array.');
35+
assert.equal(arr[0], 'test');
36+
2737
assert.equal(jsonpointer.get(obj, "/a"), 2);
2838
assert.equal(jsonpointer.get(obj, "/b/c"), 3);
2939
assert.equal(jsonpointer.get(obj, "/d/e/0/a"), 4);
@@ -62,8 +72,8 @@ assert.equal(jsonpointer.get(complexKeys, "/~1"), null);
6272
var ary = [ "zero", "one", "two" ];
6373
assert.equal(jsonpointer.get(ary, "/01"), null);
6474

65-
//assert.equal(jsonpointer.set(ary, "/-", "three"), null);
66-
//assert.equal(ary[3], "three");
75+
assert.equal(jsonpointer.set(ary, "/-", "three"), null);
76+
assert.equal(ary[3], "three");
6777

6878
// Examples from the draft:
6979
var example = {

0 commit comments

Comments
 (0)