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

rfc6902

Package Overview
Dependencies
Maintainers
1
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

rfc6902 - npm Package Compare versions

Comparing version 0.0.2 to 0.0.3

117

diff.js
'use strict'; /*jslint node: true, es5: true, indent: 2 */
var async = require('async');
var optimist = require('optimist');
var underscore = require('underscore');
var pointer = require('./pointer');
var errors = require('./errors');
// var temp = require('temp');
// temp.track();
var _union = function(xs) {
var obj = {};
xs.forEach(function(x) {
for (var key in x) {
obj[key] = 1;
}
});
return Object.keys(obj);
};
// error:
// {op: 'add', message: 'nonexistent target'}
var _subtract = function(a, b) {
var obj = {};
for (var add_key in a) {
obj[add_key] = 1;
}
for (var del_key in b) {
delete obj[del_key];
}
return Object.keys(obj);
};
var _intersection = function(xs) {
// start similarly to _union
var obj = {};
xs.forEach(function(x) {
for (var key in x) {
obj[key] = (obj[key] || 0) + 1;
}
});
// but then, extra requirement: delete less commonly-seen keys
var threshold = xs.length;
for (var key in obj) {
if (obj[key] < threshold) {
delete obj[key];
}
}
return Object.keys(obj);
};
var _diffArrays = function(input, output, ptr) {
// do the stupid thing first...
var operations = [];
for (var i = 0, l = Math.max(input.length, output.length); i < l; i++) {
var operation = _diff(input[i], output[i], ptr.add(i));
operations.push(operation);
// if (input[i] !== undefined && output[i] !== ) {
}
// TODO here
return operations;
};
var _diffObjects = function(input, output, ptr) {
// if a key is in input but not output -> remove
var operations = [];
_subtract(input, output).forEach(function(key) {
operations.push({op: 'remove', path: ptr.add(key)});
});
// if a key is in output but not input -> add
_subtract(output, input).forEach(function(key) {
operations.push({op: 'add', path: ptr.add(key), value: output[key]});
});
// if a key is in both, diff it
_intersection([input, output]).forEach(function(key) {
operations = operations.concat(_diff(input[key], output[key], ptr.add(key)));
});
return operations;
};
var _diff = function(input, output, ptr) {
// Arrays first, since Arrays are subsets of Objects
if (Array.isArray(input) && Array.isArray(output)) {
return _diffArrays(input, output, ptr);
}
if (input === Object(input) && output === Object(output)) {
return _diffObjects(input, output, ptr);
}
// only pairs of arrays and objects can go down a path to produce a smaller diff;
// everything else must be wholesale replaced
return [{op: 'replace', path: ptr.toString(), value: output}];
};
var diff = module.exports = function(input, output) {
/** Produce a 'application/json-patch+json'-type patch to get from one object to another
Returns list of operations to perform on `input` to produce `output`.
*/
var ptr = new pointer.Pointer();
return _diff(input, output, ptr);
};
var print_diff = function(input, output) {
console.log('input:', input);
console.log('output:', output);
var ops = diff(input, output);
var util = require('util');
console.log('ops...');
ops.forEach(function(op) {
// var op_str = util.inspect(op, {depth: null});
console.log(JSON.stringify(op, null, ' '));
});
};
print_diff({level: 5, difficulty: 'hard'}, {level: 6, player: {name: 'chris'}});

2

package.json
{
"name": "rfc6902",
"version": "0.0.2",
"version": "0.0.3",
"description": "Complete implementation of RFC6902 (patch and diff)",

@@ -5,0 +5,0 @@ "keywords": [

@@ -33,7 +33,21 @@ 'use strict'; /*jslint node: true, es5: true, indent: 2 */

var at = exports.at = function(obj, pointer) {
var Pointer = exports.Pointer = function(tokens) {
/** JSON Pointer (http://tools.ietf.org/html/rfc6901) resolver.
*/
this.tokens = tokens || [''];
};
Pointer.parse = function(path) {
/**
`path` *must* be a properly escaped string.
*/
var tokens = path.split('/').map(unescape);
if (tokens[0] !== '') throw new Error('Invalid JSON Pointer: ' + path);
return new Pointer(tokens);
};
Pointer.prototype.toString = Pointer.prototype.toJSON = function() {
return this.tokens.map(escape).join('/');
};
Pointer.prototype.evaluate = function(object) {
/**
`pointer` *must* be a string.
Returns an object with 'parent', 'key', and 'value' properties.

@@ -43,12 +57,9 @@ In the special case that pointer = "", parent and key will be null, and `value = obj`

*/
var tokens = pointer.split('/').map(unescape);
if (tokens[0] !== '') throw new Error('Invalid JSON Pointer: ' + pointer);
var parent = null;
var token = null;
for (var i = 1, l = tokens.length; i < l; i++) {
parent = obj;
token = tokens[i];
for (var i = 1, l = this.tokens.length; i < l; i++) {
parent = object;
token = this.tokens[i];
// not sure if this the best way to handle non-existant paths...
obj = (parent || {})[token];
object = (parent || {})[token];
}

@@ -58,4 +69,18 @@ return {

key: token,
value: obj,
value: object,
};
};
Pointer.prototype.push = function(token) {
// mutable
this.tokens.push(token);
};
Pointer.prototype.add = function(token) {
// immutable (shallowly)
var tokens = Array.prototype.concat.call([], this.tokens, [token]);
return new Pointer(tokens);
};
var at = exports.at = function(object, path) {
var pointer = Pointer.parse(path);
return pointer.evaluate(object);
};
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