Skip to content

JSONPatch Formatter Results Are Invalid With Multiple Moves #380

@mgreystone

Description

@mgreystone

When performing multiple move operations, the results from the jsonpatch formatter are not correct. Applying them does not results in the desired object.

Here is an example reversing the items in an array.

import { create } from 'jsondiffpatch'
import { format } from 'jsondiffpatch/formatters/jsonpatch'
import jsonpatch from 'jsonpatch'

const jsondiffpatch = create({
  arrays: {
    detectMove: true,
  },
});

const a = ["first", "second", "third", "fourth", "fifth"];
const b = ["fifth", "fourth", "third", "second", "first"];

const diff = jsondiffpatch.diff(a, b);
/*
diff is {
  _t: 'a',
  _1: [ '', 3, 3 ],
  _2: [ '', 2, 3 ],
  _3: [ '', 1, 3 ],
  _4: [ '', 0, 3 ]
}
*/

const patchedwithdiff = jsondiffpatch.patch(a, diff)
/*
This is correct:
patchedwithdiff is [ 'fifth', 'fourth', 'third', 'second', 'first' ]
*/

const patch = format(diff, a)
/*
This is not correct:
patch is: [
  { op: 'move', from: '/1', path: '/3' },
  { op: 'move', from: '/2', path: '/2' },
  { op: 'move', from: '/3', path: '/1' },
  { op: 'move', from: '/4', path: '/0' }
]
---
There are many ways to get the desired results,
but one way looks like this: [
  { op: 'move', from: '/0', path: '/4' },
  { op: 'move', from: '/0', path: '/4' },
  { op: 'move', from: '/0', path: '/4' },
  { op: 'move', from: '/0', path: '/4' },
  { op: 'move', from: '/0', path: '/4' },
]
*/

const patchedwithjson = jsonpatch.apply_patch(a, patch)
/*
patchedwithjson is: [ 'first', 'fifth', 'fourth', 'third', 'second' ]
we expected: ["fifth", "fourth", "third", "second", "first"]
*/

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions