immutable-json-patch
Advanced tools
Comparing version
@@ -17,18 +17,14 @@ "use strict"; | ||
var _utils = require("./utils.js"); | ||
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } | ||
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } | ||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } | ||
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } | ||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } /** | ||
* Immutability helpers | ||
* | ||
* inspiration: | ||
* | ||
* https://www.npmjs.com/package/seamless-immutable | ||
* https://www.npmjs.com/package/ih | ||
* https://www.npmjs.com/package/mutatis | ||
* https://github.com/mariocasciaro/object-path-immutable | ||
*/ | ||
/** | ||
* Immutability helpers | ||
* | ||
* inspiration: | ||
* | ||
* https://www.npmjs.com/package/seamless-immutable | ||
* https://www.npmjs.com/package/ih | ||
* https://www.npmjs.com/package/mutatis | ||
* https://github.com/mariocasciaro/object-path-immutable | ||
*/ | ||
/** | ||
* Shallow clone of an Object, Array, or value | ||
@@ -40,6 +36,6 @@ * Symbols are cloned too. | ||
// copy array items | ||
var copy = value.slice(); | ||
const copy = value.slice(); | ||
// copy all symbols | ||
Object.getOwnPropertySymbols(value).forEach(function (symbol) { | ||
Object.getOwnPropertySymbols(value).forEach(symbol => { | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
@@ -52,11 +48,13 @@ // @ts-ignore | ||
// copy object properties | ||
var _copy = _objectSpread({}, value); | ||
const copy = { | ||
...value | ||
}; | ||
// copy all symbols | ||
Object.getOwnPropertySymbols(value).forEach(function (symbol) { | ||
Object.getOwnPropertySymbols(value).forEach(symbol => { | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
_copy[symbol] = value[symbol]; | ||
copy[symbol] = value[symbol]; | ||
}); | ||
return _copy; | ||
return copy; | ||
} else { | ||
@@ -78,3 +76,3 @@ return value; | ||
} else { | ||
var updatedObject = shallowClone(object); | ||
const updatedObject = shallowClone(object); | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
@@ -93,4 +91,4 @@ // @ts-ignore | ||
function getIn(object, path) { | ||
var value = object; | ||
var i = 0; | ||
let value = object; | ||
let i = 0; | ||
while (i < path.length) { | ||
@@ -126,10 +124,10 @@ if ((0, _typeguards.isJSONObject)(value)) { | ||
function setIn(object, path, value) { | ||
var createPath = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; | ||
let createPath = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; | ||
if (path.length === 0) { | ||
return value; | ||
} | ||
var key = path[0]; | ||
const key = path[0]; | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
var updatedValue = setIn(object ? object[key] : undefined, path.slice(1), value, createPath); | ||
const updatedValue = setIn(object ? object[key] : undefined, path.slice(1), value, createPath); | ||
if ((0, _typeguards.isJSONObject)(object) || (0, _typeguards.isJSONArray)(object)) { | ||
@@ -139,3 +137,3 @@ return applyProp(object, key, updatedValue); | ||
if (createPath) { | ||
var newObject = IS_INTEGER_REGEX.test(key) ? [] : {}; | ||
const newObject = IS_INTEGER_REGEX.test(key) ? [] : {}; | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
@@ -150,3 +148,3 @@ // @ts-ignore | ||
} | ||
var IS_INTEGER_REGEX = /^\d+$/; | ||
const IS_INTEGER_REGEX = /^\d+$/; | ||
@@ -159,5 +157,5 @@ /** | ||
*/ | ||
function updateIn(object, path, callback) { | ||
function updateIn(object, path, transform) { | ||
if (path.length === 0) { | ||
return callback(object); | ||
return transform(object); | ||
} | ||
@@ -167,6 +165,6 @@ if (!(0, _utils.isObjectOrArray)(object)) { | ||
} | ||
var key = path[0]; | ||
const key = path[0]; | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
var updatedValue = updateIn(object[key], path.slice(1), callback); | ||
const updatedValue = updateIn(object[key], path.slice(1), transform); | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
@@ -191,13 +189,13 @@ // @ts-ignore | ||
if (path.length === 1) { | ||
var _key = path[0]; | ||
if (!(_key in object)) { | ||
const key = path[0]; | ||
if (!(key in object)) { | ||
// key doesn't exist. return object unchanged | ||
return object; | ||
} else { | ||
var updatedObject = shallowClone(object); | ||
const updatedObject = shallowClone(object); | ||
if ((0, _typeguards.isJSONArray)(updatedObject)) { | ||
updatedObject.splice(parseInt(_key), 1); | ||
updatedObject.splice(parseInt(key), 1); | ||
} | ||
if ((0, _typeguards.isJSONObject)(updatedObject)) { | ||
delete updatedObject[_key]; | ||
delete updatedObject[key]; | ||
} | ||
@@ -207,6 +205,6 @@ return updatedObject; | ||
} | ||
var key = path[0]; | ||
const key = path[0]; | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
var updatedValue = deleteIn(object[key], path.slice(1)); | ||
const updatedValue = deleteIn(object[key], path.slice(1)); | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
@@ -224,9 +222,9 @@ // @ts-ignore | ||
function insertAt(document, path, value) { | ||
var parentPath = path.slice(0, path.length - 1); | ||
var index = path[path.length - 1]; | ||
return updateIn(document, parentPath, function (items) { | ||
const parentPath = path.slice(0, path.length - 1); | ||
const index = path[path.length - 1]; | ||
return updateIn(document, parentPath, items => { | ||
if (!Array.isArray(items)) { | ||
throw new TypeError('Array expected at path ' + JSON.stringify(parentPath)); | ||
} | ||
var updatedItems = shallowClone(items); | ||
const updatedItems = shallowClone(items); | ||
updatedItems.splice(parseInt(index), 0, value); | ||
@@ -242,13 +240,14 @@ return updatedItems; | ||
function transform(document, callback) { | ||
var path = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; | ||
var updated1 = callback(document, path); | ||
let path = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; | ||
// eslint-disable-next-line n/no-callback-literal | ||
const updated1 = callback(document, path); | ||
if ((0, _typeguards.isJSONArray)(updated1)) { | ||
// array | ||
var updated2; | ||
for (var i = 0; i < updated1.length; i++) { | ||
var before = updated1[i]; | ||
let updated2; | ||
for (let i = 0; i < updated1.length; i++) { | ||
const before = updated1[i]; | ||
// we stringify the index here, so the path only contains strings and can be safely | ||
// stringified/parsed to JSONPointer without loosing information. | ||
// We do not want to rely on path keys being numeric/string. | ||
var after = transform(before, callback, path.concat(i + '')); | ||
const after = transform(before, callback, path.concat(i + '')); | ||
if (after !== before) { | ||
@@ -264,16 +263,16 @@ if (!updated2) { | ||
// object | ||
var _updated; | ||
for (var key in updated1) { | ||
let updated2; | ||
for (const key in updated1) { | ||
if (Object.hasOwnProperty.call(updated1, key)) { | ||
var _before = updated1[key]; | ||
var _after = transform(_before, callback, path.concat(key)); | ||
if (_after !== _before) { | ||
if (!_updated) { | ||
_updated = shallowClone(updated1); | ||
const before = updated1[key]; | ||
const after = transform(before, callback, path.concat(key)); | ||
if (after !== before) { | ||
if (!updated2) { | ||
updated2 = shallowClone(updated1); | ||
} | ||
_updated[key] = _after; | ||
updated2[key] = after; | ||
} | ||
} | ||
} | ||
return _updated || updated1; | ||
return updated2 || updated1; | ||
} else { | ||
@@ -280,0 +279,0 @@ // number, string, boolean, null |
@@ -27,10 +27,10 @@ "use strict"; | ||
function immutableJSONPatch(document, operations, options) { | ||
var updatedDocument = document; | ||
for (var i = 0; i < operations.length; i++) { | ||
let updatedDocument = document; | ||
for (let i = 0; i < operations.length; i++) { | ||
validateJSONPatchOperation(operations[i]); | ||
var operation = operations[i]; | ||
let operation = operations[i]; | ||
// TODO: test before | ||
if (options && options.before) { | ||
var result = options.before(updatedDocument, operation); | ||
const result = options.before(updatedDocument, operation); | ||
if (result !== undefined) { | ||
@@ -51,4 +51,4 @@ if (result.document !== undefined) { | ||
} | ||
var previousDocument = updatedDocument; | ||
var path = parsePath(updatedDocument, operation.path); | ||
const previousDocument = updatedDocument; | ||
const path = parsePath(updatedDocument, operation.path); | ||
if (operation.op === 'add') { | ||
@@ -72,5 +72,5 @@ updatedDocument = add(updatedDocument, path, operation.value); | ||
if (options && options.after) { | ||
var _result = options.after(updatedDocument, operation, previousDocument); | ||
if (_result !== undefined) { | ||
updatedDocument = _result; | ||
const result = options.after(updatedDocument, operation, previousDocument); | ||
if (result !== undefined) { | ||
updatedDocument = result; | ||
} | ||
@@ -111,8 +111,8 @@ } | ||
function copy(document, path, from) { | ||
var value = (0, _immutabilityHelpers.getIn)(document, from); | ||
const value = (0, _immutabilityHelpers.getIn)(document, from); | ||
if (isArrayItem(document, path)) { | ||
return (0, _immutabilityHelpers.insertAt)(document, path, value); | ||
} else { | ||
var _value = (0, _immutabilityHelpers.getIn)(document, from); | ||
return (0, _immutabilityHelpers.setIn)(document, path, _value); | ||
const value = (0, _immutabilityHelpers.getIn)(document, from); | ||
return (0, _immutabilityHelpers.setIn)(document, path, value); | ||
} | ||
@@ -125,6 +125,6 @@ } | ||
function move(document, path, from) { | ||
var value = (0, _immutabilityHelpers.getIn)(document, from); | ||
const value = (0, _immutabilityHelpers.getIn)(document, from); | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
var removedJson = (0, _immutabilityHelpers.deleteIn)(document, from); | ||
const removedJson = (0, _immutabilityHelpers.deleteIn)(document, from); | ||
return isArrayItem(removedJson, path) ? (0, _immutabilityHelpers.insertAt)(removedJson, path, value) : (0, _immutabilityHelpers.setIn)(removedJson, path, value); | ||
@@ -139,10 +139,10 @@ } | ||
if (value === undefined) { | ||
throw new Error("Test failed: no value provided (path: \"".concat((0, _jsonPointer.compileJSONPointer)(path), "\")")); | ||
throw new Error(`Test failed: no value provided (path: "${(0, _jsonPointer.compileJSONPointer)(path)}")`); | ||
} | ||
if (!(0, _immutabilityHelpers.existsIn)(document, path)) { | ||
throw new Error("Test failed: path not found (path: \"".concat((0, _jsonPointer.compileJSONPointer)(path), "\")")); | ||
throw new Error(`Test failed: path not found (path: "${(0, _jsonPointer.compileJSONPointer)(path)}")`); | ||
} | ||
var actualValue = (0, _immutabilityHelpers.getIn)(document, path); | ||
const actualValue = (0, _immutabilityHelpers.getIn)(document, path); | ||
if (!(0, _utils.isEqual)(actualValue, value)) { | ||
throw new Error("Test failed, value differs (path: \"".concat((0, _jsonPointer.compileJSONPointer)(path), "\")")); | ||
throw new Error(`Test failed, value differs (path: "${(0, _jsonPointer.compileJSONPointer)(path)}")`); | ||
} | ||
@@ -154,3 +154,3 @@ } | ||
} | ||
var parent = (0, _immutabilityHelpers.getIn)(document, (0, _utils.initial)(path)); | ||
const parent = (0, _immutabilityHelpers.getIn)(document, (0, _utils.initial)(path)); | ||
return Array.isArray(parent); | ||
@@ -167,4 +167,4 @@ } | ||
} | ||
var parentPath = (0, _utils.initial)(path); | ||
var parent = (0, _immutabilityHelpers.getIn)(document, parentPath); | ||
const parentPath = (0, _utils.initial)(path); | ||
const parent = (0, _immutabilityHelpers.getIn)(document, parentPath); | ||
@@ -182,3 +182,3 @@ // eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// TODO: write unit tests | ||
var ops = ['add', 'remove', 'replace', 'copy', 'move', 'test']; | ||
const ops = ['add', 'remove', 'replace', 'copy', 'move', 'test']; | ||
if (!ops.includes(operation.op)) { | ||
@@ -185,0 +185,0 @@ throw new Error('Unknown JSONPatch op ' + JSON.stringify(operation.op)); |
@@ -21,3 +21,3 @@ "use strict"; | ||
enumerable: true, | ||
get: function get() { | ||
get: function () { | ||
return _immutabilityHelpers.deleteIn; | ||
@@ -28,3 +28,3 @@ } | ||
enumerable: true, | ||
get: function get() { | ||
get: function () { | ||
return _immutabilityHelpers.existsIn; | ||
@@ -35,3 +35,3 @@ } | ||
enumerable: true, | ||
get: function get() { | ||
get: function () { | ||
return _immutabilityHelpers.getIn; | ||
@@ -42,3 +42,3 @@ } | ||
enumerable: true, | ||
get: function get() { | ||
get: function () { | ||
return _immutableJSONPatch.immutableJSONPatch; | ||
@@ -49,3 +49,3 @@ } | ||
enumerable: true, | ||
get: function get() { | ||
get: function () { | ||
return _immutabilityHelpers.insertAt; | ||
@@ -56,3 +56,3 @@ } | ||
enumerable: true, | ||
get: function get() { | ||
get: function () { | ||
return _immutableJSONPatch.parseFrom; | ||
@@ -63,3 +63,3 @@ } | ||
enumerable: true, | ||
get: function get() { | ||
get: function () { | ||
return _immutableJSONPatch.parsePath; | ||
@@ -70,3 +70,3 @@ } | ||
enumerable: true, | ||
get: function get() { | ||
get: function () { | ||
return _revertJSONPatch.revertJSONPatch; | ||
@@ -77,3 +77,3 @@ } | ||
enumerable: true, | ||
get: function get() { | ||
get: function () { | ||
return _immutabilityHelpers.setIn; | ||
@@ -84,3 +84,3 @@ } | ||
enumerable: true, | ||
get: function get() { | ||
get: function () { | ||
return _immutabilityHelpers.transform; | ||
@@ -91,3 +91,3 @@ } | ||
enumerable: true, | ||
get: function get() { | ||
get: function () { | ||
return _immutabilityHelpers.updateIn; | ||
@@ -105,3 +105,3 @@ } | ||
enumerable: true, | ||
get: function get() { | ||
get: function () { | ||
return _types[key]; | ||
@@ -118,3 +118,3 @@ } | ||
enumerable: true, | ||
get: function get() { | ||
get: function () { | ||
return _jsonPointer[key]; | ||
@@ -131,3 +131,3 @@ } | ||
enumerable: true, | ||
get: function get() { | ||
get: function () { | ||
return _typeguards[key]; | ||
@@ -134,0 +134,0 @@ } |
@@ -15,8 +15,6 @@ "use strict"; | ||
function parseJSONPointer(pointer) { | ||
var path = pointer.split('/'); | ||
const path = pointer.split('/'); | ||
path.shift(); // remove the first empty entry | ||
return path.map(function (p) { | ||
return p.replace(/~1/g, '/').replace(/~0/g, '~'); | ||
}); | ||
return path.map(p => p.replace(/~1/g, '/').replace(/~0/g, '~')); | ||
} | ||
@@ -23,0 +21,0 @@ |
@@ -11,8 +11,2 @@ "use strict"; | ||
var _utils = require("./utils.js"); | ||
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } | ||
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } | ||
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } | ||
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } | ||
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } | ||
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } | ||
/** | ||
@@ -26,45 +20,46 @@ * Create the inverse of a set of json patch operations | ||
function revertJSONPatch(document, operations, options) { | ||
var allRevertOperations = []; | ||
(0, _immutableJSONPatch.immutableJSONPatch)(document, operations, { | ||
before: function before(document, operation) { | ||
var revertOperations; | ||
var 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 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 && options.before) { | ||
const res = options.before(document, operation, revertOperations); | ||
if (res && res.revertOperations) { | ||
revertOperations = res.revertOperations; | ||
} | ||
var updatedJson; | ||
if (options && options.before) { | ||
var res = options.before(document, operation, revertOperations); | ||
if (res && res.revertOperations) { | ||
revertOperations = res.revertOperations; | ||
} | ||
if (res && res.document) { | ||
updatedJson = res.document; | ||
} | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
if (res && 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"'); | ||
} | ||
if (res && res.document) { | ||
updatedJson = res.document; | ||
} | ||
allRevertOperations = revertOperations.concat(allRevertOperations); | ||
if (updatedJson !== undefined) { | ||
return { | ||
document: updatedJson | ||
}; | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
if (res && 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 | ||
}); | ||
@@ -109,3 +104,3 @@ return allRevertOperations; | ||
} | ||
var move = { | ||
const move = { | ||
op: 'move', | ||
@@ -117,3 +112,3 @@ from: (0, _jsonPointer.compileJSONPointer)(path), | ||
// the move replaces an existing value in an object | ||
return [move].concat(_toConsumableArray(revertRemove(document, path))); | ||
return [move, ...revertRemove(document, path)]; | ||
} else { | ||
@@ -120,0 +115,0 @@ return [move]; |
@@ -15,3 +15,2 @@ "use strict"; | ||
exports.isJSONPatchTest = isJSONPatchTest; | ||
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } | ||
function isJSONArray(value) { | ||
@@ -21,10 +20,9 @@ return Array.isArray(value); | ||
function isJSONObject(value) { | ||
return value !== null && _typeof(value) === 'object' && value.constructor === Object // do not match on classes or Array | ||
return value !== null && typeof value === 'object' && value.constructor === Object // do not match on classes or Array | ||
; | ||
} | ||
function isJSONPatchOperation(value) { | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
return value && _typeof(value) === 'object' ? typeof value.op === 'string' : false; | ||
return value && typeof value === 'object' ? typeof value.op === 'string' : false; | ||
} | ||
@@ -34,3 +32,3 @@ function isJSONPatchAdd(value) { | ||
// @ts-ignore | ||
return value && _typeof(value) === 'object' ? value.op === 'add' : false; | ||
return value && typeof value === 'object' ? value.op === 'add' : false; | ||
} | ||
@@ -40,3 +38,3 @@ function isJSONPatchRemove(value) { | ||
// @ts-ignore | ||
return value && _typeof(value) === 'object' ? value.op === 'remove' : false; | ||
return value && typeof value === 'object' ? value.op === 'remove' : false; | ||
} | ||
@@ -46,3 +44,3 @@ function isJSONPatchReplace(value) { | ||
// @ts-ignore | ||
return value && _typeof(value) === 'object' ? value.op === 'replace' : false; | ||
return value && typeof value === 'object' ? value.op === 'replace' : false; | ||
} | ||
@@ -52,3 +50,3 @@ function isJSONPatchCopy(value) { | ||
// @ts-ignore | ||
return value && _typeof(value) === 'object' ? value.op === 'copy' : false; | ||
return value && typeof value === 'object' ? value.op === 'copy' : false; | ||
} | ||
@@ -58,3 +56,3 @@ function isJSONPatchMove(value) { | ||
// @ts-ignore | ||
return value && _typeof(value) === 'object' ? value.op === 'move' : false; | ||
return value && typeof value === 'object' ? value.op === 'move' : false; | ||
} | ||
@@ -64,4 +62,4 @@ function isJSONPatchTest(value) { | ||
// @ts-ignore | ||
return value && _typeof(value) === 'object' ? value.op === 'test' : false; | ||
return value && typeof value === 'object' ? value.op === 'test' : false; | ||
} | ||
//# sourceMappingURL=typeguards.js.map |
@@ -12,3 +12,2 @@ "use strict"; | ||
exports.strictEqual = strictEqual; | ||
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } | ||
/** | ||
@@ -54,7 +53,7 @@ * Test deep equality of two JSON values, objects, or arrays | ||
function startsWith(array1, array2) { | ||
var isEqual = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : strictEqual; | ||
let isEqual = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : strictEqual; | ||
if (array1.length < array2.length) { | ||
return false; | ||
} | ||
for (var i = 0; i < array2.length; i++) { | ||
for (let i = 0; i < array2.length; i++) { | ||
if (!isEqual(array1[i], array2[i])) { | ||
@@ -72,4 +71,4 @@ return false; | ||
function isObjectOrArray(value) { | ||
return _typeof(value) === 'object' && value !== null; | ||
return typeof value === 'object' && value !== null; | ||
} | ||
//# sourceMappingURL=utils.js.map |
@@ -1,7 +0,1 @@ | ||
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } | ||
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } | ||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } | ||
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } | ||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } | ||
/** | ||
@@ -27,6 +21,6 @@ * Immutability helpers | ||
// copy array items | ||
var copy = value.slice(); | ||
const copy = value.slice(); | ||
// copy all symbols | ||
Object.getOwnPropertySymbols(value).forEach(function (symbol) { | ||
Object.getOwnPropertySymbols(value).forEach(symbol => { | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
@@ -39,11 +33,13 @@ // @ts-ignore | ||
// copy object properties | ||
var _copy = _objectSpread({}, value); | ||
const copy = { | ||
...value | ||
}; | ||
// copy all symbols | ||
Object.getOwnPropertySymbols(value).forEach(function (symbol) { | ||
Object.getOwnPropertySymbols(value).forEach(symbol => { | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
_copy[symbol] = value[symbol]; | ||
copy[symbol] = value[symbol]; | ||
}); | ||
return _copy; | ||
return copy; | ||
} else { | ||
@@ -65,3 +61,3 @@ return value; | ||
} else { | ||
var updatedObject = shallowClone(object); | ||
const updatedObject = shallowClone(object); | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
@@ -80,4 +76,4 @@ // @ts-ignore | ||
export function getIn(object, path) { | ||
var value = object; | ||
var i = 0; | ||
let value = object; | ||
let i = 0; | ||
while (i < path.length) { | ||
@@ -113,10 +109,10 @@ if (isJSONObject(value)) { | ||
export function setIn(object, path, value) { | ||
var createPath = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; | ||
let createPath = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; | ||
if (path.length === 0) { | ||
return value; | ||
} | ||
var key = path[0]; | ||
const key = path[0]; | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
var updatedValue = setIn(object ? object[key] : undefined, path.slice(1), value, createPath); | ||
const updatedValue = setIn(object ? object[key] : undefined, path.slice(1), value, createPath); | ||
if (isJSONObject(object) || isJSONArray(object)) { | ||
@@ -126,3 +122,3 @@ return applyProp(object, key, updatedValue); | ||
if (createPath) { | ||
var newObject = IS_INTEGER_REGEX.test(key) ? [] : {}; | ||
const newObject = IS_INTEGER_REGEX.test(key) ? [] : {}; | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
@@ -137,3 +133,3 @@ // @ts-ignore | ||
} | ||
var IS_INTEGER_REGEX = /^\d+$/; | ||
const IS_INTEGER_REGEX = /^\d+$/; | ||
@@ -146,5 +142,5 @@ /** | ||
*/ | ||
export function updateIn(object, path, callback) { | ||
export function updateIn(object, path, transform) { | ||
if (path.length === 0) { | ||
return callback(object); | ||
return transform(object); | ||
} | ||
@@ -154,6 +150,6 @@ if (!isObjectOrArray(object)) { | ||
} | ||
var key = path[0]; | ||
const key = path[0]; | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
var updatedValue = updateIn(object[key], path.slice(1), callback); | ||
const updatedValue = updateIn(object[key], path.slice(1), transform); | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
@@ -178,13 +174,13 @@ // @ts-ignore | ||
if (path.length === 1) { | ||
var _key = path[0]; | ||
if (!(_key in object)) { | ||
const key = path[0]; | ||
if (!(key in object)) { | ||
// key doesn't exist. return object unchanged | ||
return object; | ||
} else { | ||
var updatedObject = shallowClone(object); | ||
const updatedObject = shallowClone(object); | ||
if (isJSONArray(updatedObject)) { | ||
updatedObject.splice(parseInt(_key), 1); | ||
updatedObject.splice(parseInt(key), 1); | ||
} | ||
if (isJSONObject(updatedObject)) { | ||
delete updatedObject[_key]; | ||
delete updatedObject[key]; | ||
} | ||
@@ -194,6 +190,6 @@ return updatedObject; | ||
} | ||
var key = path[0]; | ||
const key = path[0]; | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
var updatedValue = deleteIn(object[key], path.slice(1)); | ||
const updatedValue = deleteIn(object[key], path.slice(1)); | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
@@ -211,9 +207,9 @@ // @ts-ignore | ||
export function insertAt(document, path, value) { | ||
var parentPath = path.slice(0, path.length - 1); | ||
var index = path[path.length - 1]; | ||
return updateIn(document, parentPath, function (items) { | ||
const parentPath = path.slice(0, path.length - 1); | ||
const index = path[path.length - 1]; | ||
return updateIn(document, parentPath, items => { | ||
if (!Array.isArray(items)) { | ||
throw new TypeError('Array expected at path ' + JSON.stringify(parentPath)); | ||
} | ||
var updatedItems = shallowClone(items); | ||
const updatedItems = shallowClone(items); | ||
updatedItems.splice(parseInt(index), 0, value); | ||
@@ -229,13 +225,14 @@ return updatedItems; | ||
export function transform(document, callback) { | ||
var path = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; | ||
var updated1 = callback(document, path); | ||
let path = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; | ||
// eslint-disable-next-line n/no-callback-literal | ||
const updated1 = callback(document, path); | ||
if (isJSONArray(updated1)) { | ||
// array | ||
var updated2; | ||
for (var i = 0; i < updated1.length; i++) { | ||
var before = updated1[i]; | ||
let updated2; | ||
for (let i = 0; i < updated1.length; i++) { | ||
const before = updated1[i]; | ||
// we stringify the index here, so the path only contains strings and can be safely | ||
// stringified/parsed to JSONPointer without loosing information. | ||
// We do not want to rely on path keys being numeric/string. | ||
var after = transform(before, callback, path.concat(i + '')); | ||
const after = transform(before, callback, path.concat(i + '')); | ||
if (after !== before) { | ||
@@ -251,16 +248,16 @@ if (!updated2) { | ||
// object | ||
var _updated; | ||
for (var key in updated1) { | ||
let updated2; | ||
for (const key in updated1) { | ||
if (Object.hasOwnProperty.call(updated1, key)) { | ||
var _before = updated1[key]; | ||
var _after = transform(_before, callback, path.concat(key)); | ||
if (_after !== _before) { | ||
if (!_updated) { | ||
_updated = shallowClone(updated1); | ||
const before = updated1[key]; | ||
const after = transform(before, callback, path.concat(key)); | ||
if (after !== before) { | ||
if (!updated2) { | ||
updated2 = shallowClone(updated1); | ||
} | ||
_updated[key] = _after; | ||
updated2[key] = after; | ||
} | ||
} | ||
} | ||
return _updated || updated1; | ||
return updated2 || updated1; | ||
} else { | ||
@@ -267,0 +264,0 @@ // number, string, boolean, null |
@@ -11,10 +11,10 @@ import { deleteIn, existsIn, getIn, insertAt, setIn } from './immutabilityHelpers.js'; | ||
export function immutableJSONPatch(document, operations, options) { | ||
var updatedDocument = document; | ||
for (var i = 0; i < operations.length; i++) { | ||
let updatedDocument = document; | ||
for (let i = 0; i < operations.length; i++) { | ||
validateJSONPatchOperation(operations[i]); | ||
var operation = operations[i]; | ||
let operation = operations[i]; | ||
// TODO: test before | ||
if (options && options.before) { | ||
var result = options.before(updatedDocument, operation); | ||
const result = options.before(updatedDocument, operation); | ||
if (result !== undefined) { | ||
@@ -35,4 +35,4 @@ if (result.document !== undefined) { | ||
} | ||
var previousDocument = updatedDocument; | ||
var path = parsePath(updatedDocument, operation.path); | ||
const previousDocument = updatedDocument; | ||
const path = parsePath(updatedDocument, operation.path); | ||
if (operation.op === 'add') { | ||
@@ -56,5 +56,5 @@ updatedDocument = add(updatedDocument, path, operation.value); | ||
if (options && options.after) { | ||
var _result = options.after(updatedDocument, operation, previousDocument); | ||
if (_result !== undefined) { | ||
updatedDocument = _result; | ||
const result = options.after(updatedDocument, operation, previousDocument); | ||
if (result !== undefined) { | ||
updatedDocument = result; | ||
} | ||
@@ -95,8 +95,8 @@ } | ||
export function copy(document, path, from) { | ||
var value = getIn(document, from); | ||
const value = getIn(document, from); | ||
if (isArrayItem(document, path)) { | ||
return insertAt(document, path, value); | ||
} else { | ||
var _value = getIn(document, from); | ||
return setIn(document, path, _value); | ||
const value = getIn(document, from); | ||
return setIn(document, path, value); | ||
} | ||
@@ -109,6 +109,6 @@ } | ||
export function move(document, path, from) { | ||
var value = getIn(document, from); | ||
const value = getIn(document, from); | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
var removedJson = deleteIn(document, from); | ||
const removedJson = deleteIn(document, from); | ||
return isArrayItem(removedJson, path) ? insertAt(removedJson, path, value) : setIn(removedJson, path, value); | ||
@@ -123,10 +123,10 @@ } | ||
if (value === undefined) { | ||
throw new Error("Test failed: no value provided (path: \"".concat(compileJSONPointer(path), "\")")); | ||
throw new Error(`Test failed: no value provided (path: "${compileJSONPointer(path)}")`); | ||
} | ||
if (!existsIn(document, path)) { | ||
throw new Error("Test failed: path not found (path: \"".concat(compileJSONPointer(path), "\")")); | ||
throw new Error(`Test failed: path not found (path: "${compileJSONPointer(path)}")`); | ||
} | ||
var actualValue = getIn(document, path); | ||
const actualValue = getIn(document, path); | ||
if (!isEqual(actualValue, value)) { | ||
throw new Error("Test failed, value differs (path: \"".concat(compileJSONPointer(path), "\")")); | ||
throw new Error(`Test failed, value differs (path: "${compileJSONPointer(path)}")`); | ||
} | ||
@@ -138,3 +138,3 @@ } | ||
} | ||
var parent = getIn(document, initial(path)); | ||
const parent = getIn(document, initial(path)); | ||
return Array.isArray(parent); | ||
@@ -151,4 +151,4 @@ } | ||
} | ||
var parentPath = initial(path); | ||
var parent = getIn(document, parentPath); | ||
const parentPath = initial(path); | ||
const parent = getIn(document, parentPath); | ||
@@ -166,3 +166,3 @@ // eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// TODO: write unit tests | ||
var ops = ['add', 'remove', 'replace', 'copy', 'move', 'test']; | ||
const ops = ['add', 'remove', 'replace', 'copy', 'move', 'test']; | ||
if (!ops.includes(operation.op)) { | ||
@@ -169,0 +169,0 @@ throw new Error('Unknown JSONPatch op ' + JSON.stringify(operation.op)); |
@@ -5,8 +5,6 @@ /** | ||
export function parseJSONPointer(pointer) { | ||
var path = pointer.split('/'); | ||
const path = pointer.split('/'); | ||
path.shift(); // remove the first empty entry | ||
return path.map(function (p) { | ||
return p.replace(/~1/g, '/').replace(/~0/g, '~'); | ||
}); | ||
return path.map(p => p.replace(/~1/g, '/').replace(/~0/g, '~')); | ||
} | ||
@@ -13,0 +11,0 @@ |
@@ -1,7 +0,1 @@ | ||
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } | ||
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } | ||
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } | ||
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } | ||
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } | ||
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } | ||
import { existsIn, getIn } from './immutabilityHelpers.js'; | ||
@@ -20,45 +14,46 @@ import { immutableJSONPatch, isArrayItem, parseFrom, parsePath } from './immutableJSONPatch.js'; | ||
export function revertJSONPatch(document, operations, options) { | ||
var allRevertOperations = []; | ||
immutableJSONPatch(document, operations, { | ||
before: function before(document, operation) { | ||
var revertOperations; | ||
var path = 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, parseFrom(operation.from)); | ||
} else if (operation.op === 'test') { | ||
revertOperations = []; | ||
} else { | ||
throw new Error('Unknown JSONPatch operation ' + JSON.stringify(operation)); | ||
let allRevertOperations = []; | ||
const before = (document, operation) => { | ||
let revertOperations; | ||
const path = 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, parseFrom(operation.from)); | ||
} else if (operation.op === 'test') { | ||
revertOperations = []; | ||
} else { | ||
throw new Error('Unknown JSONPatch operation ' + JSON.stringify(operation)); | ||
} | ||
let updatedJson; | ||
if (options && options.before) { | ||
const res = options.before(document, operation, revertOperations); | ||
if (res && res.revertOperations) { | ||
revertOperations = res.revertOperations; | ||
} | ||
var updatedJson; | ||
if (options && options.before) { | ||
var res = options.before(document, operation, revertOperations); | ||
if (res && res.revertOperations) { | ||
revertOperations = res.revertOperations; | ||
} | ||
if (res && res.document) { | ||
updatedJson = res.document; | ||
} | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
if (res && 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"'); | ||
} | ||
if (res && res.document) { | ||
updatedJson = res.document; | ||
} | ||
allRevertOperations = revertOperations.concat(allRevertOperations); | ||
if (updatedJson !== undefined) { | ||
return { | ||
document: updatedJson | ||
}; | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
if (res && 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 | ||
}; | ||
} | ||
}; | ||
immutableJSONPatch(document, operations, { | ||
before | ||
}); | ||
@@ -103,3 +98,3 @@ return allRevertOperations; | ||
} | ||
var move = { | ||
const move = { | ||
op: 'move', | ||
@@ -111,3 +106,3 @@ from: compileJSONPointer(path), | ||
// the move replaces an existing value in an object | ||
return [move].concat(_toConsumableArray(revertRemove(document, path))); | ||
return [move, ...revertRemove(document, path)]; | ||
} else { | ||
@@ -114,0 +109,0 @@ return [move]; |
@@ -1,2 +0,1 @@ | ||
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } | ||
export function isJSONArray(value) { | ||
@@ -6,10 +5,9 @@ return Array.isArray(value); | ||
export function isJSONObject(value) { | ||
return value !== null && _typeof(value) === 'object' && value.constructor === Object // do not match on classes or Array | ||
return value !== null && typeof value === 'object' && value.constructor === Object // do not match on classes or Array | ||
; | ||
} | ||
export function isJSONPatchOperation(value) { | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
return value && _typeof(value) === 'object' ? typeof value.op === 'string' : false; | ||
return value && typeof value === 'object' ? typeof value.op === 'string' : false; | ||
} | ||
@@ -19,3 +17,3 @@ export function isJSONPatchAdd(value) { | ||
// @ts-ignore | ||
return value && _typeof(value) === 'object' ? value.op === 'add' : false; | ||
return value && typeof value === 'object' ? value.op === 'add' : false; | ||
} | ||
@@ -25,3 +23,3 @@ export function isJSONPatchRemove(value) { | ||
// @ts-ignore | ||
return value && _typeof(value) === 'object' ? value.op === 'remove' : false; | ||
return value && typeof value === 'object' ? value.op === 'remove' : false; | ||
} | ||
@@ -31,3 +29,3 @@ export function isJSONPatchReplace(value) { | ||
// @ts-ignore | ||
return value && _typeof(value) === 'object' ? value.op === 'replace' : false; | ||
return value && typeof value === 'object' ? value.op === 'replace' : false; | ||
} | ||
@@ -37,3 +35,3 @@ export function isJSONPatchCopy(value) { | ||
// @ts-ignore | ||
return value && _typeof(value) === 'object' ? value.op === 'copy' : false; | ||
return value && typeof value === 'object' ? value.op === 'copy' : false; | ||
} | ||
@@ -43,3 +41,3 @@ export function isJSONPatchMove(value) { | ||
// @ts-ignore | ||
return value && _typeof(value) === 'object' ? value.op === 'move' : false; | ||
return value && typeof value === 'object' ? value.op === 'move' : false; | ||
} | ||
@@ -49,4 +47,4 @@ export function isJSONPatchTest(value) { | ||
// @ts-ignore | ||
return value && _typeof(value) === 'object' ? value.op === 'test' : false; | ||
return value && typeof value === 'object' ? value.op === 'test' : false; | ||
} | ||
//# sourceMappingURL=typeguards.js.map |
@@ -1,5 +0,5 @@ | ||
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } | ||
/** | ||
* Test deep equality of two JSON values, objects, or arrays | ||
*/ // TODO: write unit tests | ||
*/ | ||
// TODO: write unit tests | ||
export function isEqual(a, b) { | ||
@@ -41,7 +41,7 @@ // FIXME: this function will return false for two objects with the same keys | ||
export function startsWith(array1, array2) { | ||
var isEqual = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : strictEqual; | ||
let isEqual = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : strictEqual; | ||
if (array1.length < array2.length) { | ||
return false; | ||
} | ||
for (var i = 0; i < array2.length; i++) { | ||
for (let i = 0; i < array2.length; i++) { | ||
if (!isEqual(array1[i], array2[i])) { | ||
@@ -59,4 +59,4 @@ return false; | ||
export function isObjectOrArray(value) { | ||
return _typeof(value) === 'object' && value !== null; | ||
return typeof value === 'object' && value !== null; | ||
} | ||
//# sourceMappingURL=utils.js.map |
@@ -1,2 +0,2 @@ | ||
import type { JSONArray, JSONValue, JSONObject, JSONPath } from './types'; | ||
import type { JSONPath } from './types'; | ||
/** | ||
@@ -6,3 +6,3 @@ * Shallow clone of an Object, Array, or value | ||
*/ | ||
export declare function shallowClone<T extends JSONValue>(value: T): T; | ||
export declare function shallowClone<T>(value: T): T; | ||
/** | ||
@@ -12,3 +12,3 @@ * Update a value in an object in an immutable way. | ||
*/ | ||
export declare function applyProp<T extends JSONObject | JSONArray>(object: T, key: string | number, value: JSONValue): T; | ||
export declare function applyProp<T, U = unknown>(object: T, key: string | number, value: U): T; | ||
/** | ||
@@ -19,3 +19,3 @@ * helper function to get a nested property in an object or array | ||
*/ | ||
export declare function getIn(object: JSONValue, path: JSONPath): JSONValue | undefined; | ||
export declare function getIn<T, U = unknown>(object: U, path: JSONPath): T | undefined; | ||
/** | ||
@@ -37,3 +37,3 @@ * helper function to replace a nested property in an object with a new value | ||
*/ | ||
export declare function setIn(object: JSONValue, path: JSONPath, value: JSONValue, createPath?: boolean): JSONValue; | ||
export declare function setIn<T, U = unknown, V = unknown>(object: U, path: JSONPath, value: V, createPath?: boolean): T; | ||
/** | ||
@@ -45,3 +45,3 @@ * helper function to replace a nested property in an object with a new value | ||
*/ | ||
export declare function updateIn(object: JSONValue, path: JSONPath, callback: (value: JSONValue) => JSONValue): JSONValue; | ||
export declare function updateIn<T, U = unknown, V = unknown>(object: T, path: JSONPath, transform: (value: U) => V): T; | ||
/** | ||
@@ -53,3 +53,3 @@ * helper function to delete a nested property in an object | ||
*/ | ||
export declare function deleteIn<T extends JSONValue>(object: T, path: JSONPath): T; | ||
export declare function deleteIn<T, U = unknown>(object: U, path: JSONPath): T; | ||
/** | ||
@@ -61,3 +61,3 @@ * Insert a new item in an array at a specific index. | ||
*/ | ||
export declare function insertAt(document: JSONObject | JSONArray, path: JSONPath, value: JSONValue): JSONValue; | ||
export declare function insertAt<T, U = unknown>(document: T, path: JSONPath, value: U): T; | ||
/** | ||
@@ -67,3 +67,3 @@ * Transform a JSON object, traverse over the whole object, | ||
*/ | ||
export declare function transform(document: JSONValue, callback: (document: JSONValue, path: JSONPath) => JSONValue, path?: JSONPath): JSONValue; | ||
export declare function transform<T, U = unknown, V = unknown, W = unknown>(document: U, callback: (document: V, path: JSONPath) => W, path?: JSONPath): T; | ||
/** | ||
@@ -73,3 +73,3 @@ * Test whether a path exists in a JSON object | ||
*/ | ||
export declare function existsIn(document: JSONValue, path: JSONPath): boolean; | ||
export declare function existsIn<T>(document: T, path: JSONPath): boolean; | ||
//# sourceMappingURL=immutabilityHelpers.d.ts.map |
@@ -1,2 +0,2 @@ | ||
import { JSONArray, JSONValue, JSONObject, JSONPatchDocument, JSONPatchOperation, JSONPatchOptions, JSONPath, JSONPointer } from './types'; | ||
import { JSONPatchDocument, JSONPatchOperation, JSONPatchOptions, JSONPath, JSONPointer } from './types'; | ||
/** | ||
@@ -7,23 +7,23 @@ * Apply a patch to a JSON object | ||
*/ | ||
export declare function immutableJSONPatch(document: JSONValue, operations: JSONPatchDocument, options?: JSONPatchOptions): JSONValue; | ||
export declare function immutableJSONPatch<T, U = unknown>(document: U, operations: JSONPatchDocument, options?: JSONPatchOptions): T; | ||
/** | ||
* Replace an existing item | ||
*/ | ||
export declare function replace(document: JSONValue, path: JSONPath, value: JSONValue): JSONValue; | ||
export declare function replace<T, U, V>(document: U, path: JSONPath, value: V): T; | ||
/** | ||
* Remove an item or property | ||
*/ | ||
export declare function remove<T extends JSONArray | JSONObject>(document: T, path: JSONPath): T; | ||
export declare function remove<T, U>(document: U, path: JSONPath): T; | ||
/** | ||
* Add an item or property | ||
*/ | ||
export declare function add(document: JSONValue, path: JSONPath, value: JSONValue): JSONValue; | ||
export declare function add<T, U, V>(document: U, path: JSONPath, value: V): T; | ||
/** | ||
* Copy a value | ||
*/ | ||
export declare function copy(document: JSONValue, path: JSONPath, from: JSONPath): JSONValue; | ||
export declare function copy<T, U>(document: U, path: JSONPath, from: JSONPath): T; | ||
/** | ||
* Move a value | ||
*/ | ||
export declare function move(document: JSONValue, path: JSONPath, from: JSONPath): JSONValue; | ||
export declare function move<T, U>(document: U, path: JSONPath, from: JSONPath): T; | ||
/** | ||
@@ -33,4 +33,4 @@ * Test whether the data contains the provided value at the specified path. | ||
*/ | ||
export declare function test(document: JSONValue, path: JSONPath, value: JSONValue): void; | ||
export declare function isArrayItem(document: JSONValue, path: JSONPath): document is JSONArray; | ||
export declare function test<T, U>(document: T, path: JSONPath, value: U): void; | ||
export declare function isArrayItem(document: unknown, path: JSONPath): document is Array<unknown>; | ||
/** | ||
@@ -40,3 +40,3 @@ * Resolve the path index of an array, resolves indexes '-' | ||
*/ | ||
export declare function resolvePathIndex(document: JSONValue, path: JSONPath): JSONPath; | ||
export declare function resolvePathIndex<T>(document: T, path: JSONPath): JSONPath; | ||
/** | ||
@@ -47,4 +47,4 @@ * Validate a JSONPatch operation. | ||
export declare function validateJSONPatchOperation(operation: JSONPatchOperation): void; | ||
export declare function parsePath(document: JSONValue, pointer: JSONPointer): JSONPath; | ||
export declare function parsePath<T>(document: T, pointer: JSONPointer): JSONPath; | ||
export declare function parseFrom(fromPointer: JSONPointer): JSONPath; | ||
//# sourceMappingURL=immutableJSONPatch.d.ts.map |
@@ -1,2 +0,2 @@ | ||
import type { JSONValue, JSONPatchDocument, RevertJSONPatchOptions } from './types.js'; | ||
import { JSONPatchDocument, RevertJSONPatchOptions } from './types.js'; | ||
/** | ||
@@ -9,3 +9,3 @@ * Create the inverse of a set of json patch operations | ||
*/ | ||
export declare function revertJSONPatch(document: JSONValue, operations: JSONPatchDocument, options?: RevertJSONPatchOptions): JSONPatchDocument; | ||
export declare function revertJSONPatch<T, U>(document: T, operations: JSONPatchDocument, options?: RevertJSONPatchOptions): JSONPatchDocument; | ||
//# sourceMappingURL=revertJSONPatch.d.ts.map |
@@ -1,4 +0,4 @@ | ||
import { JSONArray, JSONObject, JSONPatchAdd, JSONPatchCopy, JSONPatchMove, JSONPatchOperation, JSONPatchRemove, JSONPatchReplace, JSONPatchTest } from './types'; | ||
export declare function isJSONArray(value: unknown): value is JSONArray; | ||
export declare function isJSONObject(value: unknown): value is JSONObject; | ||
import { JSONPatchAdd, JSONPatchCopy, JSONPatchMove, JSONPatchOperation, JSONPatchRemove, JSONPatchReplace, JSONPatchTest } from './types'; | ||
export declare function isJSONArray(value: unknown): value is Array<unknown>; | ||
export declare function isJSONObject(value: unknown): value is Record<string, unknown>; | ||
export declare function isJSONPatchOperation(value: unknown): value is JSONPatchOperation; | ||
@@ -5,0 +5,0 @@ export declare function isJSONPatchAdd(value: unknown): value is JSONPatchAdd; |
export type JSONPointer = string; | ||
export type JSONPath = string[]; | ||
export type JSONPrimitive = string | number | boolean | null; | ||
export type JSONValue = { | ||
[key: string]: JSONValue; | ||
} | JSONValue[] | JSONPrimitive; | ||
export type JSONObject = { | ||
[key: string]: JSONValue; | ||
}; | ||
export type JSONArray = JSONValue[]; | ||
/** | ||
* @deprecated JSONData has been renamed to JSONValue since v5.0.0 | ||
*/ | ||
export type JSONData = JSONValue; | ||
export interface JSONPatchAdd { | ||
op: 'add'; | ||
path: JSONPointer; | ||
value: JSONValue; | ||
value: unknown; | ||
} | ||
@@ -27,3 +15,3 @@ export interface JSONPatchRemove { | ||
path: JSONPointer; | ||
value: JSONValue; | ||
value: unknown; | ||
} | ||
@@ -43,19 +31,39 @@ export interface JSONPatchCopy { | ||
path: JSONPointer; | ||
value: JSONValue; | ||
value: unknown; | ||
} | ||
export type JSONPatchOperation = JSONPatchAdd | JSONPatchRemove | JSONPatchReplace | JSONPatchCopy | JSONPatchMove | JSONPatchTest; | ||
export type JSONPatchDocument = JSONPatchOperation[]; | ||
export type JSONPatchOptions = { | ||
before?: (document: JSONValue, operation: JSONPatchOperation) => { | ||
document?: JSONValue; | ||
export type JSONPatchOptions<T = unknown, U = unknown, V = unknown, W = unknown, X = unknown> = { | ||
before?: (document: T, operation: JSONPatchOperation) => { | ||
document?: U; | ||
operation?: JSONPatchOperation; | ||
}; | ||
after?: (document: JSONValue, operation: JSONPatchOperation, previousDocument: JSONValue) => JSONValue; | ||
after?: (document: V, operation: JSONPatchOperation, previousDocument: W) => X; | ||
}; | ||
export type RevertJSONPatchOptions = { | ||
before?: (document: JSONValue, operation: JSONPatchOperation, revertOperations: JSONPatchOperation[]) => { | ||
document?: JSONValue; | ||
export type RevertJSONPatchOptions<T = unknown, U = unknown> = { | ||
before?: (document: T, operation: JSONPatchOperation, revertOperations: JSONPatchOperation[]) => { | ||
document?: U; | ||
revertOperations?: JSONPatchOperation[]; | ||
}; | ||
}; | ||
/** | ||
* @deprecated use generics or `unknown` instead | ||
*/ | ||
export type JSONPrimitive = string | number | boolean | null; | ||
/** | ||
* @deprecated use generics or `unknown` instead | ||
*/ | ||
export type JSONValue = { | ||
[key: string]: JSONValue; | ||
} | JSONValue[] | JSONPrimitive; | ||
/** | ||
* @deprecated use generics or `unknown` instead | ||
*/ | ||
export type JSONObject = { | ||
[key: string]: JSONValue; | ||
}; | ||
/** | ||
* @deprecated use generics or `unknown` instead | ||
*/ | ||
export type JSONArray = JSONValue[]; | ||
//# sourceMappingURL=types.d.ts.map |
@@ -1,6 +0,5 @@ | ||
import type { JSONValue } from './types'; | ||
/** | ||
* Test deep equality of two JSON values, objects, or arrays | ||
*/ | ||
export declare function isEqual(a: JSONValue, b: JSONValue): boolean; | ||
export declare function isEqual<T, U>(a: T, b: U): boolean; | ||
/** | ||
@@ -7,0 +6,0 @@ * Test whether two values are strictly equal |
@@ -7,3 +7,2 @@ (function (global, factory) { | ||
function _typeof$2(obj) { "@babel/helpers - typeof"; return _typeof$2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof$2(obj); } | ||
function isJSONArray(value) { | ||
@@ -13,10 +12,9 @@ return Array.isArray(value); | ||
function isJSONObject(value) { | ||
return value !== null && _typeof$2(value) === 'object' && value.constructor === Object // do not match on classes or Array | ||
return value !== null && typeof value === 'object' && value.constructor === Object // do not match on classes or Array | ||
; | ||
} | ||
function isJSONPatchOperation(value) { | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
return value && _typeof$2(value) === 'object' ? typeof value.op === 'string' : false; | ||
return value && typeof value === 'object' ? typeof value.op === 'string' : false; | ||
} | ||
@@ -26,3 +24,3 @@ function isJSONPatchAdd(value) { | ||
// @ts-ignore | ||
return value && _typeof$2(value) === 'object' ? value.op === 'add' : false; | ||
return value && typeof value === 'object' ? value.op === 'add' : false; | ||
} | ||
@@ -32,3 +30,3 @@ function isJSONPatchRemove(value) { | ||
// @ts-ignore | ||
return value && _typeof$2(value) === 'object' ? value.op === 'remove' : false; | ||
return value && typeof value === 'object' ? value.op === 'remove' : false; | ||
} | ||
@@ -38,3 +36,3 @@ function isJSONPatchReplace(value) { | ||
// @ts-ignore | ||
return value && _typeof$2(value) === 'object' ? value.op === 'replace' : false; | ||
return value && typeof value === 'object' ? value.op === 'replace' : false; | ||
} | ||
@@ -44,3 +42,3 @@ function isJSONPatchCopy(value) { | ||
// @ts-ignore | ||
return value && _typeof$2(value) === 'object' ? value.op === 'copy' : false; | ||
return value && typeof value === 'object' ? value.op === 'copy' : false; | ||
} | ||
@@ -50,3 +48,3 @@ function isJSONPatchMove(value) { | ||
// @ts-ignore | ||
return value && _typeof$2(value) === 'object' ? value.op === 'move' : false; | ||
return value && typeof value === 'object' ? value.op === 'move' : false; | ||
} | ||
@@ -56,9 +54,9 @@ function isJSONPatchTest(value) { | ||
// @ts-ignore | ||
return value && _typeof$2(value) === 'object' ? value.op === 'test' : false; | ||
return value && typeof value === 'object' ? value.op === 'test' : false; | ||
} | ||
function _typeof$1(obj) { "@babel/helpers - typeof"; return _typeof$1 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof$1(obj); } | ||
/** | ||
* Test deep equality of two JSON values, objects, or arrays | ||
*/ // TODO: write unit tests | ||
*/ | ||
// TODO: write unit tests | ||
function isEqual(a, b) { | ||
@@ -100,7 +98,7 @@ // FIXME: this function will return false for two objects with the same keys | ||
function startsWith(array1, array2) { | ||
var isEqual = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : strictEqual; | ||
let isEqual = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : strictEqual; | ||
if (array1.length < array2.length) { | ||
return false; | ||
} | ||
for (var i = 0; i < array2.length; i++) { | ||
for (let i = 0; i < array2.length; i++) { | ||
if (!isEqual(array1[i], array2[i])) { | ||
@@ -118,11 +116,15 @@ return false; | ||
function isObjectOrArray(value) { | ||
return _typeof$1(value) === 'object' && value !== null; | ||
return typeof value === 'object' && value !== null; | ||
} | ||
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } | ||
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } | ||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } | ||
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } | ||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } | ||
/** | ||
* Immutability helpers | ||
* | ||
* inspiration: | ||
* | ||
* https://www.npmjs.com/package/seamless-immutable | ||
* https://www.npmjs.com/package/ih | ||
* https://www.npmjs.com/package/mutatis | ||
* https://github.com/mariocasciaro/object-path-immutable | ||
*/ | ||
@@ -136,6 +138,6 @@ /** | ||
// copy array items | ||
var copy = value.slice(); | ||
const copy = value.slice(); | ||
// copy all symbols | ||
Object.getOwnPropertySymbols(value).forEach(function (symbol) { | ||
Object.getOwnPropertySymbols(value).forEach(symbol => { | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
@@ -148,11 +150,13 @@ // @ts-ignore | ||
// copy object properties | ||
var _copy = _objectSpread({}, value); | ||
const copy = { | ||
...value | ||
}; | ||
// copy all symbols | ||
Object.getOwnPropertySymbols(value).forEach(function (symbol) { | ||
Object.getOwnPropertySymbols(value).forEach(symbol => { | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
_copy[symbol] = value[symbol]; | ||
copy[symbol] = value[symbol]; | ||
}); | ||
return _copy; | ||
return copy; | ||
} else { | ||
@@ -174,3 +178,3 @@ return value; | ||
} else { | ||
var updatedObject = shallowClone(object); | ||
const updatedObject = shallowClone(object); | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
@@ -189,4 +193,4 @@ // @ts-ignore | ||
function getIn(object, path) { | ||
var value = object; | ||
var i = 0; | ||
let value = object; | ||
let i = 0; | ||
while (i < path.length) { | ||
@@ -222,10 +226,10 @@ if (isJSONObject(value)) { | ||
function setIn(object, path, value) { | ||
var createPath = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; | ||
let createPath = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; | ||
if (path.length === 0) { | ||
return value; | ||
} | ||
var key = path[0]; | ||
const key = path[0]; | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
var updatedValue = setIn(object ? object[key] : undefined, path.slice(1), value, createPath); | ||
const updatedValue = setIn(object ? object[key] : undefined, path.slice(1), value, createPath); | ||
if (isJSONObject(object) || isJSONArray(object)) { | ||
@@ -235,3 +239,3 @@ return applyProp(object, key, updatedValue); | ||
if (createPath) { | ||
var newObject = IS_INTEGER_REGEX.test(key) ? [] : {}; | ||
const newObject = IS_INTEGER_REGEX.test(key) ? [] : {}; | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
@@ -246,3 +250,3 @@ // @ts-ignore | ||
} | ||
var IS_INTEGER_REGEX = /^\d+$/; | ||
const IS_INTEGER_REGEX = /^\d+$/; | ||
@@ -255,5 +259,5 @@ /** | ||
*/ | ||
function updateIn(object, path, callback) { | ||
function updateIn(object, path, transform) { | ||
if (path.length === 0) { | ||
return callback(object); | ||
return transform(object); | ||
} | ||
@@ -263,6 +267,6 @@ if (!isObjectOrArray(object)) { | ||
} | ||
var key = path[0]; | ||
const key = path[0]; | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
var updatedValue = updateIn(object[key], path.slice(1), callback); | ||
const updatedValue = updateIn(object[key], path.slice(1), transform); | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
@@ -287,13 +291,13 @@ // @ts-ignore | ||
if (path.length === 1) { | ||
var _key = path[0]; | ||
if (!(_key in object)) { | ||
const key = path[0]; | ||
if (!(key in object)) { | ||
// key doesn't exist. return object unchanged | ||
return object; | ||
} else { | ||
var updatedObject = shallowClone(object); | ||
const updatedObject = shallowClone(object); | ||
if (isJSONArray(updatedObject)) { | ||
updatedObject.splice(parseInt(_key), 1); | ||
updatedObject.splice(parseInt(key), 1); | ||
} | ||
if (isJSONObject(updatedObject)) { | ||
delete updatedObject[_key]; | ||
delete updatedObject[key]; | ||
} | ||
@@ -303,6 +307,6 @@ return updatedObject; | ||
} | ||
var key = path[0]; | ||
const key = path[0]; | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
var updatedValue = deleteIn(object[key], path.slice(1)); | ||
const updatedValue = deleteIn(object[key], path.slice(1)); | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
@@ -320,9 +324,9 @@ // @ts-ignore | ||
function insertAt(document, path, value) { | ||
var parentPath = path.slice(0, path.length - 1); | ||
var index = path[path.length - 1]; | ||
return updateIn(document, parentPath, function (items) { | ||
const parentPath = path.slice(0, path.length - 1); | ||
const index = path[path.length - 1]; | ||
return updateIn(document, parentPath, items => { | ||
if (!Array.isArray(items)) { | ||
throw new TypeError('Array expected at path ' + JSON.stringify(parentPath)); | ||
} | ||
var updatedItems = shallowClone(items); | ||
const updatedItems = shallowClone(items); | ||
updatedItems.splice(parseInt(index), 0, value); | ||
@@ -338,13 +342,14 @@ return updatedItems; | ||
function transform(document, callback) { | ||
var path = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; | ||
var updated1 = callback(document, path); | ||
let path = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; | ||
// eslint-disable-next-line n/no-callback-literal | ||
const updated1 = callback(document, path); | ||
if (isJSONArray(updated1)) { | ||
// array | ||
var updated2; | ||
for (var i = 0; i < updated1.length; i++) { | ||
var before = updated1[i]; | ||
let updated2; | ||
for (let i = 0; i < updated1.length; i++) { | ||
const before = updated1[i]; | ||
// we stringify the index here, so the path only contains strings and can be safely | ||
// stringified/parsed to JSONPointer without loosing information. | ||
// We do not want to rely on path keys being numeric/string. | ||
var after = transform(before, callback, path.concat(i + '')); | ||
const after = transform(before, callback, path.concat(i + '')); | ||
if (after !== before) { | ||
@@ -360,16 +365,16 @@ if (!updated2) { | ||
// object | ||
var _updated; | ||
for (var key in updated1) { | ||
let updated2; | ||
for (const key in updated1) { | ||
if (Object.hasOwnProperty.call(updated1, key)) { | ||
var _before = updated1[key]; | ||
var _after = transform(_before, callback, path.concat(key)); | ||
if (_after !== _before) { | ||
if (!_updated) { | ||
_updated = shallowClone(updated1); | ||
const before = updated1[key]; | ||
const after = transform(before, callback, path.concat(key)); | ||
if (after !== before) { | ||
if (!updated2) { | ||
updated2 = shallowClone(updated1); | ||
} | ||
_updated[key] = _after; | ||
updated2[key] = after; | ||
} | ||
} | ||
} | ||
return _updated || updated1; | ||
return updated2 || updated1; | ||
} else { | ||
@@ -405,8 +410,6 @@ // number, string, boolean, null | ||
function parseJSONPointer(pointer) { | ||
var path = pointer.split('/'); | ||
const path = pointer.split('/'); | ||
path.shift(); // remove the first empty entry | ||
return path.map(function (p) { | ||
return p.replace(/~1/g, '/').replace(/~0/g, '~'); | ||
}); | ||
return path.map(p => p.replace(/~1/g, '/').replace(/~0/g, '~')); | ||
} | ||
@@ -448,10 +451,10 @@ | ||
function immutableJSONPatch(document, operations, options) { | ||
var updatedDocument = document; | ||
for (var i = 0; i < operations.length; i++) { | ||
let updatedDocument = document; | ||
for (let i = 0; i < operations.length; i++) { | ||
validateJSONPatchOperation(operations[i]); | ||
var operation = operations[i]; | ||
let operation = operations[i]; | ||
// TODO: test before | ||
if (options && options.before) { | ||
var result = options.before(updatedDocument, operation); | ||
const result = options.before(updatedDocument, operation); | ||
if (result !== undefined) { | ||
@@ -472,4 +475,4 @@ if (result.document !== undefined) { | ||
} | ||
var previousDocument = updatedDocument; | ||
var path = parsePath(updatedDocument, operation.path); | ||
const previousDocument = updatedDocument; | ||
const path = parsePath(updatedDocument, operation.path); | ||
if (operation.op === 'add') { | ||
@@ -493,5 +496,5 @@ updatedDocument = add(updatedDocument, path, operation.value); | ||
if (options && options.after) { | ||
var _result = options.after(updatedDocument, operation, previousDocument); | ||
if (_result !== undefined) { | ||
updatedDocument = _result; | ||
const result = options.after(updatedDocument, operation, previousDocument); | ||
if (result !== undefined) { | ||
updatedDocument = result; | ||
} | ||
@@ -532,8 +535,8 @@ } | ||
function copy(document, path, from) { | ||
var value = getIn(document, from); | ||
const value = getIn(document, from); | ||
if (isArrayItem(document, path)) { | ||
return insertAt(document, path, value); | ||
} else { | ||
var _value = getIn(document, from); | ||
return setIn(document, path, _value); | ||
const value = getIn(document, from); | ||
return setIn(document, path, value); | ||
} | ||
@@ -546,6 +549,6 @@ } | ||
function move(document, path, from) { | ||
var value = getIn(document, from); | ||
const value = getIn(document, from); | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
var removedJson = deleteIn(document, from); | ||
const removedJson = deleteIn(document, from); | ||
return isArrayItem(removedJson, path) ? insertAt(removedJson, path, value) : setIn(removedJson, path, value); | ||
@@ -560,10 +563,10 @@ } | ||
if (value === undefined) { | ||
throw new Error("Test failed: no value provided (path: \"".concat(compileJSONPointer(path), "\")")); | ||
throw new Error(`Test failed: no value provided (path: "${compileJSONPointer(path)}")`); | ||
} | ||
if (!existsIn(document, path)) { | ||
throw new Error("Test failed: path not found (path: \"".concat(compileJSONPointer(path), "\")")); | ||
throw new Error(`Test failed: path not found (path: "${compileJSONPointer(path)}")`); | ||
} | ||
var actualValue = getIn(document, path); | ||
const actualValue = getIn(document, path); | ||
if (!isEqual(actualValue, value)) { | ||
throw new Error("Test failed, value differs (path: \"".concat(compileJSONPointer(path), "\")")); | ||
throw new Error(`Test failed, value differs (path: "${compileJSONPointer(path)}")`); | ||
} | ||
@@ -575,3 +578,3 @@ } | ||
} | ||
var parent = getIn(document, initial(path)); | ||
const parent = getIn(document, initial(path)); | ||
return Array.isArray(parent); | ||
@@ -588,4 +591,4 @@ } | ||
} | ||
var parentPath = initial(path); | ||
var parent = getIn(document, parentPath); | ||
const parentPath = initial(path); | ||
const parent = getIn(document, parentPath); | ||
@@ -603,3 +606,3 @@ // eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// TODO: write unit tests | ||
var ops = ['add', 'remove', 'replace', 'copy', 'move', 'test']; | ||
const ops = ['add', 'remove', 'replace', 'copy', 'move', 'test']; | ||
if (!ops.includes(operation.op)) { | ||
@@ -624,9 +627,2 @@ throw new Error('Unknown JSONPatch op ' + JSON.stringify(operation.op)); | ||
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } | ||
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } | ||
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } | ||
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } | ||
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } | ||
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } | ||
/** | ||
@@ -640,45 +636,46 @@ * Create the inverse of a set of json patch operations | ||
function revertJSONPatch(document, operations, options) { | ||
var allRevertOperations = []; | ||
immutableJSONPatch(document, operations, { | ||
before: function before(document, operation) { | ||
var revertOperations; | ||
var path = 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, parseFrom(operation.from)); | ||
} else if (operation.op === 'test') { | ||
revertOperations = []; | ||
} else { | ||
throw new Error('Unknown JSONPatch operation ' + JSON.stringify(operation)); | ||
let allRevertOperations = []; | ||
const before = (document, operation) => { | ||
let revertOperations; | ||
const path = 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, parseFrom(operation.from)); | ||
} else if (operation.op === 'test') { | ||
revertOperations = []; | ||
} else { | ||
throw new Error('Unknown JSONPatch operation ' + JSON.stringify(operation)); | ||
} | ||
let updatedJson; | ||
if (options && options.before) { | ||
const res = options.before(document, operation, revertOperations); | ||
if (res && res.revertOperations) { | ||
revertOperations = res.revertOperations; | ||
} | ||
var updatedJson; | ||
if (options && options.before) { | ||
var res = options.before(document, operation, revertOperations); | ||
if (res && res.revertOperations) { | ||
revertOperations = res.revertOperations; | ||
} | ||
if (res && res.document) { | ||
updatedJson = res.document; | ||
} | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
if (res && 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"'); | ||
} | ||
if (res && res.document) { | ||
updatedJson = res.document; | ||
} | ||
allRevertOperations = revertOperations.concat(allRevertOperations); | ||
if (updatedJson !== undefined) { | ||
return { | ||
document: updatedJson | ||
}; | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
if (res && 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 | ||
}; | ||
} | ||
}; | ||
immutableJSONPatch(document, operations, { | ||
before | ||
}); | ||
@@ -723,3 +720,3 @@ return allRevertOperations; | ||
} | ||
var move = { | ||
const move = { | ||
op: 'move', | ||
@@ -731,3 +728,3 @@ from: compileJSONPointer(path), | ||
// the move replaces an existing value in an object | ||
return [move].concat(_toConsumableArray(revertRemove(document, path))); | ||
return [move, ...revertRemove(document, path)]; | ||
} else { | ||
@@ -734,0 +731,0 @@ return [move]; |
@@ -1,1 +0,1 @@ | ||
!function(t,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):r((t="undefined"!=typeof globalThis?globalThis:t||self).immutableJSONPatch={})}(this,function(t){"use strict";function r(t){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function y(t){return Array.isArray(t)}function h(t){return null!==t&&"object"===r(t)&&t.constructor===Object}function e(t){return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function u(t,r){return t===r}function n(t){return t.slice(0,t.length-1)}function o(t){return"object"===e(t)&&null!==t}function i(t){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function c(r,t){var e,n=Object.keys(r);return Object.getOwnPropertySymbols&&(e=Object.getOwnPropertySymbols(r),t&&(e=e.filter(function(t){return Object.getOwnPropertyDescriptor(r,t).enumerable})),n.push.apply(n,e)),n}function f(n){for(var t=1;t<arguments.length;t++){var o=null!=arguments[t]?arguments[t]:{};t%2?c(Object(o),!0).forEach(function(t){var r,e;r=n,e=o[t=t],(t=function(t){t=function(t,r){if("object"!==i(t)||null===t)return t;var e=t[Symbol.toPrimitive];if(void 0===e)return("string"===r?String:Number)(t);e=e.call(t,r||"default");if("object"!==i(e))return e;throw new TypeError("@@toPrimitive must return a primitive value.")}(t,"string");return"symbol"===i(t)?t:String(t)}(t))in r?Object.defineProperty(r,t,{value:e,enumerable:!0,configurable:!0,writable:!0}):r[t]=e}):Object.getOwnPropertyDescriptors?Object.defineProperties(n,Object.getOwnPropertyDescriptors(o)):c(Object(o)).forEach(function(t){Object.defineProperty(n,t,Object.getOwnPropertyDescriptor(o,t))})}return n}function m(r){var e,n;return y(r)?(e=r.slice(),Object.getOwnPropertySymbols(r).forEach(function(t){e[t]=r[t]}),e):h(r)?(n=f({},r),Object.getOwnPropertySymbols(r).forEach(function(t){n[t]=r[t]}),n):r}function a(t,r,e){return t[r]===e?t:((t=m(t))[r]=e,t)}function d(t,r){for(var e=t,n=0;n<r.length;)e=h(e)?e[r[n]]:y(e)?e[parseInt(r[n])]:void 0,n++;return e}function v(t,r,e){var n=3<arguments.length&&void 0!==arguments[3]&&arguments[3];if(0===r.length)return e;var o=r[0],r=v(t?t[o]:void 0,r.slice(1),e,n);if(h(t)||y(t))return a(t,o,r);if(n)return(e=p.test(o)?[]:{})[o]=r,e;throw new Error("Path does not exist")}var p=/^\d+$/;function l(t,r,e){if(0===r.length)return e(t);var n;if(o(t))return a(t,n=r[0],l(t[n],r.slice(1),e));throw new Error("Path doesn't exist")}function g(t,r){if(0===r.length)return t;var e,n;if(o(t))return 1===r.length?(n=r[0])in t?(y(e=m(t))&&e.splice(parseInt(n),1),h(e)&&delete e[n],e):t:a(t,n=r[0],g(t[n],r.slice(1)));throw new Error("Path does not exist")}function O(t,r,e){var n=r.slice(0,r.length-1),o=r[r.length-1];return l(t,n,function(t){if(Array.isArray(t))return(t=m(t)).splice(parseInt(o),0,e),t;throw new TypeError("Array expected at path "+JSON.stringify(n))})}function S(t,r){return void 0!==t&&(0===r.length||null!==t&&S(t[r[0]],r.slice(1)))}function s(t){t=t.split("/");return t.shift(),t.map(function(t){return t.replace(/~1/g,"/").replace(/~0/g,"~")})}function w(t){return t.map(b).join("")}function b(t){return"/"+String(t).replace(/~/g,"~0").replace(/\//g,"~1")}function j(t,r,e){for(var n,o,i,c,u,f,a=t,p=0;p<r.length;p++){l=void 0;var l=r[p];if(!["add","remove","replace","copy","move","test"].includes(l.op))throw new Error("Unknown JSONPatch op "+JSON.stringify(l.op));if("string"!=typeof l.path)throw new Error('Required property "path" missing or not a string in operation '+JSON.stringify(l));if(("copy"===l.op||"move"===l.op)&&"string"!=typeof l.from)throw new Error('Required property "from" missing or not a string in operation '+JSON.stringify(l));l=r[p];if(e&&e.before){var s=e.before(a,l);if(void 0!==s){if(void 0!==s.document&&(a=s.document),void 0!==s.json)throw new Error('Deprecation warning: returned object property ".json" has been renamed to ".document"');void 0!==s.operation&&(l=s.operation)}}var s=a,y=N(a,l.path);if("add"===l.op)c=a,u=y,f=l.value,a=(P(c,u)?O:v)(c,u,f);else if("remove"===l.op)a=g(a,y);else if("replace"===l.op)c=a,u=l.value,a=v(c,y,u);else if("copy"===l.op)f=a,n=y,o=J(l.from),i=void 0,i=d(f,o),a=P(f,n)?O(f,n,i):(i=d(f,o),v(f,n,i));else if("move"===l.op)o=a,n=y,i=J(l.from),h=void 0,h=d(o,i),a=(P(o=g(o,i),n)?O:v)(o,n,h);else{if("test"!==l.op)throw new Error("Unknown JSONPatch operation "+JSON.stringify(l));b=m=h=void 0;var h=a,m=y,b=l.value;if(void 0===b)throw new Error('Test failed: no value provided (path: "'.concat(w(m),'")'));if(!S(h,m))throw new Error('Test failed: path not found (path: "'.concat(w(m),'")'));if(!function(t,r){return JSON.stringify(t)===JSON.stringify(r)}(d(h,m),b))throw new Error('Test failed, value differs (path: "'.concat(w(m),'")'))}e&&e.after&&void 0!==(y=e.after(a,l,s))&&(a=y)}return a}function P(t,r){if(0!==r.length)return t=d(t,n(r)),Array.isArray(t)}function N(t,r){return t=t,"-"!==(r=s(r))[r.length-1]?r:(r=d(t,t=n(r)),t.concat(r.length))}function J(t){return s(t)}function E(t){return function(t){if(Array.isArray(t))return A(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,r){var e;if(t)return"string"==typeof t?A(t,r):"Map"===(e="Object"===(e=Object.prototype.toString.call(t).slice(8,-1))&&t.constructor?t.constructor.name:e)||"Set"===e?Array.from(t):"Arguments"===e||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)?A(t,r):void 0}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function A(t,r){(null==r||r>t.length)&&(r=t.length);for(var e=0,n=new Array(r);e<r;e++)n[e]=t[e];return n}function I(t,r){return[{op:"replace",path:w(r),value:d(t,r)}]}function T(t,r){return[{op:"add",path:w(r),value:d(t,r)}]}function x(t,r){return P(t,r)||!S(t,r)?[{op:"remove",path:w(r)}]:I(t,r)}t.appendToJSONPointer=function(t,r){return t+b(r)},t.compileJSONPointer=w,t.compileJSONPointerProp=b,t.deleteIn=g,t.existsIn=S,t.getIn=d,t.immutableJSONPatch=j,t.insertAt=O,t.isJSONArray=y,t.isJSONObject=h,t.isJSONPatchAdd=function(t){return!(!t||"object"!==r(t))&&"add"===t.op},t.isJSONPatchCopy=function(t){return!(!t||"object"!==r(t))&&"copy"===t.op},t.isJSONPatchMove=function(t){return!(!t||"object"!==r(t))&&"move"===t.op},t.isJSONPatchOperation=function(t){return!(!t||"object"!==r(t))&&"string"==typeof t.op},t.isJSONPatchRemove=function(t){return!(!t||"object"!==r(t))&&"remove"===t.op},t.isJSONPatchReplace=function(t){return!(!t||"object"!==r(t))&&"replace"===t.op},t.isJSONPatchTest=function(t){return!(!t||"object"!==r(t))&&"test"===t.op},t.parseFrom=J,t.parseJSONPointer=s,t.parsePath=N,t.revertJSONPatch=function(t,r,i){var c=[];return j(t,r,{before:function(t,r){var e,n,o=N(t,r.path);if("add"===r.op)e=x(t,o);else if("remove"===r.op)e=T(t,o);else if("replace"===r.op)e=I(t,o);else if("copy"===r.op)e=x(t,o);else if("move"===r.op)e=function(t,r,e){if(r.length<e.length&&function(t,r,e){var n=2<arguments.length&&void 0!==e?e:u;if(!(t.length<r.length)){for(var o=0;o<r.length;o++)if(!n(t[o],r[o]))return;return 1}}(e,r))return[{op:"replace",path:w(r),value:t}];e={op:"move",from:w(r),path:w(e)};return!P(t,r)&&S(t,r)?[e].concat(E(T(t,r))):[e]}(t,o,J(r.from));else{if("test"!==r.op)throw new Error("Unknown JSONPatch operation "+JSON.stringify(r));e=[]}if(i&&i.before){o=i.before(t,r,e);if(o&&o.revertOperations&&(e=o.revertOperations),o&&o.document&&(n=o.document),o&&o.json)throw new Error('Deprecation warning: returned object property ".json" has been renamed to ".document"')}if(c=e.concat(c),void 0!==n)return{document:n}}}),c},t.setIn=v,t.startsWithJSONPointer=function(t,r){return t.startsWith(r)&&(t.length===r.length||"/"===t[r.length])},t.transform=function t(r,e){var n,o,i,c,u=2<arguments.length&&void 0!==arguments[2]?arguments[2]:[],f=e(r,u);if(y(f)){for(var a,p=0;p<f.length;p++){var l=f[p],s=t(l,e,u.concat(p+""));s!==l&&((a=a||m(f))[p]=s)}return a||f}if(h(f)){for(o in f)Object.hasOwnProperty.call(f,o)&&(c=t(i=f[o],e,u.concat(o)))!==i&&((n=n||m(f))[o]=c);return n||f}return f},t.updateIn=l}); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).immutableJSONPatch={})}(this,function(e){"use strict";function p(e){return Array.isArray(e)}function s(e){return null!==e&&"object"==typeof e&&e.constructor===Object}function c(e,t){return e===t}function r(e){return e.slice(0,e.length-1)}function o(e){return"object"==typeof e&&null!==e}function l(t){if(p(t)){const r=t.slice();return Object.getOwnPropertySymbols(t).forEach(e=>{r[e]=t[e]}),r}if(s(t)){const n={...t};return Object.getOwnPropertySymbols(t).forEach(e=>{n[e]=t[e]}),n}return t}function i(e,t,r){return e[t]===r?e:((e=l(e))[t]=r,e)}function h(e,t){let r=e,n=0;for(;n<t.length;)r=s(r)?r[t[n]]:p(r)?r[parseInt(t[n])]:void 0,n++;return r}function d(e,t,r){var n=3<arguments.length&&void 0!==arguments[3]&&arguments[3];if(0===t.length)return r;var o=t[0],t=d(e?e[o]:void 0,t.slice(1),r,n);if(s(e)||p(e))return i(e,o,t);if(n)return(r=f.test(o)?[]:{})[o]=t,r;throw new Error("Path does not exist")}const f=/^\d+$/;function a(e,t,r){if(0===t.length)return r(e);var n;if(o(e))return i(e,n=t[0],a(e[n],t.slice(1),r));throw new Error("Path doesn't exist")}function g(e,t){if(0===t.length)return e;if(!o(e))throw new Error("Path does not exist");if(1===t.length){const r=t[0];return r in e?(p(n=l(e))&&n.splice(parseInt(r),1),s(n)&&delete n[r],n):e}const r=t[0];var n=g(e[r],t.slice(1));return i(e,r,n)}function v(e,t,r){const n=t.slice(0,t.length-1),o=t[t.length-1];return a(e,n,e=>{if(Array.isArray(e))return(e=l(e)).splice(parseInt(o),0,r),e;throw new TypeError("Array expected at path "+JSON.stringify(n))})}function y(e,t){return void 0!==e&&(0===t.length||null!==e&&y(e[t[0]],t.slice(1)))}function n(e){e=e.split("/");return e.shift(),e.map(e=>e.replace(/~1/g,"/").replace(/~0/g,"~"))}function m(e){return e.map(u).join("")}function u(e){return"/"+String(e).replace(/~/g,"~0").replace(/\//g,"~1")}function O(e,r,n){let o=e;for(let t=0;t<r.length;t++){i=void 0;var i=r[t];if(!["add","remove","replace","copy","move","test"].includes(i.op))throw new Error("Unknown JSONPatch op "+JSON.stringify(i.op));if("string"!=typeof i.path)throw new Error('Required property "path" missing or not a string in operation '+JSON.stringify(i));if(("copy"===i.op||"move"===i.op)&&"string"!=typeof i.from)throw new Error('Required property "from" missing or not a string in operation '+JSON.stringify(i));let e=r[t];if(n&&n.before){i=n.before(o,e);if(void 0!==i){if(void 0!==i.document&&(o=i.document),void 0!==i.json)throw new Error('Deprecation warning: returned object property ".json" has been renamed to ".document"');void 0!==i.operation&&(e=i.operation)}}var i=o,f=S(o,e.path);if("add"===e.op)o=(p=o,s=f,l=e.value,(w(p,s)?v:d)(p,s,l));else if("remove"===e.op)o=g(o,f);else if("replace"===e.op)o=(p=o,s=e.value,d(p,f,s));else if("copy"===e.op)o=function(e,t,r){const n=h(e,r);{if(w(e,t))return v(e,t,n);{const n=h(e,r);return d(e,t,n)}}}(o,f,b(e.from));else if("move"===e.op)o=(l=o,c=f,a=b(e.from),u=void 0,u=h(l,a),(w(l=g(l,a),c)?v:d)(l,c,u));else{if("test"!==e.op)throw new Error("Unknown JSONPatch operation "+JSON.stringify(e));u=c=a=void 0;a=o,c=f,u=e.value;if(void 0===u)throw new Error(`Test failed: no value provided (path: "${m(c)}")`);if(!y(a,c))throw new Error(`Test failed: path not found (path: "${m(c)}")`);if(!function(e,t){return JSON.stringify(e)===JSON.stringify(t)}(a=h(a,c),u))throw new Error(`Test failed, value differs (path: "${m(c)}")`)}n&&n.after&&void 0!==(f=n.after(o,e,i))&&(o=f)}var c,a,u,p,s,l;return o}function w(e,t){if(0!==t.length)return e=h(e,r(t)),Array.isArray(e)}function S(e,t){return e=e,"-"!==(t=n(t))[t.length-1]?t:(t=h(e,e=r(t)),e.concat(t.length))}function b(e){return n(e)}function J(e,t){return[{op:"replace",path:m(t),value:h(e,t)}]}function N(e,t){return[{op:"add",path:m(t),value:h(e,t)}]}function P(e,t){return w(e,t)||!y(e,t)?[{op:"remove",path:m(t)}]:J(e,t)}e.appendToJSONPointer=function(e,t){return e+u(t)},e.compileJSONPointer=m,e.compileJSONPointerProp=u,e.deleteIn=g,e.existsIn=y,e.getIn=h,e.immutableJSONPatch=O,e.insertAt=v,e.isJSONArray=p,e.isJSONObject=s,e.isJSONPatchAdd=function(e){return!(!e||"object"!=typeof e)&&"add"===e.op},e.isJSONPatchCopy=function(e){return!(!e||"object"!=typeof e)&&"copy"===e.op},e.isJSONPatchMove=function(e){return!(!e||"object"!=typeof e)&&"move"===e.op},e.isJSONPatchOperation=function(e){return!(!e||"object"!=typeof e)&&"string"==typeof e.op},e.isJSONPatchRemove=function(e){return!(!e||"object"!=typeof e)&&"remove"===e.op},e.isJSONPatchReplace=function(e){return!(!e||"object"!=typeof e)&&"replace"===e.op},e.isJSONPatchTest=function(e){return!(!e||"object"!=typeof e)&&"test"===e.op},e.parseFrom=b,e.parseJSONPointer=n,e.parsePath=S,e.revertJSONPatch=function(e,t,i){let f=[];return O(e,t,{before:(e,t)=>{let r;var n=S(e,t.path);if("add"===t.op)r=P(e,n);else if("remove"===t.op)r=N(e,n);else if("replace"===t.op)r=J(e,n);else if("copy"===t.op)r=P(e,n);else if("move"===t.op)r=function(e,t,r){if(t.length<r.length&&function(t,r,e){var n=2<arguments.length&&void 0!==e?e:c;if(!(t.length<r.length)){for(let e=0;e<r.length;e++)if(!n(t[e],r[e]))return;return 1}}(r,t))return[{op:"replace",path:m(t),value:e}];r={op:"move",from:m(t),path:m(r)};return!w(e,t)&&y(e,t)?[r,...N(e,t)]:[r]}(e,n,b(t.from));else{if("test"!==t.op)throw new Error("Unknown JSONPatch operation "+JSON.stringify(t));r=[]}let o;if(i&&i.before){n=i.before(e,t,r);if(n&&n.revertOperations&&(r=n.revertOperations),n&&n.document&&(o=n.document),n&&n.json)throw new Error('Deprecation warning: returned object property ".json" has been renamed to ".document"')}if(f=r.concat(f),void 0!==o)return{document:o}}}),f},e.setIn=d,e.startsWithJSONPointer=function(e,t){return e.startsWith(t)&&(e.length===t.length||"/"===e[t.length])},e.transform=function r(e,n){var t,o,i=2<arguments.length&&void 0!==arguments[2]?arguments[2]:[],f=n(e,i);if(p(f)){let t;for(let e=0;e<f.length;e++){var c=f[e],a=r(c,n,i.concat(e+""));a!==c&&((t=t||l(f))[e]=a)}return t||f}if(s(f)){let e;for(const u in f)Object.hasOwnProperty.call(f,u)&&(o=r(t=f[u],n,i.concat(u)))!==t&&((e=e||l(f))[u]=o);return e||f}return f},e.updateIn=a}); |
{ | ||
"name": "immutable-json-patch", | ||
"version": "5.1.3", | ||
"version": "6.0.0", | ||
"description": "Immutable JSON patch with support for reverting operations", | ||
@@ -32,3 +32,2 @@ "repository": { | ||
"test": "mocha", | ||
"test:lib": "mocha test-lib/*.test.*", | ||
"build": "npm run clean && npm-run-all build:**", | ||
@@ -41,4 +40,6 @@ "clean": "del-cli lib", | ||
"build:types": "tsc --project tsconfig-types.json", | ||
"build:test": "mocha test-lib/*.test.*", | ||
"lint": "eslint src/**/*.ts", | ||
"build-and-test": "npm run lint && npm run build && npm run test:lib", | ||
"format": "eslint src/**/*.ts --fix", | ||
"build-and-test": "npm run lint && npm run build", | ||
"prepublishOnly": "npm run build-and-test" | ||
@@ -54,26 +55,27 @@ }, | ||
"devDependencies": { | ||
"@babel/cli": "7.22.6", | ||
"@babel/core": "7.22.8", | ||
"@babel/plugin-transform-typescript": "7.22.5", | ||
"@babel/preset-env": "7.22.7", | ||
"@babel/preset-typescript": "7.22.5", | ||
"@types/mocha": "10.0.1", | ||
"@types/node": "20.4.0", | ||
"@typescript-eslint/eslint-plugin": "5.61.0", | ||
"@typescript-eslint/parser": "5.61.0", | ||
"@babel/cli": "7.23.4", | ||
"@babel/core": "7.23.6", | ||
"@babel/plugin-transform-typescript": "7.23.6", | ||
"@babel/preset-env": "7.23.6", | ||
"@babel/preset-typescript": "7.23.3", | ||
"@types/mocha": "10.0.6", | ||
"@types/node": "20.10.4", | ||
"@typescript-eslint/eslint-plugin": "6.14.0", | ||
"@typescript-eslint/parser": "6.14.0", | ||
"cpy-cli": "5.0.0", | ||
"del-cli": "5.0.0", | ||
"eslint": "8.44.0", | ||
"del-cli": "5.1.0", | ||
"eslint": "8.55.0", | ||
"eslint-config-standard": "17.1.0", | ||
"eslint-plugin-import": "2.27.5", | ||
"eslint-plugin-n": "16.0.1", | ||
"eslint-plugin-import": "2.29.0", | ||
"eslint-plugin-n": "16.4.0", | ||
"eslint-plugin-node": "11.1.0", | ||
"eslint-plugin-promise": "6.1.1", | ||
"expect-type": "0.17.3", | ||
"mocha": "10.2.0", | ||
"npm-run-all": "4.1.5", | ||
"rollup": "3.26.2", | ||
"ts-node": "10.9.1", | ||
"typescript": "5.1.6", | ||
"rollup": "4.9.0", | ||
"ts-node": "10.9.2", | ||
"typescript": "5.3.3", | ||
"uglify-js": "3.17.4" | ||
} | ||
} |
@@ -87,4 +87,6 @@ # immutable-json-patch | ||
Apply a list with JSON Patch operations to a JSON document. | ||
```ts | ||
declare function immutableJSONPatch (document: JSONValue, operations: JSONPatchDocument, options?: JSONPatchOptions) : JSONValue | ||
declare function immutableJSONPatch<T, U = unknown> (document: T, operations: JSONPatchDocument, options?: JSONPatchOptions) : U | ||
``` | ||
@@ -94,5 +96,5 @@ | ||
- `document: JSONValue` is a JSON document | ||
- `document: T` is a JSON document | ||
- `operations: JSONPatchDocument` is an array with JSONPatch operations | ||
- `options: JSONPatchOptions` is an optional object allowing passing hooks `before` and `after`. With those hooks it is possible to alter the JSON document and/or applied operation before and after this is applied. This allows for example to instantiate classes or special, additional data structures when applying a JSON patch operation. Or you can keep certain data stats up to date. For example, it is possible to have an array with `Customer` class instances, and instantiate a `new Customer` when an `add` operation is performed. And in this library itself, the `before` callback is used to create inverse operations whilst applying the actual operations on the document. | ||
- `options: JSONPatchOptions` is an optional object allowing passing hooks `before` and `after`. With those hooks it is possible to alter the JSON document and/or applied operation before and after this is applied. This allows for example to instantiate classes or additional data structures when applying a JSON patch operation. Or you can keep certain data stats up to date. For example, it is possible to have an array with `Customer` class instances, and instantiate a `new Customer` when an `add` operation is performed. And in this library itself, the `before` callback is used to create inverse operations whilst applying the actual operations on the document. | ||
@@ -103,10 +105,10 @@ The callbacks look like: | ||
const options = { | ||
before: (document: JSONValue, operation: JSONPatchOperation) => { | ||
before: (document: unknown, operation: JSONPatchOperation) => { | ||
console.log('before operation', { document, operation }) | ||
// return { document?: JSONValue, operation?: JSONPatchOperation } | undefined | ||
// return { document?: unknown, operation?: JSONPatchOperation } | undefined | ||
}, | ||
after: (document: JSONValue, operation: JSONPatchOperation, previousDocument: JSONValue) => { | ||
after: (document: unknown, operation: JSONPatchOperation, previousDocument: unknown) => { | ||
console.log('after operation', { document, operation, previousDocument }) | ||
// return JSONValue | undefined | ||
// return document | undefined | ||
} | ||
@@ -122,4 +124,6 @@ } | ||
Generate the JSON patch operations that will revert the provided list with JSON Patch operations when applied to the provided JSON document. | ||
```ts | ||
declare function revertJSONPatch (document: JSONValue, operations: JSONPatchDocument, options?: RevertJSONPatchOptions) : JSONPatchDocument | ||
declare function revertJSONPatch<T, U> (document: T, operations: JSONPatchDocument, options?: RevertJSONPatchOptions) : JSONPatchDocument | ||
``` | ||
@@ -129,3 +133,3 @@ | ||
- `document: JSONValue` is a JSON document | ||
- `document: T` is a JSON document | ||
- `operations: JSONPatchDocument` is an array with JSONPatch operations | ||
@@ -141,3 +145,3 @@ - `options: JSONPatchOptions` is an optional object allowing passing a hook `before`. With this hook it is possible to alter the JSON document and/or generated `reverseOperations` before this is applied. | ||
```ts | ||
declare function parsePath(document: JSONValue, path: JSONPointer): JSONPath | ||
declare function parsePath<T>(document: T, path: JSONPointer): JSONPath | ||
declare function parseFrom(path: JSONPointer): JSONPath | ||
@@ -159,9 +163,12 @@ | ||
declare function getIn(document: JSONValue, path: JSONPath) : JSONValue | ||
declare function setIn(document: JSONValue, path: JSONPath, value: JSONValue, createPath?: boolean) : JSONValue | ||
declare function updateIn(document: JSONValue, path: JSONPath, callback: (value: JSONValue) => JSONValue) : JSONValue | ||
declare function deleteIn(document: JSONValue, path: JSONPath) : JSONValue | ||
declare function existsIn(document: JSONValue, path: JSONPath) : boolean | ||
declare function insertAt(document: JSONValue, path: JSONPath, value: JSONValue) : JSONValue | ||
declare function transform (document: JSONValue, callback: (document: JSONValue, path: JSONPath) => JSONValue, path: JSONPath = []) : JSONValue | ||
declare function getIn<T, U = unknown>(object: U, path: JSONPath) : T | undefined | ||
declare function setIn<T, U = unknown, V = unknown> (object: U, path: JSONPath, value: V, createPath = false) : T | ||
declare function updateIn<T, U = unknown, V = unknown> (object: T, path: JSONPath, transform: (value: U) => V) : T | ||
declare function deleteIn<T, U = unknown> (object: U, path: JSONPath) : T | ||
declare function existsIn<T> (document: T, path: JSONPath) : boolean | ||
declare function insertAt<T, U = unknown> (document: T, path: JSONPath, value: U) : T | ||
declare function transform <T, U = unknown, V = unknown, W = unknown> ( | ||
document: U, | ||
callback: (document: V, path: JSONPath) => W, path: JSONPath = [] | ||
) : T | ||
``` | ||
@@ -168,0 +175,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
200
3.63%258059
-11.32%24
4.35%2453
-1.49%