Skip to content

Commit

Permalink
fix: respect maxDepth for array values
Browse files Browse the repository at this point in the history
  • Loading branch information
marcolink committed Sep 3, 2024
1 parent dbf3739 commit 623fc53
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 4 deletions.
52 changes: 51 additions & 1 deletion src/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,7 @@ describe('a generate json patch function', () => {
fourthLevel: 'hello-world',
},
thirdLevelTwo: 'hello',
thirdLevelThree: ['hello', 'world'],
},
},
};
Expand All @@ -673,6 +674,7 @@ describe('a generate json patch function', () => {
fourthLevel: 'hello-brave-new-world',
},
thirdLevelTwo: 'hello',
thirdLevelThree: ['hello', 'world'],
},
},
};
Expand All @@ -688,13 +690,16 @@ describe('a generate json patch function', () => {
fourthLevel: 'hello-brave-new-world',
},
thirdLevelTwo: 'hello',
thirdLevelThree: ['hello', 'world'],
},
},
]);
});

it('detects changes as a given depth of 4', () => {
const patch = generateJSONPatch(before, after, { maxDepth: 4 });
const afterModified = structuredClone(after);
afterModified.firstLevel.secondLevel.thirdLevelTwo = 'hello-world';
const patch = generateJSONPatch(before, afterModified, { maxDepth: 4 });
expect(patch).to.eql([
{
op: 'replace',
Expand All @@ -703,6 +708,51 @@ describe('a generate json patch function', () => {
fourthLevel: 'hello-brave-new-world',
},
},
{
op: 'replace',
path: '/firstLevel/secondLevel/thirdLevelTwo',
value: 'hello-world',
},
]);
});

it('detects changes as a given depth of 4 for an array value', () => {
const afterModified = structuredClone(before);
afterModified.firstLevel.secondLevel.thirdLevelThree = ['test'];
const patch = generateJSONPatch(before, afterModified, { maxDepth: 4 });
expect(patch).to.eql([
{
op: 'replace',
path: '/firstLevel/secondLevel/thirdLevelThree',
value: ['test'],
},
]);
});

it('detects changes as a given depth of 4 for an removed array value', () => {
const afterModified = structuredClone(before);
// @ts-ignore
delete afterModified.firstLevel.secondLevel.thirdLevelThree;
const patch = generateJSONPatch(before, afterModified, { maxDepth: 4 });
expect(patch).to.eql([
{
op: 'remove',
path: '/firstLevel/secondLevel/thirdLevelThree',
},
]);
});

it('detects changes as a given depth of 4 for an nullyfied array value', () => {
const afterModified = structuredClone(before);
// @ts-ignore
afterModified.firstLevel.secondLevel.thirdLevelThree = null;
const patch = generateJSONPatch(before, afterModified, { maxDepth: 4 });
expect(patch).to.eql([
{
op: 'replace',
path: '/firstLevel/secondLevel/thirdLevelThree',
value: null,
},
]);
});
});
Expand Down
17 changes: 14 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ export function generateJSONPatch(
const patch: Patch = [];
const hasPropertyFilter = typeof propertyFilter === 'function';

function maxDepthReached(path: string) {
return maxDepth <= path.split('/').length;
}

function compareArrays(leftArr: any[], rightArr: any[], path: string) {
// if arrays are equal, no further comparison is required
if (JSON.stringify(leftArr) === JSON.stringify(rightArr)) return;
Expand All @@ -105,6 +109,11 @@ export function generateJSONPatch(
let currentIndex = leftArr.length - 1;
const targetHashes: string[] = [];

if (maxDepthReached(path)) {
patch.push({ op: 'replace', path: path, value: rightArr });
return;
}

// Change iteration direction: from back to front
for (let i = leftArr.length - 1; i >= 0; i--) {
const newPathIndex = `${path}/${currentIndex--}`;
Expand Down Expand Up @@ -154,7 +163,7 @@ export function generateJSONPatch(
path === '' && [leftJsonValue, rightJsonValue].every(Array.isArray);

if (isPrimitiveValue(leftJsonValue) || isPrimitiveValue(rightJsonValue)) {
if (leftJsonValue !== rightJsonValue) {
if (JSON.stringify(leftJsonValue) !== JSON.stringify(rightJsonValue)) {
patch.push({ op: 'replace', path: path, value: rightJsonValue });
}
return;
Expand Down Expand Up @@ -186,8 +195,10 @@ export function generateJSONPatch(
compareArrays(leftValue, rightValue, newPath);
} else if (isJsonObject(rightValue)) {
if (isJsonObject(leftValue)) {
if (maxDepth <= newPath.split('/').length) {
patch.push({ op: 'replace', path: newPath, value: rightValue });
if (maxDepthReached(newPath)) {
if (JSON.stringify(leftValue) !== JSON.stringify(rightValue)) {
patch.push({ op: 'replace', path: newPath, value: rightValue });
}
} else {
compareObjects(newPath, leftValue, rightValue);
}
Expand Down

0 comments on commit 623fc53

Please sign in to comment.