Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 43 additions & 19 deletions jsonpointer.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,51 @@ var untilde = function(str) {
}

var traverse = function(obj, pointer, value) {
// assert(isArray(pointer))
var part = untilde(pointer.shift());
if(!obj.hasOwnProperty(part)) {
return null;
var isJustReading = arguments.length === 2;

if (obj[part] == null) {
if (isJustReading) return null;

// support setting of /-
if (part === '-' && obj instanceof Array) {
part = obj.length;
}

// support nested objects/array when setting values
var nextPart = pointer[0];
if (nextPart === '-' || !isNaN(nextPart)) {
obj[part] = [];
} else if (nextPart) {
obj[part] = {};
}
}
if(pointer.length !== 0) { // keep traversin!
return traverse(obj[part], pointer, value);

// keep traversing
if (pointer.length !== 0) {
if (isJustReading) {
return traverse(obj[part], pointer);
} else {
return traverse(obj[part], pointer, value);
}
}

// we're done
if(typeof value === "undefined") {
// just reading
if (isJustReading) {
return obj[part];
}

// set new value, return old value
var old_value = obj[part];
if(value === null) {
var oldValue = obj[part];
if (value === null) {
delete obj[part];
} else {
obj[part] = value;
}
return old_value;
return oldValue;
}

var validate_input = function(obj, pointer) {
if(typeof obj !== "object") {
throw new Error("Invalid input object.");
}

var compilePointer = function(pointer) {
if(pointer === "") {
return [];
}
Expand All @@ -47,15 +64,22 @@ var validate_input = function(obj, pointer) {
throw new Error("Invalid JSON pointer.");
}

pointer = pointer.split("/");
var first = pointer.shift();
if (first !== "") {
throw new Error("Invalid JSON pointer.");
if (!(pointer instanceof Array)) {
pointer = pointer.split("/");
if (pointer.shift() !== "") throw new Error("Invalid JSON pointer.")
}

return pointer;
}

var validate_input = function(obj, pointer) {
if(typeof obj !== "object") {
throw new Error("Invalid input object.");
}

return compilePointer(pointer);
}

var get = function(obj, pointer) {
pointer = validate_input(obj, pointer);
if (pointer.length === 0) {
Expand Down
18 changes: 14 additions & 4 deletions test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
var assert = require("assert");
var jsonpointer = require("./jsonpointer");
var assert = require('assert');
var jsonpointer = require('./jsonpointer');

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

// set nested properties
assert.equal(jsonpointer.set(obj, "/f/g/h/i", 6), undefined);
assert.equal(jsonpointer.get(obj, "/f/g/h/i"), 6);

// set an array
assert.equal(jsonpointer.set(obj, "/f/g/h/foo/-", 'test'), undefined);
arr = jsonpointer.get(obj, "/f/g/h/foo")
assert(Array.isArray(arr), 'set /- creates an array.');
assert.equal(arr[0], 'test');

assert.equal(jsonpointer.get(obj, "/a"), 2);
assert.equal(jsonpointer.get(obj, "/b/c"), 3);
assert.equal(jsonpointer.get(obj, "/d/e/0/a"), 4);
Expand Down Expand Up @@ -62,8 +72,8 @@ assert.equal(jsonpointer.get(complexKeys, "/~1"), null);
var ary = [ "zero", "one", "two" ];
assert.equal(jsonpointer.get(ary, "/01"), null);

//assert.equal(jsonpointer.set(ary, "/-", "three"), null);
//assert.equal(ary[3], "three");
assert.equal(jsonpointer.set(ary, "/-", "three"), null);
assert.equal(ary[3], "three");

// Examples from the draft:
var example = {
Expand Down