From 23c12c086c61728466e1ced5e621548fbd420492 Mon Sep 17 00:00:00 2001 From: lukascivil Date: Sun, 23 Jul 2023 00:18:54 -0300 Subject: [PATCH 1/5] feat: add json patch generator --- .../src/core/generate-json-patch.spec.ts | 59 +++++++++++++++++++ .../src/core/generate-json-patch.ts | 31 ++++++++++ .../src/models/jsondiffer.model.ts | 19 ++++++ 3 files changed, 109 insertions(+) create mode 100644 libs/json-difference/src/core/generate-json-patch.spec.ts create mode 100644 libs/json-difference/src/core/generate-json-patch.ts diff --git a/libs/json-difference/src/core/generate-json-patch.spec.ts b/libs/json-difference/src/core/generate-json-patch.spec.ts new file mode 100644 index 0000000..51ee43d --- /dev/null +++ b/libs/json-difference/src/core/generate-json-patch.spec.ts @@ -0,0 +1,59 @@ +// Packages +import { getDiff } from '.' + +// Models +import { JsonPatch } from '../models/jsondiffer.model' +import { generateJsonPatch } from './generate-json-patch' + +describe('GenerateJsonPatch function', () => { + test('Should return the difference between two basic structures', () => { + const struct1 = { '0': [{ '0': 1 }] } + const struct2 = { '0': { '0': [1] } } + const expectedResult: Array = [ + { op: 'remove', path: '0/0' }, + { op: 'remove', path: '0/0/0[]' }, + { op: 'replace', path: '0', value: [] }, + { op: 'add', path: '0/0[]', value: {} }, + { op: 'add', path: '0/0[]/0', value: 1 } + ] + const delta = getDiff(struct1, struct2) + const result = generateJsonPatch(delta) + + expect(result).toEqual(expectedResult) + }) + + test('Should return the difference between two basic structures', () => { + const struct1 = { + baz: 'qux', + foo: 'bar' + } + const struct2 = { + baz: 'boo', + hello: ['world'] + } + const expectedResult: Array = [ + { + op: 'remove', + path: 'hello' + }, + { + op: 'remove', + path: 'hello/0[]' + }, + { + op: 'replace', + path: 'baz', + value: 'qux' + }, + { + op: 'add', + path: 'foo', + value: 'bar' + } + ] + const delta = getDiff(struct1, struct2) + const result = generateJsonPatch(delta) + + expect(result).toEqual(expectedResult) + }) +}) diff --git a/libs/json-difference/src/core/generate-json-patch.ts b/libs/json-difference/src/core/generate-json-patch.ts new file mode 100644 index 0000000..890563f --- /dev/null +++ b/libs/json-difference/src/core/generate-json-patch.ts @@ -0,0 +1,31 @@ +// Models +import { Delta, JsonPatch } from '../models/jsondiffer.model' + +export const generateJsonPatch = (delta: Delta): Array => { + const operations: Array = [] + + delta.added.forEach((path) => { + operations.push({ + op: 'remove', + path: path[0] + }) + }) + + delta.edited.forEach((path) => { + operations.push({ + op: 'replace', + path: path[0], + value: path[1] + }) + }) + + delta.removed.forEach((path) => { + operations.push({ + op: 'add', + path: path[0], + value: path[1] + }) + }) + + return operations +} diff --git a/libs/json-difference/src/models/jsondiffer.model.ts b/libs/json-difference/src/models/jsondiffer.model.ts index 659fa7c..5254c98 100644 --- a/libs/json-difference/src/models/jsondiffer.model.ts +++ b/libs/json-difference/src/models/jsondiffer.model.ts @@ -13,3 +13,22 @@ export interface Delta { export interface JsonDiffOptions { isLodashLike?: boolean } + +export interface JsonPatchRemove { + op: 'remove' + path: string +} + +export interface JsonPatchReplace { + op: 'replace' + path: string + value: any +} + +export interface JsonPatchAdd { + op: 'add' + path: string + value: any +} + +export type JsonPatch = JsonPatchRemove | JsonPatchReplace | JsonPatchAdd From 3dc9bf603eb275b6ecea3a0786d4c17b78f83301 Mon Sep 17 00:00:00 2001 From: lukascivil Date: Sun, 23 Jul 2023 00:50:01 -0300 Subject: [PATCH 2/5] Update generate-json-patch.spec.ts --- libs/json-difference/src/core/generate-json-patch.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/json-difference/src/core/generate-json-patch.spec.ts b/libs/json-difference/src/core/generate-json-patch.spec.ts index 51ee43d..471abe5 100644 --- a/libs/json-difference/src/core/generate-json-patch.spec.ts +++ b/libs/json-difference/src/core/generate-json-patch.spec.ts @@ -6,7 +6,7 @@ import { JsonPatch } from '../models/jsondiffer.model' import { generateJsonPatch } from './generate-json-patch' describe('GenerateJsonPatch function', () => { - test('Should return the difference between two basic structures', () => { + test('Should generate JSON Patch operations from delta', () => { const struct1 = { '0': [{ '0': 1 }] } const struct2 = { '0': { '0': [1] } } const expectedResult: Array = [ @@ -22,7 +22,7 @@ describe('GenerateJsonPatch function', () => { expect(result).toEqual(expectedResult) }) - test('Should return the difference between two basic structures', () => { + test('Should generate JSON Patch operations from delta', () => { const struct1 = { baz: 'qux', foo: 'bar' From 47166f1776bc7864f875d3ce80e9775899641b31 Mon Sep 17 00:00:00 2001 From: lukascivil Date: Sun, 23 Jul 2023 00:53:47 -0300 Subject: [PATCH 3/5] refactor: adjust path --- .../src/core/generate-json-patch.spec.ts | 2 +- .../src/core/generate-json-patch.ts | 2 +- .../json-difference/src/core/get-diff.spec.ts | 2 +- libs/json-difference/src/core/get-diff.ts | 2 +- .../src/core/get-edited-paths.spec.ts | 2 +- .../src/core/get-edited-paths.ts | 2 +- .../src/core/get-paths-diff.spec.ts | 2 +- .../src/core/get-paths-diff.ts | 2 +- .../src/core/get-struct-paths.ts | 2 +- libs/json-difference/src/models/index.ts | 2 +- .../src/models/json-difference.model.ts | 34 +++++++++++++++++++ 11 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 libs/json-difference/src/models/json-difference.model.ts diff --git a/libs/json-difference/src/core/generate-json-patch.spec.ts b/libs/json-difference/src/core/generate-json-patch.spec.ts index 471abe5..fc5cd61 100644 --- a/libs/json-difference/src/core/generate-json-patch.spec.ts +++ b/libs/json-difference/src/core/generate-json-patch.spec.ts @@ -2,7 +2,7 @@ import { getDiff } from '.' // Models -import { JsonPatch } from '../models/jsondiffer.model' +import { JsonPatch } from '../models/json-difference.model' import { generateJsonPatch } from './generate-json-patch' describe('GenerateJsonPatch function', () => { diff --git a/libs/json-difference/src/core/generate-json-patch.ts b/libs/json-difference/src/core/generate-json-patch.ts index 890563f..3412aa8 100644 --- a/libs/json-difference/src/core/generate-json-patch.ts +++ b/libs/json-difference/src/core/generate-json-patch.ts @@ -1,5 +1,5 @@ // Models -import { Delta, JsonPatch } from '../models/jsondiffer.model' +import { Delta, JsonPatch } from '../models/json-difference.model' export const generateJsonPatch = (delta: Delta): Array => { const operations: Array = [] diff --git a/libs/json-difference/src/core/get-diff.spec.ts b/libs/json-difference/src/core/get-diff.spec.ts index 6d542e3..272bcfc 100644 --- a/libs/json-difference/src/core/get-diff.spec.ts +++ b/libs/json-difference/src/core/get-diff.spec.ts @@ -2,7 +2,7 @@ import { getDiff } from '.' // Models -import { Delta } from '../models/jsondiffer.model' +import { Delta } from '../models/json-difference.model' describe('GetDiff function', () => { test('Should return the difference between two basic structures', () => { diff --git a/libs/json-difference/src/core/get-diff.ts b/libs/json-difference/src/core/get-diff.ts index 9b223d7..8c7a542 100644 --- a/libs/json-difference/src/core/get-diff.ts +++ b/libs/json-difference/src/core/get-diff.ts @@ -4,8 +4,8 @@ import { getPathsDiff } from './get-paths-diff' import { getStructPaths } from './get-struct-paths' // Models -import { Delta, JsonDiffOptions } from '../models/jsondiffer.model' import sanitizeDelta from '../helpers/sanitize-delta' +import { Delta, JsonDiffOptions } from '../models/json-difference.model' const defaultOptions: JsonDiffOptions = { isLodashLike: false diff --git a/libs/json-difference/src/core/get-edited-paths.spec.ts b/libs/json-difference/src/core/get-edited-paths.spec.ts index 33b8473..1c6556a 100644 --- a/libs/json-difference/src/core/get-edited-paths.spec.ts +++ b/libs/json-difference/src/core/get-edited-paths.spec.ts @@ -1,5 +1,5 @@ import { getEditedPaths } from '.' -import { EditedPath } from '../models/jsondiffer.model' +import { EditedPath } from '../models/json-difference.model' describe('GetEditedPaths function', () => { test('Should return empty when there is no edited value', () => { diff --git a/libs/json-difference/src/core/get-edited-paths.ts b/libs/json-difference/src/core/get-edited-paths.ts index 31d41dc..e9f3d33 100644 --- a/libs/json-difference/src/core/get-edited-paths.ts +++ b/libs/json-difference/src/core/get-edited-paths.ts @@ -1,5 +1,5 @@ // Models -import { EditedPath, StructPaths } from '../models/jsondiffer.model' +import { EditedPath, StructPaths } from '../models/json-difference.model' /** * This method returns all paths whose leaf value has changed diff --git a/libs/json-difference/src/core/get-paths-diff.spec.ts b/libs/json-difference/src/core/get-paths-diff.spec.ts index 821d8d9..63a7a12 100644 --- a/libs/json-difference/src/core/get-paths-diff.spec.ts +++ b/libs/json-difference/src/core/get-paths-diff.spec.ts @@ -1,6 +1,6 @@ // Packages import { getPathsDiff } from '.' -import { PathsDiff } from '../models/jsondiffer.model' +import { PathsDiff } from '../models/json-difference.model' describe('GetPathsDiff function', () => { test('Should return empty when there is no key difference', () => { diff --git a/libs/json-difference/src/core/get-paths-diff.ts b/libs/json-difference/src/core/get-paths-diff.ts index e75b95e..fb7482c 100644 --- a/libs/json-difference/src/core/get-paths-diff.ts +++ b/libs/json-difference/src/core/get-paths-diff.ts @@ -1,5 +1,5 @@ // Models -import { PathsDiff, StructPaths } from '../models/jsondiffer.model' +import { PathsDiff, StructPaths } from '../models/json-difference.model' /** * This method returns all paths whose leaf value has changed diff --git a/libs/json-difference/src/core/get-struct-paths.ts b/libs/json-difference/src/core/get-struct-paths.ts index d64786d..a896348 100644 --- a/libs/json-difference/src/core/get-struct-paths.ts +++ b/libs/json-difference/src/core/get-struct-paths.ts @@ -1,5 +1,5 @@ // Models -import { StructPaths } from '../models/jsondiffer.model' +import { StructPaths } from '../models/json-difference.model' const generatePath = (isArray: boolean, currentPath: string, newPath: string, lodashLike: boolean): string => { const prefix = lodashLike ? (isArray ? '[' : '.') : '/' diff --git a/libs/json-difference/src/models/index.ts b/libs/json-difference/src/models/index.ts index 62d3b9a..f8f1f66 100644 --- a/libs/json-difference/src/models/index.ts +++ b/libs/json-difference/src/models/index.ts @@ -1 +1 @@ -export * from './jsondiffer.model' +export * from './json-difference.model' diff --git a/libs/json-difference/src/models/json-difference.model.ts b/libs/json-difference/src/models/json-difference.model.ts new file mode 100644 index 0000000..5254c98 --- /dev/null +++ b/libs/json-difference/src/models/json-difference.model.ts @@ -0,0 +1,34 @@ +export type EditedPath = [string, any, any] + +export type StructPaths = Record + +export type PathsDiff = [string, any] + +export interface Delta { + added: Array + removed: Array + edited: Array +} + +export interface JsonDiffOptions { + isLodashLike?: boolean +} + +export interface JsonPatchRemove { + op: 'remove' + path: string +} + +export interface JsonPatchReplace { + op: 'replace' + path: string + value: any +} + +export interface JsonPatchAdd { + op: 'add' + path: string + value: any +} + +export type JsonPatch = JsonPatchRemove | JsonPatchReplace | JsonPatchAdd From 44b98c7a41610bcecb866a4a1d8ed323ce66f679 Mon Sep 17 00:00:00 2001 From: lukascivil Date: Sat, 30 Dec 2023 12:23:26 -0300 Subject: [PATCH 4/5] Delete jsondiffer.model.ts --- .../src/models/jsondiffer.model.ts | 34 ------------------- 1 file changed, 34 deletions(-) delete mode 100644 libs/json-difference/src/models/jsondiffer.model.ts diff --git a/libs/json-difference/src/models/jsondiffer.model.ts b/libs/json-difference/src/models/jsondiffer.model.ts deleted file mode 100644 index 5254c98..0000000 --- a/libs/json-difference/src/models/jsondiffer.model.ts +++ /dev/null @@ -1,34 +0,0 @@ -export type EditedPath = [string, any, any] - -export type StructPaths = Record - -export type PathsDiff = [string, any] - -export interface Delta { - added: Array - removed: Array - edited: Array -} - -export interface JsonDiffOptions { - isLodashLike?: boolean -} - -export interface JsonPatchRemove { - op: 'remove' - path: string -} - -export interface JsonPatchReplace { - op: 'replace' - path: string - value: any -} - -export interface JsonPatchAdd { - op: 'add' - path: string - value: any -} - -export type JsonPatch = JsonPatchRemove | JsonPatchReplace | JsonPatchAdd From 5bbb905c325dc564f3c5b3aa605a46601c774f77 Mon Sep 17 00:00:00 2001 From: lukascivil Date: Sat, 30 Dec 2023 12:26:10 -0300 Subject: [PATCH 5/5] Update sanitize-delta.spec.ts --- libs/json-difference/src/helpers/sanitize-delta.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/json-difference/src/helpers/sanitize-delta.spec.ts b/libs/json-difference/src/helpers/sanitize-delta.spec.ts index 630ddaf..a5cd9da 100644 --- a/libs/json-difference/src/helpers/sanitize-delta.spec.ts +++ b/libs/json-difference/src/helpers/sanitize-delta.spec.ts @@ -2,7 +2,7 @@ import sanitizeDelta from './sanitize-delta' // Models -import { Delta } from '../models/jsondiffer.model' +import { Delta } from '../models/json-difference.model' describe('sanitizeDelta helper', () => { test.only('Should remove unnecessary @{}', () => {