Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

deep-diff

Package Overview
Dependencies
Maintainers
1
Versions
22
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

deep-diff - npm Package Compare versions

Comparing version 0.3.8 to 1.0.0-pre.1

.circleci/config.yml

802

index.js

@@ -1,415 +0,501 @@

(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.DeepDiff = factory());
}(this, (function () { 'use strict';
(function (root, factory) {
if (typeof define === 'function' && define.amd) { // eslint-disable-line no-undef
define([], factory);// eslint-disable-line no-undef
} else if (typeof module === 'object' && module.exports) {
module.exports = factory();
} else {
root.returnExports = factory();
}
// eslint-disable-next-line no-undef
}(typeof self !== 'undefined' ? self : this, function () {
var root = this;
var $conflict = root.DeepDiff;
var $scope;
var conflict;
var conflictResolution = [];
if (typeof global === 'object' && global) {
$scope = global;
} else if (typeof window !== 'undefined') {
$scope = window;
} else {
$scope = {};
}
conflict = $scope.DeepDiff;
if (conflict) {
conflictResolution.push(
function() {
if ('undefined' !== typeof conflict && $scope.DeepDiff === accumulateDiff) {
$scope.DeepDiff = conflict;
conflict = undefined;
// nodejs compatible on server side and in the browser.
function inherits(ctor, superCtor) {
ctor.super_ = superCtor;
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
}
});
}
}
// nodejs compatible on server side and in the browser.
function inherits(ctor, superCtor) {
ctor.super_ = superCtor;
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
function Diff(kind, path) {
Object.defineProperty(this, 'kind', {
value: kind,
enumerable: true
});
if (path && path.length) {
Object.defineProperty(this, 'path', {
value: path,
enumerable: true
});
}
});
}
}
function Diff(kind, path) {
Object.defineProperty(this, 'kind', {
value: kind,
enumerable: true
});
if (path && path.length) {
Object.defineProperty(this, 'path', {
value: path,
function DiffEdit(path, origin, value) {
DiffEdit.super_.call(this, 'E', path);
Object.defineProperty(this, 'lhs', {
value: origin,
enumerable: true
});
Object.defineProperty(this, 'rhs', {
value: value,
enumerable: true
});
}
}
inherits(DiffEdit, Diff);
function DiffEdit(path, origin, value) {
DiffEdit.super_.call(this, 'E', path);
Object.defineProperty(this, 'lhs', {
value: origin,
enumerable: true
});
Object.defineProperty(this, 'rhs', {
value: value,
enumerable: true
});
}
inherits(DiffEdit, Diff);
function DiffNew(path, value) {
DiffNew.super_.call(this, 'N', path);
Object.defineProperty(this, 'rhs', {
value: value,
enumerable: true
});
}
inherits(DiffNew, Diff);
function DiffNew(path, value) {
DiffNew.super_.call(this, 'N', path);
Object.defineProperty(this, 'rhs', {
value: value,
enumerable: true
});
}
inherits(DiffNew, Diff);
function DiffDeleted(path, value) {
DiffDeleted.super_.call(this, 'D', path);
Object.defineProperty(this, 'lhs', {
value: value,
enumerable: true
});
}
inherits(DiffDeleted, Diff);
function DiffDeleted(path, value) {
DiffDeleted.super_.call(this, 'D', path);
Object.defineProperty(this, 'lhs', {
value: value,
enumerable: true
});
}
inherits(DiffDeleted, Diff);
function DiffArray(path, index, item) {
DiffArray.super_.call(this, 'A', path);
Object.defineProperty(this, 'index', {
value: index,
enumerable: true
});
Object.defineProperty(this, 'item', {
value: item,
enumerable: true
});
}
inherits(DiffArray, Diff);
function DiffArray(path, index, item) {
DiffArray.super_.call(this, 'A', path);
Object.defineProperty(this, 'index', {
value: index,
enumerable: true
});
Object.defineProperty(this, 'item', {
value: item,
enumerable: true
});
}
inherits(DiffArray, Diff);
function arrayRemove(arr, from, to) {
var rest = arr.slice((to || from) + 1 || arr.length);
arr.length = from < 0 ? arr.length + from : from;
arr.push.apply(arr, rest);
return arr;
}
function arrayRemove(arr, from, to) {
var rest = arr.slice((to || from) + 1 || arr.length);
arr.length = from < 0 ? arr.length + from : from;
arr.push.apply(arr, rest);
return arr;
}
function realTypeOf(subject) {
var type = typeof subject;
if (type !== 'object') {
return type;
}
function realTypeOf(subject) {
var type = typeof subject;
if (type !== 'object') {
return type;
if (subject === Math) {
return 'math';
} else if (subject === null) {
return 'null';
} else if (Array.isArray(subject)) {
return 'array';
} else if (Object.prototype.toString.call(subject) === '[object Date]') {
return 'date';
} else if (typeof subject.toString === 'function' && /^\/.*\//.test(subject.toString())) {
return 'regexp';
}
return 'object';
}
if (subject === Math) {
return 'math';
} else if (subject === null) {
return 'null';
} else if (Array.isArray(subject)) {
return 'array';
} else if (Object.prototype.toString.call(subject) === '[object Date]') {
return 'date';
} else if (typeof subject.toString === 'function' && /^\/.*\//.test(subject.toString())) {
return 'regexp';
// http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/
function hashThisString(string) {
var hash = 0;
if (string.length === 0) { return hash; }
for (var i = 0; i < string.length; i++) {
var char = string.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
}
return 'object';
}
function deepDiff(lhs, rhs, changes, prefilter, path, key, stack) {
path = path || [];
stack = stack || [];
var currentPath = path.slice(0);
if (typeof key !== 'undefined') {
if (prefilter) {
if (typeof(prefilter) === 'function' && prefilter(currentPath, key)) {
return; } else if (typeof(prefilter) === 'object') {
if (prefilter.prefilter && prefilter.prefilter(currentPath, key)) {
return; }
if (prefilter.normalize) {
var alt = prefilter.normalize(currentPath, key, lhs, rhs);
if (alt) {
lhs = alt[0];
rhs = alt[1];
}
// Gets a hash of the given object in an array order-independent fashion
// also object key order independent (easier since they can be alphabetized)
function getOrderIndependentHash(object) {
var accum = 0;
var type = realTypeOf(object);
if (type === 'array') {
object.forEach(function (item) {
// Addition is commutative so this is order indep
accum += getOrderIndependentHash(item);
});
var arrayString = '[type: array, hash: ' + accum + ']';
return accum + hashThisString(arrayString);
}
if (type === 'object') {
for (var key in object) {
if (object.hasOwnProperty(key)) {
var keyValueString = '[ type: object, key: ' + key + ', value hash: ' + getOrderIndependentHash(object[key]) + ']';
accum += hashThisString(keyValueString);
}
}
return accum;
}
currentPath.push(key);
}
// Use string comparison for regexes
if (realTypeOf(lhs) === 'regexp' && realTypeOf(rhs) === 'regexp') {
lhs = lhs.toString();
rhs = rhs.toString();
// Non object, non array...should be good?
var stringToHash = '[ type: ' + type + ' ; value: ' + object + ']';
return accum + hashThisString(stringToHash);
}
var ltype = typeof lhs;
var rtype = typeof rhs;
var ldefined = ltype !== 'undefined' || (stack && stack[stack.length - 1].lhs && stack[stack.length - 1].lhs.hasOwnProperty(key));
var rdefined = rtype !== 'undefined' || (stack && stack[stack.length - 1].rhs && stack[stack.length - 1].rhs.hasOwnProperty(key));
if (!ldefined && rdefined) {
changes(new DiffNew(currentPath, rhs));
} else if (!rdefined && ldefined) {
changes(new DiffDeleted(currentPath, lhs));
} else if (realTypeOf(lhs) !== realTypeOf(rhs)) {
changes(new DiffEdit(currentPath, lhs, rhs));
} else if (realTypeOf(lhs) === 'date' && (lhs - rhs) !== 0) {
changes(new DiffEdit(currentPath, lhs, rhs));
} else if (ltype === 'object' && lhs !== null && rhs !== null) {
if (!stack.filter(function(x) {
return x.lhs === lhs; }).length) {
stack.push({ lhs: lhs, rhs: rhs });
if (Array.isArray(lhs)) {
var i, len = lhs.length;
for (i = 0; i < lhs.length; i++) {
if (i >= rhs.length) {
changes(new DiffArray(currentPath, i, new DiffDeleted(undefined, lhs[i])));
} else {
deepDiff(lhs[i], rhs[i], changes, prefilter, currentPath, i, stack);
function deepDiff(lhs, rhs, changes, prefilter, path, key, stack, orderIndependent) {
path = path || [];
stack = stack || [];
var currentPath = path.slice(0);
if (typeof key !== 'undefined') {
if (prefilter) {
if (typeof (prefilter) === 'function' && prefilter(currentPath, key)) {
return;
} else if (typeof (prefilter) === 'object') {
if (prefilter.prefilter && prefilter.prefilter(currentPath, key)) {
return;
}
if (prefilter.normalize) {
var alt = prefilter.normalize(currentPath, key, lhs, rhs);
if (alt) {
lhs = alt[0];
rhs = alt[1];
}
}
}
while (i < rhs.length) {
changes(new DiffArray(currentPath, i, new DiffNew(undefined, rhs[i++])));
}
currentPath.push(key);
}
// Use string comparison for regexes
if (realTypeOf(lhs) === 'regexp' && realTypeOf(rhs) === 'regexp') {
lhs = lhs.toString();
rhs = rhs.toString();
}
var ltype = typeof lhs;
var rtype = typeof rhs;
var ldefined = ltype !== 'undefined' ||
(stack && (stack.length > 0) && stack[stack.length - 1].lhs &&
Object.getOwnPropertyDescriptor(stack[stack.length - 1].lhs, key));
var rdefined = rtype !== 'undefined' ||
(stack && (stack.length > 0) && stack[stack.length - 1].rhs &&
Object.getOwnPropertyDescriptor(stack[stack.length - 1].rhs, key));
if (!ldefined && rdefined) {
changes(new DiffNew(currentPath, rhs));
} else if (!rdefined && ldefined) {
changes(new DiffDeleted(currentPath, lhs));
} else if (realTypeOf(lhs) !== realTypeOf(rhs)) {
changes(new DiffEdit(currentPath, lhs, rhs));
} else if (realTypeOf(lhs) === 'date' && (lhs - rhs) !== 0) {
changes(new DiffEdit(currentPath, lhs, rhs));
} else if (ltype === 'object' && lhs !== null && rhs !== null) {
if (!stack.filter(function (x) {
return x.lhs === lhs;
}).length) {
stack.push({ lhs: lhs, rhs: rhs });
if (Array.isArray(lhs)) {
// If order doesn't matter, we need to sort our arrays
if (orderIndependent) {
lhs.sort(function (a, b) {
return getOrderIndependentHash(a) - getOrderIndependentHash(b);
});
rhs.sort(function (a, b) {
return getOrderIndependentHash(a) - getOrderIndependentHash(b);
});
}
var i;
for (i = 0; i < lhs.length; i++) {
if (i >= rhs.length) {
changes(new DiffArray(currentPath, i, new DiffDeleted(undefined, lhs[i])));
} else {
deepDiff(lhs[i], rhs[i], changes, prefilter, currentPath, i, stack, orderIndependent);
}
}
while (i < rhs.length) {
changes(new DiffArray(currentPath, i, new DiffNew(undefined, rhs[i++])));
}
} else {
var akeys = Object.keys(lhs);
var pkeys = Object.keys(rhs);
akeys.forEach(function (k) {
var other = pkeys.indexOf(k);
if (other >= 0) {
deepDiff(lhs[k], rhs[k], changes, prefilter, currentPath, k, stack, orderIndependent);
pkeys = arrayRemove(pkeys, other);
} else {
deepDiff(lhs[k], undefined, changes, prefilter, currentPath, k, stack, orderIndependent);
}
});
pkeys.forEach(function (k) {
deepDiff(undefined, rhs[k], changes, prefilter, currentPath, k, stack, orderIndependent);
});
}
} else {
var akeys = Object.keys(lhs);
var pkeys = Object.keys(rhs);
akeys.forEach(function(k, i) {
var other = pkeys.indexOf(k);
if (other >= 0) {
deepDiff(lhs[k], rhs[k], changes, prefilter, currentPath, k, stack);
pkeys = arrayRemove(pkeys, other);
} else {
deepDiff(lhs[k], undefined, changes, prefilter, currentPath, k, stack);
}
});
pkeys.forEach(function(k) {
deepDiff(undefined, rhs[k], changes, prefilter, currentPath, k, stack);
});
stack.length = stack.length - 1;
} else if (lhs !== rhs) {
// lhs is contains a cycle at this element and it differs from rhs
changes(new DiffEdit(currentPath, lhs, rhs));
}
stack.length = stack.length - 1;
} else if (lhs !== rhs) {
// lhs is contains a cycle at this element and it differs from rhs
changes(new DiffEdit(currentPath, lhs, rhs));
if (!(ltype === 'number' && isNaN(lhs) && isNaN(rhs))) {
changes(new DiffEdit(currentPath, lhs, rhs));
}
}
} else if (lhs !== rhs) {
if (!(ltype === 'number' && isNaN(lhs) && isNaN(rhs))) {
changes(new DiffEdit(currentPath, lhs, rhs));
}
}
}
function accumulateDiff(lhs, rhs, prefilter, accum) {
accum = accum || [];
deepDiff(lhs, rhs,
function(diff) {
if (diff) {
accum.push(diff);
}
},
prefilter);
return (accum.length) ? accum : undefined;
}
function orderIndependentDeepDiff(lhs, rhs, changes, prefilter, path, key, stack) {
return deepDiff(lhs, rhs, changes, prefilter, path, key, stack, true);
}
function applyArrayChange(arr, index, change) {
if (change.path && change.path.length) {
var it = arr[index],
i, u = change.path.length - 1;
for (i = 0; i < u; i++) {
it = it[change.path[i]];
}
switch (change.kind) {
case 'A':
applyArrayChange(it[change.path[i]], change.index, change.item);
break;
case 'D':
delete it[change.path[i]];
break;
case 'E':
case 'N':
it[change.path[i]] = change.rhs;
break;
}
} else {
switch (change.kind) {
case 'A':
applyArrayChange(arr[index], change.index, change.item);
break;
case 'D':
arr = arrayRemove(arr, index);
break;
case 'E':
case 'N':
arr[index] = change.rhs;
break;
}
function accumulateDiff(lhs, rhs, prefilter, accum) {
accum = accum || [];
deepDiff(lhs, rhs,
function (diff) {
if (diff) {
accum.push(diff);
}
},
prefilter);
return (accum.length) ? accum : undefined;
}
return arr;
}
function applyChange(target, source, change) {
if (target && source && change && change.kind) {
var it = target,
i = -1,
last = change.path ? change.path.length - 1 : 0;
while (++i < last) {
if (typeof it[change.path[i]] === 'undefined') {
it[change.path[i]] = (typeof change.path[i] === 'number') ? [] : {};
function accumulateOrderIndependentDiff(lhs, rhs, prefilter, accum) {
accum = accum || [];
deepDiff(lhs, rhs,
function (diff) {
if (diff) {
accum.push(diff);
}
},
prefilter, null, null, null, true);
return (accum.length) ? accum : undefined;
}
function applyArrayChange(arr, index, change) {
if (change.path && change.path.length) {
var it = arr[index],
i, u = change.path.length - 1;
for (i = 0; i < u; i++) {
it = it[change.path[i]];
}
it = it[change.path[i]];
switch (change.kind) {
case 'A':
applyArrayChange(it[change.path[i]], change.index, change.item);
break;
case 'D':
delete it[change.path[i]];
break;
case 'E':
case 'N':
it[change.path[i]] = change.rhs;
break;
}
} else {
switch (change.kind) {
case 'A':
applyArrayChange(arr[index], change.index, change.item);
break;
case 'D':
arr = arrayRemove(arr, index);
break;
case 'E':
case 'N':
arr[index] = change.rhs;
break;
}
}
switch (change.kind) {
case 'A':
applyArrayChange(change.path ? it[change.path[i]] : it, change.index, change.item);
break;
case 'D':
delete it[change.path[i]];
break;
case 'E':
case 'N':
it[change.path[i]] = change.rhs;
break;
}
return arr;
}
}
function revertArrayChange(arr, index, change) {
if (change.path && change.path.length) {
// the structure of the object at the index has changed...
var it = arr[index],
i, u = change.path.length - 1;
for (i = 0; i < u; i++) {
it = it[change.path[i]];
function applyChange(target, source, change) {
if (target && source && change && change.kind) {
var it = target,
i = -1,
last = change.path ? change.path.length - 1 : 0;
while (++i < last) {
if (typeof it[change.path[i]] === 'undefined') {
it[change.path[i]] = (typeof change.path[i + 1] !== 'undefined' && typeof change.path[i + 1] === 'number') ? [] : {};
}
it = it[change.path[i]];
}
switch (change.kind) {
case 'A':
if (change.path && typeof it[change.path[i]] === 'undefined') {
it[change.path[i]] = [];
}
applyArrayChange(change.path ? it[change.path[i]] : it, change.index, change.item);
break;
case 'D':
delete it[change.path[i]];
break;
case 'E':
case 'N':
it[change.path[i]] = change.rhs;
break;
}
}
switch (change.kind) {
case 'A':
revertArrayChange(it[change.path[i]], change.index, change.item);
break;
case 'D':
it[change.path[i]] = change.lhs;
break;
case 'E':
it[change.path[i]] = change.lhs;
break;
case 'N':
delete it[change.path[i]];
break;
}
} else {
// the array item is different...
switch (change.kind) {
case 'A':
revertArrayChange(arr[index], change.index, change.item);
break;
case 'D':
arr[index] = change.lhs;
break;
case 'E':
arr[index] = change.lhs;
break;
case 'N':
arr = arrayRemove(arr, index);
break;
}
}
return arr;
}
function revertChange(target, source, change) {
if (target && source && change && change.kind) {
var it = target,
i, u;
u = change.path.length - 1;
for (i = 0; i < u; i++) {
if (typeof it[change.path[i]] === 'undefined') {
it[change.path[i]] = {};
function revertArrayChange(arr, index, change) {
if (change.path && change.path.length) {
// the structure of the object at the index has changed...
var it = arr[index],
i, u = change.path.length - 1;
for (i = 0; i < u; i++) {
it = it[change.path[i]];
}
it = it[change.path[i]];
switch (change.kind) {
case 'A':
revertArrayChange(it[change.path[i]], change.index, change.item);
break;
case 'D':
it[change.path[i]] = change.lhs;
break;
case 'E':
it[change.path[i]] = change.lhs;
break;
case 'N':
delete it[change.path[i]];
break;
}
} else {
// the array item is different...
switch (change.kind) {
case 'A':
revertArrayChange(arr[index], change.index, change.item);
break;
case 'D':
arr[index] = change.lhs;
break;
case 'E':
arr[index] = change.lhs;
break;
case 'N':
arr = arrayRemove(arr, index);
break;
}
}
switch (change.kind) {
case 'A':
// Array was modified...
// it will be an array...
revertArrayChange(it[change.path[i]], change.index, change.item);
break;
case 'D':
// Item was deleted...
it[change.path[i]] = change.lhs;
break;
case 'E':
// Item was edited...
it[change.path[i]] = change.lhs;
break;
case 'N':
// Item is new...
delete it[change.path[i]];
break;
}
return arr;
}
}
function applyDiff(target, source, filter) {
if (target && source) {
var onChange = function(change) {
if (!filter || filter(target, source, change)) {
applyChange(target, source, change);
function revertChange(target, source, change) {
if (target && source && change && change.kind) {
var it = target,
i, u;
u = change.path.length - 1;
for (i = 0; i < u; i++) {
if (typeof it[change.path[i]] === 'undefined') {
it[change.path[i]] = {};
}
it = it[change.path[i]];
}
};
deepDiff(target, source, onChange);
switch (change.kind) {
case 'A':
// Array was modified...
// it will be an array...
revertArrayChange(it[change.path[i]], change.index, change.item);
break;
case 'D':
// Item was deleted...
it[change.path[i]] = change.lhs;
break;
case 'E':
// Item was edited...
it[change.path[i]] = change.lhs;
break;
case 'N':
// Item is new...
delete it[change.path[i]];
break;
}
}
}
}
Object.defineProperties(accumulateDiff, {
function applyDiff(target, source, filter) {
if (target && source) {
var onChange = function (change) {
if (!filter || filter(target, source, change)) {
applyChange(target, source, change);
}
};
deepDiff(target, source, onChange);
}
}
diff: {
value: accumulateDiff,
enumerable: true
},
observableDiff: {
value: deepDiff,
enumerable: true
},
applyDiff: {
value: applyDiff,
enumerable: true
},
applyChange: {
value: applyChange,
enumerable: true
},
revertChange: {
value: revertChange,
enumerable: true
},
isConflict: {
value: function() {
return 'undefined' !== typeof conflict;
Object.defineProperties(accumulateDiff, {
diff: {
value: accumulateDiff,
enumerable: true
},
enumerable: true
},
noConflict: {
value: function() {
if (conflictResolution) {
conflictResolution.forEach(function(it) {
it();
});
conflictResolution = null;
}
return accumulateDiff;
orderIndependentDiff: {
value: accumulateOrderIndependentDiff,
enumerable: true
},
enumerable: true
}
});
observableDiff: {
value: deepDiff,
enumerable: true
},
orderIndependentObservableDiff: {
value: orderIndependentDeepDiff,
enumerable: true
},
orderIndepHash: {
value: getOrderIndependentHash,
enumerable: true
},
applyDiff: {
value: applyDiff,
enumerable: true
},
applyChange: {
value: applyChange,
enumerable: true
},
revertChange: {
value: revertChange,
enumerable: true
},
isConflict: {
value: function () {
return typeof $conflict !== 'undefined';
},
enumerable: true
},
noConflict: {
value: function () {
if ($conflict) {
root.DeepDiff = accumulateDiff;
$conflict = null;
}
return accumulateDiff;
},
enumerable: true
}
});
return accumulateDiff;
// hackish...
accumulateDiff.DeepDiff = accumulateDiff;
// ...but works with:
// import DeepDiff from 'deep-diff'
// import { DeepDiff } from 'deep-diff'
// const DeepDiff = require('deep-diff');
// const { DeepDiff } = require('deep-diff');
})));
root.DeepDiff = accumulateDiff;
return accumulateDiff;
}));
{
"name": "deep-diff",
"description": "Javascript utility for calculating deep difference, capturing changes, and applying changes across objects; for nodejs and the browser.",
"version": "0.3.8",
"version": "1.0.0-pre.1",
"license": "MIT",

@@ -41,7 +41,2 @@ "keywords": [

],
"files": [
"index.js",
"index.es.js",
"releases/"
],
"repository": {

@@ -52,30 +47,28 @@ "type": "git",

"main": "./index.js",
"module": "./index.es.js",
"jsnext:main": "/index.es.js",
"directories": {
"examples": "./examples",
"releases": "./releases",
"test": "./test"
"scripts": {
"prerelease": "npm run clean && npm run test",
"release": "uglifyjs -c -m -o dist/deep-diff.min.js --source-map -r '$,require,exports,self,module,define' index.js",
"clean": "rimraf dist && mkdir dist",
"preversion": "npm run release",
"postversion": "git push && git push --tags",
"pretest": "npm run lint",
"test": "mocha test/**/*.js",
"test:watch": "nodemon --ext js,json --ignore dist/ --exec 'npm test'",
"preci": "npm run lint",
"ci": "mocha --reporter mocha-junit-reporter test/**/*.js",
"lint": "eslint index.js test"
},
"devDependencies": {
"deep-equal": "~1.0.0",
"bluebird": "^3.5.1",
"deep-equal": "^1.0.1",
"eslint": "^4.18.1",
"eslint-plugin-mocha": "^4.11.0",
"expect.js": "^0.3.1",
"jscs": "^1.12.0",
"jshint": "^2.6.3",
"mocha": "^2.2.1",
"rollup": "^0.41.6",
"uglifyjs": "^2.4.10"
},
"scripts": {
"lint": "jscs index.es.js test/ -e && jshint index.es.js test/",
"build": "rollup index.es.js -f umd -o index.js -n DeepDiff",
"test": "mocha test/",
"release": "uglifyjs index.js -o releases/deep-diff-$npm_package_version.min.js -r '$,require,exports,module,window,global' -m --comments '/^!/'",
"prepublish": "npm run build",
"prerelease": "npm test",
"prebuild": "npm run lint",
"pretest": "npm run build"
"json": "^9.0.6",
"mocha": "^5.0.1",
"mocha-junit-reporter": "^1.17.0",
"nodemon": "^1.15.1",
"rimraf": "^2.6.2",
"uglify-js": "^3.3.12"
}
}

@@ -1,2 +0,5 @@

# deep-diff [![Build Status](https://travis-ci.org/flitbit/diff.png?branch=master)](https://travis-ci.org/flitbit/diff)
# deep-diff
[![Build Status](https://travis-ci.org/flitbit/diff.png?branch=master)](https://travis-ci.org/flitbit/diff)
[![NPM](https://nodei.co/npm/deep-diff.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/deep-diff/)

@@ -15,50 +18,8 @@

`0.3.8` - 2017-05-03
* reconciled recently introduced difference between `index.es.js` and `index.js`
* improved npm commands for more reliable contributions
* added a few notes to README regarding contributing.
## Installation
`0.3.7` - 2017-05-01
* fixed issue #98 by merging @sberan's pull request #99 &mdash; better handling of property with `undefined` value existing on either operand. Unit tests supplied.
`0.3.6` - 2017-04-25 &mdash; Fixed, closed lingering issues:
* fixed #74 &mdash; comparing objects with longer cycles
* fixed #70 &mdash; was not properly detecting a deletion when a property on the operand (lhs) had a value of `undefined` and was _undefined_ on the comparand (rhs). :o).
* WARNING! [Still broken when importing in Typescript](https://github.com/flitbit/diff/issues/97).
`0.3.5` - 2017-04-23 &mdash; Rolled up recent fixes; patches:
* @stevemao &mdash; #79, #80: now testing latest version of node4
* @mortonfox &mdash; #85: referencing mocha's new home
* @tdebarochez &mdash; #90: fixed error when .toString not a function
* @thiamsantos &mdash; #92, #93: changed module system for improved es2015 modules. WARNING! [This PR broke importing `deep-diff` in Typescript as reported by @kgentes in #97](https://github.com/flitbit/diff/issues/97)
`0.3.4` - Typescript users, reference this version until #97 is fixed!
`0.3.3` - Thanks @SimenB: enabled npm script for release (alternate to the Makefile). Also linting as part of `npm test`. Thanks @joeldenning: Fixed issue #35; diffs of top level arrays now working.
`0.3.3` - Thanks @SimenB: enabled npm script for release (alternate to the Makefile). Also linting as part of `npm test`. Thanks @joeldenning: Fixed issue #35; diffs of top level arrays now working.
`0.3.2` - Resolves #46; support more robust filters by including `lhs` and `rhs` in the filter callback. By @Orlando80
`0.3.1` - Better type checking by @Drinks, UMD wrapper by @SimenB. Now certifies against nodejs 12 and iojs (Thanks @SimenB).
`0.2.0` - [Fixes Bug #17](https://github.com/flitbit/diff/issues/17), [Fixes Bug #19](https://github.com/flitbit/diff/issues/19), [Enhancement #21](https://github.com/flitbit/diff/issues/21) Applying changes that are properly structured can now be applied as a change (no longer requires typeof Diff) - supports differences being applied after round-trip serialization to JSON format. Prefilter now reports the path of all changes - it was not showing a path for arrays and anything in the structure below (reported by @ravishvt).
*Breaking Change* &ndash; The structure of change records for differences below an array element has changed. Array indexes are now reported as numeric elements in the `path` if the changes is merely edited (an `E` kind). Changes of kind `A` (array) are only reported for changes in the terminal array itself and will have a nested `N` (new) item or a nested `D` (deleted) item.
`0.1.7` - [Enhancement #11](https://github.com/flitbit/diff/issues/11) Added the ability to filter properties that should not be analyzed while calculating differences. Makes `deep-diff` more usable with frameworks that attach housekeeping properties to existing objects. AngularJS does this, and the new filter ability should ease working with it.
`0.1.6` - Changed objects within nested arrays can now be applied. They were previously recording the changes appropriately but `applyDiff` would error. Comparison of `NaN` works more sanely - comparison to number shows difference, comparison to another `Nan` does not.
## Installation
```
```bash
npm install deep-diff
```
For the browser, you can install with [bower](http://bower.io/):
```
bower install deep-diff
```
## Tests

@@ -86,12 +47,26 @@

**nodejs**
#### nodejs
```javascript
var deep = require('deep-diff')
var diff = require('deep-diff')
// or:
// const diff = require('deep-diff');
// const { diff } = require('deep-diff');
// or:
// const DeepDiff = require('deep-diff');
// const { DeepDiff } = require('deep-diff');
// es6+:
// import diff from 'deep-diff';
// import { diff } from 'deep-diff';
// es6+:
// import DeepDiff from 'deep-diff';
// import { DeepDiff } from 'deep-diff';
```
**browser**
#### browser
```html
<script src="deep-diff-0.3.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/deep-diff@1/dist/deep-diff.min.js"></script>
```
> Minified, browser release of the current version of the module is under the `releases` folder.
> In a browser, `deep-diff` defines a global variable `DeepDiff`. If there is a conflict in the global namespace you can restore the conflicting definition and assign `deep-diff` to another variable like this: `var deep = DeepDiff.noConflict();`.

@@ -128,3 +103,5 @@

```
*up to v 0.1.7* The code snippet above would result in the following structure describing the differences:
``` javascript

@@ -151,2 +128,3 @@ // Versions < 0.2.0

*v 0.2.0 and above* The code snippet above would result in the following structure describing the differences:
``` javascript

@@ -176,6 +154,6 @@ [ { kind: 'E',

* `kind` - indicates the kind of change; will be one of the following:
* `N` - indicates a newly added property/element
* `D` - indicates a property/element was deleted
* `E` - indicates a property/element was edited
* `A` - indicates a change occurred within an array
* `N` - indicates a newly added property/element
* `D` - indicates a property/element was deleted
* `E` - indicates a property/element was edited
* `A` - indicates a change occurred within an array
* `path` - the property path (from the left-hand-side root)

@@ -195,2 +173,3 @@ * `lhs` - the value on the left-hand-side of the comparison (undefined if kind === 'N')

When two objects differ, you can observe the differences as they are calculated and selectively apply those changes to the origin object (left-hand-side).
``` javascript

@@ -244,6 +223,6 @@ var observableDiff = require('deep-diff').observableDiff,

+ `lhs` - the left-hand operand; the origin object.
+ `rhs` - the right-hand operand; the object being compared structurally with the origin object.
+ `prefilter` - an optional function that determines whether difference analysis should continue down the object graph.
+ `acc` - an optional accumulator/array (requirement is that it have a `push` function). Each difference is pushed to the specified accumulator.
* `lhs` - the left-hand operand; the origin object.
* `rhs` - the right-hand operand; the object being compared structurally with the origin object.
* `prefilter` - an optional function that determines whether difference analysis should continue down the object graph.
* `acc` - an optional accumulator/array (requirement is that it have a `push` function). Each difference is pushed to the specified accumulator.

@@ -254,23 +233,10 @@ #### Pre-filtering Object Properties

# Compatibility
## Contributing
Currently testing on Travis CI against:
+ nodejs `6`
+ nodejs `5`
+ nodejs `4`
+ nodejs `0.12`
+ nodejs `0.11`
+ nodejs `0.10`
# Contributing
When contributing, keep in mind that it is an objective of `deep-diff` to have no package dependencies. This may change in the future, but for now, no-dependencies.
As of release 0.3.5, all edits/changes should be made to `index.es.js`. You must run the unit tests before submitting your PR: `npm test`. Hopefully your PR includes additional unit tests to illustrate your change/modification!
Please run the unit tests before submitting your PR: `npm test`. Hopefully your PR includes additional unit tests to illustrate your change/modification!
When you run `npm test`, linting will be performed and `index.js` will be built from `index.es.js`. Any linting errors will fail the tests... this includes code formatting.
When you run `npm test`, linting will be performed and any linting errors will fail the tests... this includes code formatting.
This module still uses `jshint` but the plan is to switch to `eslint` very soon as I have done in several of my other modules.
**Thanks to all those who have contributed so far!**
> Thanks to all those who have contributed so far!

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc