rfc6902
Version:
Complete implementation of RFC6902 (patch and diff)
90 lines (80 loc) • 3.43 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.createTests = exports.createPatch = exports.applyPatch = exports.Pointer = void 0;
var pointer_1 = require("./pointer");
Object.defineProperty(exports, "Pointer", { enumerable: true, get: function () { return pointer_1.Pointer; } });
var patch_1 = require("./patch");
var diff_1 = require("./diff");
/**
Apply a 'application/json-patch+json'-type patch to an object.
`patch` *must* be an array of operations.
> Operation objects MUST have exactly one "op" member, whose value
> indicates the operation to perform. Its value MUST be one of "add",
> "remove", "replace", "move", "copy", or "test"; other values are
> errors.
This method mutates the target object in-place.
@returns list of results, one for each operation: `null` indicated success,
otherwise, the result will be an instance of one of the Error classes:
MissingError, InvalidOperationError, or TestError.
*/
function applyPatch(object, patch) {
return patch.map(function (operation) { return (0, patch_1.apply)(object, operation); });
}
exports.applyPatch = applyPatch;
function wrapVoidableDiff(diff) {
function wrappedDiff(input, output, ptr) {
var custom_patch = diff(input, output, ptr);
// ensure an array is always returned
return Array.isArray(custom_patch) ? custom_patch : (0, diff_1.diffAny)(input, output, ptr, wrappedDiff);
}
return wrappedDiff;
}
/**
Produce a 'application/json-patch+json'-type patch to get from one object to
another.
This does not alter `input` or `output` unless they have a property getter with
side-effects (which is not a good idea anyway).
`diff` is called on each pair of comparable non-primitive nodes in the
`input`/`output` object trees, producing nested patches. Return `undefined`
to fall back to default behaviour.
Returns list of operations to perform on `input` to produce `output`.
*/
function createPatch(input, output, diff) {
var ptr = new pointer_1.Pointer();
// a new Pointer gets a default path of [''] if not specified
return (diff ? wrapVoidableDiff(diff) : diff_1.diffAny)(input, output, ptr);
}
exports.createPatch = createPatch;
/**
Create a test operation based on `input`'s current evaluation of the JSON
Pointer `path`; if such a pointer cannot be resolved, returns undefined.
*/
function createTest(input, path) {
var endpoint = pointer_1.Pointer.fromJSON(path).evaluate(input);
if (endpoint !== undefined) {
return { op: 'test', path: path, value: endpoint.value };
}
}
/**
Produce an 'application/json-patch+json'-type list of tests, to verify that
existing values in an object are identical to the those captured at some
checkpoint (whenever this function is called).
This does not alter `input` or `output` unless they have a property getter with
side-effects (which is not a good idea anyway).
Returns list of test operations.
*/
function createTests(input, patch) {
var tests = new Array();
patch.filter(diff_1.isDestructive).forEach(function (operation) {
var pathTest = createTest(input, operation.path);
if (pathTest)
tests.push(pathTest);
if ('from' in operation) {
var fromTest = createTest(input, operation.from);
if (fromTest)
tests.push(fromTest);
}
});
return tests;
}
exports.createTests = createTests;
;