182 lines
5.6 KiB
JavaScript
182 lines
5.6 KiB
JavaScript
|
/*!
|
||
|
* https://github.com/Starcounter-Jack/JSON-Patch
|
||
|
* (c) 2017-2022 Joachim Wester
|
||
|
* MIT licensed
|
||
|
*/
|
||
|
var __extends = (this && this.__extends) || (function () {
|
||
|
var extendStatics = function (d, b) {
|
||
|
extendStatics = Object.setPrototypeOf ||
|
||
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||
|
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||
|
return extendStatics(d, b);
|
||
|
};
|
||
|
return function (d, b) {
|
||
|
extendStatics(d, b);
|
||
|
function __() { this.constructor = d; }
|
||
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||
|
};
|
||
|
})();
|
||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||
|
var _hasOwnProperty = Object.prototype.hasOwnProperty;
|
||
|
function hasOwnProperty(obj, key) {
|
||
|
return _hasOwnProperty.call(obj, key);
|
||
|
}
|
||
|
exports.hasOwnProperty = hasOwnProperty;
|
||
|
function _objectKeys(obj) {
|
||
|
if (Array.isArray(obj)) {
|
||
|
var keys_1 = new Array(obj.length);
|
||
|
for (var k = 0; k < keys_1.length; k++) {
|
||
|
keys_1[k] = "" + k;
|
||
|
}
|
||
|
return keys_1;
|
||
|
}
|
||
|
if (Object.keys) {
|
||
|
return Object.keys(obj);
|
||
|
}
|
||
|
var keys = [];
|
||
|
for (var i in obj) {
|
||
|
if (hasOwnProperty(obj, i)) {
|
||
|
keys.push(i);
|
||
|
}
|
||
|
}
|
||
|
return keys;
|
||
|
}
|
||
|
exports._objectKeys = _objectKeys;
|
||
|
;
|
||
|
/**
|
||
|
* Deeply clone the object.
|
||
|
* https://jsperf.com/deep-copy-vs-json-stringify-json-parse/25 (recursiveDeepCopy)
|
||
|
* @param {any} obj value to clone
|
||
|
* @return {any} cloned obj
|
||
|
*/
|
||
|
function _deepClone(obj) {
|
||
|
switch (typeof obj) {
|
||
|
case "object":
|
||
|
return JSON.parse(JSON.stringify(obj)); //Faster than ES5 clone - http://jsperf.com/deep-cloning-of-objects/5
|
||
|
case "undefined":
|
||
|
return null; //this is how JSON.stringify behaves for array items
|
||
|
default:
|
||
|
return obj; //no need to clone primitives
|
||
|
}
|
||
|
}
|
||
|
exports._deepClone = _deepClone;
|
||
|
//3x faster than cached /^\d+$/.test(str)
|
||
|
function isInteger(str) {
|
||
|
var i = 0;
|
||
|
var len = str.length;
|
||
|
var charCode;
|
||
|
while (i < len) {
|
||
|
charCode = str.charCodeAt(i);
|
||
|
if (charCode >= 48 && charCode <= 57) {
|
||
|
i++;
|
||
|
continue;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
exports.isInteger = isInteger;
|
||
|
/**
|
||
|
* Escapes a json pointer path
|
||
|
* @param path The raw pointer
|
||
|
* @return the Escaped path
|
||
|
*/
|
||
|
function escapePathComponent(path) {
|
||
|
if (path.indexOf('/') === -1 && path.indexOf('~') === -1)
|
||
|
return path;
|
||
|
return path.replace(/~/g, '~0').replace(/\//g, '~1');
|
||
|
}
|
||
|
exports.escapePathComponent = escapePathComponent;
|
||
|
/**
|
||
|
* Unescapes a json pointer path
|
||
|
* @param path The escaped pointer
|
||
|
* @return The unescaped path
|
||
|
*/
|
||
|
function unescapePathComponent(path) {
|
||
|
return path.replace(/~1/g, '/').replace(/~0/g, '~');
|
||
|
}
|
||
|
exports.unescapePathComponent = unescapePathComponent;
|
||
|
function _getPathRecursive(root, obj) {
|
||
|
var found;
|
||
|
for (var key in root) {
|
||
|
if (hasOwnProperty(root, key)) {
|
||
|
if (root[key] === obj) {
|
||
|
return escapePathComponent(key) + '/';
|
||
|
}
|
||
|
else if (typeof root[key] === 'object') {
|
||
|
found = _getPathRecursive(root[key], obj);
|
||
|
if (found != '') {
|
||
|
return escapePathComponent(key) + '/' + found;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return '';
|
||
|
}
|
||
|
exports._getPathRecursive = _getPathRecursive;
|
||
|
function getPath(root, obj) {
|
||
|
if (root === obj) {
|
||
|
return '/';
|
||
|
}
|
||
|
var path = _getPathRecursive(root, obj);
|
||
|
if (path === '') {
|
||
|
throw new Error("Object not found in root");
|
||
|
}
|
||
|
return "/" + path;
|
||
|
}
|
||
|
exports.getPath = getPath;
|
||
|
/**
|
||
|
* Recursively checks whether an object has any undefined values inside.
|
||
|
*/
|
||
|
function hasUndefined(obj) {
|
||
|
if (obj === undefined) {
|
||
|
return true;
|
||
|
}
|
||
|
if (obj) {
|
||
|
if (Array.isArray(obj)) {
|
||
|
for (var i_1 = 0, len = obj.length; i_1 < len; i_1++) {
|
||
|
if (hasUndefined(obj[i_1])) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if (typeof obj === "object") {
|
||
|
var objKeys = _objectKeys(obj);
|
||
|
var objKeysLength = objKeys.length;
|
||
|
for (var i = 0; i < objKeysLength; i++) {
|
||
|
if (hasUndefined(obj[objKeys[i]])) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
exports.hasUndefined = hasUndefined;
|
||
|
function patchErrorMessageFormatter(message, args) {
|
||
|
var messageParts = [message];
|
||
|
for (var key in args) {
|
||
|
var value = typeof args[key] === 'object' ? JSON.stringify(args[key], null, 2) : args[key]; // pretty print
|
||
|
if (typeof value !== 'undefined') {
|
||
|
messageParts.push(key + ": " + value);
|
||
|
}
|
||
|
}
|
||
|
return messageParts.join('\n');
|
||
|
}
|
||
|
var PatchError = /** @class */ (function (_super) {
|
||
|
__extends(PatchError, _super);
|
||
|
function PatchError(message, name, index, operation, tree) {
|
||
|
var _newTarget = this.constructor;
|
||
|
var _this = _super.call(this, patchErrorMessageFormatter(message, { name: name, index: index, operation: operation, tree: tree })) || this;
|
||
|
_this.name = name;
|
||
|
_this.index = index;
|
||
|
_this.operation = operation;
|
||
|
_this.tree = tree;
|
||
|
Object.setPrototypeOf(_this, _newTarget.prototype); // restore prototype chain, see https://stackoverflow.com/a/48342359
|
||
|
_this.message = patchErrorMessageFormatter(message, { name: name, index: index, operation: operation, tree: tree });
|
||
|
return _this;
|
||
|
}
|
||
|
return PatchError;
|
||
|
}(Error));
|
||
|
exports.PatchError = PatchError;
|