Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

first commit

  • Loading branch information...
commit 451656bde7bc0f641ce2114fb4a0fa8d0521269e 0 parents
@andreineculau authored
Showing with 144 additions and 0 deletions.
  1. +25 −0 README.md
  2. +41 −0 package.json
  3. +78 −0 src/jsondiff.coffee
25 README.md
@@ -0,0 +1,25 @@
+# JSONdiff.js
+
+JSONdiff.js is a port of [JSONdiff](https://github.com/algesten/jsondiff) from Java to JavaScript (actually CoffeeScript),
+also extended to support [JSON pointer](https://github.com/andreineculau/node-jsonpointer).
+
+
+# Usage
+
+```coffee
+jsonDiff = require 'jsondiff'
+instance =
+ a: 1
+ b: 2
+diff =
+ '/a': 2
+ '-/b': 0
+instance2 = jsonDiff.parse instances, diff
+instance2.a is 2
+instance2.b is undefined
+```
+
+
+# License
+
+[MIT](http://opensource.org/licenses/MIT)
41 package.json
@@ -0,0 +1,41 @@
+{
+ "name": "jsondiff",
+ "preferGlobal": false,
+ "private": true,
+ "version": "0.0.1",
+ "author": "Andrei Neculau <andrei.neculau@gmail.com>",
+ "description": "Port of Martin Algesten's jsondiff from Java to JavaScript.",
+ "contributors": [
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/andreineculau/jsondiff.js.git"
+ },
+ "keywords": [
+ "json",
+ "diff"
+ ],
+ "license": "MIT",
+
+ "engines": {
+ "node": "~0.8.5"
+ },
+ "dependencies": {
+ "coffee-script": "~1.3.1",
+ "json3": "~3.2.2",
+ "jsonpointer": "git://github.com/andreineculau/node-jsonpointer",
+ "jsonlint": "~1.3.1",
+ "node.extend": "~1.0.0"
+ },
+ "devDependencies": {
+ "nodeunit": "~0.7.4"
+ },
+ "bundleDependencies": [
+ ],
+
+ "scripts": {
+ },
+ "bin": {
+ },
+ "main": "src/jsondiff.coffee"
+}
78 src/jsondiff.coffee
@@ -0,0 +1,78 @@
+jsonLint = require '../node_modules/jsonlint'
+jsonPointer = require '../node_modules/jsonpointer'
+JSON = require '../node_modules/json3'
+extend = require '../node_modules/node.extend'
+
+type = (obj) ->
+ if obj is null or obj is undefined
+ return String(obj)
+ Object.prototype.toString.call(obj).slice(8, -1).toLowerCase() || 'object'
+
+
+exports.parse = (instance1, instance2) ->
+ throw 'Not yet implemented'
+
+
+exports.apply = (instance, diff) ->
+ silentGet = (pointer) ->
+ jsonPointer.silentGet instance, pointer
+ get = (pointer) ->
+ jsonPointer.get instance, pointer
+ set = (pointer, value) ->
+ jsonPointer.set instance, pointer, value
+ del = (pointer) ->
+ jsonPointer.del instance, pointer
+
+
+ if type(instance) is 'array'
+ instance = extend true, [], instance
+ else
+ instance = extend true, {}, instance
+
+ diff ?= []
+ for instruction, value of diff
+ mode = ''
+ path = instruction
+ switch path[0]
+ when '~'
+ mode = 'merge'
+ path = path.substr 1
+ when '-'
+ mode = 'remove'
+ path = path.substr 1
+ [path, arrayInfo] = path.split '['
+ if arrayInfo
+ arrayAdd = false
+ arrayInfo = arrayInfo.substr 0, arrayInfo.length-1
+ if arrayInfo[0] is '+' # array insert
+ arrayInfo = arrayInfo.substr 1
+ arrayAdd = true
+
+ try
+ currentValue = get path
+ catch e
+ set path, value if mode isnt 'remove'
+ continue
+
+ if arrayInfo
+ if type(currentValue) isnt 'array'
+ throw 'looks like different types ?! expecting array at ' + path
+ currentArray = currentValue
+ path = "#{path}/#{arrayInfo}"
+ currentValue = currentValue[arrayInfo]
+
+ switch mode
+ when 'remove'
+ del path
+ when 'merge'
+ if arrayInfo and arrayAdd # array insert
+ currentArray.splice arrayInfo, 0, value
+ continue
+ if type(currentValue) is 'object' and type(value) is 'object'
+ extend currentValue, value # object merge, or array object-item merge
+ else
+ set path, value # replace instead of merge for primite data types or array items
+ else
+ set path, value
+
+ instance
Please sign in to comment.
Something went wrong with that request. Please try again.