immutable-json-patch
Version:
Immutable JSON patch with support for reverting operations
112 lines (110 loc) • 3.84 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.revertJSONPatch = revertJSONPatch;
var _immutabilityHelpers = require("./immutabilityHelpers.js");
var _immutableJSONPatch = require("./immutableJSONPatch.js");
var _jsonPointer = require("./jsonPointer.js");
var _utils = require("./utils.js");
/**
* Create the inverse of a set of json patch operations
* @param document
* @param operations Array with JSON patch actions
* @param [options]
* @return Returns the operations to revert the changes
*/
function revertJSONPatch(document, operations, options) {
let allRevertOperations = [];
const before = (document, operation) => {
let revertOperations;
const path = (0, _immutableJSONPatch.parsePath)(document, operation.path);
if (operation.op === 'add') {
revertOperations = revertAdd(document, path);
} else if (operation.op === 'remove') {
revertOperations = revertRemove(document, path);
} else if (operation.op === 'replace') {
revertOperations = revertReplace(document, path);
} else if (operation.op === 'copy') {
revertOperations = revertCopy(document, path);
} else if (operation.op === 'move') {
revertOperations = revertMove(document, path, (0, _immutableJSONPatch.parseFrom)(operation.from));
} else if (operation.op === 'test') {
revertOperations = [];
} else {
throw new Error(`Unknown JSONPatch operation ${JSON.stringify(operation)}`);
}
let updatedJson;
if (options?.before) {
const res = options.before(document, operation, revertOperations);
if (res?.revertOperations) {
revertOperations = res.revertOperations;
}
if (res?.document) {
updatedJson = res.document;
}
// @ts-ignore
if (res?.json) {
// TODO: deprecated since v5.0.0. Cleanup this warning some day
throw new Error('Deprecation warning: returned object property ".json" has been renamed to ".document"');
}
}
allRevertOperations = revertOperations.concat(allRevertOperations);
if (updatedJson !== undefined) {
return {
document: updatedJson
};
}
};
(0, _immutableJSONPatch.immutableJSONPatch)(document, operations, {
before
});
return allRevertOperations;
}
function revertReplace(document, path) {
return (0, _immutabilityHelpers.existsIn)(document, path) ? [{
op: 'replace',
path: (0, _jsonPointer.compileJSONPointer)(path),
value: (0, _immutabilityHelpers.getIn)(document, path)
}] : [];
}
function revertRemove(document, path) {
return [{
op: 'add',
path: (0, _jsonPointer.compileJSONPointer)(path),
value: (0, _immutabilityHelpers.getIn)(document, path)
}];
}
function revertAdd(document, path) {
if ((0, _immutableJSONPatch.isArrayItem)(document, path) || !(0, _immutabilityHelpers.existsIn)(document, path)) {
return [{
op: 'remove',
path: (0, _jsonPointer.compileJSONPointer)(path)
}];
}
return revertReplace(document, path);
}
function revertCopy(document, path) {
return revertAdd(document, path);
}
function revertMove(document, path, from) {
if (path.length < from.length && (0, _utils.startsWith)(from, path)) {
// replacing the parent with the child
return [{
op: 'replace',
path: (0, _jsonPointer.compileJSONPointer)(path),
value: document
}];
}
const move = {
op: 'move',
from: (0, _jsonPointer.compileJSONPointer)(path),
path: (0, _jsonPointer.compileJSONPointer)(from)
};
if (!(0, _immutableJSONPatch.isArrayItem)(document, path) && (0, _immutabilityHelpers.existsIn)(document, path)) {
// the move replaces an existing value in an object
return [move, ...revertRemove(document, path)];
}
return [move];
}
//# sourceMappingURL=revertJSONPatch.js.map