fast-json-patch.js 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928
  1. /*! fast-json-patch, version: 3.1.1 */
  2. var jsonpatch =
  3. /******/ (function(modules) { // webpackBootstrap
  4. /******/ // The module cache
  5. /******/ var installedModules = {};
  6. /******/
  7. /******/ // The require function
  8. /******/ function __webpack_require__(moduleId) {
  9. /******/
  10. /******/ // Check if module is in cache
  11. /******/ if(installedModules[moduleId]) {
  12. /******/ return installedModules[moduleId].exports;
  13. /******/ }
  14. /******/ // Create a new module (and put it into the cache)
  15. /******/ var module = installedModules[moduleId] = {
  16. /******/ i: moduleId,
  17. /******/ l: false,
  18. /******/ exports: {}
  19. /******/ };
  20. /******/
  21. /******/ // Execute the module function
  22. /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  23. /******/
  24. /******/ // Flag the module as loaded
  25. /******/ module.l = true;
  26. /******/
  27. /******/ // Return the exports of the module
  28. /******/ return module.exports;
  29. /******/ }
  30. /******/
  31. /******/
  32. /******/ // expose the modules object (__webpack_modules__)
  33. /******/ __webpack_require__.m = modules;
  34. /******/
  35. /******/ // expose the module cache
  36. /******/ __webpack_require__.c = installedModules;
  37. /******/
  38. /******/ // define getter function for harmony exports
  39. /******/ __webpack_require__.d = function(exports, name, getter) {
  40. /******/ if(!__webpack_require__.o(exports, name)) {
  41. /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
  42. /******/ }
  43. /******/ };
  44. /******/
  45. /******/ // define __esModule on exports
  46. /******/ __webpack_require__.r = function(exports) {
  47. /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
  48. /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
  49. /******/ }
  50. /******/ Object.defineProperty(exports, '__esModule', { value: true });
  51. /******/ };
  52. /******/
  53. /******/ // create a fake namespace object
  54. /******/ // mode & 1: value is a module id, require it
  55. /******/ // mode & 2: merge all properties of value into the ns
  56. /******/ // mode & 4: return value when already ns object
  57. /******/ // mode & 8|1: behave like require
  58. /******/ __webpack_require__.t = function(value, mode) {
  59. /******/ if(mode & 1) value = __webpack_require__(value);
  60. /******/ if(mode & 8) return value;
  61. /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
  62. /******/ var ns = Object.create(null);
  63. /******/ __webpack_require__.r(ns);
  64. /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
  65. /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
  66. /******/ return ns;
  67. /******/ };
  68. /******/
  69. /******/ // getDefaultExport function for compatibility with non-harmony modules
  70. /******/ __webpack_require__.n = function(module) {
  71. /******/ var getter = module && module.__esModule ?
  72. /******/ function getDefault() { return module['default']; } :
  73. /******/ function getModuleExports() { return module; };
  74. /******/ __webpack_require__.d(getter, 'a', getter);
  75. /******/ return getter;
  76. /******/ };
  77. /******/
  78. /******/ // Object.prototype.hasOwnProperty.call
  79. /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
  80. /******/
  81. /******/ // __webpack_public_path__
  82. /******/ __webpack_require__.p = "";
  83. /******/
  84. /******/
  85. /******/ // Load entry module and return exports
  86. /******/ return __webpack_require__(__webpack_require__.s = 2);
  87. /******/ })
  88. /************************************************************************/
  89. /******/ ([
  90. /* 0 */
  91. /***/ (function(module, exports) {
  92. /*!
  93. * https://github.com/Starcounter-Jack/JSON-Patch
  94. * (c) 2017-2022 Joachim Wester
  95. * MIT licensed
  96. */
  97. var __extends = (this && this.__extends) || (function () {
  98. var extendStatics = function (d, b) {
  99. extendStatics = Object.setPrototypeOf ||
  100. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  101. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  102. return extendStatics(d, b);
  103. };
  104. return function (d, b) {
  105. extendStatics(d, b);
  106. function __() { this.constructor = d; }
  107. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  108. };
  109. })();
  110. Object.defineProperty(exports, "__esModule", { value: true });
  111. var _hasOwnProperty = Object.prototype.hasOwnProperty;
  112. function hasOwnProperty(obj, key) {
  113. return _hasOwnProperty.call(obj, key);
  114. }
  115. exports.hasOwnProperty = hasOwnProperty;
  116. function _objectKeys(obj) {
  117. if (Array.isArray(obj)) {
  118. var keys_1 = new Array(obj.length);
  119. for (var k = 0; k < keys_1.length; k++) {
  120. keys_1[k] = "" + k;
  121. }
  122. return keys_1;
  123. }
  124. if (Object.keys) {
  125. return Object.keys(obj);
  126. }
  127. var keys = [];
  128. for (var i in obj) {
  129. if (hasOwnProperty(obj, i)) {
  130. keys.push(i);
  131. }
  132. }
  133. return keys;
  134. }
  135. exports._objectKeys = _objectKeys;
  136. ;
  137. /**
  138. * Deeply clone the object.
  139. * https://jsperf.com/deep-copy-vs-json-stringify-json-parse/25 (recursiveDeepCopy)
  140. * @param {any} obj value to clone
  141. * @return {any} cloned obj
  142. */
  143. function _deepClone(obj) {
  144. switch (typeof obj) {
  145. case "object":
  146. return JSON.parse(JSON.stringify(obj)); //Faster than ES5 clone - http://jsperf.com/deep-cloning-of-objects/5
  147. case "undefined":
  148. return null; //this is how JSON.stringify behaves for array items
  149. default:
  150. return obj; //no need to clone primitives
  151. }
  152. }
  153. exports._deepClone = _deepClone;
  154. //3x faster than cached /^\d+$/.test(str)
  155. function isInteger(str) {
  156. var i = 0;
  157. var len = str.length;
  158. var charCode;
  159. while (i < len) {
  160. charCode = str.charCodeAt(i);
  161. if (charCode >= 48 && charCode <= 57) {
  162. i++;
  163. continue;
  164. }
  165. return false;
  166. }
  167. return true;
  168. }
  169. exports.isInteger = isInteger;
  170. /**
  171. * Escapes a json pointer path
  172. * @param path The raw pointer
  173. * @return the Escaped path
  174. */
  175. function escapePathComponent(path) {
  176. if (path.indexOf('/') === -1 && path.indexOf('~') === -1)
  177. return path;
  178. return path.replace(/~/g, '~0').replace(/\//g, '~1');
  179. }
  180. exports.escapePathComponent = escapePathComponent;
  181. /**
  182. * Unescapes a json pointer path
  183. * @param path The escaped pointer
  184. * @return The unescaped path
  185. */
  186. function unescapePathComponent(path) {
  187. return path.replace(/~1/g, '/').replace(/~0/g, '~');
  188. }
  189. exports.unescapePathComponent = unescapePathComponent;
  190. function _getPathRecursive(root, obj) {
  191. var found;
  192. for (var key in root) {
  193. if (hasOwnProperty(root, key)) {
  194. if (root[key] === obj) {
  195. return escapePathComponent(key) + '/';
  196. }
  197. else if (typeof root[key] === 'object') {
  198. found = _getPathRecursive(root[key], obj);
  199. if (found != '') {
  200. return escapePathComponent(key) + '/' + found;
  201. }
  202. }
  203. }
  204. }
  205. return '';
  206. }
  207. exports._getPathRecursive = _getPathRecursive;
  208. function getPath(root, obj) {
  209. if (root === obj) {
  210. return '/';
  211. }
  212. var path = _getPathRecursive(root, obj);
  213. if (path === '') {
  214. throw new Error("Object not found in root");
  215. }
  216. return "/" + path;
  217. }
  218. exports.getPath = getPath;
  219. /**
  220. * Recursively checks whether an object has any undefined values inside.
  221. */
  222. function hasUndefined(obj) {
  223. if (obj === undefined) {
  224. return true;
  225. }
  226. if (obj) {
  227. if (Array.isArray(obj)) {
  228. for (var i_1 = 0, len = obj.length; i_1 < len; i_1++) {
  229. if (hasUndefined(obj[i_1])) {
  230. return true;
  231. }
  232. }
  233. }
  234. else if (typeof obj === "object") {
  235. var objKeys = _objectKeys(obj);
  236. var objKeysLength = objKeys.length;
  237. for (var i = 0; i < objKeysLength; i++) {
  238. if (hasUndefined(obj[objKeys[i]])) {
  239. return true;
  240. }
  241. }
  242. }
  243. }
  244. return false;
  245. }
  246. exports.hasUndefined = hasUndefined;
  247. function patchErrorMessageFormatter(message, args) {
  248. var messageParts = [message];
  249. for (var key in args) {
  250. var value = typeof args[key] === 'object' ? JSON.stringify(args[key], null, 2) : args[key]; // pretty print
  251. if (typeof value !== 'undefined') {
  252. messageParts.push(key + ": " + value);
  253. }
  254. }
  255. return messageParts.join('\n');
  256. }
  257. var PatchError = /** @class */ (function (_super) {
  258. __extends(PatchError, _super);
  259. function PatchError(message, name, index, operation, tree) {
  260. var _newTarget = this.constructor;
  261. var _this = _super.call(this, patchErrorMessageFormatter(message, { name: name, index: index, operation: operation, tree: tree })) || this;
  262. _this.name = name;
  263. _this.index = index;
  264. _this.operation = operation;
  265. _this.tree = tree;
  266. Object.setPrototypeOf(_this, _newTarget.prototype); // restore prototype chain, see https://stackoverflow.com/a/48342359
  267. _this.message = patchErrorMessageFormatter(message, { name: name, index: index, operation: operation, tree: tree });
  268. return _this;
  269. }
  270. return PatchError;
  271. }(Error));
  272. exports.PatchError = PatchError;
  273. /***/ }),
  274. /* 1 */
  275. /***/ (function(module, exports, __webpack_require__) {
  276. Object.defineProperty(exports, "__esModule", { value: true });
  277. var helpers_js_1 = __webpack_require__(0);
  278. exports.JsonPatchError = helpers_js_1.PatchError;
  279. exports.deepClone = helpers_js_1._deepClone;
  280. /* We use a Javascript hash to store each
  281. function. Each hash entry (property) uses
  282. the operation identifiers specified in rfc6902.
  283. In this way, we can map each patch operation
  284. to its dedicated function in efficient way.
  285. */
  286. /* The operations applicable to an object */
  287. var objOps = {
  288. add: function (obj, key, document) {
  289. obj[key] = this.value;
  290. return { newDocument: document };
  291. },
  292. remove: function (obj, key, document) {
  293. var removed = obj[key];
  294. delete obj[key];
  295. return { newDocument: document, removed: removed };
  296. },
  297. replace: function (obj, key, document) {
  298. var removed = obj[key];
  299. obj[key] = this.value;
  300. return { newDocument: document, removed: removed };
  301. },
  302. move: function (obj, key, document) {
  303. /* in case move target overwrites an existing value,
  304. return the removed value, this can be taxing performance-wise,
  305. and is potentially unneeded */
  306. var removed = getValueByPointer(document, this.path);
  307. if (removed) {
  308. removed = helpers_js_1._deepClone(removed);
  309. }
  310. var originalValue = applyOperation(document, { op: "remove", path: this.from }).removed;
  311. applyOperation(document, { op: "add", path: this.path, value: originalValue });
  312. return { newDocument: document, removed: removed };
  313. },
  314. copy: function (obj, key, document) {
  315. var valueToCopy = getValueByPointer(document, this.from);
  316. // enforce copy by value so further operations don't affect source (see issue #177)
  317. applyOperation(document, { op: "add", path: this.path, value: helpers_js_1._deepClone(valueToCopy) });
  318. return { newDocument: document };
  319. },
  320. test: function (obj, key, document) {
  321. return { newDocument: document, test: _areEquals(obj[key], this.value) };
  322. },
  323. _get: function (obj, key, document) {
  324. this.value = obj[key];
  325. return { newDocument: document };
  326. }
  327. };
  328. /* The operations applicable to an array. Many are the same as for the object */
  329. var arrOps = {
  330. add: function (arr, i, document) {
  331. if (helpers_js_1.isInteger(i)) {
  332. arr.splice(i, 0, this.value);
  333. }
  334. else { // array props
  335. arr[i] = this.value;
  336. }
  337. // this may be needed when using '-' in an array
  338. return { newDocument: document, index: i };
  339. },
  340. remove: function (arr, i, document) {
  341. var removedList = arr.splice(i, 1);
  342. return { newDocument: document, removed: removedList[0] };
  343. },
  344. replace: function (arr, i, document) {
  345. var removed = arr[i];
  346. arr[i] = this.value;
  347. return { newDocument: document, removed: removed };
  348. },
  349. move: objOps.move,
  350. copy: objOps.copy,
  351. test: objOps.test,
  352. _get: objOps._get
  353. };
  354. /**
  355. * Retrieves a value from a JSON document by a JSON pointer.
  356. * Returns the value.
  357. *
  358. * @param document The document to get the value from
  359. * @param pointer an escaped JSON pointer
  360. * @return The retrieved value
  361. */
  362. function getValueByPointer(document, pointer) {
  363. if (pointer == '') {
  364. return document;
  365. }
  366. var getOriginalDestination = { op: "_get", path: pointer };
  367. applyOperation(document, getOriginalDestination);
  368. return getOriginalDestination.value;
  369. }
  370. exports.getValueByPointer = getValueByPointer;
  371. /**
  372. * Apply a single JSON Patch Operation on a JSON document.
  373. * Returns the {newDocument, result} of the operation.
  374. * It modifies the `document` and `operation` objects - it gets the values by reference.
  375. * If you would like to avoid touching your values, clone them:
  376. * `jsonpatch.applyOperation(document, jsonpatch._deepClone(operation))`.
  377. *
  378. * @param document The document to patch
  379. * @param operation The operation to apply
  380. * @param validateOperation `false` is without validation, `true` to use default jsonpatch's validation, or you can pass a `validateOperation` callback to be used for validation.
  381. * @param mutateDocument Whether to mutate the original document or clone it before applying
  382. * @param banPrototypeModifications Whether to ban modifications to `__proto__`, defaults to `true`.
  383. * @return `{newDocument, result}` after the operation
  384. */
  385. function applyOperation(document, operation, validateOperation, mutateDocument, banPrototypeModifications, index) {
  386. if (validateOperation === void 0) { validateOperation = false; }
  387. if (mutateDocument === void 0) { mutateDocument = true; }
  388. if (banPrototypeModifications === void 0) { banPrototypeModifications = true; }
  389. if (index === void 0) { index = 0; }
  390. if (validateOperation) {
  391. if (typeof validateOperation == 'function') {
  392. validateOperation(operation, 0, document, operation.path);
  393. }
  394. else {
  395. validator(operation, 0);
  396. }
  397. }
  398. /* ROOT OPERATIONS */
  399. if (operation.path === "") {
  400. var returnValue = { newDocument: document };
  401. if (operation.op === 'add') {
  402. returnValue.newDocument = operation.value;
  403. return returnValue;
  404. }
  405. else if (operation.op === 'replace') {
  406. returnValue.newDocument = operation.value;
  407. returnValue.removed = document; //document we removed
  408. return returnValue;
  409. }
  410. else if (operation.op === 'move' || operation.op === 'copy') { // it's a move or copy to root
  411. returnValue.newDocument = getValueByPointer(document, operation.from); // get the value by json-pointer in `from` field
  412. if (operation.op === 'move') { // report removed item
  413. returnValue.removed = document;
  414. }
  415. return returnValue;
  416. }
  417. else if (operation.op === 'test') {
  418. returnValue.test = _areEquals(document, operation.value);
  419. if (returnValue.test === false) {
  420. throw new exports.JsonPatchError("Test operation failed", 'TEST_OPERATION_FAILED', index, operation, document);
  421. }
  422. returnValue.newDocument = document;
  423. return returnValue;
  424. }
  425. else if (operation.op === 'remove') { // a remove on root
  426. returnValue.removed = document;
  427. returnValue.newDocument = null;
  428. return returnValue;
  429. }
  430. else if (operation.op === '_get') {
  431. operation.value = document;
  432. return returnValue;
  433. }
  434. else { /* bad operation */
  435. if (validateOperation) {
  436. throw new exports.JsonPatchError('Operation `op` property is not one of operations defined in RFC-6902', 'OPERATION_OP_INVALID', index, operation, document);
  437. }
  438. else {
  439. return returnValue;
  440. }
  441. }
  442. } /* END ROOT OPERATIONS */
  443. else {
  444. if (!mutateDocument) {
  445. document = helpers_js_1._deepClone(document);
  446. }
  447. var path = operation.path || "";
  448. var keys = path.split('/');
  449. var obj = document;
  450. var t = 1; //skip empty element - http://jsperf.com/to-shift-or-not-to-shift
  451. var len = keys.length;
  452. var existingPathFragment = undefined;
  453. var key = void 0;
  454. var validateFunction = void 0;
  455. if (typeof validateOperation == 'function') {
  456. validateFunction = validateOperation;
  457. }
  458. else {
  459. validateFunction = validator;
  460. }
  461. while (true) {
  462. key = keys[t];
  463. if (key && key.indexOf('~') != -1) {
  464. key = helpers_js_1.unescapePathComponent(key);
  465. }
  466. if (banPrototypeModifications &&
  467. (key == '__proto__' ||
  468. (key == 'prototype' && t > 0 && keys[t - 1] == 'constructor'))) {
  469. throw new TypeError('JSON-Patch: modifying `__proto__` or `constructor/prototype` prop is banned for security reasons, if this was on purpose, please set `banPrototypeModifications` flag false and pass it to this function. More info in fast-json-patch README');
  470. }
  471. if (validateOperation) {
  472. if (existingPathFragment === undefined) {
  473. if (obj[key] === undefined) {
  474. existingPathFragment = keys.slice(0, t).join('/');
  475. }
  476. else if (t == len - 1) {
  477. existingPathFragment = operation.path;
  478. }
  479. if (existingPathFragment !== undefined) {
  480. validateFunction(operation, 0, document, existingPathFragment);
  481. }
  482. }
  483. }
  484. t++;
  485. if (Array.isArray(obj)) {
  486. if (key === '-') {
  487. key = obj.length;
  488. }
  489. else {
  490. if (validateOperation && !helpers_js_1.isInteger(key)) {
  491. throw new exports.JsonPatchError("Expected an unsigned base-10 integer value, making the new referenced value the array element with the zero-based index", "OPERATION_PATH_ILLEGAL_ARRAY_INDEX", index, operation, document);
  492. } // only parse key when it's an integer for `arr.prop` to work
  493. else if (helpers_js_1.isInteger(key)) {
  494. key = ~~key;
  495. }
  496. }
  497. if (t >= len) {
  498. if (validateOperation && operation.op === "add" && key > obj.length) {
  499. throw new exports.JsonPatchError("The specified index MUST NOT be greater than the number of elements in the array", "OPERATION_VALUE_OUT_OF_BOUNDS", index, operation, document);
  500. }
  501. var returnValue = arrOps[operation.op].call(operation, obj, key, document); // Apply patch
  502. if (returnValue.test === false) {
  503. throw new exports.JsonPatchError("Test operation failed", 'TEST_OPERATION_FAILED', index, operation, document);
  504. }
  505. return returnValue;
  506. }
  507. }
  508. else {
  509. if (t >= len) {
  510. var returnValue = objOps[operation.op].call(operation, obj, key, document); // Apply patch
  511. if (returnValue.test === false) {
  512. throw new exports.JsonPatchError("Test operation failed", 'TEST_OPERATION_FAILED', index, operation, document);
  513. }
  514. return returnValue;
  515. }
  516. }
  517. obj = obj[key];
  518. // If we have more keys in the path, but the next value isn't a non-null object,
  519. // throw an OPERATION_PATH_UNRESOLVABLE error instead of iterating again.
  520. if (validateOperation && t < len && (!obj || typeof obj !== "object")) {
  521. throw new exports.JsonPatchError('Cannot perform operation at the desired path', 'OPERATION_PATH_UNRESOLVABLE', index, operation, document);
  522. }
  523. }
  524. }
  525. }
  526. exports.applyOperation = applyOperation;
  527. /**
  528. * Apply a full JSON Patch array on a JSON document.
  529. * Returns the {newDocument, result} of the patch.
  530. * It modifies the `document` object and `patch` - it gets the values by reference.
  531. * If you would like to avoid touching your values, clone them:
  532. * `jsonpatch.applyPatch(document, jsonpatch._deepClone(patch))`.
  533. *
  534. * @param document The document to patch
  535. * @param patch The patch to apply
  536. * @param validateOperation `false` is without validation, `true` to use default jsonpatch's validation, or you can pass a `validateOperation` callback to be used for validation.
  537. * @param mutateDocument Whether to mutate the original document or clone it before applying
  538. * @param banPrototypeModifications Whether to ban modifications to `__proto__`, defaults to `true`.
  539. * @return An array of `{newDocument, result}` after the patch
  540. */
  541. function applyPatch(document, patch, validateOperation, mutateDocument, banPrototypeModifications) {
  542. if (mutateDocument === void 0) { mutateDocument = true; }
  543. if (banPrototypeModifications === void 0) { banPrototypeModifications = true; }
  544. if (validateOperation) {
  545. if (!Array.isArray(patch)) {
  546. throw new exports.JsonPatchError('Patch sequence must be an array', 'SEQUENCE_NOT_AN_ARRAY');
  547. }
  548. }
  549. if (!mutateDocument) {
  550. document = helpers_js_1._deepClone(document);
  551. }
  552. var results = new Array(patch.length);
  553. for (var i = 0, length_1 = patch.length; i < length_1; i++) {
  554. // we don't need to pass mutateDocument argument because if it was true, we already deep cloned the object, we'll just pass `true`
  555. results[i] = applyOperation(document, patch[i], validateOperation, true, banPrototypeModifications, i);
  556. document = results[i].newDocument; // in case root was replaced
  557. }
  558. results.newDocument = document;
  559. return results;
  560. }
  561. exports.applyPatch = applyPatch;
  562. /**
  563. * Apply a single JSON Patch Operation on a JSON document.
  564. * Returns the updated document.
  565. * Suitable as a reducer.
  566. *
  567. * @param document The document to patch
  568. * @param operation The operation to apply
  569. * @return The updated document
  570. */
  571. function applyReducer(document, operation, index) {
  572. var operationResult = applyOperation(document, operation);
  573. if (operationResult.test === false) { // failed test
  574. throw new exports.JsonPatchError("Test operation failed", 'TEST_OPERATION_FAILED', index, operation, document);
  575. }
  576. return operationResult.newDocument;
  577. }
  578. exports.applyReducer = applyReducer;
  579. /**
  580. * Validates a single operation. Called from `jsonpatch.validate`. Throws `JsonPatchError` in case of an error.
  581. * @param {object} operation - operation object (patch)
  582. * @param {number} index - index of operation in the sequence
  583. * @param {object} [document] - object where the operation is supposed to be applied
  584. * @param {string} [existingPathFragment] - comes along with `document`
  585. */
  586. function validator(operation, index, document, existingPathFragment) {
  587. if (typeof operation !== 'object' || operation === null || Array.isArray(operation)) {
  588. throw new exports.JsonPatchError('Operation is not an object', 'OPERATION_NOT_AN_OBJECT', index, operation, document);
  589. }
  590. else if (!objOps[operation.op]) {
  591. throw new exports.JsonPatchError('Operation `op` property is not one of operations defined in RFC-6902', 'OPERATION_OP_INVALID', index, operation, document);
  592. }
  593. else if (typeof operation.path !== 'string') {
  594. throw new exports.JsonPatchError('Operation `path` property is not a string', 'OPERATION_PATH_INVALID', index, operation, document);
  595. }
  596. else if (operation.path.indexOf('/') !== 0 && operation.path.length > 0) {
  597. // paths that aren't empty string should start with "/"
  598. throw new exports.JsonPatchError('Operation `path` property must start with "/"', 'OPERATION_PATH_INVALID', index, operation, document);
  599. }
  600. else if ((operation.op === 'move' || operation.op === 'copy') && typeof operation.from !== 'string') {
  601. throw new exports.JsonPatchError('Operation `from` property is not present (applicable in `move` and `copy` operations)', 'OPERATION_FROM_REQUIRED', index, operation, document);
  602. }
  603. else if ((operation.op === 'add' || operation.op === 'replace' || operation.op === 'test') && operation.value === undefined) {
  604. throw new exports.JsonPatchError('Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)', 'OPERATION_VALUE_REQUIRED', index, operation, document);
  605. }
  606. else if ((operation.op === 'add' || operation.op === 'replace' || operation.op === 'test') && helpers_js_1.hasUndefined(operation.value)) {
  607. throw new exports.JsonPatchError('Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)', 'OPERATION_VALUE_CANNOT_CONTAIN_UNDEFINED', index, operation, document);
  608. }
  609. else if (document) {
  610. if (operation.op == "add") {
  611. var pathLen = operation.path.split("/").length;
  612. var existingPathLen = existingPathFragment.split("/").length;
  613. if (pathLen !== existingPathLen + 1 && pathLen !== existingPathLen) {
  614. throw new exports.JsonPatchError('Cannot perform an `add` operation at the desired path', 'OPERATION_PATH_CANNOT_ADD', index, operation, document);
  615. }
  616. }
  617. else if (operation.op === 'replace' || operation.op === 'remove' || operation.op === '_get') {
  618. if (operation.path !== existingPathFragment) {
  619. throw new exports.JsonPatchError('Cannot perform the operation at a path that does not exist', 'OPERATION_PATH_UNRESOLVABLE', index, operation, document);
  620. }
  621. }
  622. else if (operation.op === 'move' || operation.op === 'copy') {
  623. var existingValue = { op: "_get", path: operation.from, value: undefined };
  624. var error = validate([existingValue], document);
  625. if (error && error.name === 'OPERATION_PATH_UNRESOLVABLE') {
  626. throw new exports.JsonPatchError('Cannot perform the operation from a path that does not exist', 'OPERATION_FROM_UNRESOLVABLE', index, operation, document);
  627. }
  628. }
  629. }
  630. }
  631. exports.validator = validator;
  632. /**
  633. * Validates a sequence of operations. If `document` parameter is provided, the sequence is additionally validated against the object document.
  634. * If error is encountered, returns a JsonPatchError object
  635. * @param sequence
  636. * @param document
  637. * @returns {JsonPatchError|undefined}
  638. */
  639. function validate(sequence, document, externalValidator) {
  640. try {
  641. if (!Array.isArray(sequence)) {
  642. throw new exports.JsonPatchError('Patch sequence must be an array', 'SEQUENCE_NOT_AN_ARRAY');
  643. }
  644. if (document) {
  645. //clone document and sequence so that we can safely try applying operations
  646. applyPatch(helpers_js_1._deepClone(document), helpers_js_1._deepClone(sequence), externalValidator || true);
  647. }
  648. else {
  649. externalValidator = externalValidator || validator;
  650. for (var i = 0; i < sequence.length; i++) {
  651. externalValidator(sequence[i], i, document, undefined);
  652. }
  653. }
  654. }
  655. catch (e) {
  656. if (e instanceof exports.JsonPatchError) {
  657. return e;
  658. }
  659. else {
  660. throw e;
  661. }
  662. }
  663. }
  664. exports.validate = validate;
  665. // based on https://github.com/epoberezkin/fast-deep-equal
  666. // MIT License
  667. // Copyright (c) 2017 Evgeny Poberezkin
  668. // Permission is hereby granted, free of charge, to any person obtaining a copy
  669. // of this software and associated documentation files (the "Software"), to deal
  670. // in the Software without restriction, including without limitation the rights
  671. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  672. // copies of the Software, and to permit persons to whom the Software is
  673. // furnished to do so, subject to the following conditions:
  674. // The above copyright notice and this permission notice shall be included in all
  675. // copies or substantial portions of the Software.
  676. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  677. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  678. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  679. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  680. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  681. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  682. // SOFTWARE.
  683. function _areEquals(a, b) {
  684. if (a === b)
  685. return true;
  686. if (a && b && typeof a == 'object' && typeof b == 'object') {
  687. var arrA = Array.isArray(a), arrB = Array.isArray(b), i, length, key;
  688. if (arrA && arrB) {
  689. length = a.length;
  690. if (length != b.length)
  691. return false;
  692. for (i = length; i-- !== 0;)
  693. if (!_areEquals(a[i], b[i]))
  694. return false;
  695. return true;
  696. }
  697. if (arrA != arrB)
  698. return false;
  699. var keys = Object.keys(a);
  700. length = keys.length;
  701. if (length !== Object.keys(b).length)
  702. return false;
  703. for (i = length; i-- !== 0;)
  704. if (!b.hasOwnProperty(keys[i]))
  705. return false;
  706. for (i = length; i-- !== 0;) {
  707. key = keys[i];
  708. if (!_areEquals(a[key], b[key]))
  709. return false;
  710. }
  711. return true;
  712. }
  713. return a !== a && b !== b;
  714. }
  715. exports._areEquals = _areEquals;
  716. ;
  717. /***/ }),
  718. /* 2 */
  719. /***/ (function(module, exports, __webpack_require__) {
  720. var core = __webpack_require__(1);
  721. Object.assign(exports, core);
  722. var duplex = __webpack_require__(3);
  723. Object.assign(exports, duplex);
  724. var helpers = __webpack_require__(0);
  725. exports.JsonPatchError = helpers.PatchError;
  726. exports.deepClone = helpers._deepClone;
  727. exports.escapePathComponent = helpers.escapePathComponent;
  728. exports.unescapePathComponent = helpers.unescapePathComponent;
  729. /***/ }),
  730. /* 3 */
  731. /***/ (function(module, exports, __webpack_require__) {
  732. Object.defineProperty(exports, "__esModule", { value: true });
  733. /*!
  734. * https://github.com/Starcounter-Jack/JSON-Patch
  735. * (c) 2017-2021 Joachim Wester
  736. * MIT license
  737. */
  738. var helpers_js_1 = __webpack_require__(0);
  739. var core_js_1 = __webpack_require__(1);
  740. var beforeDict = new WeakMap();
  741. var Mirror = /** @class */ (function () {
  742. function Mirror(obj) {
  743. this.observers = new Map();
  744. this.obj = obj;
  745. }
  746. return Mirror;
  747. }());
  748. var ObserverInfo = /** @class */ (function () {
  749. function ObserverInfo(callback, observer) {
  750. this.callback = callback;
  751. this.observer = observer;
  752. }
  753. return ObserverInfo;
  754. }());
  755. function getMirror(obj) {
  756. return beforeDict.get(obj);
  757. }
  758. function getObserverFromMirror(mirror, callback) {
  759. return mirror.observers.get(callback);
  760. }
  761. function removeObserverFromMirror(mirror, observer) {
  762. mirror.observers.delete(observer.callback);
  763. }
  764. /**
  765. * Detach an observer from an object
  766. */
  767. function unobserve(root, observer) {
  768. observer.unobserve();
  769. }
  770. exports.unobserve = unobserve;
  771. /**
  772. * Observes changes made to an object, which can then be retrieved using generate
  773. */
  774. function observe(obj, callback) {
  775. var patches = [];
  776. var observer;
  777. var mirror = getMirror(obj);
  778. if (!mirror) {
  779. mirror = new Mirror(obj);
  780. beforeDict.set(obj, mirror);
  781. }
  782. else {
  783. var observerInfo = getObserverFromMirror(mirror, callback);
  784. observer = observerInfo && observerInfo.observer;
  785. }
  786. if (observer) {
  787. return observer;
  788. }
  789. observer = {};
  790. mirror.value = helpers_js_1._deepClone(obj);
  791. if (callback) {
  792. observer.callback = callback;
  793. observer.next = null;
  794. var dirtyCheck = function () {
  795. generate(observer);
  796. };
  797. var fastCheck = function () {
  798. clearTimeout(observer.next);
  799. observer.next = setTimeout(dirtyCheck);
  800. };
  801. if (typeof window !== 'undefined') { //not Node
  802. window.addEventListener('mouseup', fastCheck);
  803. window.addEventListener('keyup', fastCheck);
  804. window.addEventListener('mousedown', fastCheck);
  805. window.addEventListener('keydown', fastCheck);
  806. window.addEventListener('change', fastCheck);
  807. }
  808. }
  809. observer.patches = patches;
  810. observer.object = obj;
  811. observer.unobserve = function () {
  812. generate(observer);
  813. clearTimeout(observer.next);
  814. removeObserverFromMirror(mirror, observer);
  815. if (typeof window !== 'undefined') {
  816. window.removeEventListener('mouseup', fastCheck);
  817. window.removeEventListener('keyup', fastCheck);
  818. window.removeEventListener('mousedown', fastCheck);
  819. window.removeEventListener('keydown', fastCheck);
  820. window.removeEventListener('change', fastCheck);
  821. }
  822. };
  823. mirror.observers.set(callback, new ObserverInfo(callback, observer));
  824. return observer;
  825. }
  826. exports.observe = observe;
  827. /**
  828. * Generate an array of patches from an observer
  829. */
  830. function generate(observer, invertible) {
  831. if (invertible === void 0) { invertible = false; }
  832. var mirror = beforeDict.get(observer.object);
  833. _generate(mirror.value, observer.object, observer.patches, "", invertible);
  834. if (observer.patches.length) {
  835. core_js_1.applyPatch(mirror.value, observer.patches);
  836. }
  837. var temp = observer.patches;
  838. if (temp.length > 0) {
  839. observer.patches = [];
  840. if (observer.callback) {
  841. observer.callback(temp);
  842. }
  843. }
  844. return temp;
  845. }
  846. exports.generate = generate;
  847. // Dirty check if obj is different from mirror, generate patches and update mirror
  848. function _generate(mirror, obj, patches, path, invertible) {
  849. if (obj === mirror) {
  850. return;
  851. }
  852. if (typeof obj.toJSON === "function") {
  853. obj = obj.toJSON();
  854. }
  855. var newKeys = helpers_js_1._objectKeys(obj);
  856. var oldKeys = helpers_js_1._objectKeys(mirror);
  857. var changed = false;
  858. var deleted = false;
  859. //if ever "move" operation is implemented here, make sure this test runs OK: "should not generate the same patch twice (move)"
  860. for (var t = oldKeys.length - 1; t >= 0; t--) {
  861. var key = oldKeys[t];
  862. var oldVal = mirror[key];
  863. if (helpers_js_1.hasOwnProperty(obj, key) && !(obj[key] === undefined && oldVal !== undefined && Array.isArray(obj) === false)) {
  864. var newVal = obj[key];
  865. if (typeof oldVal == "object" && oldVal != null && typeof newVal == "object" && newVal != null && Array.isArray(oldVal) === Array.isArray(newVal)) {
  866. _generate(oldVal, newVal, patches, path + "/" + helpers_js_1.escapePathComponent(key), invertible);
  867. }
  868. else {
  869. if (oldVal !== newVal) {
  870. changed = true;
  871. if (invertible) {
  872. patches.push({ op: "test", path: path + "/" + helpers_js_1.escapePathComponent(key), value: helpers_js_1._deepClone(oldVal) });
  873. }
  874. patches.push({ op: "replace", path: path + "/" + helpers_js_1.escapePathComponent(key), value: helpers_js_1._deepClone(newVal) });
  875. }
  876. }
  877. }
  878. else if (Array.isArray(mirror) === Array.isArray(obj)) {
  879. if (invertible) {
  880. patches.push({ op: "test", path: path + "/" + helpers_js_1.escapePathComponent(key), value: helpers_js_1._deepClone(oldVal) });
  881. }
  882. patches.push({ op: "remove", path: path + "/" + helpers_js_1.escapePathComponent(key) });
  883. deleted = true; // property has been deleted
  884. }
  885. else {
  886. if (invertible) {
  887. patches.push({ op: "test", path: path, value: mirror });
  888. }
  889. patches.push({ op: "replace", path: path, value: obj });
  890. changed = true;
  891. }
  892. }
  893. if (!deleted && newKeys.length == oldKeys.length) {
  894. return;
  895. }
  896. for (var t = 0; t < newKeys.length; t++) {
  897. var key = newKeys[t];
  898. if (!helpers_js_1.hasOwnProperty(mirror, key) && obj[key] !== undefined) {
  899. patches.push({ op: "add", path: path + "/" + helpers_js_1.escapePathComponent(key), value: helpers_js_1._deepClone(obj[key]) });
  900. }
  901. }
  902. }
  903. /**
  904. * Create an array of patches from the differences in two objects
  905. */
  906. function compare(tree1, tree2, invertible) {
  907. if (invertible === void 0) { invertible = false; }
  908. var patches = [];
  909. _generate(tree1, tree2, patches, '', invertible);
  910. return patches;
  911. }
  912. exports.compare = compare;
  913. /***/ })
  914. /******/ ]);