1.1.0 • Published 8 months ago

generate-json-patch v1.1.0

Weekly downloads
-
License
MIT
Repository
github
Last release
8 months ago

generate-json-patch

Create RFC 6902 compliant JSON Patch objects based on two given JSON objects with a configurable interface.

Version Downloads/week Size Tests License TypeScript

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

1.1.0

8 months ago

1.0.1

9 months ago

1.0.0

9 months ago

0.0.5

9 months ago

0.0.6

9 months ago

0.0.4

10 months ago

0.0.3

10 months ago

0.0.2

10 months ago

0.0.1

10 months ago