json-diff-ts 3.0.0-beta.4 → 3.0.0-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -37,7 +37,7 @@ __export(src_exports, {
37
37
  module.exports = __toCommonJS(src_exports);
38
38
 
39
39
  // src/jsonDiff.ts
40
- var import_lodash_es = require("lodash-es");
40
+ var import_lodash = require("lodash");
41
41
  var Operation = /* @__PURE__ */ ((Operation2) => {
42
42
  Operation2["REMOVE"] = "REMOVE";
43
43
  Operation2["ADD"] = "ADD";
@@ -274,7 +274,7 @@ var compareObject = (oldObj, newObj, path, embeddedObjKeys, keyPath, skipPath =
274
274
  let changes = [];
275
275
  const oldObjKeys = Object.keys(oldObj).filter((key) => keysToSkip.indexOf(key) === -1);
276
276
  const newObjKeys = Object.keys(newObj).filter((key) => keysToSkip.indexOf(key) === -1);
277
- const intersectionKeys = (0, import_lodash_es.intersection)(oldObjKeys, newObjKeys);
277
+ const intersectionKeys = (0, import_lodash.intersection)(oldObjKeys, newObjKeys);
278
278
  for (k of intersectionKeys) {
279
279
  newPath = path.concat([k]);
280
280
  newKeyPath = skipPath ? keyPath : keyPath.concat([k]);
@@ -283,7 +283,7 @@ var compareObject = (oldObj, newObj, path, embeddedObjKeys, keyPath, skipPath =
283
283
  changes = changes.concat(diffs);
284
284
  }
285
285
  }
286
- const addedKeys = (0, import_lodash_es.difference)(newObjKeys, oldObjKeys);
286
+ const addedKeys = (0, import_lodash.difference)(newObjKeys, oldObjKeys);
287
287
  for (k of addedKeys) {
288
288
  newPath = path.concat([k]);
289
289
  newKeyPath = skipPath ? keyPath : keyPath.concat([k]);
@@ -293,7 +293,7 @@ var compareObject = (oldObj, newObj, path, embeddedObjKeys, keyPath, skipPath =
293
293
  value: newObj[k]
294
294
  });
295
295
  }
296
- const deletedKeys = (0, import_lodash_es.difference)(oldObjKeys, newObjKeys);
296
+ const deletedKeys = (0, import_lodash.difference)(oldObjKeys, newObjKeys);
297
297
  for (k of deletedKeys) {
298
298
  newPath = path.concat([k]);
299
299
  newKeyPath = skipPath ? keyPath : keyPath.concat([k]);
@@ -352,7 +352,7 @@ var convertArrayToObj = (arr, uniqKey) => {
352
352
  obj[value] = value;
353
353
  });
354
354
  } else if (uniqKey !== "$index") {
355
- obj = (0, import_lodash_es.keyBy)(arr, uniqKey);
355
+ obj = (0, import_lodash.keyBy)(arr, uniqKey);
356
356
  } else {
357
357
  for (let i = 0; i < arr.length; i++) {
358
358
  const value = arr[i];
@@ -437,7 +437,7 @@ var applyArrayChange = (arr, change) => (() => {
437
437
  element = arr[index];
438
438
  }
439
439
  } else {
440
- element = (0, import_lodash_es.find)(arr, (el) => el[change.embeddedKey]?.toString() === subchange.key.toString());
440
+ element = (0, import_lodash.find)(arr, (el) => el[change.embeddedKey]?.toString() === subchange.key.toString());
441
441
  }
442
442
  result.push(applyChangeset(element, subchange.changes));
443
443
  }
@@ -472,7 +472,7 @@ var revertArrayChange = (arr, change) => (() => {
472
472
  if (change.embeddedKey === "$index") {
473
473
  element = arr[+subchange.key];
474
474
  } else {
475
- element = (0, import_lodash_es.find)(arr, (el) => el[change.embeddedKey].toString() === subchange.key);
475
+ element = (0, import_lodash.find)(arr, (el) => el[change.embeddedKey].toString() === subchange.key);
476
476
  }
477
477
  result.push(revertChangeset(element, subchange.changes));
478
478
  }
@@ -495,7 +495,7 @@ function filterExpression(basePath, filterKey, filterValue) {
495
495
  }
496
496
 
497
497
  // src/jsonCompare.ts
498
- var import_lodash_es2 = require("lodash-es");
498
+ var import_lodash2 = require("lodash");
499
499
  var CompareOperation = /* @__PURE__ */ ((CompareOperation2) => {
500
500
  CompareOperation2["CONTAINER"] = "CONTAINER";
501
501
  CompareOperation2["UNCHANGED"] = "UNCHANGED";
@@ -510,12 +510,12 @@ var enrich = (object) => {
510
510
  const objectType = getTypeOfObj(object);
511
511
  switch (objectType) {
512
512
  case "Object":
513
- return (0, import_lodash_es2.keys)(object).map((key) => ({ key, value: enrich(object[key]) })).reduce((accumulator, entry) => {
513
+ return (0, import_lodash2.keys)(object).map((key) => ({ key, value: enrich(object[key]) })).reduce((accumulator, entry) => {
514
514
  accumulator.value[entry.key] = entry.value;
515
515
  return accumulator;
516
516
  }, createContainer({}));
517
517
  case "Array":
518
- return (0, import_lodash_es2.chain)(object).map((value) => enrich(value)).reduce((accumulator, value) => {
518
+ return (0, import_lodash2.chain)(object).map((value) => enrich(value)).reduce((accumulator, value) => {
519
519
  accumulator.value.push(value);
520
520
  return accumulator;
521
521
  }, createContainer([])).value();
@@ -527,17 +527,17 @@ var enrich = (object) => {
527
527
  }
528
528
  };
529
529
  var applyChangelist = (object, changelist) => {
530
- (0, import_lodash_es2.chain)(changelist).map((entry) => ({ ...entry, path: (0, import_lodash_es2.replace)(entry.path, "$.", ".") })).map((entry) => ({
530
+ (0, import_lodash2.chain)(changelist).map((entry) => ({ ...entry, path: (0, import_lodash2.replace)(entry.path, "$.", ".") })).map((entry) => ({
531
531
  ...entry,
532
- path: (0, import_lodash_es2.replace)(entry.path, /(\[(?<array>\d)\]\.)/g, "ARRVAL_START$<array>ARRVAL_END")
533
- })).map((entry) => ({ ...entry, path: (0, import_lodash_es2.replace)(entry.path, /(?<dot>\.)/g, ".value$<dot>") })).map((entry) => ({ ...entry, path: (0, import_lodash_es2.replace)(entry.path, /\./, "") })).map((entry) => ({ ...entry, path: (0, import_lodash_es2.replace)(entry.path, /ARRVAL_START/g, ".value[") })).map((entry) => ({ ...entry, path: (0, import_lodash_es2.replace)(entry.path, /ARRVAL_END/g, "].value.") })).value().forEach((entry) => {
532
+ path: (0, import_lodash2.replace)(entry.path, /(\[(?<array>\d)\]\.)/g, "ARRVAL_START$<array>ARRVAL_END")
533
+ })).map((entry) => ({ ...entry, path: (0, import_lodash2.replace)(entry.path, /(?<dot>\.)/g, ".value$<dot>") })).map((entry) => ({ ...entry, path: (0, import_lodash2.replace)(entry.path, /\./, "") })).map((entry) => ({ ...entry, path: (0, import_lodash2.replace)(entry.path, /ARRVAL_START/g, ".value[") })).map((entry) => ({ ...entry, path: (0, import_lodash2.replace)(entry.path, /ARRVAL_END/g, "].value.") })).value().forEach((entry) => {
534
534
  switch (entry.type) {
535
535
  case "ADD" /* ADD */:
536
536
  case "UPDATE" /* UPDATE */:
537
- (0, import_lodash_es2.set)(object, entry.path, { type: entry.type, value: entry.value, oldValue: entry.oldValue });
537
+ (0, import_lodash2.set)(object, entry.path, { type: entry.type, value: entry.value, oldValue: entry.oldValue });
538
538
  break;
539
539
  case "REMOVE" /* REMOVE */:
540
- (0, import_lodash_es2.set)(object, entry.path, { type: entry.type, value: void 0, oldValue: entry.value });
540
+ (0, import_lodash2.set)(object, entry.path, { type: entry.type, value: void 0, oldValue: entry.value });
541
541
  break;
542
542
  default:
543
543
  throw new Error();
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/jsonDiff.ts","../src/jsonCompare.ts"],"sourcesContent":["export * from './jsonDiff.js';\nexport * from './jsonCompare.js';\n","import { difference, find, intersection, keyBy } from 'lodash-es';\n\ntype FunctionKey = (obj: any, shouldReturnKeyName?: boolean) => any;\nexport type EmbeddedObjKeysType = Record<string, string | FunctionKey>;\nexport type EmbeddedObjKeysMapType = Map<string | RegExp, string | FunctionKey>;\nexport enum Operation {\n REMOVE = 'REMOVE',\n ADD = 'ADD',\n UPDATE = 'UPDATE'\n}\n\nexport interface IChange {\n type: Operation;\n key: string;\n embeddedKey?: string | FunctionKey;\n value?: any | any[];\n oldValue?: any;\n changes?: IChange[];\n}\nexport type Changeset = IChange[];\n\nexport interface IFlatChange {\n type: Operation;\n key: string;\n path: string;\n valueType: string | null;\n value?: any;\n oldValue?: any;\n}\n\n/**\n * Computes the difference between two objects.\n *\n * @param {any} oldObj - The original object.\n * @param {any} newObj - The updated object.\n * @param {EmbeddedObjKeysType | EmbeddedObjKeysMapType} embeddedObjKeys - An optional parameter specifying keys of embedded objects.\n * @returns {IChange[]} - An array of changes that transform the old object into the new object.\n */\nexport function diff(\n oldObj: any,\n newObj: any,\n embeddedObjKeys?: EmbeddedObjKeysType | EmbeddedObjKeysMapType,\n keysToSkip?: string[]\n): IChange[] {\n // Trim leading '.' from keys in embeddedObjKeys\n if (embeddedObjKeys instanceof Map) {\n embeddedObjKeys = new Map(\n Array.from(embeddedObjKeys.entries()).map(([key, value]) => [\n key instanceof RegExp ? key : key.replace(/^\\./, ''),\n value\n ])\n );\n } else if (embeddedObjKeys) {\n embeddedObjKeys = Object.fromEntries(\n Object.entries(embeddedObjKeys).map(([key, value]) => [key.replace(/^\\./, ''), value])\n );\n }\n\n // Compare old and new objects to generate a list of changes\n return compare(oldObj, newObj, [], embeddedObjKeys, [], keysToSkip);\n}\n\n/**\n * Applies all changes in the changeset to the object.\n *\n * @param {any} obj - The object to apply changes to.\n * @param {Changeset} changeset - The changeset to apply.\n * @returns {any} - The object after the changes from the changeset have been applied.\n *\n * The function first checks if a changeset is provided. If so, it iterates over each change in the changeset.\n * If the change value is not null or undefined, or if the change type is REMOVE, it applies the change to the object directly.\n * Otherwise, it applies the change to the corresponding branch of the object.\n */\nexport const applyChangeset = (obj: any, changeset: Changeset) => {\n if (changeset) {\n changeset.forEach((change) => {\n const { type, key, value, embeddedKey } = change;\n\n if ((value !== null && value !== undefined) || type === Operation.REMOVE) {\n // Apply the change to the object\n applyLeafChange(obj, change, embeddedKey);\n } else {\n // Apply the change to the branch\n applyBranchChange(obj[key], change);\n }\n });\n }\n return obj;\n};\n\n/**\n * Reverts the changes made to an object based on a given changeset.\n *\n * @param {any} obj - The object on which to revert changes.\n * @param {Changeset} changeset - The changeset to revert.\n * @returns {any} - The object after the changes from the changeset have been reverted.\n *\n * The function first checks if a changeset is provided. If so, it reverses the changeset to start reverting from the last change.\n * It then iterates over each change in the changeset. If the change does not have any nested changes, it reverts the change on the object directly.\n * If the change does have nested changes, it reverts the changes on the corresponding branch of the object.\n */\nexport const revertChangeset = (obj: any, changeset: Changeset) => {\n if (changeset) {\n changeset\n .reverse()\n .forEach((change: IChange): any =>\n !change.changes ? revertLeafChange(obj, change) : revertBranchChange(obj[change.key], change)\n );\n }\n\n return obj;\n};\n\n/**\n * Flattens a changeset into an array of flat changes.\n *\n * @param {Changeset | IChange} obj - The changeset or change to flatten.\n * @param {string} [path='$'] - The current path in the changeset.\n * @param {string | FunctionKey} [embeddedKey] - The key to use for embedded objects.\n * @returns {IFlatChange[]} - An array of flat changes.\n *\n * The function first checks if the input is an array. If so, it recursively flattens each change in the array.\n * If the input is not an array, it checks if the change has nested changes or an embedded key.\n * If so, it updates the path and recursively flattens the nested changes or the embedded object.\n * If the change does not have nested changes or an embedded key, it creates a flat change and returns it in an array.\n */\nexport const flattenChangeset = (\n obj: Changeset | IChange,\n path = '$',\n embeddedKey?: string | FunctionKey\n): IFlatChange[] => {\n if (Array.isArray(obj)) {\n return obj.reduce((memo, change) => [...memo, ...flattenChangeset(change, path, embeddedKey)], [] as IFlatChange[]);\n } else {\n if (obj.changes || embeddedKey) {\n if (embeddedKey) {\n if (embeddedKey === '$index') {\n path = `${path}[${obj.key}]`;\n } else if (embeddedKey === '$value') {\n path = `${path}[?(@='${obj.key}')]`;\n const valueType = getTypeOfObj(obj.value);\n return [\n {\n ...obj,\n path,\n valueType\n }\n ];\n } else if (obj.type === Operation.ADD) {\n // do nothing\n } else {\n path = filterExpression(path, embeddedKey, obj.key);\n }\n } else {\n path = append(path, obj.key);\n }\n\n return flattenChangeset(obj.changes || obj, path, obj.embeddedKey);\n } else {\n const valueType = getTypeOfObj(obj.value);\n return [\n {\n ...obj,\n path: valueType === 'Object' || path.endsWith(`[${obj.key}]`) ? path : append(path, obj.key),\n valueType\n }\n ];\n }\n }\n};\n\n/**\n * Transforms a flat changeset into a nested changeset.\n *\n * @param {IFlatChange | IFlatChange[]} changes - The flat changeset to unflatten.\n * @returns {IChange[]} - The unflattened changeset.\n *\n * The function first checks if the input is a single change or an array of changes.\n * It then iterates over each change and splits its path into segments.\n * For each segment, it checks if it represents an array or a leaf node.\n * If it represents an array, it creates a new change object and updates the pointer to this new object.\n * If it represents a leaf node, it sets the key, type, value, and oldValue of the current change object.\n * Finally, it pushes the unflattened change object into the changes array.\n */\nexport const unflattenChanges = (changes: IFlatChange | IFlatChange[]) => {\n if (!Array.isArray(changes)) {\n changes = [changes];\n }\n\n const changesArr: IChange[] = [];\n\n changes.forEach((change) => {\n const obj = {} as IChange;\n let ptr = obj;\n\n const segments = change.path.split(/(?<=[^@])\\.(?=[^@])/);\n\n if (segments.length === 1) {\n ptr.key = change.key;\n ptr.type = change.type;\n ptr.value = change.value;\n ptr.oldValue = change.oldValue;\n changesArr.push(ptr);\n } else {\n for (let i = 1; i < segments.length; i++) {\n const segment = segments[i];\n // Matches JSONPath segments: \"items[?(@.id=='123')]\", \"items[?(@.id==123)]\", \"items[2]\", \"items[?(@='123')]\"\n const result = /^(.+?)\\[\\?\\(@.?(?:([^=]*))?={1,2}'(.*)'\\)\\]$|^(.+?)\\[(\\d+)\\]$/.exec(segment); //NOSONAR\n // array\n if (result) {\n let key: string;\n let embeddedKey: string;\n let arrKey: string | number;\n if (result[1]) {\n key = result[1];\n embeddedKey = result[2] || '$value';\n arrKey = result[3];\n } else {\n key = result[4];\n embeddedKey = '$index';\n arrKey = Number(result[4]);\n }\n // leaf\n if (i === segments.length - 1) {\n ptr.key = key!;\n ptr.embeddedKey = embeddedKey!;\n ptr.type = Operation.UPDATE;\n ptr.changes = [\n {\n type: change.type,\n key: arrKey!,\n value: change.value,\n oldValue: change.oldValue\n } as IChange\n ];\n } else {\n // object\n ptr.key = key;\n ptr.embeddedKey = embeddedKey;\n ptr.type = Operation.UPDATE;\n const newPtr = {} as IChange;\n ptr.changes = [\n {\n type: Operation.UPDATE,\n key: arrKey,\n changes: [newPtr]\n } as IChange\n ];\n ptr = newPtr;\n }\n } else {\n // leaf\n if (i === segments.length - 1) {\n // check if value is a primitive or object\n if (change.value !== null && change.valueType === 'Object') {\n ptr.key = segment;\n ptr.type = Operation.UPDATE;\n ptr.changes = [\n {\n key: change.key,\n type: change.type,\n value: change.value\n } as IChange\n ];\n } else {\n ptr.key = change.key;\n ptr.type = change.type;\n ptr.value = change.value;\n ptr.oldValue = change.oldValue;\n }\n } else {\n // branch\n ptr.key = segment;\n ptr.type = Operation.UPDATE;\n const newPtr = {} as IChange;\n ptr.changes = [newPtr];\n ptr = newPtr;\n }\n }\n }\n changesArr.push(obj);\n }\n });\n return changesArr;\n};\n\n/**\n * Determines the type of a given object.\n *\n * @param {any} obj - The object whose type is to be determined.\n * @returns {string | null} - The type of the object, or null if the object is null.\n *\n * This function first checks if the object is undefined or null, and returns 'undefined' or null respectively.\n * If the object is neither undefined nor null, it uses Object.prototype.toString to get the object's type.\n * The type is extracted from the string returned by Object.prototype.toString using a regular expression.\n */\nexport const getTypeOfObj = (obj: any) => {\n if (typeof obj === 'undefined') {\n return 'undefined';\n }\n\n if (obj === null) {\n return null;\n }\n\n // Extracts the \"Type\" from \"[object Type]\" string.\n return Object.prototype.toString.call(obj).match(/^\\[object\\s(.*)\\]$/)[1];\n};\n\nconst getKey = (path: string) => {\n const left = path[path.length - 1];\n return left != null ? left : '$root';\n};\n\nconst compare = (oldObj: any, newObj: any, path: any, embeddedObjKeys: any, keyPath: any, keysToSkip: string[]) => {\n let changes: any[] = [];\n\n const typeOfOldObj = getTypeOfObj(oldObj);\n const typeOfNewObj = getTypeOfObj(newObj);\n\n // if type of object changes, consider it as old obj has been deleted and a new object has been added\n if (typeOfOldObj !== typeOfNewObj) {\n changes.push({ type: Operation.REMOVE, key: getKey(path), value: oldObj });\n changes.push({ type: Operation.ADD, key: getKey(path), value: newObj });\n return changes;\n }\n\n switch (typeOfOldObj) {\n case 'Date':\n changes = changes.concat(\n comparePrimitives(oldObj.getTime(), newObj.getTime(), path).map((x) => ({\n ...x,\n value: new Date(x.value),\n oldValue: new Date(x.oldValue)\n }))\n );\n break;\n case 'Object':\n const diffs = compareObject(oldObj, newObj, path, embeddedObjKeys, keyPath, false, keysToSkip);\n if (diffs.length) {\n if (path.length) {\n changes.push({\n type: Operation.UPDATE,\n key: getKey(path),\n changes: diffs\n });\n } else {\n changes = changes.concat(diffs);\n }\n }\n break;\n case 'Array':\n changes = changes.concat(compareArray(oldObj, newObj, path, embeddedObjKeys, keyPath, keysToSkip));\n break;\n case 'Function':\n break;\n // do nothing\n default:\n changes = changes.concat(comparePrimitives(oldObj, newObj, path));\n }\n\n return changes;\n};\n\nconst compareObject = (\n oldObj: any,\n newObj: any,\n path: any,\n embeddedObjKeys: any,\n keyPath: any,\n skipPath = false,\n keysToSkip: string[] = []\n) => {\n let k;\n let newKeyPath;\n let newPath;\n\n if (skipPath == null) {\n skipPath = false;\n }\n let changes: any[] = [];\n\n const oldObjKeys = Object.keys(oldObj).filter((key) => keysToSkip.indexOf(key) === -1);\n const newObjKeys = Object.keys(newObj).filter((key) => keysToSkip.indexOf(key) === -1);\n\n const intersectionKeys = intersection(oldObjKeys, newObjKeys);\n for (k of intersectionKeys) {\n newPath = path.concat([k]);\n newKeyPath = skipPath ? keyPath : keyPath.concat([k]);\n const diffs = compare(oldObj[k], newObj[k], newPath, embeddedObjKeys, newKeyPath, keysToSkip);\n if (diffs.length) {\n changes = changes.concat(diffs);\n }\n }\n\n const addedKeys = difference(newObjKeys, oldObjKeys);\n for (k of addedKeys) {\n newPath = path.concat([k]);\n newKeyPath = skipPath ? keyPath : keyPath.concat([k]);\n changes.push({\n type: Operation.ADD,\n key: getKey(newPath),\n value: newObj[k]\n });\n }\n\n const deletedKeys = difference(oldObjKeys, newObjKeys);\n for (k of deletedKeys) {\n newPath = path.concat([k]);\n newKeyPath = skipPath ? keyPath : keyPath.concat([k]);\n changes.push({\n type: Operation.REMOVE,\n key: getKey(newPath),\n value: oldObj[k]\n });\n }\n return changes;\n};\n\nconst compareArray = (\n oldObj: any,\n newObj: any,\n path: any,\n embeddedObjKeys: any,\n keyPath: any,\n keysToSkip: string[]\n) => {\n const left = getObjectKey(embeddedObjKeys, keyPath);\n const uniqKey = left != null ? left : '$index';\n const indexedOldObj = convertArrayToObj(oldObj, uniqKey);\n const indexedNewObj = convertArrayToObj(newObj, uniqKey);\n const diffs = compareObject(indexedOldObj, indexedNewObj, path, embeddedObjKeys, keyPath, true, keysToSkip);\n if (diffs.length) {\n return [\n {\n type: Operation.UPDATE,\n key: getKey(path),\n embeddedKey: typeof uniqKey === 'function' && uniqKey.length === 2 ? uniqKey(newObj[0], true) : uniqKey,\n changes: diffs\n }\n ];\n } else {\n return [];\n }\n};\n\nconst getObjectKey = (embeddedObjKeys: any, keyPath: any) => {\n if (embeddedObjKeys != null) {\n const path = keyPath.join('.');\n\n if (embeddedObjKeys instanceof Map) {\n for (const [key, value] of embeddedObjKeys.entries()) {\n if (key instanceof RegExp) {\n if (path.match(key)) {\n return value;\n }\n } else if (path === key) {\n return value;\n }\n }\n }\n\n const key = embeddedObjKeys[path];\n if (key != null) {\n return key;\n }\n }\n return undefined;\n};\n\nconst convertArrayToObj = (arr: any[], uniqKey: any) => {\n let obj: any = {};\n if (uniqKey === '$value') {\n arr.forEach((value) => {\n obj[value] = value;\n });\n } else if (uniqKey !== '$index') {\n obj = keyBy(arr, uniqKey);\n } else {\n for (let i = 0; i < arr.length; i++) {\n const value = arr[i];\n obj[i] = value;\n }\n }\n return obj;\n};\n\nconst comparePrimitives = (oldObj: any, newObj: any, path: any) => {\n const changes = [];\n if (oldObj !== newObj) {\n changes.push({\n type: Operation.UPDATE,\n key: getKey(path),\n value: newObj,\n oldValue: oldObj\n });\n }\n return changes;\n};\n\nconst removeKey = (obj: any, key: any, embeddedKey: any) => {\n if (Array.isArray(obj)) {\n if (embeddedKey === '$index') {\n obj.splice(key);\n return;\n }\n const index = indexOfItemInArray(obj, embeddedKey, key);\n if (index === -1) {\n // tslint:disable-next-line:no-console\n console.warn(`Element with the key '${embeddedKey}' and value '${key}' could not be found in the array'`);\n return;\n }\n return obj.splice(index != null ? index : key, 1);\n } else {\n obj[key] = undefined;\n delete obj[key];\n return;\n }\n};\n\nconst indexOfItemInArray = (arr: any[], key: any, value: any) => {\n if (key === '$value') {\n return arr.indexOf(value);\n }\n for (let i = 0; i < arr.length; i++) {\n const item = arr[i];\n if (item && item[key] ? item[key].toString() === value.toString() : undefined) {\n return i;\n }\n }\n return -1;\n};\n\nconst modifyKeyValue = (obj: any, key: any, value: any) => (obj[key] = value);\n\nconst addKeyValue = (obj: any, key: any, value: any) => {\n if (Array.isArray(obj)) {\n return obj.push(value);\n } else {\n return obj ? (obj[key] = value) : null;\n }\n};\n\nconst applyLeafChange = (obj: any, change: any, embeddedKey: any) => {\n const { type, key, value } = change;\n switch (type) {\n case Operation.ADD:\n return addKeyValue(obj, key, value);\n case Operation.UPDATE:\n return modifyKeyValue(obj, key, value);\n case Operation.REMOVE:\n return removeKey(obj, key, embeddedKey);\n }\n};\n\nconst applyArrayChange = (arr: any, change: any) =>\n (() => {\n const result = [];\n for (const subchange of change.changes) {\n if (subchange.value != null || subchange.type === Operation.REMOVE) {\n result.push(applyLeafChange(arr, subchange, change.embeddedKey));\n } else {\n let element;\n if (change.embeddedKey === '$index') {\n element = arr[subchange.key];\n } else if (change.embeddedKey === '$value') {\n const index = arr.indexOf(subchange.key);\n if (index !== -1) {\n element = arr[index];\n }\n } else {\n element = find(arr, (el) => el[change.embeddedKey]?.toString() === subchange.key.toString());\n }\n result.push(applyChangeset(element, subchange.changes));\n }\n }\n return result;\n })();\n\nconst applyBranchChange = (obj: any, change: any) => {\n if (Array.isArray(obj)) {\n return applyArrayChange(obj, change);\n } else {\n return applyChangeset(obj, change.changes);\n }\n};\n\nconst revertLeafChange = (obj: any, change: any, embeddedKey = '$index') => {\n const { type, key, value, oldValue } = change;\n switch (type) {\n case Operation.ADD:\n return removeKey(obj, key, embeddedKey);\n case Operation.UPDATE:\n return modifyKeyValue(obj, key, oldValue);\n case Operation.REMOVE:\n return addKeyValue(obj, key, value);\n }\n};\n\nconst revertArrayChange = (arr: any, change: any) =>\n (() => {\n const result = [];\n for (const subchange of change.changes) {\n if (subchange.value != null || subchange.type === Operation.REMOVE) {\n result.push(revertLeafChange(arr, subchange, change.embeddedKey));\n } else {\n let element;\n if (change.embeddedKey === '$index') {\n element = arr[+subchange.key];\n } else {\n element = find(arr, (el) => el[change.embeddedKey].toString() === subchange.key);\n }\n result.push(revertChangeset(element, subchange.changes));\n }\n }\n return result;\n })();\n\nconst revertBranchChange = (obj: any, change: any) => {\n if (Array.isArray(obj)) {\n return revertArrayChange(obj, change);\n } else {\n return revertChangeset(obj, change.changes);\n }\n};\n\n/** combine a base JSON Path with a subsequent segment */\nfunction append(basePath: string, nextSegment: string): string {\n return nextSegment.includes('.') ? `${basePath}[${nextSegment}]` : `${basePath}.${nextSegment}`;\n}\n\n/** returns a JSON Path filter expression; e.g., `$.pet[(?name='spot')]` */\nfunction filterExpression(basePath: string, filterKey: string | FunctionKey, filterValue: string | number) {\n const value = typeof filterValue === 'number' ? filterValue : `'${filterValue}'`;\n return typeof filterKey === 'string' && filterKey.includes('.')\n ? `${basePath}[?(@[${filterKey}]==${value})]`\n : `${basePath}[?(@.${filterKey}==${value})]`;\n}\n","import { chain, keys, replace, set } from 'lodash-es';\nimport { diff, flattenChangeset, getTypeOfObj, IFlatChange, Operation } from './jsonDiff.js';\n\nexport enum CompareOperation {\n CONTAINER = 'CONTAINER',\n UNCHANGED = 'UNCHANGED'\n}\n\nexport interface IComparisonEnrichedNode {\n type: Operation | CompareOperation;\n value: IComparisonEnrichedNode | IComparisonEnrichedNode[] | any | any[];\n oldValue?: any;\n}\n\nexport const createValue = (value: any): IComparisonEnrichedNode => ({ type: CompareOperation.UNCHANGED, value });\nexport const createContainer = (value: object | []): IComparisonEnrichedNode => ({\n type: CompareOperation.CONTAINER,\n value\n});\n\nexport const enrich = (object: any): IComparisonEnrichedNode => {\n const objectType = getTypeOfObj(object);\n\n switch (objectType) {\n case 'Object':\n return keys(object)\n .map((key: string) => ({ key, value: enrich(object[key]) }))\n .reduce((accumulator, entry) => {\n accumulator.value[entry.key] = entry.value;\n return accumulator;\n }, createContainer({}));\n case 'Array':\n return chain(object)\n .map((value) => enrich(value))\n .reduce((accumulator, value) => {\n accumulator.value.push(value);\n return accumulator;\n }, createContainer([]))\n .value();\n case 'Function':\n return undefined;\n case 'Date':\n default:\n // Primitive value\n return createValue(object);\n }\n};\n\nexport const applyChangelist = (\n object: IComparisonEnrichedNode,\n changelist: IFlatChange[]\n): IComparisonEnrichedNode => {\n chain(changelist)\n .map((entry) => ({ ...entry, path: replace(entry.path, '$.', '.') }))\n .map((entry) => ({\n ...entry,\n path: replace(entry.path, /(\\[(?<array>\\d)\\]\\.)/g, 'ARRVAL_START$<array>ARRVAL_END')\n }))\n .map((entry) => ({ ...entry, path: replace(entry.path, /(?<dot>\\.)/g, '.value$<dot>') }))\n .map((entry) => ({ ...entry, path: replace(entry.path, /\\./, '') }))\n .map((entry) => ({ ...entry, path: replace(entry.path, /ARRVAL_START/g, '.value[') }))\n .map((entry) => ({ ...entry, path: replace(entry.path, /ARRVAL_END/g, '].value.') }))\n .value()\n .forEach((entry) => {\n switch (entry.type) {\n case Operation.ADD:\n case Operation.UPDATE:\n set(object, entry.path, { type: entry.type, value: entry.value, oldValue: entry.oldValue });\n break;\n case Operation.REMOVE:\n set(object, entry.path, { type: entry.type, value: undefined, oldValue: entry.value });\n break;\n default:\n throw new Error();\n }\n });\n return object;\n};\n\nexport const compare = (oldObject: any, newObject: any): IComparisonEnrichedNode => {\n return applyChangelist(enrich(oldObject), flattenChangeset(diff(oldObject, newObject)));\n};\n"],"mappings":"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","names":["compare","Operation","key","import_lodash_es","CompareOperation","compare"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/jsonDiff.ts","../src/jsonCompare.ts"],"sourcesContent":["export * from './jsonDiff.js';\nexport * from './jsonCompare.js';\n","import { difference, find, intersection, keyBy } from 'lodash';\n\ntype FunctionKey = (obj: any, shouldReturnKeyName?: boolean) => any;\nexport type EmbeddedObjKeysType = Record<string, string | FunctionKey>;\nexport type EmbeddedObjKeysMapType = Map<string | RegExp, string | FunctionKey>;\nexport enum Operation {\n REMOVE = 'REMOVE',\n ADD = 'ADD',\n UPDATE = 'UPDATE'\n}\n\nexport interface IChange {\n type: Operation;\n key: string;\n embeddedKey?: string | FunctionKey;\n value?: any | any[];\n oldValue?: any;\n changes?: IChange[];\n}\nexport type Changeset = IChange[];\n\nexport interface IFlatChange {\n type: Operation;\n key: string;\n path: string;\n valueType: string | null;\n value?: any;\n oldValue?: any;\n}\n\n/**\n * Computes the difference between two objects.\n *\n * @param {any} oldObj - The original object.\n * @param {any} newObj - The updated object.\n * @param {EmbeddedObjKeysType | EmbeddedObjKeysMapType} embeddedObjKeys - An optional parameter specifying keys of embedded objects.\n * @returns {IChange[]} - An array of changes that transform the old object into the new object.\n */\nexport function diff(\n oldObj: any,\n newObj: any,\n embeddedObjKeys?: EmbeddedObjKeysType | EmbeddedObjKeysMapType,\n keysToSkip?: string[]\n): IChange[] {\n // Trim leading '.' from keys in embeddedObjKeys\n if (embeddedObjKeys instanceof Map) {\n embeddedObjKeys = new Map(\n Array.from(embeddedObjKeys.entries()).map(([key, value]) => [\n key instanceof RegExp ? key : key.replace(/^\\./, ''),\n value\n ])\n );\n } else if (embeddedObjKeys) {\n embeddedObjKeys = Object.fromEntries(\n Object.entries(embeddedObjKeys).map(([key, value]) => [key.replace(/^\\./, ''), value])\n );\n }\n\n // Compare old and new objects to generate a list of changes\n return compare(oldObj, newObj, [], embeddedObjKeys, [], keysToSkip);\n}\n\n/**\n * Applies all changes in the changeset to the object.\n *\n * @param {any} obj - The object to apply changes to.\n * @param {Changeset} changeset - The changeset to apply.\n * @returns {any} - The object after the changes from the changeset have been applied.\n *\n * The function first checks if a changeset is provided. If so, it iterates over each change in the changeset.\n * If the change value is not null or undefined, or if the change type is REMOVE, it applies the change to the object directly.\n * Otherwise, it applies the change to the corresponding branch of the object.\n */\nexport const applyChangeset = (obj: any, changeset: Changeset) => {\n if (changeset) {\n changeset.forEach((change) => {\n const { type, key, value, embeddedKey } = change;\n\n if ((value !== null && value !== undefined) || type === Operation.REMOVE) {\n // Apply the change to the object\n applyLeafChange(obj, change, embeddedKey);\n } else {\n // Apply the change to the branch\n applyBranchChange(obj[key], change);\n }\n });\n }\n return obj;\n};\n\n/**\n * Reverts the changes made to an object based on a given changeset.\n *\n * @param {any} obj - The object on which to revert changes.\n * @param {Changeset} changeset - The changeset to revert.\n * @returns {any} - The object after the changes from the changeset have been reverted.\n *\n * The function first checks if a changeset is provided. If so, it reverses the changeset to start reverting from the last change.\n * It then iterates over each change in the changeset. If the change does not have any nested changes, it reverts the change on the object directly.\n * If the change does have nested changes, it reverts the changes on the corresponding branch of the object.\n */\nexport const revertChangeset = (obj: any, changeset: Changeset) => {\n if (changeset) {\n changeset\n .reverse()\n .forEach((change: IChange): any =>\n !change.changes ? revertLeafChange(obj, change) : revertBranchChange(obj[change.key], change)\n );\n }\n\n return obj;\n};\n\n/**\n * Flattens a changeset into an array of flat changes.\n *\n * @param {Changeset | IChange} obj - The changeset or change to flatten.\n * @param {string} [path='$'] - The current path in the changeset.\n * @param {string | FunctionKey} [embeddedKey] - The key to use for embedded objects.\n * @returns {IFlatChange[]} - An array of flat changes.\n *\n * The function first checks if the input is an array. If so, it recursively flattens each change in the array.\n * If the input is not an array, it checks if the change has nested changes or an embedded key.\n * If so, it updates the path and recursively flattens the nested changes or the embedded object.\n * If the change does not have nested changes or an embedded key, it creates a flat change and returns it in an array.\n */\nexport const flattenChangeset = (\n obj: Changeset | IChange,\n path = '$',\n embeddedKey?: string | FunctionKey\n): IFlatChange[] => {\n if (Array.isArray(obj)) {\n return obj.reduce((memo, change) => [...memo, ...flattenChangeset(change, path, embeddedKey)], [] as IFlatChange[]);\n } else {\n if (obj.changes || embeddedKey) {\n if (embeddedKey) {\n if (embeddedKey === '$index') {\n path = `${path}[${obj.key}]`;\n } else if (embeddedKey === '$value') {\n path = `${path}[?(@='${obj.key}')]`;\n const valueType = getTypeOfObj(obj.value);\n return [\n {\n ...obj,\n path,\n valueType\n }\n ];\n } else if (obj.type === Operation.ADD) {\n // do nothing\n } else {\n path = filterExpression(path, embeddedKey, obj.key);\n }\n } else {\n path = append(path, obj.key);\n }\n\n return flattenChangeset(obj.changes || obj, path, obj.embeddedKey);\n } else {\n const valueType = getTypeOfObj(obj.value);\n return [\n {\n ...obj,\n path: valueType === 'Object' || path.endsWith(`[${obj.key}]`) ? path : append(path, obj.key),\n valueType\n }\n ];\n }\n }\n};\n\n/**\n * Transforms a flat changeset into a nested changeset.\n *\n * @param {IFlatChange | IFlatChange[]} changes - The flat changeset to unflatten.\n * @returns {IChange[]} - The unflattened changeset.\n *\n * The function first checks if the input is a single change or an array of changes.\n * It then iterates over each change and splits its path into segments.\n * For each segment, it checks if it represents an array or a leaf node.\n * If it represents an array, it creates a new change object and updates the pointer to this new object.\n * If it represents a leaf node, it sets the key, type, value, and oldValue of the current change object.\n * Finally, it pushes the unflattened change object into the changes array.\n */\nexport const unflattenChanges = (changes: IFlatChange | IFlatChange[]) => {\n if (!Array.isArray(changes)) {\n changes = [changes];\n }\n\n const changesArr: IChange[] = [];\n\n changes.forEach((change) => {\n const obj = {} as IChange;\n let ptr = obj;\n\n const segments = change.path.split(/(?<=[^@])\\.(?=[^@])/);\n\n if (segments.length === 1) {\n ptr.key = change.key;\n ptr.type = change.type;\n ptr.value = change.value;\n ptr.oldValue = change.oldValue;\n changesArr.push(ptr);\n } else {\n for (let i = 1; i < segments.length; i++) {\n const segment = segments[i];\n // Matches JSONPath segments: \"items[?(@.id=='123')]\", \"items[?(@.id==123)]\", \"items[2]\", \"items[?(@='123')]\"\n const result = /^(.+?)\\[\\?\\(@.?(?:([^=]*))?={1,2}'(.*)'\\)\\]$|^(.+?)\\[(\\d+)\\]$/.exec(segment); //NOSONAR\n // array\n if (result) {\n let key: string;\n let embeddedKey: string;\n let arrKey: string | number;\n if (result[1]) {\n key = result[1];\n embeddedKey = result[2] || '$value';\n arrKey = result[3];\n } else {\n key = result[4];\n embeddedKey = '$index';\n arrKey = Number(result[4]);\n }\n // leaf\n if (i === segments.length - 1) {\n ptr.key = key!;\n ptr.embeddedKey = embeddedKey!;\n ptr.type = Operation.UPDATE;\n ptr.changes = [\n {\n type: change.type,\n key: arrKey!,\n value: change.value,\n oldValue: change.oldValue\n } as IChange\n ];\n } else {\n // object\n ptr.key = key;\n ptr.embeddedKey = embeddedKey;\n ptr.type = Operation.UPDATE;\n const newPtr = {} as IChange;\n ptr.changes = [\n {\n type: Operation.UPDATE,\n key: arrKey,\n changes: [newPtr]\n } as IChange\n ];\n ptr = newPtr;\n }\n } else {\n // leaf\n if (i === segments.length - 1) {\n // check if value is a primitive or object\n if (change.value !== null && change.valueType === 'Object') {\n ptr.key = segment;\n ptr.type = Operation.UPDATE;\n ptr.changes = [\n {\n key: change.key,\n type: change.type,\n value: change.value\n } as IChange\n ];\n } else {\n ptr.key = change.key;\n ptr.type = change.type;\n ptr.value = change.value;\n ptr.oldValue = change.oldValue;\n }\n } else {\n // branch\n ptr.key = segment;\n ptr.type = Operation.UPDATE;\n const newPtr = {} as IChange;\n ptr.changes = [newPtr];\n ptr = newPtr;\n }\n }\n }\n changesArr.push(obj);\n }\n });\n return changesArr;\n};\n\n/**\n * Determines the type of a given object.\n *\n * @param {any} obj - The object whose type is to be determined.\n * @returns {string | null} - The type of the object, or null if the object is null.\n *\n * This function first checks if the object is undefined or null, and returns 'undefined' or null respectively.\n * If the object is neither undefined nor null, it uses Object.prototype.toString to get the object's type.\n * The type is extracted from the string returned by Object.prototype.toString using a regular expression.\n */\nexport const getTypeOfObj = (obj: any) => {\n if (typeof obj === 'undefined') {\n return 'undefined';\n }\n\n if (obj === null) {\n return null;\n }\n\n // Extracts the \"Type\" from \"[object Type]\" string.\n return Object.prototype.toString.call(obj).match(/^\\[object\\s(.*)\\]$/)[1];\n};\n\nconst getKey = (path: string) => {\n const left = path[path.length - 1];\n return left != null ? left : '$root';\n};\n\nconst compare = (oldObj: any, newObj: any, path: any, embeddedObjKeys: any, keyPath: any, keysToSkip: string[]) => {\n let changes: any[] = [];\n\n const typeOfOldObj = getTypeOfObj(oldObj);\n const typeOfNewObj = getTypeOfObj(newObj);\n\n // if type of object changes, consider it as old obj has been deleted and a new object has been added\n if (typeOfOldObj !== typeOfNewObj) {\n changes.push({ type: Operation.REMOVE, key: getKey(path), value: oldObj });\n changes.push({ type: Operation.ADD, key: getKey(path), value: newObj });\n return changes;\n }\n\n switch (typeOfOldObj) {\n case 'Date':\n changes = changes.concat(\n comparePrimitives(oldObj.getTime(), newObj.getTime(), path).map((x) => ({\n ...x,\n value: new Date(x.value),\n oldValue: new Date(x.oldValue)\n }))\n );\n break;\n case 'Object':\n const diffs = compareObject(oldObj, newObj, path, embeddedObjKeys, keyPath, false, keysToSkip);\n if (diffs.length) {\n if (path.length) {\n changes.push({\n type: Operation.UPDATE,\n key: getKey(path),\n changes: diffs\n });\n } else {\n changes = changes.concat(diffs);\n }\n }\n break;\n case 'Array':\n changes = changes.concat(compareArray(oldObj, newObj, path, embeddedObjKeys, keyPath, keysToSkip));\n break;\n case 'Function':\n break;\n // do nothing\n default:\n changes = changes.concat(comparePrimitives(oldObj, newObj, path));\n }\n\n return changes;\n};\n\nconst compareObject = (\n oldObj: any,\n newObj: any,\n path: any,\n embeddedObjKeys: any,\n keyPath: any,\n skipPath = false,\n keysToSkip: string[] = []\n) => {\n let k;\n let newKeyPath;\n let newPath;\n\n if (skipPath == null) {\n skipPath = false;\n }\n let changes: any[] = [];\n\n const oldObjKeys = Object.keys(oldObj).filter((key) => keysToSkip.indexOf(key) === -1);\n const newObjKeys = Object.keys(newObj).filter((key) => keysToSkip.indexOf(key) === -1);\n\n const intersectionKeys = intersection(oldObjKeys, newObjKeys);\n for (k of intersectionKeys) {\n newPath = path.concat([k]);\n newKeyPath = skipPath ? keyPath : keyPath.concat([k]);\n const diffs = compare(oldObj[k], newObj[k], newPath, embeddedObjKeys, newKeyPath, keysToSkip);\n if (diffs.length) {\n changes = changes.concat(diffs);\n }\n }\n\n const addedKeys = difference(newObjKeys, oldObjKeys);\n for (k of addedKeys) {\n newPath = path.concat([k]);\n newKeyPath = skipPath ? keyPath : keyPath.concat([k]);\n changes.push({\n type: Operation.ADD,\n key: getKey(newPath),\n value: newObj[k]\n });\n }\n\n const deletedKeys = difference(oldObjKeys, newObjKeys);\n for (k of deletedKeys) {\n newPath = path.concat([k]);\n newKeyPath = skipPath ? keyPath : keyPath.concat([k]);\n changes.push({\n type: Operation.REMOVE,\n key: getKey(newPath),\n value: oldObj[k]\n });\n }\n return changes;\n};\n\nconst compareArray = (\n oldObj: any,\n newObj: any,\n path: any,\n embeddedObjKeys: any,\n keyPath: any,\n keysToSkip: string[]\n) => {\n const left = getObjectKey(embeddedObjKeys, keyPath);\n const uniqKey = left != null ? left : '$index';\n const indexedOldObj = convertArrayToObj(oldObj, uniqKey);\n const indexedNewObj = convertArrayToObj(newObj, uniqKey);\n const diffs = compareObject(indexedOldObj, indexedNewObj, path, embeddedObjKeys, keyPath, true, keysToSkip);\n if (diffs.length) {\n return [\n {\n type: Operation.UPDATE,\n key: getKey(path),\n embeddedKey: typeof uniqKey === 'function' && uniqKey.length === 2 ? uniqKey(newObj[0], true) : uniqKey,\n changes: diffs\n }\n ];\n } else {\n return [];\n }\n};\n\nconst getObjectKey = (embeddedObjKeys: any, keyPath: any) => {\n if (embeddedObjKeys != null) {\n const path = keyPath.join('.');\n\n if (embeddedObjKeys instanceof Map) {\n for (const [key, value] of embeddedObjKeys.entries()) {\n if (key instanceof RegExp) {\n if (path.match(key)) {\n return value;\n }\n } else if (path === key) {\n return value;\n }\n }\n }\n\n const key = embeddedObjKeys[path];\n if (key != null) {\n return key;\n }\n }\n return undefined;\n};\n\nconst convertArrayToObj = (arr: any[], uniqKey: any) => {\n let obj: any = {};\n if (uniqKey === '$value') {\n arr.forEach((value) => {\n obj[value] = value;\n });\n } else if (uniqKey !== '$index') {\n obj = keyBy(arr, uniqKey);\n } else {\n for (let i = 0; i < arr.length; i++) {\n const value = arr[i];\n obj[i] = value;\n }\n }\n return obj;\n};\n\nconst comparePrimitives = (oldObj: any, newObj: any, path: any) => {\n const changes = [];\n if (oldObj !== newObj) {\n changes.push({\n type: Operation.UPDATE,\n key: getKey(path),\n value: newObj,\n oldValue: oldObj\n });\n }\n return changes;\n};\n\nconst removeKey = (obj: any, key: any, embeddedKey: any) => {\n if (Array.isArray(obj)) {\n if (embeddedKey === '$index') {\n obj.splice(key);\n return;\n }\n const index = indexOfItemInArray(obj, embeddedKey, key);\n if (index === -1) {\n // tslint:disable-next-line:no-console\n console.warn(`Element with the key '${embeddedKey}' and value '${key}' could not be found in the array'`);\n return;\n }\n return obj.splice(index != null ? index : key, 1);\n } else {\n obj[key] = undefined;\n delete obj[key];\n return;\n }\n};\n\nconst indexOfItemInArray = (arr: any[], key: any, value: any) => {\n if (key === '$value') {\n return arr.indexOf(value);\n }\n for (let i = 0; i < arr.length; i++) {\n const item = arr[i];\n if (item && item[key] ? item[key].toString() === value.toString() : undefined) {\n return i;\n }\n }\n return -1;\n};\n\nconst modifyKeyValue = (obj: any, key: any, value: any) => (obj[key] = value);\n\nconst addKeyValue = (obj: any, key: any, value: any) => {\n if (Array.isArray(obj)) {\n return obj.push(value);\n } else {\n return obj ? (obj[key] = value) : null;\n }\n};\n\nconst applyLeafChange = (obj: any, change: any, embeddedKey: any) => {\n const { type, key, value } = change;\n switch (type) {\n case Operation.ADD:\n return addKeyValue(obj, key, value);\n case Operation.UPDATE:\n return modifyKeyValue(obj, key, value);\n case Operation.REMOVE:\n return removeKey(obj, key, embeddedKey);\n }\n};\n\nconst applyArrayChange = (arr: any, change: any) =>\n (() => {\n const result = [];\n for (const subchange of change.changes) {\n if (subchange.value != null || subchange.type === Operation.REMOVE) {\n result.push(applyLeafChange(arr, subchange, change.embeddedKey));\n } else {\n let element;\n if (change.embeddedKey === '$index') {\n element = arr[subchange.key];\n } else if (change.embeddedKey === '$value') {\n const index = arr.indexOf(subchange.key);\n if (index !== -1) {\n element = arr[index];\n }\n } else {\n element = find(arr, (el) => el[change.embeddedKey]?.toString() === subchange.key.toString());\n }\n result.push(applyChangeset(element, subchange.changes));\n }\n }\n return result;\n })();\n\nconst applyBranchChange = (obj: any, change: any) => {\n if (Array.isArray(obj)) {\n return applyArrayChange(obj, change);\n } else {\n return applyChangeset(obj, change.changes);\n }\n};\n\nconst revertLeafChange = (obj: any, change: any, embeddedKey = '$index') => {\n const { type, key, value, oldValue } = change;\n switch (type) {\n case Operation.ADD:\n return removeKey(obj, key, embeddedKey);\n case Operation.UPDATE:\n return modifyKeyValue(obj, key, oldValue);\n case Operation.REMOVE:\n return addKeyValue(obj, key, value);\n }\n};\n\nconst revertArrayChange = (arr: any, change: any) =>\n (() => {\n const result = [];\n for (const subchange of change.changes) {\n if (subchange.value != null || subchange.type === Operation.REMOVE) {\n result.push(revertLeafChange(arr, subchange, change.embeddedKey));\n } else {\n let element;\n if (change.embeddedKey === '$index') {\n element = arr[+subchange.key];\n } else {\n element = find(arr, (el) => el[change.embeddedKey].toString() === subchange.key);\n }\n result.push(revertChangeset(element, subchange.changes));\n }\n }\n return result;\n })();\n\nconst revertBranchChange = (obj: any, change: any) => {\n if (Array.isArray(obj)) {\n return revertArrayChange(obj, change);\n } else {\n return revertChangeset(obj, change.changes);\n }\n};\n\n/** combine a base JSON Path with a subsequent segment */\nfunction append(basePath: string, nextSegment: string): string {\n return nextSegment.includes('.') ? `${basePath}[${nextSegment}]` : `${basePath}.${nextSegment}`;\n}\n\n/** returns a JSON Path filter expression; e.g., `$.pet[(?name='spot')]` */\nfunction filterExpression(basePath: string, filterKey: string | FunctionKey, filterValue: string | number) {\n const value = typeof filterValue === 'number' ? filterValue : `'${filterValue}'`;\n return typeof filterKey === 'string' && filterKey.includes('.')\n ? `${basePath}[?(@[${filterKey}]==${value})]`\n : `${basePath}[?(@.${filterKey}==${value})]`;\n}\n","import { chain, keys, replace, set } from 'lodash';\nimport { diff, flattenChangeset, getTypeOfObj, IFlatChange, Operation } from './jsonDiff.js';\n\nexport enum CompareOperation {\n CONTAINER = 'CONTAINER',\n UNCHANGED = 'UNCHANGED'\n}\n\nexport interface IComparisonEnrichedNode {\n type: Operation | CompareOperation;\n value: IComparisonEnrichedNode | IComparisonEnrichedNode[] | any | any[];\n oldValue?: any;\n}\n\nexport const createValue = (value: any): IComparisonEnrichedNode => ({ type: CompareOperation.UNCHANGED, value });\nexport const createContainer = (value: object | []): IComparisonEnrichedNode => ({\n type: CompareOperation.CONTAINER,\n value\n});\n\nexport const enrich = (object: any): IComparisonEnrichedNode => {\n const objectType = getTypeOfObj(object);\n\n switch (objectType) {\n case 'Object':\n return keys(object)\n .map((key: string) => ({ key, value: enrich(object[key]) }))\n .reduce((accumulator, entry) => {\n accumulator.value[entry.key] = entry.value;\n return accumulator;\n }, createContainer({}));\n case 'Array':\n return chain(object)\n .map((value) => enrich(value))\n .reduce((accumulator, value) => {\n accumulator.value.push(value);\n return accumulator;\n }, createContainer([]))\n .value();\n case 'Function':\n return undefined;\n case 'Date':\n default:\n // Primitive value\n return createValue(object);\n }\n};\n\nexport const applyChangelist = (\n object: IComparisonEnrichedNode,\n changelist: IFlatChange[]\n): IComparisonEnrichedNode => {\n chain(changelist)\n .map((entry) => ({ ...entry, path: replace(entry.path, '$.', '.') }))\n .map((entry) => ({\n ...entry,\n path: replace(entry.path, /(\\[(?<array>\\d)\\]\\.)/g, 'ARRVAL_START$<array>ARRVAL_END')\n }))\n .map((entry) => ({ ...entry, path: replace(entry.path, /(?<dot>\\.)/g, '.value$<dot>') }))\n .map((entry) => ({ ...entry, path: replace(entry.path, /\\./, '') }))\n .map((entry) => ({ ...entry, path: replace(entry.path, /ARRVAL_START/g, '.value[') }))\n .map((entry) => ({ ...entry, path: replace(entry.path, /ARRVAL_END/g, '].value.') }))\n .value()\n .forEach((entry) => {\n switch (entry.type) {\n case Operation.ADD:\n case Operation.UPDATE:\n set(object, entry.path, { type: entry.type, value: entry.value, oldValue: entry.oldValue });\n break;\n case Operation.REMOVE:\n set(object, entry.path, { type: entry.type, value: undefined, oldValue: entry.value });\n break;\n default:\n throw new Error();\n }\n });\n return object;\n};\n\nexport const compare = (oldObject: any, newObject: any): IComparisonEnrichedNode => {\n return applyChangelist(enrich(oldObject), flattenChangeset(diff(oldObject, newObject)));\n};\n"],"mappings":"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","names":["compare","Operation","key","import_lodash","CompareOperation","compare"]}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/jsonDiff.ts
2
- import { difference, find, intersection, keyBy } from "lodash-es";
2
+ import { difference, find, intersection, keyBy } from "lodash";
3
3
  var Operation = /* @__PURE__ */ ((Operation2) => {
4
4
  Operation2["REMOVE"] = "REMOVE";
5
5
  Operation2["ADD"] = "ADD";
@@ -457,7 +457,7 @@ function filterExpression(basePath, filterKey, filterValue) {
457
457
  }
458
458
 
459
459
  // src/jsonCompare.ts
460
- import { chain, keys, replace, set } from "lodash-es";
460
+ import { chain, keys, replace, set } from "lodash";
461
461
  var CompareOperation = /* @__PURE__ */ ((CompareOperation2) => {
462
462
  CompareOperation2["CONTAINER"] = "CONTAINER";
463
463
  CompareOperation2["UNCHANGED"] = "UNCHANGED";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/jsonDiff.ts","../src/jsonCompare.ts"],"sourcesContent":["import { difference, find, intersection, keyBy } from 'lodash-es';\n\ntype FunctionKey = (obj: any, shouldReturnKeyName?: boolean) => any;\nexport type EmbeddedObjKeysType = Record<string, string | FunctionKey>;\nexport type EmbeddedObjKeysMapType = Map<string | RegExp, string | FunctionKey>;\nexport enum Operation {\n REMOVE = 'REMOVE',\n ADD = 'ADD',\n UPDATE = 'UPDATE'\n}\n\nexport interface IChange {\n type: Operation;\n key: string;\n embeddedKey?: string | FunctionKey;\n value?: any | any[];\n oldValue?: any;\n changes?: IChange[];\n}\nexport type Changeset = IChange[];\n\nexport interface IFlatChange {\n type: Operation;\n key: string;\n path: string;\n valueType: string | null;\n value?: any;\n oldValue?: any;\n}\n\n/**\n * Computes the difference between two objects.\n *\n * @param {any} oldObj - The original object.\n * @param {any} newObj - The updated object.\n * @param {EmbeddedObjKeysType | EmbeddedObjKeysMapType} embeddedObjKeys - An optional parameter specifying keys of embedded objects.\n * @returns {IChange[]} - An array of changes that transform the old object into the new object.\n */\nexport function diff(\n oldObj: any,\n newObj: any,\n embeddedObjKeys?: EmbeddedObjKeysType | EmbeddedObjKeysMapType,\n keysToSkip?: string[]\n): IChange[] {\n // Trim leading '.' from keys in embeddedObjKeys\n if (embeddedObjKeys instanceof Map) {\n embeddedObjKeys = new Map(\n Array.from(embeddedObjKeys.entries()).map(([key, value]) => [\n key instanceof RegExp ? key : key.replace(/^\\./, ''),\n value\n ])\n );\n } else if (embeddedObjKeys) {\n embeddedObjKeys = Object.fromEntries(\n Object.entries(embeddedObjKeys).map(([key, value]) => [key.replace(/^\\./, ''), value])\n );\n }\n\n // Compare old and new objects to generate a list of changes\n return compare(oldObj, newObj, [], embeddedObjKeys, [], keysToSkip);\n}\n\n/**\n * Applies all changes in the changeset to the object.\n *\n * @param {any} obj - The object to apply changes to.\n * @param {Changeset} changeset - The changeset to apply.\n * @returns {any} - The object after the changes from the changeset have been applied.\n *\n * The function first checks if a changeset is provided. If so, it iterates over each change in the changeset.\n * If the change value is not null or undefined, or if the change type is REMOVE, it applies the change to the object directly.\n * Otherwise, it applies the change to the corresponding branch of the object.\n */\nexport const applyChangeset = (obj: any, changeset: Changeset) => {\n if (changeset) {\n changeset.forEach((change) => {\n const { type, key, value, embeddedKey } = change;\n\n if ((value !== null && value !== undefined) || type === Operation.REMOVE) {\n // Apply the change to the object\n applyLeafChange(obj, change, embeddedKey);\n } else {\n // Apply the change to the branch\n applyBranchChange(obj[key], change);\n }\n });\n }\n return obj;\n};\n\n/**\n * Reverts the changes made to an object based on a given changeset.\n *\n * @param {any} obj - The object on which to revert changes.\n * @param {Changeset} changeset - The changeset to revert.\n * @returns {any} - The object after the changes from the changeset have been reverted.\n *\n * The function first checks if a changeset is provided. If so, it reverses the changeset to start reverting from the last change.\n * It then iterates over each change in the changeset. If the change does not have any nested changes, it reverts the change on the object directly.\n * If the change does have nested changes, it reverts the changes on the corresponding branch of the object.\n */\nexport const revertChangeset = (obj: any, changeset: Changeset) => {\n if (changeset) {\n changeset\n .reverse()\n .forEach((change: IChange): any =>\n !change.changes ? revertLeafChange(obj, change) : revertBranchChange(obj[change.key], change)\n );\n }\n\n return obj;\n};\n\n/**\n * Flattens a changeset into an array of flat changes.\n *\n * @param {Changeset | IChange} obj - The changeset or change to flatten.\n * @param {string} [path='$'] - The current path in the changeset.\n * @param {string | FunctionKey} [embeddedKey] - The key to use for embedded objects.\n * @returns {IFlatChange[]} - An array of flat changes.\n *\n * The function first checks if the input is an array. If so, it recursively flattens each change in the array.\n * If the input is not an array, it checks if the change has nested changes or an embedded key.\n * If so, it updates the path and recursively flattens the nested changes or the embedded object.\n * If the change does not have nested changes or an embedded key, it creates a flat change and returns it in an array.\n */\nexport const flattenChangeset = (\n obj: Changeset | IChange,\n path = '$',\n embeddedKey?: string | FunctionKey\n): IFlatChange[] => {\n if (Array.isArray(obj)) {\n return obj.reduce((memo, change) => [...memo, ...flattenChangeset(change, path, embeddedKey)], [] as IFlatChange[]);\n } else {\n if (obj.changes || embeddedKey) {\n if (embeddedKey) {\n if (embeddedKey === '$index') {\n path = `${path}[${obj.key}]`;\n } else if (embeddedKey === '$value') {\n path = `${path}[?(@='${obj.key}')]`;\n const valueType = getTypeOfObj(obj.value);\n return [\n {\n ...obj,\n path,\n valueType\n }\n ];\n } else if (obj.type === Operation.ADD) {\n // do nothing\n } else {\n path = filterExpression(path, embeddedKey, obj.key);\n }\n } else {\n path = append(path, obj.key);\n }\n\n return flattenChangeset(obj.changes || obj, path, obj.embeddedKey);\n } else {\n const valueType = getTypeOfObj(obj.value);\n return [\n {\n ...obj,\n path: valueType === 'Object' || path.endsWith(`[${obj.key}]`) ? path : append(path, obj.key),\n valueType\n }\n ];\n }\n }\n};\n\n/**\n * Transforms a flat changeset into a nested changeset.\n *\n * @param {IFlatChange | IFlatChange[]} changes - The flat changeset to unflatten.\n * @returns {IChange[]} - The unflattened changeset.\n *\n * The function first checks if the input is a single change or an array of changes.\n * It then iterates over each change and splits its path into segments.\n * For each segment, it checks if it represents an array or a leaf node.\n * If it represents an array, it creates a new change object and updates the pointer to this new object.\n * If it represents a leaf node, it sets the key, type, value, and oldValue of the current change object.\n * Finally, it pushes the unflattened change object into the changes array.\n */\nexport const unflattenChanges = (changes: IFlatChange | IFlatChange[]) => {\n if (!Array.isArray(changes)) {\n changes = [changes];\n }\n\n const changesArr: IChange[] = [];\n\n changes.forEach((change) => {\n const obj = {} as IChange;\n let ptr = obj;\n\n const segments = change.path.split(/(?<=[^@])\\.(?=[^@])/);\n\n if (segments.length === 1) {\n ptr.key = change.key;\n ptr.type = change.type;\n ptr.value = change.value;\n ptr.oldValue = change.oldValue;\n changesArr.push(ptr);\n } else {\n for (let i = 1; i < segments.length; i++) {\n const segment = segments[i];\n // Matches JSONPath segments: \"items[?(@.id=='123')]\", \"items[?(@.id==123)]\", \"items[2]\", \"items[?(@='123')]\"\n const result = /^(.+?)\\[\\?\\(@.?(?:([^=]*))?={1,2}'(.*)'\\)\\]$|^(.+?)\\[(\\d+)\\]$/.exec(segment); //NOSONAR\n // array\n if (result) {\n let key: string;\n let embeddedKey: string;\n let arrKey: string | number;\n if (result[1]) {\n key = result[1];\n embeddedKey = result[2] || '$value';\n arrKey = result[3];\n } else {\n key = result[4];\n embeddedKey = '$index';\n arrKey = Number(result[4]);\n }\n // leaf\n if (i === segments.length - 1) {\n ptr.key = key!;\n ptr.embeddedKey = embeddedKey!;\n ptr.type = Operation.UPDATE;\n ptr.changes = [\n {\n type: change.type,\n key: arrKey!,\n value: change.value,\n oldValue: change.oldValue\n } as IChange\n ];\n } else {\n // object\n ptr.key = key;\n ptr.embeddedKey = embeddedKey;\n ptr.type = Operation.UPDATE;\n const newPtr = {} as IChange;\n ptr.changes = [\n {\n type: Operation.UPDATE,\n key: arrKey,\n changes: [newPtr]\n } as IChange\n ];\n ptr = newPtr;\n }\n } else {\n // leaf\n if (i === segments.length - 1) {\n // check if value is a primitive or object\n if (change.value !== null && change.valueType === 'Object') {\n ptr.key = segment;\n ptr.type = Operation.UPDATE;\n ptr.changes = [\n {\n key: change.key,\n type: change.type,\n value: change.value\n } as IChange\n ];\n } else {\n ptr.key = change.key;\n ptr.type = change.type;\n ptr.value = change.value;\n ptr.oldValue = change.oldValue;\n }\n } else {\n // branch\n ptr.key = segment;\n ptr.type = Operation.UPDATE;\n const newPtr = {} as IChange;\n ptr.changes = [newPtr];\n ptr = newPtr;\n }\n }\n }\n changesArr.push(obj);\n }\n });\n return changesArr;\n};\n\n/**\n * Determines the type of a given object.\n *\n * @param {any} obj - The object whose type is to be determined.\n * @returns {string | null} - The type of the object, or null if the object is null.\n *\n * This function first checks if the object is undefined or null, and returns 'undefined' or null respectively.\n * If the object is neither undefined nor null, it uses Object.prototype.toString to get the object's type.\n * The type is extracted from the string returned by Object.prototype.toString using a regular expression.\n */\nexport const getTypeOfObj = (obj: any) => {\n if (typeof obj === 'undefined') {\n return 'undefined';\n }\n\n if (obj === null) {\n return null;\n }\n\n // Extracts the \"Type\" from \"[object Type]\" string.\n return Object.prototype.toString.call(obj).match(/^\\[object\\s(.*)\\]$/)[1];\n};\n\nconst getKey = (path: string) => {\n const left = path[path.length - 1];\n return left != null ? left : '$root';\n};\n\nconst compare = (oldObj: any, newObj: any, path: any, embeddedObjKeys: any, keyPath: any, keysToSkip: string[]) => {\n let changes: any[] = [];\n\n const typeOfOldObj = getTypeOfObj(oldObj);\n const typeOfNewObj = getTypeOfObj(newObj);\n\n // if type of object changes, consider it as old obj has been deleted and a new object has been added\n if (typeOfOldObj !== typeOfNewObj) {\n changes.push({ type: Operation.REMOVE, key: getKey(path), value: oldObj });\n changes.push({ type: Operation.ADD, key: getKey(path), value: newObj });\n return changes;\n }\n\n switch (typeOfOldObj) {\n case 'Date':\n changes = changes.concat(\n comparePrimitives(oldObj.getTime(), newObj.getTime(), path).map((x) => ({\n ...x,\n value: new Date(x.value),\n oldValue: new Date(x.oldValue)\n }))\n );\n break;\n case 'Object':\n const diffs = compareObject(oldObj, newObj, path, embeddedObjKeys, keyPath, false, keysToSkip);\n if (diffs.length) {\n if (path.length) {\n changes.push({\n type: Operation.UPDATE,\n key: getKey(path),\n changes: diffs\n });\n } else {\n changes = changes.concat(diffs);\n }\n }\n break;\n case 'Array':\n changes = changes.concat(compareArray(oldObj, newObj, path, embeddedObjKeys, keyPath, keysToSkip));\n break;\n case 'Function':\n break;\n // do nothing\n default:\n changes = changes.concat(comparePrimitives(oldObj, newObj, path));\n }\n\n return changes;\n};\n\nconst compareObject = (\n oldObj: any,\n newObj: any,\n path: any,\n embeddedObjKeys: any,\n keyPath: any,\n skipPath = false,\n keysToSkip: string[] = []\n) => {\n let k;\n let newKeyPath;\n let newPath;\n\n if (skipPath == null) {\n skipPath = false;\n }\n let changes: any[] = [];\n\n const oldObjKeys = Object.keys(oldObj).filter((key) => keysToSkip.indexOf(key) === -1);\n const newObjKeys = Object.keys(newObj).filter((key) => keysToSkip.indexOf(key) === -1);\n\n const intersectionKeys = intersection(oldObjKeys, newObjKeys);\n for (k of intersectionKeys) {\n newPath = path.concat([k]);\n newKeyPath = skipPath ? keyPath : keyPath.concat([k]);\n const diffs = compare(oldObj[k], newObj[k], newPath, embeddedObjKeys, newKeyPath, keysToSkip);\n if (diffs.length) {\n changes = changes.concat(diffs);\n }\n }\n\n const addedKeys = difference(newObjKeys, oldObjKeys);\n for (k of addedKeys) {\n newPath = path.concat([k]);\n newKeyPath = skipPath ? keyPath : keyPath.concat([k]);\n changes.push({\n type: Operation.ADD,\n key: getKey(newPath),\n value: newObj[k]\n });\n }\n\n const deletedKeys = difference(oldObjKeys, newObjKeys);\n for (k of deletedKeys) {\n newPath = path.concat([k]);\n newKeyPath = skipPath ? keyPath : keyPath.concat([k]);\n changes.push({\n type: Operation.REMOVE,\n key: getKey(newPath),\n value: oldObj[k]\n });\n }\n return changes;\n};\n\nconst compareArray = (\n oldObj: any,\n newObj: any,\n path: any,\n embeddedObjKeys: any,\n keyPath: any,\n keysToSkip: string[]\n) => {\n const left = getObjectKey(embeddedObjKeys, keyPath);\n const uniqKey = left != null ? left : '$index';\n const indexedOldObj = convertArrayToObj(oldObj, uniqKey);\n const indexedNewObj = convertArrayToObj(newObj, uniqKey);\n const diffs = compareObject(indexedOldObj, indexedNewObj, path, embeddedObjKeys, keyPath, true, keysToSkip);\n if (diffs.length) {\n return [\n {\n type: Operation.UPDATE,\n key: getKey(path),\n embeddedKey: typeof uniqKey === 'function' && uniqKey.length === 2 ? uniqKey(newObj[0], true) : uniqKey,\n changes: diffs\n }\n ];\n } else {\n return [];\n }\n};\n\nconst getObjectKey = (embeddedObjKeys: any, keyPath: any) => {\n if (embeddedObjKeys != null) {\n const path = keyPath.join('.');\n\n if (embeddedObjKeys instanceof Map) {\n for (const [key, value] of embeddedObjKeys.entries()) {\n if (key instanceof RegExp) {\n if (path.match(key)) {\n return value;\n }\n } else if (path === key) {\n return value;\n }\n }\n }\n\n const key = embeddedObjKeys[path];\n if (key != null) {\n return key;\n }\n }\n return undefined;\n};\n\nconst convertArrayToObj = (arr: any[], uniqKey: any) => {\n let obj: any = {};\n if (uniqKey === '$value') {\n arr.forEach((value) => {\n obj[value] = value;\n });\n } else if (uniqKey !== '$index') {\n obj = keyBy(arr, uniqKey);\n } else {\n for (let i = 0; i < arr.length; i++) {\n const value = arr[i];\n obj[i] = value;\n }\n }\n return obj;\n};\n\nconst comparePrimitives = (oldObj: any, newObj: any, path: any) => {\n const changes = [];\n if (oldObj !== newObj) {\n changes.push({\n type: Operation.UPDATE,\n key: getKey(path),\n value: newObj,\n oldValue: oldObj\n });\n }\n return changes;\n};\n\nconst removeKey = (obj: any, key: any, embeddedKey: any) => {\n if (Array.isArray(obj)) {\n if (embeddedKey === '$index') {\n obj.splice(key);\n return;\n }\n const index = indexOfItemInArray(obj, embeddedKey, key);\n if (index === -1) {\n // tslint:disable-next-line:no-console\n console.warn(`Element with the key '${embeddedKey}' and value '${key}' could not be found in the array'`);\n return;\n }\n return obj.splice(index != null ? index : key, 1);\n } else {\n obj[key] = undefined;\n delete obj[key];\n return;\n }\n};\n\nconst indexOfItemInArray = (arr: any[], key: any, value: any) => {\n if (key === '$value') {\n return arr.indexOf(value);\n }\n for (let i = 0; i < arr.length; i++) {\n const item = arr[i];\n if (item && item[key] ? item[key].toString() === value.toString() : undefined) {\n return i;\n }\n }\n return -1;\n};\n\nconst modifyKeyValue = (obj: any, key: any, value: any) => (obj[key] = value);\n\nconst addKeyValue = (obj: any, key: any, value: any) => {\n if (Array.isArray(obj)) {\n return obj.push(value);\n } else {\n return obj ? (obj[key] = value) : null;\n }\n};\n\nconst applyLeafChange = (obj: any, change: any, embeddedKey: any) => {\n const { type, key, value } = change;\n switch (type) {\n case Operation.ADD:\n return addKeyValue(obj, key, value);\n case Operation.UPDATE:\n return modifyKeyValue(obj, key, value);\n case Operation.REMOVE:\n return removeKey(obj, key, embeddedKey);\n }\n};\n\nconst applyArrayChange = (arr: any, change: any) =>\n (() => {\n const result = [];\n for (const subchange of change.changes) {\n if (subchange.value != null || subchange.type === Operation.REMOVE) {\n result.push(applyLeafChange(arr, subchange, change.embeddedKey));\n } else {\n let element;\n if (change.embeddedKey === '$index') {\n element = arr[subchange.key];\n } else if (change.embeddedKey === '$value') {\n const index = arr.indexOf(subchange.key);\n if (index !== -1) {\n element = arr[index];\n }\n } else {\n element = find(arr, (el) => el[change.embeddedKey]?.toString() === subchange.key.toString());\n }\n result.push(applyChangeset(element, subchange.changes));\n }\n }\n return result;\n })();\n\nconst applyBranchChange = (obj: any, change: any) => {\n if (Array.isArray(obj)) {\n return applyArrayChange(obj, change);\n } else {\n return applyChangeset(obj, change.changes);\n }\n};\n\nconst revertLeafChange = (obj: any, change: any, embeddedKey = '$index') => {\n const { type, key, value, oldValue } = change;\n switch (type) {\n case Operation.ADD:\n return removeKey(obj, key, embeddedKey);\n case Operation.UPDATE:\n return modifyKeyValue(obj, key, oldValue);\n case Operation.REMOVE:\n return addKeyValue(obj, key, value);\n }\n};\n\nconst revertArrayChange = (arr: any, change: any) =>\n (() => {\n const result = [];\n for (const subchange of change.changes) {\n if (subchange.value != null || subchange.type === Operation.REMOVE) {\n result.push(revertLeafChange(arr, subchange, change.embeddedKey));\n } else {\n let element;\n if (change.embeddedKey === '$index') {\n element = arr[+subchange.key];\n } else {\n element = find(arr, (el) => el[change.embeddedKey].toString() === subchange.key);\n }\n result.push(revertChangeset(element, subchange.changes));\n }\n }\n return result;\n })();\n\nconst revertBranchChange = (obj: any, change: any) => {\n if (Array.isArray(obj)) {\n return revertArrayChange(obj, change);\n } else {\n return revertChangeset(obj, change.changes);\n }\n};\n\n/** combine a base JSON Path with a subsequent segment */\nfunction append(basePath: string, nextSegment: string): string {\n return nextSegment.includes('.') ? `${basePath}[${nextSegment}]` : `${basePath}.${nextSegment}`;\n}\n\n/** returns a JSON Path filter expression; e.g., `$.pet[(?name='spot')]` */\nfunction filterExpression(basePath: string, filterKey: string | FunctionKey, filterValue: string | number) {\n const value = typeof filterValue === 'number' ? filterValue : `'${filterValue}'`;\n return typeof filterKey === 'string' && filterKey.includes('.')\n ? `${basePath}[?(@[${filterKey}]==${value})]`\n : `${basePath}[?(@.${filterKey}==${value})]`;\n}\n","import { chain, keys, replace, set } from 'lodash-es';\nimport { diff, flattenChangeset, getTypeOfObj, IFlatChange, Operation } from './jsonDiff.js';\n\nexport enum CompareOperation {\n CONTAINER = 'CONTAINER',\n UNCHANGED = 'UNCHANGED'\n}\n\nexport interface IComparisonEnrichedNode {\n type: Operation | CompareOperation;\n value: IComparisonEnrichedNode | IComparisonEnrichedNode[] | any | any[];\n oldValue?: any;\n}\n\nexport const createValue = (value: any): IComparisonEnrichedNode => ({ type: CompareOperation.UNCHANGED, value });\nexport const createContainer = (value: object | []): IComparisonEnrichedNode => ({\n type: CompareOperation.CONTAINER,\n value\n});\n\nexport const enrich = (object: any): IComparisonEnrichedNode => {\n const objectType = getTypeOfObj(object);\n\n switch (objectType) {\n case 'Object':\n return keys(object)\n .map((key: string) => ({ key, value: enrich(object[key]) }))\n .reduce((accumulator, entry) => {\n accumulator.value[entry.key] = entry.value;\n return accumulator;\n }, createContainer({}));\n case 'Array':\n return chain(object)\n .map((value) => enrich(value))\n .reduce((accumulator, value) => {\n accumulator.value.push(value);\n return accumulator;\n }, createContainer([]))\n .value();\n case 'Function':\n return undefined;\n case 'Date':\n default:\n // Primitive value\n return createValue(object);\n }\n};\n\nexport const applyChangelist = (\n object: IComparisonEnrichedNode,\n changelist: IFlatChange[]\n): IComparisonEnrichedNode => {\n chain(changelist)\n .map((entry) => ({ ...entry, path: replace(entry.path, '$.', '.') }))\n .map((entry) => ({\n ...entry,\n path: replace(entry.path, /(\\[(?<array>\\d)\\]\\.)/g, 'ARRVAL_START$<array>ARRVAL_END')\n }))\n .map((entry) => ({ ...entry, path: replace(entry.path, /(?<dot>\\.)/g, '.value$<dot>') }))\n .map((entry) => ({ ...entry, path: replace(entry.path, /\\./, '') }))\n .map((entry) => ({ ...entry, path: replace(entry.path, /ARRVAL_START/g, '.value[') }))\n .map((entry) => ({ ...entry, path: replace(entry.path, /ARRVAL_END/g, '].value.') }))\n .value()\n .forEach((entry) => {\n switch (entry.type) {\n case Operation.ADD:\n case Operation.UPDATE:\n set(object, entry.path, { type: entry.type, value: entry.value, oldValue: entry.oldValue });\n break;\n case Operation.REMOVE:\n set(object, entry.path, { type: entry.type, value: undefined, oldValue: entry.value });\n break;\n default:\n throw new Error();\n }\n });\n return object;\n};\n\nexport const compare = (oldObject: any, newObject: any): IComparisonEnrichedNode => {\n return applyChangelist(enrich(oldObject), flattenChangeset(diff(oldObject, newObject)));\n};\n"],"mappings":"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","names":["Operation","key","CompareOperation","compare"]}
1
+ {"version":3,"sources":["../src/jsonDiff.ts","../src/jsonCompare.ts"],"sourcesContent":["import { difference, find, intersection, keyBy } from 'lodash';\n\ntype FunctionKey = (obj: any, shouldReturnKeyName?: boolean) => any;\nexport type EmbeddedObjKeysType = Record<string, string | FunctionKey>;\nexport type EmbeddedObjKeysMapType = Map<string | RegExp, string | FunctionKey>;\nexport enum Operation {\n REMOVE = 'REMOVE',\n ADD = 'ADD',\n UPDATE = 'UPDATE'\n}\n\nexport interface IChange {\n type: Operation;\n key: string;\n embeddedKey?: string | FunctionKey;\n value?: any | any[];\n oldValue?: any;\n changes?: IChange[];\n}\nexport type Changeset = IChange[];\n\nexport interface IFlatChange {\n type: Operation;\n key: string;\n path: string;\n valueType: string | null;\n value?: any;\n oldValue?: any;\n}\n\n/**\n * Computes the difference between two objects.\n *\n * @param {any} oldObj - The original object.\n * @param {any} newObj - The updated object.\n * @param {EmbeddedObjKeysType | EmbeddedObjKeysMapType} embeddedObjKeys - An optional parameter specifying keys of embedded objects.\n * @returns {IChange[]} - An array of changes that transform the old object into the new object.\n */\nexport function diff(\n oldObj: any,\n newObj: any,\n embeddedObjKeys?: EmbeddedObjKeysType | EmbeddedObjKeysMapType,\n keysToSkip?: string[]\n): IChange[] {\n // Trim leading '.' from keys in embeddedObjKeys\n if (embeddedObjKeys instanceof Map) {\n embeddedObjKeys = new Map(\n Array.from(embeddedObjKeys.entries()).map(([key, value]) => [\n key instanceof RegExp ? key : key.replace(/^\\./, ''),\n value\n ])\n );\n } else if (embeddedObjKeys) {\n embeddedObjKeys = Object.fromEntries(\n Object.entries(embeddedObjKeys).map(([key, value]) => [key.replace(/^\\./, ''), value])\n );\n }\n\n // Compare old and new objects to generate a list of changes\n return compare(oldObj, newObj, [], embeddedObjKeys, [], keysToSkip);\n}\n\n/**\n * Applies all changes in the changeset to the object.\n *\n * @param {any} obj - The object to apply changes to.\n * @param {Changeset} changeset - The changeset to apply.\n * @returns {any} - The object after the changes from the changeset have been applied.\n *\n * The function first checks if a changeset is provided. If so, it iterates over each change in the changeset.\n * If the change value is not null or undefined, or if the change type is REMOVE, it applies the change to the object directly.\n * Otherwise, it applies the change to the corresponding branch of the object.\n */\nexport const applyChangeset = (obj: any, changeset: Changeset) => {\n if (changeset) {\n changeset.forEach((change) => {\n const { type, key, value, embeddedKey } = change;\n\n if ((value !== null && value !== undefined) || type === Operation.REMOVE) {\n // Apply the change to the object\n applyLeafChange(obj, change, embeddedKey);\n } else {\n // Apply the change to the branch\n applyBranchChange(obj[key], change);\n }\n });\n }\n return obj;\n};\n\n/**\n * Reverts the changes made to an object based on a given changeset.\n *\n * @param {any} obj - The object on which to revert changes.\n * @param {Changeset} changeset - The changeset to revert.\n * @returns {any} - The object after the changes from the changeset have been reverted.\n *\n * The function first checks if a changeset is provided. If so, it reverses the changeset to start reverting from the last change.\n * It then iterates over each change in the changeset. If the change does not have any nested changes, it reverts the change on the object directly.\n * If the change does have nested changes, it reverts the changes on the corresponding branch of the object.\n */\nexport const revertChangeset = (obj: any, changeset: Changeset) => {\n if (changeset) {\n changeset\n .reverse()\n .forEach((change: IChange): any =>\n !change.changes ? revertLeafChange(obj, change) : revertBranchChange(obj[change.key], change)\n );\n }\n\n return obj;\n};\n\n/**\n * Flattens a changeset into an array of flat changes.\n *\n * @param {Changeset | IChange} obj - The changeset or change to flatten.\n * @param {string} [path='$'] - The current path in the changeset.\n * @param {string | FunctionKey} [embeddedKey] - The key to use for embedded objects.\n * @returns {IFlatChange[]} - An array of flat changes.\n *\n * The function first checks if the input is an array. If so, it recursively flattens each change in the array.\n * If the input is not an array, it checks if the change has nested changes or an embedded key.\n * If so, it updates the path and recursively flattens the nested changes or the embedded object.\n * If the change does not have nested changes or an embedded key, it creates a flat change and returns it in an array.\n */\nexport const flattenChangeset = (\n obj: Changeset | IChange,\n path = '$',\n embeddedKey?: string | FunctionKey\n): IFlatChange[] => {\n if (Array.isArray(obj)) {\n return obj.reduce((memo, change) => [...memo, ...flattenChangeset(change, path, embeddedKey)], [] as IFlatChange[]);\n } else {\n if (obj.changes || embeddedKey) {\n if (embeddedKey) {\n if (embeddedKey === '$index') {\n path = `${path}[${obj.key}]`;\n } else if (embeddedKey === '$value') {\n path = `${path}[?(@='${obj.key}')]`;\n const valueType = getTypeOfObj(obj.value);\n return [\n {\n ...obj,\n path,\n valueType\n }\n ];\n } else if (obj.type === Operation.ADD) {\n // do nothing\n } else {\n path = filterExpression(path, embeddedKey, obj.key);\n }\n } else {\n path = append(path, obj.key);\n }\n\n return flattenChangeset(obj.changes || obj, path, obj.embeddedKey);\n } else {\n const valueType = getTypeOfObj(obj.value);\n return [\n {\n ...obj,\n path: valueType === 'Object' || path.endsWith(`[${obj.key}]`) ? path : append(path, obj.key),\n valueType\n }\n ];\n }\n }\n};\n\n/**\n * Transforms a flat changeset into a nested changeset.\n *\n * @param {IFlatChange | IFlatChange[]} changes - The flat changeset to unflatten.\n * @returns {IChange[]} - The unflattened changeset.\n *\n * The function first checks if the input is a single change or an array of changes.\n * It then iterates over each change and splits its path into segments.\n * For each segment, it checks if it represents an array or a leaf node.\n * If it represents an array, it creates a new change object and updates the pointer to this new object.\n * If it represents a leaf node, it sets the key, type, value, and oldValue of the current change object.\n * Finally, it pushes the unflattened change object into the changes array.\n */\nexport const unflattenChanges = (changes: IFlatChange | IFlatChange[]) => {\n if (!Array.isArray(changes)) {\n changes = [changes];\n }\n\n const changesArr: IChange[] = [];\n\n changes.forEach((change) => {\n const obj = {} as IChange;\n let ptr = obj;\n\n const segments = change.path.split(/(?<=[^@])\\.(?=[^@])/);\n\n if (segments.length === 1) {\n ptr.key = change.key;\n ptr.type = change.type;\n ptr.value = change.value;\n ptr.oldValue = change.oldValue;\n changesArr.push(ptr);\n } else {\n for (let i = 1; i < segments.length; i++) {\n const segment = segments[i];\n // Matches JSONPath segments: \"items[?(@.id=='123')]\", \"items[?(@.id==123)]\", \"items[2]\", \"items[?(@='123')]\"\n const result = /^(.+?)\\[\\?\\(@.?(?:([^=]*))?={1,2}'(.*)'\\)\\]$|^(.+?)\\[(\\d+)\\]$/.exec(segment); //NOSONAR\n // array\n if (result) {\n let key: string;\n let embeddedKey: string;\n let arrKey: string | number;\n if (result[1]) {\n key = result[1];\n embeddedKey = result[2] || '$value';\n arrKey = result[3];\n } else {\n key = result[4];\n embeddedKey = '$index';\n arrKey = Number(result[4]);\n }\n // leaf\n if (i === segments.length - 1) {\n ptr.key = key!;\n ptr.embeddedKey = embeddedKey!;\n ptr.type = Operation.UPDATE;\n ptr.changes = [\n {\n type: change.type,\n key: arrKey!,\n value: change.value,\n oldValue: change.oldValue\n } as IChange\n ];\n } else {\n // object\n ptr.key = key;\n ptr.embeddedKey = embeddedKey;\n ptr.type = Operation.UPDATE;\n const newPtr = {} as IChange;\n ptr.changes = [\n {\n type: Operation.UPDATE,\n key: arrKey,\n changes: [newPtr]\n } as IChange\n ];\n ptr = newPtr;\n }\n } else {\n // leaf\n if (i === segments.length - 1) {\n // check if value is a primitive or object\n if (change.value !== null && change.valueType === 'Object') {\n ptr.key = segment;\n ptr.type = Operation.UPDATE;\n ptr.changes = [\n {\n key: change.key,\n type: change.type,\n value: change.value\n } as IChange\n ];\n } else {\n ptr.key = change.key;\n ptr.type = change.type;\n ptr.value = change.value;\n ptr.oldValue = change.oldValue;\n }\n } else {\n // branch\n ptr.key = segment;\n ptr.type = Operation.UPDATE;\n const newPtr = {} as IChange;\n ptr.changes = [newPtr];\n ptr = newPtr;\n }\n }\n }\n changesArr.push(obj);\n }\n });\n return changesArr;\n};\n\n/**\n * Determines the type of a given object.\n *\n * @param {any} obj - The object whose type is to be determined.\n * @returns {string | null} - The type of the object, or null if the object is null.\n *\n * This function first checks if the object is undefined or null, and returns 'undefined' or null respectively.\n * If the object is neither undefined nor null, it uses Object.prototype.toString to get the object's type.\n * The type is extracted from the string returned by Object.prototype.toString using a regular expression.\n */\nexport const getTypeOfObj = (obj: any) => {\n if (typeof obj === 'undefined') {\n return 'undefined';\n }\n\n if (obj === null) {\n return null;\n }\n\n // Extracts the \"Type\" from \"[object Type]\" string.\n return Object.prototype.toString.call(obj).match(/^\\[object\\s(.*)\\]$/)[1];\n};\n\nconst getKey = (path: string) => {\n const left = path[path.length - 1];\n return left != null ? left : '$root';\n};\n\nconst compare = (oldObj: any, newObj: any, path: any, embeddedObjKeys: any, keyPath: any, keysToSkip: string[]) => {\n let changes: any[] = [];\n\n const typeOfOldObj = getTypeOfObj(oldObj);\n const typeOfNewObj = getTypeOfObj(newObj);\n\n // if type of object changes, consider it as old obj has been deleted and a new object has been added\n if (typeOfOldObj !== typeOfNewObj) {\n changes.push({ type: Operation.REMOVE, key: getKey(path), value: oldObj });\n changes.push({ type: Operation.ADD, key: getKey(path), value: newObj });\n return changes;\n }\n\n switch (typeOfOldObj) {\n case 'Date':\n changes = changes.concat(\n comparePrimitives(oldObj.getTime(), newObj.getTime(), path).map((x) => ({\n ...x,\n value: new Date(x.value),\n oldValue: new Date(x.oldValue)\n }))\n );\n break;\n case 'Object':\n const diffs = compareObject(oldObj, newObj, path, embeddedObjKeys, keyPath, false, keysToSkip);\n if (diffs.length) {\n if (path.length) {\n changes.push({\n type: Operation.UPDATE,\n key: getKey(path),\n changes: diffs\n });\n } else {\n changes = changes.concat(diffs);\n }\n }\n break;\n case 'Array':\n changes = changes.concat(compareArray(oldObj, newObj, path, embeddedObjKeys, keyPath, keysToSkip));\n break;\n case 'Function':\n break;\n // do nothing\n default:\n changes = changes.concat(comparePrimitives(oldObj, newObj, path));\n }\n\n return changes;\n};\n\nconst compareObject = (\n oldObj: any,\n newObj: any,\n path: any,\n embeddedObjKeys: any,\n keyPath: any,\n skipPath = false,\n keysToSkip: string[] = []\n) => {\n let k;\n let newKeyPath;\n let newPath;\n\n if (skipPath == null) {\n skipPath = false;\n }\n let changes: any[] = [];\n\n const oldObjKeys = Object.keys(oldObj).filter((key) => keysToSkip.indexOf(key) === -1);\n const newObjKeys = Object.keys(newObj).filter((key) => keysToSkip.indexOf(key) === -1);\n\n const intersectionKeys = intersection(oldObjKeys, newObjKeys);\n for (k of intersectionKeys) {\n newPath = path.concat([k]);\n newKeyPath = skipPath ? keyPath : keyPath.concat([k]);\n const diffs = compare(oldObj[k], newObj[k], newPath, embeddedObjKeys, newKeyPath, keysToSkip);\n if (diffs.length) {\n changes = changes.concat(diffs);\n }\n }\n\n const addedKeys = difference(newObjKeys, oldObjKeys);\n for (k of addedKeys) {\n newPath = path.concat([k]);\n newKeyPath = skipPath ? keyPath : keyPath.concat([k]);\n changes.push({\n type: Operation.ADD,\n key: getKey(newPath),\n value: newObj[k]\n });\n }\n\n const deletedKeys = difference(oldObjKeys, newObjKeys);\n for (k of deletedKeys) {\n newPath = path.concat([k]);\n newKeyPath = skipPath ? keyPath : keyPath.concat([k]);\n changes.push({\n type: Operation.REMOVE,\n key: getKey(newPath),\n value: oldObj[k]\n });\n }\n return changes;\n};\n\nconst compareArray = (\n oldObj: any,\n newObj: any,\n path: any,\n embeddedObjKeys: any,\n keyPath: any,\n keysToSkip: string[]\n) => {\n const left = getObjectKey(embeddedObjKeys, keyPath);\n const uniqKey = left != null ? left : '$index';\n const indexedOldObj = convertArrayToObj(oldObj, uniqKey);\n const indexedNewObj = convertArrayToObj(newObj, uniqKey);\n const diffs = compareObject(indexedOldObj, indexedNewObj, path, embeddedObjKeys, keyPath, true, keysToSkip);\n if (diffs.length) {\n return [\n {\n type: Operation.UPDATE,\n key: getKey(path),\n embeddedKey: typeof uniqKey === 'function' && uniqKey.length === 2 ? uniqKey(newObj[0], true) : uniqKey,\n changes: diffs\n }\n ];\n } else {\n return [];\n }\n};\n\nconst getObjectKey = (embeddedObjKeys: any, keyPath: any) => {\n if (embeddedObjKeys != null) {\n const path = keyPath.join('.');\n\n if (embeddedObjKeys instanceof Map) {\n for (const [key, value] of embeddedObjKeys.entries()) {\n if (key instanceof RegExp) {\n if (path.match(key)) {\n return value;\n }\n } else if (path === key) {\n return value;\n }\n }\n }\n\n const key = embeddedObjKeys[path];\n if (key != null) {\n return key;\n }\n }\n return undefined;\n};\n\nconst convertArrayToObj = (arr: any[], uniqKey: any) => {\n let obj: any = {};\n if (uniqKey === '$value') {\n arr.forEach((value) => {\n obj[value] = value;\n });\n } else if (uniqKey !== '$index') {\n obj = keyBy(arr, uniqKey);\n } else {\n for (let i = 0; i < arr.length; i++) {\n const value = arr[i];\n obj[i] = value;\n }\n }\n return obj;\n};\n\nconst comparePrimitives = (oldObj: any, newObj: any, path: any) => {\n const changes = [];\n if (oldObj !== newObj) {\n changes.push({\n type: Operation.UPDATE,\n key: getKey(path),\n value: newObj,\n oldValue: oldObj\n });\n }\n return changes;\n};\n\nconst removeKey = (obj: any, key: any, embeddedKey: any) => {\n if (Array.isArray(obj)) {\n if (embeddedKey === '$index') {\n obj.splice(key);\n return;\n }\n const index = indexOfItemInArray(obj, embeddedKey, key);\n if (index === -1) {\n // tslint:disable-next-line:no-console\n console.warn(`Element with the key '${embeddedKey}' and value '${key}' could not be found in the array'`);\n return;\n }\n return obj.splice(index != null ? index : key, 1);\n } else {\n obj[key] = undefined;\n delete obj[key];\n return;\n }\n};\n\nconst indexOfItemInArray = (arr: any[], key: any, value: any) => {\n if (key === '$value') {\n return arr.indexOf(value);\n }\n for (let i = 0; i < arr.length; i++) {\n const item = arr[i];\n if (item && item[key] ? item[key].toString() === value.toString() : undefined) {\n return i;\n }\n }\n return -1;\n};\n\nconst modifyKeyValue = (obj: any, key: any, value: any) => (obj[key] = value);\n\nconst addKeyValue = (obj: any, key: any, value: any) => {\n if (Array.isArray(obj)) {\n return obj.push(value);\n } else {\n return obj ? (obj[key] = value) : null;\n }\n};\n\nconst applyLeafChange = (obj: any, change: any, embeddedKey: any) => {\n const { type, key, value } = change;\n switch (type) {\n case Operation.ADD:\n return addKeyValue(obj, key, value);\n case Operation.UPDATE:\n return modifyKeyValue(obj, key, value);\n case Operation.REMOVE:\n return removeKey(obj, key, embeddedKey);\n }\n};\n\nconst applyArrayChange = (arr: any, change: any) =>\n (() => {\n const result = [];\n for (const subchange of change.changes) {\n if (subchange.value != null || subchange.type === Operation.REMOVE) {\n result.push(applyLeafChange(arr, subchange, change.embeddedKey));\n } else {\n let element;\n if (change.embeddedKey === '$index') {\n element = arr[subchange.key];\n } else if (change.embeddedKey === '$value') {\n const index = arr.indexOf(subchange.key);\n if (index !== -1) {\n element = arr[index];\n }\n } else {\n element = find(arr, (el) => el[change.embeddedKey]?.toString() === subchange.key.toString());\n }\n result.push(applyChangeset(element, subchange.changes));\n }\n }\n return result;\n })();\n\nconst applyBranchChange = (obj: any, change: any) => {\n if (Array.isArray(obj)) {\n return applyArrayChange(obj, change);\n } else {\n return applyChangeset(obj, change.changes);\n }\n};\n\nconst revertLeafChange = (obj: any, change: any, embeddedKey = '$index') => {\n const { type, key, value, oldValue } = change;\n switch (type) {\n case Operation.ADD:\n return removeKey(obj, key, embeddedKey);\n case Operation.UPDATE:\n return modifyKeyValue(obj, key, oldValue);\n case Operation.REMOVE:\n return addKeyValue(obj, key, value);\n }\n};\n\nconst revertArrayChange = (arr: any, change: any) =>\n (() => {\n const result = [];\n for (const subchange of change.changes) {\n if (subchange.value != null || subchange.type === Operation.REMOVE) {\n result.push(revertLeafChange(arr, subchange, change.embeddedKey));\n } else {\n let element;\n if (change.embeddedKey === '$index') {\n element = arr[+subchange.key];\n } else {\n element = find(arr, (el) => el[change.embeddedKey].toString() === subchange.key);\n }\n result.push(revertChangeset(element, subchange.changes));\n }\n }\n return result;\n })();\n\nconst revertBranchChange = (obj: any, change: any) => {\n if (Array.isArray(obj)) {\n return revertArrayChange(obj, change);\n } else {\n return revertChangeset(obj, change.changes);\n }\n};\n\n/** combine a base JSON Path with a subsequent segment */\nfunction append(basePath: string, nextSegment: string): string {\n return nextSegment.includes('.') ? `${basePath}[${nextSegment}]` : `${basePath}.${nextSegment}`;\n}\n\n/** returns a JSON Path filter expression; e.g., `$.pet[(?name='spot')]` */\nfunction filterExpression(basePath: string, filterKey: string | FunctionKey, filterValue: string | number) {\n const value = typeof filterValue === 'number' ? filterValue : `'${filterValue}'`;\n return typeof filterKey === 'string' && filterKey.includes('.')\n ? `${basePath}[?(@[${filterKey}]==${value})]`\n : `${basePath}[?(@.${filterKey}==${value})]`;\n}\n","import { chain, keys, replace, set } from 'lodash';\nimport { diff, flattenChangeset, getTypeOfObj, IFlatChange, Operation } from './jsonDiff.js';\n\nexport enum CompareOperation {\n CONTAINER = 'CONTAINER',\n UNCHANGED = 'UNCHANGED'\n}\n\nexport interface IComparisonEnrichedNode {\n type: Operation | CompareOperation;\n value: IComparisonEnrichedNode | IComparisonEnrichedNode[] | any | any[];\n oldValue?: any;\n}\n\nexport const createValue = (value: any): IComparisonEnrichedNode => ({ type: CompareOperation.UNCHANGED, value });\nexport const createContainer = (value: object | []): IComparisonEnrichedNode => ({\n type: CompareOperation.CONTAINER,\n value\n});\n\nexport const enrich = (object: any): IComparisonEnrichedNode => {\n const objectType = getTypeOfObj(object);\n\n switch (objectType) {\n case 'Object':\n return keys(object)\n .map((key: string) => ({ key, value: enrich(object[key]) }))\n .reduce((accumulator, entry) => {\n accumulator.value[entry.key] = entry.value;\n return accumulator;\n }, createContainer({}));\n case 'Array':\n return chain(object)\n .map((value) => enrich(value))\n .reduce((accumulator, value) => {\n accumulator.value.push(value);\n return accumulator;\n }, createContainer([]))\n .value();\n case 'Function':\n return undefined;\n case 'Date':\n default:\n // Primitive value\n return createValue(object);\n }\n};\n\nexport const applyChangelist = (\n object: IComparisonEnrichedNode,\n changelist: IFlatChange[]\n): IComparisonEnrichedNode => {\n chain(changelist)\n .map((entry) => ({ ...entry, path: replace(entry.path, '$.', '.') }))\n .map((entry) => ({\n ...entry,\n path: replace(entry.path, /(\\[(?<array>\\d)\\]\\.)/g, 'ARRVAL_START$<array>ARRVAL_END')\n }))\n .map((entry) => ({ ...entry, path: replace(entry.path, /(?<dot>\\.)/g, '.value$<dot>') }))\n .map((entry) => ({ ...entry, path: replace(entry.path, /\\./, '') }))\n .map((entry) => ({ ...entry, path: replace(entry.path, /ARRVAL_START/g, '.value[') }))\n .map((entry) => ({ ...entry, path: replace(entry.path, /ARRVAL_END/g, '].value.') }))\n .value()\n .forEach((entry) => {\n switch (entry.type) {\n case Operation.ADD:\n case Operation.UPDATE:\n set(object, entry.path, { type: entry.type, value: entry.value, oldValue: entry.oldValue });\n break;\n case Operation.REMOVE:\n set(object, entry.path, { type: entry.type, value: undefined, oldValue: entry.value });\n break;\n default:\n throw new Error();\n }\n });\n return object;\n};\n\nexport const compare = (oldObject: any, newObject: any): IComparisonEnrichedNode => {\n return applyChangelist(enrich(oldObject), flattenChangeset(diff(oldObject, newObject)));\n};\n"],"mappings":"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","names":["Operation","key","CompareOperation","compare"]}
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "json-diff-ts",
3
- "version": "3.0.0-beta.4",
3
+ "version": "3.0.0-beta.5",
4
4
  "description": "A JSON diff tool for JavaScript written in TypeScript.",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
7
7
  "types": "./dist/index.d.ts",
8
8
  "type": "module",
9
9
  "scripts": {
10
- "build": "tsup --format cjs,esm --tsconfig tsconfig.cjs.json",
10
+ "build": "tsup --format cjs,esm",
11
11
  "format": "prettier --write \"src/**/*.ts\"",
12
12
  "lint": "eslint 'src/**/*.ts'",
13
13
  "test": "NODE_OPTIONS=--experimental-vm-modules jest --config jest.config.mjs",
@@ -38,9 +38,6 @@
38
38
  "url": "https://github.com/ltwlf/json-diff-ts/issues"
39
39
  },
40
40
  "homepage": "https://github.com/ltwlf/json-diff-ts#readme",
41
- "dependencies": {
42
- "lodash-es": "^4.17.21"
43
- },
44
41
  "devDependencies": {
45
42
  "@jest/globals": "^29.7.0",
46
43
  "@types/jest": "^29.5.7",
@@ -49,8 +46,10 @@
49
46
  "jest": "^29.7.0",
50
47
  "prettier": "^3.0.3",
51
48
  "ts-jest": "^29.0.5",
52
- "tsconfig-paths": "^4.2.0",
53
49
  "tsup": "^8.0.2",
54
50
  "typescript": "^5.3.2"
51
+ },
52
+ "dependencies": {
53
+ "lodash": "^4.17.21"
55
54
  }
56
55
  }