54 lines
1.4 KiB
TypeScript
54 lines
1.4 KiB
TypeScript
import { transform, isEqual, isObject } from "lodash";
|
|
|
|
/**
|
|
* Deep diff between two object, using lodash
|
|
* @param {Object} object Object compared
|
|
* @param {Object} base Object to compare with
|
|
* @return {Object} Return a new object who represent the diff
|
|
*/
|
|
export const difference = (object, base) => {
|
|
return changes(object, base);
|
|
};
|
|
|
|
const changes = (object, base) => {
|
|
return transform(object, (result, value, key) => {
|
|
if (!isEqual(value, base[key])) {
|
|
result[key] =
|
|
isObject(value) && isObject(base[key])
|
|
? changes(value, base[key])
|
|
: value;
|
|
}
|
|
});
|
|
};
|
|
|
|
export type TraverseFunction<T> = (
|
|
obj: T,
|
|
prop: string,
|
|
value: unknown,
|
|
scope: string[],
|
|
) => void;
|
|
|
|
/**
|
|
* Deep diff between two object, using lodash
|
|
* @param {Object} object Object to traverse
|
|
* @param {Object} fn Callback function
|
|
* @return {Object} Return a new object who represent the diff
|
|
*/
|
|
export const traverseObject = <T = Record<string, unknown>>(
|
|
object: T,
|
|
fn: TraverseFunction<T>,
|
|
): void => traverseInternal(object, fn, []);
|
|
|
|
const traverseInternal = <T = Record<string, unknown>>(
|
|
object: T,
|
|
fn: TraverseFunction<T>,
|
|
scope: string[] = [],
|
|
): void => {
|
|
Object.entries(object).forEach(([key, value]) => {
|
|
fn.apply(this, [object, key, value, scope]);
|
|
if (value !== null && typeof value === "object") {
|
|
traverseInternal(value, fn, scope.concat(key));
|
|
}
|
|
});
|
|
};
|