Comparing version 0.0.2 to 0.0.3
@@ -5,3 +5,3 @@ --- | ||
 <span class="project-name">jsonpatch.js</span> is an implementation of the [JSONPatch][jsonpatch-spec] and [JSONPointer][jsonpointer-spec] IETF draft specifications. | ||
 <span class="project-name">jsonpatch.js</span> is an implementation of the [JSONPatch][jsonpatch-spec] and [JSONPointer][jsonpointer-spec] IETF draft specifications whcih supports Node.JS and use in the Browser. | ||
@@ -8,0 +8,0 @@ A [Dharmafly][df] project written by [Thomas Parslow][tom] and released with the kind permission of [NetDev][netdev]. |
@@ -18,3 +18,3 @@ --- | ||
And that's all you need for basic use. | ||
And that's all you need for basic use, if the patch is invalid or won't apply then you'll get an error thrown. The original docucment is NOT mutated so you can use it for other things afterwards. | ||
@@ -34,7 +34,17 @@ Where can jsonpatch.js be used? | ||
There are Jasmine tests for JSONPatch in the [test folder](https://github.com/dharmafly/jsonpatch.js/tree/master/test). | ||
There are [Mocha][mocha] tests for JSONPatch in the [test folder][test-folder]. To run the tests under Node.JS you must first install the test dependencies: | ||
It also passes [JSHint](http://www.jshint.com). | ||
npm install mocha expect.js | ||
(You should be able to install these at the same time as jsonpatch using the `--dev` flag to NPM, but at the time of writing this causes the Mocha install to fail, hopefully they'll fix this soon!) | ||
Once you have the test utilities installed you can run the tests with: | ||
npm test jsonpatch | ||
This will also run [JSHint][jshint] over the code, which picks up a lot of common JavaScript style problems. | ||
To run the tests in the browser navigate to the test folder and open the runner.html file in your browser of choice. | ||
Fixes and improvements | ||
@@ -54,2 +64,3 @@ ---------------------- | ||
[mocha]: http://visionmedia.github.com/mocha/ | ||
[df]: http://dharmafly.com | ||
@@ -63,1 +74,3 @@ [netdev]: http://www.netdev.co.uk | ||
[hypermedia-slides]: http://almostobsolete.net/talks/hypermedia/ | ||
[test-folder]: https://github.com/dharmafly/jsonpatch.js/tree/master/test | ||
[jshint]: http://www.jshint.com |
@@ -6,4 +6,5 @@ --- | ||
A shortcut to apply a patch given as an Array or as a JSON String (see the [draft JSONPatch spec][#jsonpatch] for the patch format) to a document. May (and usually does) mutate the given document. | ||
A shortcut to apply a patch given as an Array or as a JSON String (see the [draft JSONPatch spec][#jsonpatch] for the patch format) to a document. Will not mutate the original document, however the new document may share some structure with the original. | ||
* document - The document to operate against. May be mutated. | ||
@@ -19,3 +20,3 @@ * patch - The patch document as a JS Array of operations or as a JSON String representing the same (the latter requires JSON support in your browser or the inclusion of the JSON2 library or similar) | ||
thepatch = [ | ||
{ "replace": "/baz", "value": "boo" } | ||
{ "op": "replace", "path": "/baz", "value": "boo" } | ||
] | ||
@@ -26,3 +27,3 @@ patcheddoc = jsonpatch.apply_patch(mydoc, thepatch); | ||
[#jsonpatch]: http://tools.ietf.org/html/draft-pbryan-json-patch-01 | ||
[#jsonpatch]: https://datatracker.ietf.org/doc/draft-ietf-appsawg-json-patch/ | ||
@@ -29,0 +30,0 @@ Throws: |
@@ -11,3 +11,3 @@ --- | ||
mypatch = new JSONPatch([{ "replace": "/baz", "value": "boo" }]); | ||
mypatch = new JSONPatch([{ "op": "replace", "path": "/baz", "value": "boo" }]); | ||
@@ -14,0 +14,0 @@ |
@@ -6,5 +6,5 @@ --- | ||
Applies the patch to the given document and returns the result. May also mutate the document! | ||
Applies the patch to the given document and returns the result. Will not mutate the original document, however the new document may share some structure with the original. | ||
* document - The document to operate against. May be mutated. | ||
* document - The document to operate against. | ||
@@ -11,0 +11,0 @@ Example: |
@@ -9,3 +9,3 @@ --- | ||
[#jsonpointer]:http://tools.ietf.org/html/draft-pbryan-zyp-json-pointer-02 | ||
[#jsonpointer]: https://datatracker.ietf.org/doc/draft-ietf-appsawg-json-pointer/ | ||
@@ -13,3 +13,3 @@ --- | ||
* document - The document to operate against. May be mutated. | ||
* document - The document to operate against. | ||
* value - The value to insert at the position pointed to | ||
@@ -22,3 +22,3 @@ | ||
Returns the updated doc (the value passed in may also have been mutated) | ||
Returns the updated doc. | ||
@@ -9,3 +9,3 @@ --- | ||
* document - The document to operate against. May be mutated. | ||
* document - The document to operate against. | ||
@@ -17,3 +17,3 @@ Example: | ||
Returns the updated doc (the value passed in may also have been mutated) | ||
Returns the updated doc | ||
@@ -8,3 +8,3 @@ --- | ||
* document - The document to operate against. May be mutated. | ||
* document - The document to operate against. | ||
* value - The value to replace at the position pointed to | ||
@@ -17,2 +17,2 @@ | ||
Returns the updated doc (the value passed in may also have been mutated) | ||
Returns the updated doc |
@@ -151,2 +151,5 @@ /* JSONPatch.js | ||
return o.slice(); | ||
// typeof null is "object", but we want to copy it as null | ||
} if (o === null) { | ||
return o; | ||
} else if (typeof o === "object") { | ||
@@ -175,7 +178,7 @@ cloned = {}; | ||
*/ | ||
JSONPointer.prototype._action = function (doc, handler, dont_clone) { | ||
JSONPointer.prototype._action = function (doc, handler, mutate) { | ||
var that = this; | ||
function follow_pointer(node, index) { | ||
var segment, subnode; | ||
if (!dont_clone) { | ||
if (!mutate) { | ||
node = clone(node); | ||
@@ -201,3 +204,3 @@ } | ||
subnode = follow_pointer(node[segment], index+1); | ||
if (!dont_clone) { | ||
if (!mutate) { | ||
node[segment] = subnode; | ||
@@ -229,3 +232,3 @@ } | ||
*/ | ||
JSONPointer.prototype.add = function (doc, value) { | ||
JSONPointer.prototype.add = function (doc, value, mutate) { | ||
// Special case for a pointer to the root | ||
@@ -240,8 +243,8 @@ if (0 === this.length) { | ||
} | ||
node.splice(lastSegment, 0, value); | ||
node.splice(lastSegment, 0, clone(value)); | ||
} else { | ||
node[lastSegment] = value; | ||
node[lastSegment] = clone(value); | ||
} | ||
return node; | ||
}); | ||
}, mutate); | ||
}; | ||
@@ -263,3 +266,3 @@ | ||
*/ | ||
JSONPointer.prototype.remove = function (doc) { | ||
JSONPointer.prototype.remove = function (doc, mutate) { | ||
// Special case for a pointer to the root | ||
@@ -282,3 +285,3 @@ if (0 === this.length) { | ||
return node; | ||
}); | ||
}, mutate); | ||
}; | ||
@@ -300,3 +303,3 @@ | ||
*/ | ||
JSONPointer.prototype.replace = function (doc, value) { | ||
JSONPointer.prototype.replace = function (doc, value, mutate) { | ||
// Special case for a pointer to the root | ||
@@ -311,8 +314,8 @@ if (0 === this.length) { | ||
if (isArray(node)) { | ||
node.splice(lastSegment, 1, value); | ||
node.splice(lastSegment, 1, clone(value)); | ||
} else { | ||
node[lastSegment] = value; | ||
node[lastSegment] = clone(value); | ||
} | ||
return node; | ||
}); | ||
}, mutate); | ||
}; | ||
@@ -452,3 +455,3 @@ | ||
function compileOperation(operation) { | ||
function compileOperation(operation, mutate) { | ||
validateOp(operation); | ||
@@ -471,11 +474,11 @@ var op = operation.op; | ||
return function (doc) { | ||
return path.add(doc, value); | ||
return path.add(doc, value, mutate); | ||
}; | ||
case 'remove': | ||
return function (doc) { | ||
return path.remove(doc); | ||
return path.remove(doc, mutate); | ||
}; | ||
case 'replace': | ||
return function (doc) { | ||
return path.replace(doc, value); | ||
return path.replace(doc, value, mutate); | ||
}; | ||
@@ -485,4 +488,4 @@ case 'move': | ||
var value = from.get(doc); | ||
var intermediate = from.remove(doc); | ||
return path.add(intermediate, value); | ||
var intermediate = from.remove(doc, mutate); | ||
return path.add(intermediate, value, mutate); | ||
}; | ||
@@ -492,3 +495,3 @@ case 'copy': | ||
var value = from.get(doc); | ||
return path.add(doc, value); | ||
return path.add(doc, value, mutate); | ||
}; | ||
@@ -507,9 +510,14 @@ case 'test': | ||
* | ||
* patch - The patch as an array or as a JSON string (containing an array) | ||
* patch - The patch as an array or as a JSON string (containing an | ||
* array) | ||
* mutate - Indicates that input documents should be mutated | ||
* (default is for the input to be unaffected.) This will | ||
* not work correctly if the patch replaces the root of | ||
* the document. | ||
*/ | ||
exports.JSONPatch = JSONPatch = function JSONPatch(patch) { | ||
this._compile(patch); | ||
exports.JSONPatch = JSONPatch = function JSONPatch(patch, mutate) { | ||
this._compile(patch, mutate); | ||
}; | ||
JSONPatch.prototype._compile = function (patch) { | ||
JSONPatch.prototype._compile = function (patch, mutate) { | ||
var i, n, key; | ||
@@ -526,3 +534,3 @@ var _this = this; | ||
for(i = 0; i < patch.length; i++) { | ||
var compiled = compileOperation(patch[i]); | ||
var compiled = compileOperation(patch[i], mutate); | ||
_this.compiledOps.push(compiled); | ||
@@ -529,0 +537,0 @@ } |
{ | ||
"name": "jsonpatch", | ||
"version": "0.0.2", | ||
"version": "0.0.3", | ||
"description": "An implementation of JSON Patch and JSON Pointer IETF drafts", | ||
@@ -5,0 +5,0 @@ "keywords": ["diff", "patch", "json", "jsonpatch", "jsonpointer"], |
@@ -1,4 +0,3 @@ | ||
NEW: Now suppots JSONPointer Draft 09 and JSONPatch Draft 10 (the latest as of 21/Jan/2012) | ||
NEW: Now supports JSONPointer Draft 09 and JSONPatch Draft 10 (the latest as of 21/Jan/2013) | ||
[![Build Status](https://secure.travis-ci.org/dharmafly/jsonpatch.js.png)](http://travis-ci.org/dharmafly/jsonpatch.js) | ||
@@ -14,2 +13,4 @@ JSONPatch | ||
[![Build Status](https://secure.travis-ci.org/dharmafly/jsonpatch.js.png)](http://travis-ci.org/dharmafly/jsonpatch.js) | ||
[![browser support](http://ci.testling.com/dharmafly/jsonpatch.js.png)](http://ci.testling.com/dharmafly/jsonpatch.js) | ||
@@ -61,7 +62,9 @@ Quick Example | ||
We're using [Travis][#travis] and [Testling CI][#testling] to automatically run the tests on Node.JS and in a range of browsers every time a change is commited to this repository. The badges at the top of this readme display the current build status (which should always be passing). | ||
Origin of the project | ||
--------------------- | ||
[Dharmafly][#dharmafly] is currently working to create a collaboration web app for [NetDev][#netdev] that comprises a [Node.js][#nodejs] RESTful API on the back-end and an HTML5 [Backbone.js][#backbone] application on the front. The JSON Patch library was created as an essential part of the RESTful API, and has been subsequently open sourced for the community with NetDev's permission. | ||
[Dharmafly][#dharmafly] is currently working to create a collaboration web app for [NetDev][#netdev] that comprises a [Node.js][#nodejs] RESTful API on the back-end and an HTML5 [Backbone.js][#backbone] application on the front. The JSONPatch library was created as an essential part of the RESTful API, and has been subsequently open sourced for the community with NetDev's permission. | ||
@@ -81,2 +84,4 @@ I've fixed/improved stuff | ||
[#jsonpatch]: https://datatracker.ietf.org/doc/draft-ietf-appsawg-json-patch/ | ||
[#jsonpointer]: https://datatracker.ietf.org/doc/draft-ietf-appsawg-json-pointer/ | ||
[#jsonpointer]: https://datatracker.ietf.org/doc/draft-ietf-appsawg-json-pointer/ | ||
[#travis]: http://travis-ci.org/dharmafly/jsonpatch.js | ||
[#testling]: http://ci.testling.com/dharmafly/jsonpatch.js |
@@ -16,3 +16,11 @@ // A wrapper round the tests from https://github.com/json-patch/json-patch-tests | ||
} | ||
it(test.comment || "Un-named test", function () { | ||
var testname; | ||
if (test.comment) { | ||
testname = test.comment; | ||
} else if (typeof JSON !== "undefined") { | ||
testname = JSON.stringify(test.patch); | ||
} else { | ||
testname = "Un-named patch"; | ||
} | ||
it(testname, function () { | ||
// We want to skip this part if there isn't a JSON library | ||
@@ -19,0 +27,0 @@ // loaded |
@@ -172,6 +172,8 @@ if ('function' === typeof require) { | ||
describe('constructor', function () { | ||
it('should accept a JSON string as a patch', function () { | ||
patch = new jsonpatch.JSONPatch('[{"op":"remove", "path":"/"}]'); | ||
expect(patch = patch.compiledOps.length).equal(1); | ||
}); | ||
if (typeof JSON === 'object') { | ||
it('should accept a JSON string as a patch', function () { | ||
patch = new jsonpatch.JSONPatch('[{"op":"remove", "path":"/"}]'); | ||
expect(patch = patch.compiledOps.length).equal(1); | ||
}); | ||
} | ||
it('should accept a JS object as a patch', function () { | ||
@@ -198,4 +200,32 @@ patch = new jsonpatch.JSONPatch([{"op":"remove", "path":"/"}, {"op":"remove", "path":"/"}]); | ||
it('should not mutate the source document', function () { | ||
// Don't run this test on browsers without the JSON object | ||
if (typeof JSON === 'object') { | ||
it('should not mutate the source document', function () { | ||
var doc = { | ||
"foo": { | ||
"anArray": [ | ||
{ "prop": 44 }, | ||
"second", | ||
"third" | ||
], | ||
"another prop": { | ||
"baz": "A string" | ||
} | ||
} | ||
}; | ||
var json = JSON.stringify(doc); | ||
var patch = [ | ||
{"op": "remove", "path": "/foo/another prop/baz"}, | ||
{"op": "add", "path": "/foo/new", "value": "hello"}, | ||
{"op": "move", "from": "/foo/new", "path": "/newnew"}, | ||
{"op": "copy", "from": "/foo/anArray/1", "path": "/foo/anArray/-"}, | ||
{"op": "test", "path": "/foo/anArray/3", "value": "second"} | ||
]; | ||
var patched = jsonpatch.apply_patch(doc, patch); | ||
// Check that the doc has not been mutated | ||
expect(JSON.stringify(doc)).equal(json) | ||
}); | ||
} | ||
it('should mutate the document if the mutate flag is passed in', function () { | ||
var doc = { | ||
@@ -213,3 +243,2 @@ "foo": { | ||
}; | ||
var json = JSON.stringify(doc); | ||
var patch = [ | ||
@@ -222,10 +251,8 @@ {"op": "remove", "path": "/foo/another prop/baz"}, | ||
]; | ||
var patched = jsonpatch.apply_patch(doc, patch); | ||
patch = new jsonpatch.JSONPatch(patch, true); // mutate = true | ||
var patched = patch.apply(doc); | ||
// Check that the doc has not been mutated | ||
expect(JSON.stringify(doc)).equal(json) | ||
expect(patched).eql(doc) | ||
}); | ||
// describe('._operations', function () { | ||
// }); | ||
describe('.apply()', function () { | ||
@@ -232,0 +259,0 @@ var patch; |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
84
7
0
226002
26
7215