11cb0ef41Sopenharmony_ci/* 21cb0ef41Sopenharmony_ci const obj1 = {a: 3, b: 5}; 31cb0ef41Sopenharmony_ci diffApply(obj1, 41cb0ef41Sopenharmony_ci [ 51cb0ef41Sopenharmony_ci { "op": "remove", "path": ['b'] }, 61cb0ef41Sopenharmony_ci { "op": "replace", "path": ['a'], "value": 4 }, 71cb0ef41Sopenharmony_ci { "op": "add", "path": ['c'], "value": 5 } 81cb0ef41Sopenharmony_ci ] 91cb0ef41Sopenharmony_ci ); 101cb0ef41Sopenharmony_ci obj1; // {a: 4, c: 5} 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ci // using converter to apply jsPatch standard paths 131cb0ef41Sopenharmony_ci // see http://jsonpatch.com 141cb0ef41Sopenharmony_ci import {diff, jsonPatchPathConverter} from 'just-diff' 151cb0ef41Sopenharmony_ci const obj2 = {a: 3, b: 5}; 161cb0ef41Sopenharmony_ci diffApply(obj2, [ 171cb0ef41Sopenharmony_ci { "op": "remove", "path": '/b' }, 181cb0ef41Sopenharmony_ci { "op": "replace", "path": '/a', "value": 4 } 191cb0ef41Sopenharmony_ci { "op": "add", "path": '/c', "value": 5 } 201cb0ef41Sopenharmony_ci ], jsonPatchPathConverter); 211cb0ef41Sopenharmony_ci obj2; // {a: 4, c: 5} 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ci // arrays 241cb0ef41Sopenharmony_ci const obj3 = {a: 4, b: [1, 2, 3]}; 251cb0ef41Sopenharmony_ci diffApply(obj3, [ 261cb0ef41Sopenharmony_ci { "op": "replace", "path": ['a'], "value": 3 } 271cb0ef41Sopenharmony_ci { "op": "replace", "path": ['b', 2], "value": 4 } 281cb0ef41Sopenharmony_ci { "op": "add", "path": ['b', 3], "value": 9 } 291cb0ef41Sopenharmony_ci ]); 301cb0ef41Sopenharmony_ci obj3; // {a: 3, b: [1, 2, 4, 9]} 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci // nested paths 331cb0ef41Sopenharmony_ci const obj4 = {a: 4, b: {c: 3}}; 341cb0ef41Sopenharmony_ci diffApply(obj4, [ 351cb0ef41Sopenharmony_ci { "op": "replace", "path": ['a'], "value": 5 } 361cb0ef41Sopenharmony_ci { "op": "remove", "path": ['b', 'c']} 371cb0ef41Sopenharmony_ci { "op": "add", "path": ['b', 'd'], "value": 4 } 381cb0ef41Sopenharmony_ci ]); 391cb0ef41Sopenharmony_ci obj4; // {a: 5, b: {d: 4}} 401cb0ef41Sopenharmony_ci*/ 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_civar REMOVE = 'remove'; 431cb0ef41Sopenharmony_civar REPLACE = 'replace'; 441cb0ef41Sopenharmony_civar ADD = 'add'; 451cb0ef41Sopenharmony_civar MOVE = 'move'; 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_cifunction diffApply(obj, diff, pathConverter) { 481cb0ef41Sopenharmony_ci if (!obj || typeof obj != 'object') { 491cb0ef41Sopenharmony_ci throw new Error('base object must be an object or an array'); 501cb0ef41Sopenharmony_ci } 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci if (!Array.isArray(diff)) { 531cb0ef41Sopenharmony_ci throw new Error('diff must be an array'); 541cb0ef41Sopenharmony_ci } 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci var diffLength = diff.length; 571cb0ef41Sopenharmony_ci for (var i = 0; i < diffLength; i++) { 581cb0ef41Sopenharmony_ci var thisDiff = diff[i]; 591cb0ef41Sopenharmony_ci var subObject = obj; 601cb0ef41Sopenharmony_ci var thisOp = thisDiff.op; 611cb0ef41Sopenharmony_ci 621cb0ef41Sopenharmony_ci var thisPath = transformPath(pathConverter, thisDiff.path); 631cb0ef41Sopenharmony_ci var thisFromPath = thisDiff.from && transformPath(pathConverter, thisDiff.from); 641cb0ef41Sopenharmony_ci var toPath, toPathCopy, lastToProp, subToObject, valueToMove; 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci if (thisFromPath) { 671cb0ef41Sopenharmony_ci // MOVE only, "fromPath" is effectively path and "path" is toPath 681cb0ef41Sopenharmony_ci toPath = thisPath; 691cb0ef41Sopenharmony_ci thisPath = thisFromPath; 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ci toPathCopy = toPath.slice(); 721cb0ef41Sopenharmony_ci lastToProp = toPathCopy.pop(); 731cb0ef41Sopenharmony_ci prototypeCheck(lastToProp); 741cb0ef41Sopenharmony_ci if (lastToProp == null) { 751cb0ef41Sopenharmony_ci return false; 761cb0ef41Sopenharmony_ci } 771cb0ef41Sopenharmony_ci 781cb0ef41Sopenharmony_ci var thisToProp; 791cb0ef41Sopenharmony_ci while (((thisToProp = toPathCopy.shift())) != null) { 801cb0ef41Sopenharmony_ci prototypeCheck(thisToProp); 811cb0ef41Sopenharmony_ci if (!(thisToProp in subToObject)) { 821cb0ef41Sopenharmony_ci subToObject[thisToProp] = {}; 831cb0ef41Sopenharmony_ci } 841cb0ef41Sopenharmony_ci subToObject = subToObject[thisToProp]; 851cb0ef41Sopenharmony_ci } 861cb0ef41Sopenharmony_ci } 871cb0ef41Sopenharmony_ci 881cb0ef41Sopenharmony_ci var pathCopy = thisPath.slice(); 891cb0ef41Sopenharmony_ci var lastProp = pathCopy.pop(); 901cb0ef41Sopenharmony_ci prototypeCheck(lastProp); 911cb0ef41Sopenharmony_ci if (lastProp == null) { 921cb0ef41Sopenharmony_ci return false; 931cb0ef41Sopenharmony_ci } 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ci var thisProp; 961cb0ef41Sopenharmony_ci while (((thisProp = pathCopy.shift())) != null) { 971cb0ef41Sopenharmony_ci prototypeCheck(thisProp); 981cb0ef41Sopenharmony_ci if (!(thisProp in subObject)) { 991cb0ef41Sopenharmony_ci subObject[thisProp] = {}; 1001cb0ef41Sopenharmony_ci } 1011cb0ef41Sopenharmony_ci subObject = subObject[thisProp]; 1021cb0ef41Sopenharmony_ci } 1031cb0ef41Sopenharmony_ci if (thisOp === REMOVE || thisOp === REPLACE || thisOp === MOVE) { 1041cb0ef41Sopenharmony_ci var path = thisOp === MOVE ? thisDiff.from : thisDiff.path; 1051cb0ef41Sopenharmony_ci if (!subObject.hasOwnProperty(lastProp)) { 1061cb0ef41Sopenharmony_ci throw new Error(['expected to find property', path, 'in object', obj].join(' ')); 1071cb0ef41Sopenharmony_ci } 1081cb0ef41Sopenharmony_ci } 1091cb0ef41Sopenharmony_ci if (thisOp === REMOVE || thisOp === MOVE) { 1101cb0ef41Sopenharmony_ci if (thisOp === MOVE) { 1111cb0ef41Sopenharmony_ci valueToMove = subObject[lastProp]; 1121cb0ef41Sopenharmony_ci } 1131cb0ef41Sopenharmony_ci Array.isArray(subObject) ? subObject.splice(lastProp, 1) : delete subObject[lastProp]; 1141cb0ef41Sopenharmony_ci } 1151cb0ef41Sopenharmony_ci if (thisOp === REPLACE || thisOp === ADD) { 1161cb0ef41Sopenharmony_ci subObject[lastProp] = thisDiff.value; 1171cb0ef41Sopenharmony_ci } 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci if (thisOp === MOVE) { 1201cb0ef41Sopenharmony_ci subObject[lastToProp] = valueToMove; 1211cb0ef41Sopenharmony_ci } 1221cb0ef41Sopenharmony_ci } 1231cb0ef41Sopenharmony_ci return subObject; 1241cb0ef41Sopenharmony_ci} 1251cb0ef41Sopenharmony_ci 1261cb0ef41Sopenharmony_cifunction transformPath(pathConverter, thisPath) { 1271cb0ef41Sopenharmony_ci if(pathConverter) { 1281cb0ef41Sopenharmony_ci thisPath = pathConverter(thisPath); 1291cb0ef41Sopenharmony_ci if(!Array.isArray(thisPath)) { 1301cb0ef41Sopenharmony_ci throw new Error([ 1311cb0ef41Sopenharmony_ci 'pathConverter must return an array, returned:', 1321cb0ef41Sopenharmony_ci thisPath, 1331cb0ef41Sopenharmony_ci ].join(' ')); 1341cb0ef41Sopenharmony_ci } 1351cb0ef41Sopenharmony_ci } else { 1361cb0ef41Sopenharmony_ci if(!Array.isArray(thisPath)) { 1371cb0ef41Sopenharmony_ci throw new Error([ 1381cb0ef41Sopenharmony_ci 'diff path', 1391cb0ef41Sopenharmony_ci thisPath, 1401cb0ef41Sopenharmony_ci 'must be an array, consider supplying a path converter'] 1411cb0ef41Sopenharmony_ci .join(' ')); 1421cb0ef41Sopenharmony_ci } 1431cb0ef41Sopenharmony_ci } 1441cb0ef41Sopenharmony_ci return thisPath; 1451cb0ef41Sopenharmony_ci} 1461cb0ef41Sopenharmony_ci 1471cb0ef41Sopenharmony_cifunction jsonPatchPathConverter(stringPath) { 1481cb0ef41Sopenharmony_ci return stringPath.split('/').slice(1); 1491cb0ef41Sopenharmony_ci} 1501cb0ef41Sopenharmony_ci 1511cb0ef41Sopenharmony_cifunction prototypeCheck(prop) { 1521cb0ef41Sopenharmony_ci // coercion is intentional to catch prop values like `['__proto__']` 1531cb0ef41Sopenharmony_ci if (prop == '__proto__' || prop == 'constructor' || prop == 'prototype') { 1541cb0ef41Sopenharmony_ci throw new Error('setting of prototype values not supported'); 1551cb0ef41Sopenharmony_ci } 1561cb0ef41Sopenharmony_ci} 1571cb0ef41Sopenharmony_ci 1581cb0ef41Sopenharmony_ciexport {diffApply, jsonPatchPathConverter}; 159