@strapi/data-transfer
Version:
Data transfer capabilities for Strapi
95 lines (92 loc) • 2.29 kB
JavaScript
import { isArray, zip, isObject, uniq, isEqual } from 'lodash/fp';
const createContext = ()=>({
path: []
});
/**
* Compute differences between two JSON objects and returns them
*
* @param a - First object
* @param b - Second object
* @param ctx - Context used to keep track of the current path during recursion
*/ const diff = (a, b, ctx = createContext())=>{
const diffs = [];
const { path } = ctx;
const aType = typeof a;
const bType = typeof b;
// Define helpers
const added = ()=>{
diffs.push({
kind: 'added',
path,
type: bType,
value: b
});
return diffs;
};
const deleted = ()=>{
diffs.push({
kind: 'deleted',
path,
type: aType,
value: a
});
return diffs;
};
const modified = ()=>{
diffs.push({
kind: 'modified',
path,
types: [
aType,
bType
],
values: [
a,
b
]
});
return diffs;
};
if (isArray(a) && isArray(b)) {
let k = 0;
for (const [aItem, bItem] of zip(a, b)){
const kCtx = {
path: [
...path,
k.toString()
]
};
const kDiffs = diff(aItem, bItem, kCtx);
diffs.push(...kDiffs);
k += 1;
}
return diffs;
}
if (isObject(a) && isObject(b)) {
const keys = uniq(Object.keys(a).concat(Object.keys(b)));
for (const key of keys){
const aValue = a[key];
const bValue = b[key];
const nestedDiffs = diff(aValue, bValue, {
path: [
...path,
key
]
});
diffs.push(...nestedDiffs);
}
return diffs;
}
if (!isEqual(a, b)) {
if (aType === 'undefined') {
return added();
}
if (bType === 'undefined') {
return deleted();
}
return modified();
}
return diffs;
};
export { diff };
//# sourceMappingURL=json.mjs.map