generate-json-patch
v1.2.4
Published
A simple function to diff any two objects and generate a JSON Patch
Downloads
40,214
Maintainers
Readme
generate-json-patch
Create RFC 6902 compliant JSON Patch objects based on two given JSON objects with a configurable interface.
TL;DR
- Can diff any two JSON compliant objects - returns differences as JSON Patch.
- Elegant array diffing by providing an
objectHash
to match array elements - Ignore specific keys by providing a
propertyFilter
- :paw_prints: Is it small? Zero dependencies - it's ~3 KB (minified).
- :crystal_ball: Is it fast? I haven't done any performance comparison yet.
- :hatched_chick: Is it stable? Test coverage is high, but it's still in its early days - bugs are expected.
- The interface is inspired by jsondiffpatch
- 100% Typescript
Installation
Works on node and browser environments.
npm install generate-json-patch
Usage
import { generateJSONPatch } from 'generate-json-patch';
const before = { manufacturer: "Ford", type: "Granada", year: 1972 };
const after = { manufacturer: "Ford", type: "Granada", year: 1974 };
const patch = generateJSONPatch(before, after);
console.log(patch) // => [{op: 'replace', path: '/year', value: 1974}]
Configuration
import { generateJSONPatch, JsonPatchConfig, JsonValue, ObjectHashContext } from 'generate-json-patch';
generateJSONPatch({/*...*/}, {/*...*/}, {
// called when comparing array elements
objectHash: function(value: JsonValue, context: GeneratePatchContext) {
// for arrays of primitive values like string and numbers, a stringification is sufficent:
// return JSON.stringify(value)
// If we know the shape of the value, we can match be specific properties
return value.name
},
// called for every property on objects. Can be used to ignore sensitive or irrelevant
// properties when comparing data.
propertyFilter: function (propertyName: string, context: ObjectHashContext) {
return !['sensitiveProperty'].includes(propertyName);
},
array: {
// When true, no move operations will be created.
// The rersulting patch will not lead to identical objects,
// as postions of array elements can be different!
ignoreMove: true
}
});
Patch Context
Both config function (objectHash
, propertyFilter
), receive a context as second parameter.
This allows for granular decision-making on the provided data.
Example
import {generateJSONPatch, JsonPatchConfig, JsonValue, ObjectHashContext, pathInfo} from 'generate-json-patch';
const before = {
manufacturer: "Ford",
type: "Granada",
colors: ['red', 'silver', 'yellow'],
engine: [
{ name: 'Cologne V6 2.6', hp: 125 },
{ name: 'Cologne V6 2.0', hp: 90 },
{ name: 'Cologne V6 2.3', hp: 108 },
{ name: 'Essex V6 3.0', hp: 138 },
]
}
const after = {
manufacturer: "Ford",
type: "Granada",
colors: ['red', 'silver', 'yellow'],
engine: [
{name: 'Essex V6 3.0', hp: 138},
{name: 'Cologne V6 2.6', hp: 125},
{name: 'Cologne V6 2.0', hp: 90},
{name: 'Cologne V6 2.3', hp: 108},
]
}
const patch = generateJSONPatch(before, after, {
objectHash: function (value: JsonValue, context: ObjectHashContext) {
const {length, last} = pathInfo(context.path)
if (length === 2 && last === 'engine') {
return value.name
}
return JSON.stringify(value)
}
});
console.log(patch) // => [
// { op: 'replace', path: '/engine/3/hp', value: 138 },
// { op: 'move', from: '/engine/3', path: '/engine/0' }
// ]
For more examples, check out the tests