123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441 |
- Object.defineProperty(exports, "__esModule", { value: true });
- var helpers_js_1 = require("./helpers.js");
- exports.JsonPatchError = helpers_js_1.PatchError;
- exports.deepClone = helpers_js_1._deepClone;
- var objOps = {
- add: function (obj, key, document) {
- obj[key] = this.value;
- return { newDocument: document };
- },
- remove: function (obj, key, document) {
- var removed = obj[key];
- delete obj[key];
- return { newDocument: document, removed: removed };
- },
- replace: function (obj, key, document) {
- var removed = obj[key];
- obj[key] = this.value;
- return { newDocument: document, removed: removed };
- },
- move: function (obj, key, document) {
-
- var removed = getValueByPointer(document, this.path);
- if (removed) {
- removed = helpers_js_1._deepClone(removed);
- }
- var originalValue = applyOperation(document, { op: "remove", path: this.from }).removed;
- applyOperation(document, { op: "add", path: this.path, value: originalValue });
- return { newDocument: document, removed: removed };
- },
- copy: function (obj, key, document) {
- var valueToCopy = getValueByPointer(document, this.from);
-
- applyOperation(document, { op: "add", path: this.path, value: helpers_js_1._deepClone(valueToCopy) });
- return { newDocument: document };
- },
- test: function (obj, key, document) {
- return { newDocument: document, test: _areEquals(obj[key], this.value) };
- },
- _get: function (obj, key, document) {
- this.value = obj[key];
- return { newDocument: document };
- }
- };
- var arrOps = {
- add: function (arr, i, document) {
- if (helpers_js_1.isInteger(i)) {
- arr.splice(i, 0, this.value);
- }
- else {
- arr[i] = this.value;
- }
-
- return { newDocument: document, index: i };
- },
- remove: function (arr, i, document) {
- var removedList = arr.splice(i, 1);
- return { newDocument: document, removed: removedList[0] };
- },
- replace: function (arr, i, document) {
- var removed = arr[i];
- arr[i] = this.value;
- return { newDocument: document, removed: removed };
- },
- move: objOps.move,
- copy: objOps.copy,
- test: objOps.test,
- _get: objOps._get
- };
- function getValueByPointer(document, pointer) {
- if (pointer == '') {
- return document;
- }
- var getOriginalDestination = { op: "_get", path: pointer };
- applyOperation(document, getOriginalDestination);
- return getOriginalDestination.value;
- }
- exports.getValueByPointer = getValueByPointer;
- function applyOperation(document, operation, validateOperation, mutateDocument, banPrototypeModifications, index) {
- if (validateOperation === void 0) { validateOperation = false; }
- if (mutateDocument === void 0) { mutateDocument = true; }
- if (banPrototypeModifications === void 0) { banPrototypeModifications = true; }
- if (index === void 0) { index = 0; }
- if (validateOperation) {
- if (typeof validateOperation == 'function') {
- validateOperation(operation, 0, document, operation.path);
- }
- else {
- validator(operation, 0);
- }
- }
-
- if (operation.path === "") {
- var returnValue = { newDocument: document };
- if (operation.op === 'add') {
- returnValue.newDocument = operation.value;
- return returnValue;
- }
- else if (operation.op === 'replace') {
- returnValue.newDocument = operation.value;
- returnValue.removed = document;
- return returnValue;
- }
- else if (operation.op === 'move' || operation.op === 'copy') {
- returnValue.newDocument = getValueByPointer(document, operation.from);
- if (operation.op === 'move') {
- returnValue.removed = document;
- }
- return returnValue;
- }
- else if (operation.op === 'test') {
- returnValue.test = _areEquals(document, operation.value);
- if (returnValue.test === false) {
- throw new exports.JsonPatchError("Test operation failed", 'TEST_OPERATION_FAILED', index, operation, document);
- }
- returnValue.newDocument = document;
- return returnValue;
- }
- else if (operation.op === 'remove') {
- returnValue.removed = document;
- returnValue.newDocument = null;
- return returnValue;
- }
- else if (operation.op === '_get') {
- operation.value = document;
- return returnValue;
- }
- else {
- if (validateOperation) {
- throw new exports.JsonPatchError('Operation `op` property is not one of operations defined in RFC-6902', 'OPERATION_OP_INVALID', index, operation, document);
- }
- else {
- return returnValue;
- }
- }
- }
- else {
- if (!mutateDocument) {
- document = helpers_js_1._deepClone(document);
- }
- var path = operation.path || "";
- var keys = path.split('/');
- var obj = document;
- var t = 1;
- var len = keys.length;
- var existingPathFragment = undefined;
- var key = void 0;
- var validateFunction = void 0;
- if (typeof validateOperation == 'function') {
- validateFunction = validateOperation;
- }
- else {
- validateFunction = validator;
- }
- while (true) {
- key = keys[t];
- if (key && key.indexOf('~') != -1) {
- key = helpers_js_1.unescapePathComponent(key);
- }
- if (banPrototypeModifications &&
- (key == '__proto__' ||
- (key == 'prototype' && t > 0 && keys[t - 1] == 'constructor'))) {
- 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');
- }
- if (validateOperation) {
- if (existingPathFragment === undefined) {
- if (obj[key] === undefined) {
- existingPathFragment = keys.slice(0, t).join('/');
- }
- else if (t == len - 1) {
- existingPathFragment = operation.path;
- }
- if (existingPathFragment !== undefined) {
- validateFunction(operation, 0, document, existingPathFragment);
- }
- }
- }
- t++;
- if (Array.isArray(obj)) {
- if (key === '-') {
- key = obj.length;
- }
- else {
- if (validateOperation && !helpers_js_1.isInteger(key)) {
- 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);
- }
- else if (helpers_js_1.isInteger(key)) {
- key = ~~key;
- }
- }
- if (t >= len) {
- if (validateOperation && operation.op === "add" && key > obj.length) {
- 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);
- }
- var returnValue = arrOps[operation.op].call(operation, obj, key, document);
- if (returnValue.test === false) {
- throw new exports.JsonPatchError("Test operation failed", 'TEST_OPERATION_FAILED', index, operation, document);
- }
- return returnValue;
- }
- }
- else {
- if (t >= len) {
- var returnValue = objOps[operation.op].call(operation, obj, key, document);
- if (returnValue.test === false) {
- throw new exports.JsonPatchError("Test operation failed", 'TEST_OPERATION_FAILED', index, operation, document);
- }
- return returnValue;
- }
- }
- obj = obj[key];
-
-
- if (validateOperation && t < len && (!obj || typeof obj !== "object")) {
- throw new exports.JsonPatchError('Cannot perform operation at the desired path', 'OPERATION_PATH_UNRESOLVABLE', index, operation, document);
- }
- }
- }
- }
- exports.applyOperation = applyOperation;
- function applyPatch(document, patch, validateOperation, mutateDocument, banPrototypeModifications) {
- if (mutateDocument === void 0) { mutateDocument = true; }
- if (banPrototypeModifications === void 0) { banPrototypeModifications = true; }
- if (validateOperation) {
- if (!Array.isArray(patch)) {
- throw new exports.JsonPatchError('Patch sequence must be an array', 'SEQUENCE_NOT_AN_ARRAY');
- }
- }
- if (!mutateDocument) {
- document = helpers_js_1._deepClone(document);
- }
- var results = new Array(patch.length);
- for (var i = 0, length_1 = patch.length; i < length_1; i++) {
-
- results[i] = applyOperation(document, patch[i], validateOperation, true, banPrototypeModifications, i);
- document = results[i].newDocument;
- }
- results.newDocument = document;
- return results;
- }
- exports.applyPatch = applyPatch;
- function applyReducer(document, operation, index) {
- var operationResult = applyOperation(document, operation);
- if (operationResult.test === false) {
- throw new exports.JsonPatchError("Test operation failed", 'TEST_OPERATION_FAILED', index, operation, document);
- }
- return operationResult.newDocument;
- }
- exports.applyReducer = applyReducer;
- function validator(operation, index, document, existingPathFragment) {
- if (typeof operation !== 'object' || operation === null || Array.isArray(operation)) {
- throw new exports.JsonPatchError('Operation is not an object', 'OPERATION_NOT_AN_OBJECT', index, operation, document);
- }
- else if (!objOps[operation.op]) {
- throw new exports.JsonPatchError('Operation `op` property is not one of operations defined in RFC-6902', 'OPERATION_OP_INVALID', index, operation, document);
- }
- else if (typeof operation.path !== 'string') {
- throw new exports.JsonPatchError('Operation `path` property is not a string', 'OPERATION_PATH_INVALID', index, operation, document);
- }
- else if (operation.path.indexOf('/') !== 0 && operation.path.length > 0) {
-
- throw new exports.JsonPatchError('Operation `path` property must start with "/"', 'OPERATION_PATH_INVALID', index, operation, document);
- }
- else if ((operation.op === 'move' || operation.op === 'copy') && typeof operation.from !== 'string') {
- throw new exports.JsonPatchError('Operation `from` property is not present (applicable in `move` and `copy` operations)', 'OPERATION_FROM_REQUIRED', index, operation, document);
- }
- else if ((operation.op === 'add' || operation.op === 'replace' || operation.op === 'test') && operation.value === undefined) {
- throw new exports.JsonPatchError('Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)', 'OPERATION_VALUE_REQUIRED', index, operation, document);
- }
- else if ((operation.op === 'add' || operation.op === 'replace' || operation.op === 'test') && helpers_js_1.hasUndefined(operation.value)) {
- 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);
- }
- else if (document) {
- if (operation.op == "add") {
- var pathLen = operation.path.split("/").length;
- var existingPathLen = existingPathFragment.split("/").length;
- if (pathLen !== existingPathLen + 1 && pathLen !== existingPathLen) {
- throw new exports.JsonPatchError('Cannot perform an `add` operation at the desired path', 'OPERATION_PATH_CANNOT_ADD', index, operation, document);
- }
- }
- else if (operation.op === 'replace' || operation.op === 'remove' || operation.op === '_get') {
- if (operation.path !== existingPathFragment) {
- throw new exports.JsonPatchError('Cannot perform the operation at a path that does not exist', 'OPERATION_PATH_UNRESOLVABLE', index, operation, document);
- }
- }
- else if (operation.op === 'move' || operation.op === 'copy') {
- var existingValue = { op: "_get", path: operation.from, value: undefined };
- var error = validate([existingValue], document);
- if (error && error.name === 'OPERATION_PATH_UNRESOLVABLE') {
- throw new exports.JsonPatchError('Cannot perform the operation from a path that does not exist', 'OPERATION_FROM_UNRESOLVABLE', index, operation, document);
- }
- }
- }
- }
- exports.validator = validator;
- function validate(sequence, document, externalValidator) {
- try {
- if (!Array.isArray(sequence)) {
- throw new exports.JsonPatchError('Patch sequence must be an array', 'SEQUENCE_NOT_AN_ARRAY');
- }
- if (document) {
-
- applyPatch(helpers_js_1._deepClone(document), helpers_js_1._deepClone(sequence), externalValidator || true);
- }
- else {
- externalValidator = externalValidator || validator;
- for (var i = 0; i < sequence.length; i++) {
- externalValidator(sequence[i], i, document, undefined);
- }
- }
- }
- catch (e) {
- if (e instanceof exports.JsonPatchError) {
- return e;
- }
- else {
- throw e;
- }
- }
- }
- exports.validate = validate;
- function _areEquals(a, b) {
- if (a === b)
- return true;
- if (a && b && typeof a == 'object' && typeof b == 'object') {
- var arrA = Array.isArray(a), arrB = Array.isArray(b), i, length, key;
- if (arrA && arrB) {
- length = a.length;
- if (length != b.length)
- return false;
- for (i = length; i-- !== 0;)
- if (!_areEquals(a[i], b[i]))
- return false;
- return true;
- }
- if (arrA != arrB)
- return false;
- var keys = Object.keys(a);
- length = keys.length;
- if (length !== Object.keys(b).length)
- return false;
- for (i = length; i-- !== 0;)
- if (!b.hasOwnProperty(keys[i]))
- return false;
- for (i = length; i-- !== 0;) {
- key = keys[i];
- if (!_areEquals(a[key], b[key]))
- return false;
- }
- return true;
- }
- return a !== a && b !== b;
- }
- exports._areEquals = _areEquals;
- ;
|