diff --git a/dist.browser/json-difference.mjs b/dist.browser/json-difference.mjs index 48bc864..d56b94c 100644 --- a/dist.browser/json-difference.mjs +++ b/dist.browser/json-difference.mjs @@ -1,47 +1,311 @@ -const p = (f, i) => { - const o = []; - for (const e in f) - if (i.hasOwnProperty(e)) { - if (typeof f[e] == "object" && typeof i[e] == "object" && JSON.stringify(f[e]) === JSON.stringify(i[e]) || f[e] === i[e]) +const J = (t, e) => { + const n = []; + for (const r in t) + if (e.hasOwnProperty(r)) { + if (typeof t[r] == "object" && typeof e[r] == "object" && JSON.stringify(t[r]) === JSON.stringify(e[r]) || t[r] === e[r]) continue; - if (f[e] === "@{}" || f[e] === "@[]") { - const n = i[e] === "@{}" ? {} : i[e] === "@[]" ? [] : i[e]; - f[e] === "@{}" ? JSON.stringify(i[e]) !== "{}" && o.push([e, {}, n]) : JSON.stringify(i[e]) !== "[]" && o.push([e, [], n]); + if (t[r] === "@{}" || t[r] === "@[]") { + const o = e[r] === "@{}" ? {} : e[r] === "@[]" ? [] : e[r]; + t[r] === "@{}" ? JSON.stringify(e[r]) !== "{}" && n.push([r, {}, o]) : JSON.stringify(e[r]) !== "[]" && n.push([r, [], o]); } else - o.push([e, f[e], i[e]]); + n.push([r, t[r], e[r]]); } - return o; -}, d = (f, i) => { - const o = []; - let e = 0; - for (const n in f) - if (!(n in i)) { - const y = f[n] === "@{}" ? {} : f[n] === "@[]" ? [] : f[n]; - o[e] = [n, y], e++; + return n; +}, x = (t, e) => { + const n = []; + let r = 0; + for (const o in t) + if (!(o in e)) { + const i = t[o] === "@{}" ? {} : t[o] === "@[]" ? [] : t[o]; + n[r] = [o, i], r++; } - return o; -}, O = (f, i, o, e) => { - const n = e ? f ? "[" : "." : "/", y = e ? f ? "]" : "" : f ? "[]" : ""; - return i !== "" ? `${i}${n}${o}${y}` : `${e && f ? "[" : ""}${o}${y}`; -}, g = (f, i = !1, o = {}, e = "") => { - for (const n of Object.keys(f)) { - const y = O(Array.isArray(f), e, n, i); - typeof f[n] == "object" && f[n] !== null ? (Object.keys(f[n]).length === 0 ? o[y] = f[n] : o[y] = Array.isArray(f[n]) ? "@[]" : "@{}", g(f[n], i, o, y)) : o[y] = f[n]; + return n; +}, K = (t, e, n, r) => { + const o = r ? t ? "[" : "." : "/", i = r ? t ? "]" : "" : t ? "[]" : ""; + return e !== "" ? `${e}${o}${n}${i}` : `${r && t ? "[" : ""}${n}${i}`; +}, C = (t, e = !1, n = {}, r = "") => { + for (const o of Object.keys(t)) { + const i = K(Array.isArray(t), r, o, e); + typeof t[o] == "object" && t[o] !== null ? (Object.keys(t[o]).length === 0 ? n[i] = t[o] : n[i] = Array.isArray(t[o]) ? "@[]" : "@{}", C(t[o], e, n, i)) : n[i] = t[o]; } - return o; -}, $ = { - isLodashLike: !1 -}, b = (f, i, o) => { - const { isLodashLike: e } = o ?? $, n = { + return n; +}; +var h = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}; +function L(t) { + return t && t.__esModule && Object.prototype.hasOwnProperty.call(t, "default") ? t.default : t; +} +var U = "Expected a function", S = "__lodash_hash_undefined__", w = 1 / 0, X = 9007199254740991, q = "[object Function]", z = "[object GeneratorFunction]", P = "[object Symbol]", Y = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, B = /^\w*$/, Q = /^\./, W = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g, Z = /[\\^$.*+?()[\]{}|]/g, V = /\\(\\)?/g, k = /^\[object .+?Constructor\]$/, tt = /^(?:0|[1-9]\d*)$/, et = typeof h == "object" && h && h.Object === Object && h, nt = typeof self == "object" && self && self.Object === Object && self, j = et || nt || Function("return this")(); +function rt(t, e) { + return t == null ? void 0 : t[e]; +} +function ot(t) { + var e = !1; + if (t != null && typeof t.toString != "function") + try { + e = !!(t + ""); + } catch { + } + return e; +} +var it = Array.prototype, at = Function.prototype, F = Object.prototype, O = j["__core-js_shared__"], I = function() { + var t = /[^.]+$/.exec(O && O.keys && O.keys.IE_PROTO || ""); + return t ? "Symbol(src)_1." + t : ""; +}(), A = at.toString, y = F.hasOwnProperty, H = F.toString, ft = RegExp( + "^" + A.call(y).replace(Z, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$" +), E = j.Symbol, st = it.splice, ct = G(j, "Map"), p = G(Object, "create"), N = E ? E.prototype : void 0, D = N ? N.toString : void 0; +function s(t) { + var e = -1, n = t ? t.length : 0; + for (this.clear(); ++e < n; ) { + var r = t[e]; + this.set(r[0], r[1]); + } +} +function ut() { + this.__data__ = p ? p(null) : {}; +} +function pt(t) { + return this.has(t) && delete this.__data__[t]; +} +function dt(t) { + var e = this.__data__; + if (p) { + var n = e[t]; + return n === S ? void 0 : n; + } + return y.call(e, t) ? e[t] : void 0; +} +function lt(t) { + var e = this.__data__; + return p ? e[t] !== void 0 : y.call(e, t); +} +function ht(t, e) { + var n = this.__data__; + return n[t] = p && e === void 0 ? S : e, this; +} +s.prototype.clear = ut; +s.prototype.delete = pt; +s.prototype.get = dt; +s.prototype.has = lt; +s.prototype.set = ht; +function u(t) { + var e = -1, n = t ? t.length : 0; + for (this.clear(); ++e < n; ) { + var r = t[e]; + this.set(r[0], r[1]); + } +} +function _t() { + this.__data__ = []; +} +function yt(t) { + var e = this.__data__, n = g(e, t); + if (n < 0) + return !1; + var r = e.length - 1; + return n == r ? e.pop() : st.call(e, n, 1), !0; +} +function gt(t) { + var e = this.__data__, n = g(e, t); + return n < 0 ? void 0 : e[n][1]; +} +function bt(t) { + return g(this.__data__, t) > -1; +} +function mt(t, e) { + var n = this.__data__, r = g(n, t); + return r < 0 ? n.push([t, e]) : n[r][1] = e, this; +} +u.prototype.clear = _t; +u.prototype.delete = yt; +u.prototype.get = gt; +u.prototype.has = bt; +u.prototype.set = mt; +function c(t) { + var e = -1, n = t ? t.length : 0; + for (this.clear(); ++e < n; ) { + var r = t[e]; + this.set(r[0], r[1]); + } +} +function Ot() { + this.__data__ = { + hash: new s(), + map: new (ct || u)(), + string: new s() + }; +} +function vt(t) { + return b(this, t).delete(t); +} +function Ct(t) { + return b(this, t).get(t); +} +function jt(t) { + return b(this, t).has(t); +} +function $t(t, e) { + return b(this, t).set(t, e), this; +} +c.prototype.clear = Ot; +c.prototype.delete = vt; +c.prototype.get = Ct; +c.prototype.has = jt; +c.prototype.set = $t; +function Tt(t, e, n) { + var r = t[e]; + (!(y.call(t, e) && M(r, n)) || n === void 0 && !(e in t)) && (t[e] = n); +} +function g(t, e) { + for (var n = t.length; n--; ) + if (M(t[n][0], e)) + return n; + return -1; +} +function xt(t) { + if (!_(t) || Ft(t)) + return !1; + var e = Mt(t) || ot(t) ? ft : k; + return e.test(Gt(t)); +} +function It(t, e, n, r) { + if (!_(t)) + return t; + e = St(e, t) ? [e] : Nt(e); + for (var o = -1, i = e.length, f = i - 1, a = t; a != null && ++o < i; ) { + var d = Ht(e[o]), l = n; + if (o != f) { + var m = a[d]; + l = r ? r(m, d, a) : void 0, l === void 0 && (l = _(m) ? m : Dt(e[o + 1]) ? [] : {}); + } + Tt(a, d, l), a = a[d]; + } + return t; +} +function Et(t) { + if (typeof t == "string") + return t; + if (T(t)) + return D ? D.call(t) : ""; + var e = t + ""; + return e == "0" && 1 / t == -w ? "-0" : e; +} +function Nt(t) { + return R(t) ? t : At(t); +} +function b(t, e) { + var n = t.__data__; + return wt(e) ? n[typeof e == "string" ? "string" : "hash"] : n.map; +} +function G(t, e) { + var n = rt(t, e); + return xt(n) ? n : void 0; +} +function Dt(t, e) { + return e = e ?? X, !!e && (typeof t == "number" || tt.test(t)) && t > -1 && t % 1 == 0 && t < e; +} +function St(t, e) { + if (R(t)) + return !1; + var n = typeof t; + return n == "number" || n == "symbol" || n == "boolean" || t == null || T(t) ? !0 : B.test(t) || !Y.test(t) || e != null && t in Object(e); +} +function wt(t) { + var e = typeof t; + return e == "string" || e == "number" || e == "symbol" || e == "boolean" ? t !== "__proto__" : t === null; +} +function Ft(t) { + return !!I && I in t; +} +var At = $(function(t) { + t = Jt(t); + var e = []; + return Q.test(t) && e.push(""), t.replace(W, function(n, r, o, i) { + e.push(o ? i.replace(V, "$1") : r || n); + }), e; +}); +function Ht(t) { + if (typeof t == "string" || T(t)) + return t; + var e = t + ""; + return e == "0" && 1 / t == -w ? "-0" : e; +} +function Gt(t) { + if (t != null) { + try { + return A.call(t); + } catch { + } + try { + return t + ""; + } catch { + } + } + return ""; +} +function $(t, e) { + if (typeof t != "function" || e && typeof e != "function") + throw new TypeError(U); + var n = function() { + var r = arguments, o = e ? e.apply(this, r) : r[0], i = n.cache; + if (i.has(o)) + return i.get(o); + var f = t.apply(this, r); + return n.cache = i.set(o, f), f; + }; + return n.cache = new ($.Cache || c)(), n; +} +$.Cache = c; +function M(t, e) { + return t === e || t !== t && e !== e; +} +var R = Array.isArray; +function Mt(t) { + var e = _(t) ? H.call(t) : ""; + return e == q || e == z; +} +function _(t) { + var e = typeof t; + return !!t && (e == "object" || e == "function"); +} +function Rt(t) { + return !!t && typeof t == "object"; +} +function T(t) { + return typeof t == "symbol" || Rt(t) && H.call(t) == P; +} +function Jt(t) { + return t == null ? "" : Et(t); +} +function Kt(t, e, n) { + return t == null ? t : It(t, e, n); +} +var Lt = Kt; +const v = /* @__PURE__ */ L(Lt), Ut = (t) => { + const e = t.removed.map((o) => { + const i = {}; + return v(i, o[0], o[1]), i; + }), n = t.edited.map((o) => v({}, "cafe/123", "8888")), r = t.added.map((o) => v({}, o[0], o[1])); + return { + removed: e, + edited: n, + added: r + }; +}, Xt = { + isLodashLike: !1, + isObjectOutput: !1 +}, qt = (t, e, n) => { + const { isLodashLike: r, isObjectOutput: o } = n ?? Xt; + let i = { added: [], removed: [], edited: [] - }, y = g(f, e), s = g(i, e); - return n.removed = d(y, s), n.added = d(s, y), n.edited = p(y, s), n; + }; + const f = C(t, r), a = C(e, r); + return i.removed = x(f, a), i.added = x(a, f), i.edited = J(f, a), o && (i = Ut(i)), i; }; export { - b as getDiff, - p as getEditedPaths, - d as getPathsDiff, - g as getStructPaths + qt as getDiff, + J as getEditedPaths, + x as getPathsDiff, + C as getStructPaths }; diff --git a/dist.browser/json-difference.umd.js b/dist.browser/json-difference.umd.js index 3a8c8e8..f2e98c8 100644 --- a/dist.browser/json-difference.umd.js +++ b/dist.browser/json-difference.umd.js @@ -1 +1 @@ -(function(s,y){typeof exports=="object"&&typeof module<"u"?y(exports):typeof define=="function"&&define.amd?define(["exports"],y):(s=typeof globalThis<"u"?globalThis:s||self,y(s["json-difference"]={}))})(this,function(s){"use strict";const y=(f,n)=>{const o=[];for(const e in f)if(n.hasOwnProperty(e)){if(typeof f[e]=="object"&&typeof n[e]=="object"&&JSON.stringify(f[e])===JSON.stringify(n[e])||f[e]===n[e])continue;if(f[e]==="@{}"||f[e]==="@[]"){const i=n[e]==="@{}"?{}:n[e]==="@[]"?[]:n[e];f[e]==="@{}"?JSON.stringify(n[e])!=="{}"&&o.push([e,{},i]):JSON.stringify(n[e])!=="[]"&&o.push([e,[],i])}else o.push([e,f[e],n[e]])}return o},p=(f,n)=>{const o=[];let e=0;for(const i in f)if(!(i in n)){const d=f[i]==="@{}"?{}:f[i]==="@[]"?[]:f[i];o[e]=[i,d],e++}return o},c=(f,n,o,e)=>{const i=e?f?"[":".":"/",d=e?f?"]":"":f?"[]":"";return n!==""?`${n}${i}${o}${d}`:`${e&&f?"[":""}${o}${d}`},g=(f,n=!1,o={},e="")=>{for(const i of Object.keys(f)){const d=c(Array.isArray(f),e,i,n);typeof f[i]=="object"&&f[i]!==null?(Object.keys(f[i]).length===0?o[d]=f[i]:o[d]=Array.isArray(f[i])?"@[]":"@{}",g(f[i],n,o,d)):o[d]=f[i]}return o},O={isLodashLike:!1},b=(f,n,o)=>{const{isLodashLike:e}=o??O,i={added:[],removed:[],edited:[]},d=g(f,e),t=g(n,e);return i.removed=p(d,t),i.added=p(t,d),i.edited=y(d,t),i};s.getDiff=b,s.getEditedPaths=y,s.getPathsDiff=p,s.getStructPaths=g,Object.defineProperty(s,Symbol.toStringTag,{value:"Module"})}); +(function(f,d){typeof exports=="object"&&typeof module<"u"?d(exports):typeof define=="function"&&define.amd?define(["exports"],d):(f=typeof globalThis<"u"?globalThis:f||self,d(f["json-difference"]={}))})(this,function(f){"use strict";const d=(t,e)=>{const n=[];for(const r in t)if(e.hasOwnProperty(r)){if(typeof t[r]=="object"&&typeof e[r]=="object"&&JSON.stringify(t[r])===JSON.stringify(e[r])||t[r]===e[r])continue;if(t[r]==="@{}"||t[r]==="@[]"){const i=e[r]==="@{}"?{}:e[r]==="@[]"?[]:e[r];t[r]==="@{}"?JSON.stringify(e[r])!=="{}"&&n.push([r,{},i]):JSON.stringify(e[r])!=="[]"&&n.push([r,[],i])}else n.push([r,t[r],e[r]])}return n},j=(t,e)=>{const n=[];let r=0;for(const i in t)if(!(i in e)){const o=t[i]==="@{}"?{}:t[i]==="@[]"?[]:t[i];n[r]=[i,o],r++}return n},K=(t,e,n,r)=>{const i=r?t?"[":".":"/",o=r?t?"]":"":t?"[]":"";return e!==""?`${e}${i}${n}${o}`:`${r&&t?"[":""}${n}${o}`},h=(t,e=!1,n={},r="")=>{for(const i of Object.keys(t)){const o=K(Array.isArray(t),r,i,e);typeof t[i]=="object"&&t[i]!==null?(Object.keys(t[i]).length===0?n[o]=t[i]:n[o]=Array.isArray(t[i])?"@[]":"@{}",h(t[i],e,n,o)):n[o]=t[i]}return n};var _=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function L(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var U="Expected a function",S="__lodash_hash_undefined__",x=1/0,X=9007199254740991,q="[object Function]",z="[object GeneratorFunction]",Y="[object Symbol]",B=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,Q=/^\w*$/,W=/^\./,Z=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,V=/[\\^$.*+?()[\]{}|]/g,k=/\\(\\)?/g,tt=/^\[object .+?Constructor\]$/,et=/^(?:0|[1-9]\d*)$/,nt=typeof _=="object"&&_&&_.Object===Object&&_,rt=typeof self=="object"&&self&&self.Object===Object&&self,C=nt||rt||Function("return this")();function it(t,e){return t==null?void 0:t[e]}function ot(t){var e=!1;if(t!=null&&typeof t.toString!="function")try{e=!!(t+"")}catch{}return e}var at=Array.prototype,ft=Function.prototype,N=Object.prototype,T=C["__core-js_shared__"],w=function(){var t=/[^.]+$/.exec(T&&T.keys&&T.keys.IE_PROTO||"");return t?"Symbol(src)_1."+t:""}(),F=ft.toString,y=N.hasOwnProperty,A=N.toString,st=RegExp("^"+F.call(y).replace(V,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),H=C.Symbol,ct=at.splice,ut=R(C,"Map"),l=R(Object,"create"),M=H?H.prototype:void 0,G=M?M.toString:void 0;function c(t){var e=-1,n=t?t.length:0;for(this.clear();++e-1}function Ot(t,e){var n=this.__data__,r=g(n,t);return r<0?n.push([t,e]):n[r][1]=e,this}p.prototype.clear=yt,p.prototype.delete=gt,p.prototype.get=bt,p.prototype.has=mt,p.prototype.set=Ot;function u(t){var e=-1,n=t?t.length:0;for(this.clear();++e-1&&t%1==0&&t{const e=t.removed.map(i=>{const o={};return I(o,i[0],i[1]),o}),n=t.edited.map(i=>I({},"cafe/123","8888")),r=t.added.map(i=>I({},i[0],i[1]));return{removed:e,edited:n,added:r}},Xt={isLodashLike:!1,isObjectOutput:!1},qt=(t,e,n)=>{const{isLodashLike:r,isObjectOutput:i}=n??Xt;let o={added:[],removed:[],edited:[]};const s=h(t,r),a=h(e,r);return o.removed=j(s,a),o.added=j(a,s),o.edited=d(s,a),i&&(o=Ut(o)),o};f.getDiff=qt,f.getEditedPaths=d,f.getPathsDiff=j,f.getStructPaths=h,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})}); diff --git a/src/core/get-diff.ts b/src/core/get-diff.ts index f162a2d..28a1087 100644 --- a/src/core/get-diff.ts +++ b/src/core/get-diff.ts @@ -2,12 +2,14 @@ import { getEditedPaths } from './get-edited-paths' import { getPathsDiff } from './get-paths-diff' import { getStructPaths } from './get-struct-paths' +import transformDeltaToObject from './transform-delta-into-object' // Models import { Delta, JsonDiffOptions } from '../models/jsondiffer.model' const defaultOptions: JsonDiffOptions = { - isLodashLike: false + isLodashLike: false, + isObjectOutput: false } /** @@ -30,14 +32,14 @@ const defaultOptions: JsonDiffOptions = { * // Output: {"edited": [["1", null, "coffee"]], added: [], removed: []} */ export const getDiff = (oldStruct: Record, newStruct: Record, options?: JsonDiffOptions): Delta => { - const { isLodashLike } = options ?? defaultOptions - const delta: Delta = { + const { isLodashLike, isObjectOutput } = options ?? defaultOptions + let delta: Delta = { added: [], removed: [], edited: [] } - const oldStructPaths = getStructPaths(oldStruct, options.isLodashLike) - const newStructPaths = getStructPaths(newStruct, options.isLodashLike) + const oldStructPaths = getStructPaths(oldStruct, isLodashLike) + const newStructPaths = getStructPaths(newStruct, isLodashLike) // A-B delta.removed = getPathsDiff(oldStructPaths, newStructPaths) @@ -48,7 +50,7 @@ export const getDiff = (oldStruct: Record, newStruct: Recordb delta.edited = getEditedPaths(oldStructPaths, newStructPaths) - if (options.isObjectOutput) { + if (isObjectOutput) { delta = transformDeltaToObject(delta) } diff --git a/src/models/jsondiffer.model.ts b/src/models/jsondiffer.model.ts index 659fa7c..a658036 100644 --- a/src/models/jsondiffer.model.ts +++ b/src/models/jsondiffer.model.ts @@ -10,6 +10,13 @@ export interface Delta { edited: Array } +export interface DeltaObject { + added: Array + removed: Array + edited: Array +} + export interface JsonDiffOptions { isLodashLike?: boolean + isObjectOutput?: boolean }