ltwlf / json-diff-ts

A diff tool for JavaScript written in TypeScript.
MIT License
77 stars 24 forks source link

Problem with unflattenChanges when key has periods (`.`) #133

Closed andrewkucz closed 4 months ago

andrewkucz commented 7 months ago

Hello, first off, thank you for the library I think it is great and Im really enjoying using it.

I think I discovered an issue when attempting to unflatten changes that include a path whose key attribute contains a period.

Take the following example, loosely based on the example in the readme.

import { applyChangeset, diff, flattenChangeset, unflattenChanges } from 'json-diff-ts';

const oldData = {
  characters: [
    { id: 'LUK.SKY', name: 'Luke Skywalker', force: true },
    { id: 'LEI.ORG', name: 'Leia Organa', force: true }
  ]
};

const newData = {
  characters: [
    { id: 'LUK.SKY', name: 'Luke Skywalker', force: false },
    { id: 'LEI.ORG', name: 'Leia Organa', force: true }
  ]
};

const diffs = diff(oldData, newData, { characters: 'id' });

const flattened = flattenChangeset(diffs)
console.log('flattened', flattened)

const unflattened = unflattenChanges(flattened)
console.log('unflattened', unflattened)

// this throws an error
const applied = applyChangeset(oldData, unflattened)

Notably, I've added periods to the characters' ids and simplified the data for the sake of example.

This yields the following output:

flattened [
  {
    type: 'UPDATE',
    key: 'force',
    value: false,
    oldValue: true,
    path: "$.characters[?(@.id=='LUK.SKY')].force",
    valueType: 'Boolean'
  }
]
unflattened [
  {
    key: "characters[?(@.id=='LUK",
    type: 'UPDATE',
    changes: [ [Object] ]
  }
]
file:///Users/andrew/Desktop/diff-test/node_modules/json-diff-ts/lib/jsonDiff.js:43
        changeset.forEach((change) => {
                  ^
TypeError: Cannot read properties of undefined (reading 'SKY')]')
    at file:///Users/andrew/Desktop/diff-test/node_modules/json-diff-ts/lib/jsonDiff.js:51:38
    at Array.forEach (<anonymous>)
    at applyChangeset (file:///Users/andrew/Desktop/diff-test/node_modules/json-diff-ts/lib/jsonDiff.js:43:19)
    at applyBranchChange (file:///Users/andrew/Desktop/diff-test/node_modules/json-diff-ts/lib/jsonDiff.js:513:16)
    at file:///Users/andrew/Desktop/diff-test/node_modules/json-diff-ts/lib/jsonDiff.js:51:17
    at Array.forEach (<anonymous>)
    at applyChangeset (file:///Users/andrew/Desktop/diff-test/node_modules/json-diff-ts/lib/jsonDiff.js:43:19)
    at file:///Users/andrew/Desktop/diff-test/index.ts:27:17
    at ModuleJob.run (node:internal/modules/esm/module_job:194:25)

I suspect this is related to regex somewhere, since the key in "unflattened" stops just shy of the period: key: "characters[?(@.id=='LUK"

Thanks