// Generated by CoffeeScript 1.12.7 (function() { var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, hasProp = {}.hasOwnProperty; (function(factory) { var root; root = typeof window !== "undefined" && window !== null ? window : typeof global !== "undefined" && global !== null ? global : this; if (typeof exports !== 'undefined') { return factory(exports); } else if (typeof define === 'function' && define.amd) { return define(['exports'], function(exports) { return root.jsonpatch = factory(exports); }); } else { return root.jsonpatch = factory({}); } })(function(exports) { var AddPatch, CopyPatch, InvalidPatchError, InvalidPointerError, JSONPatch, JSONPatchError, JSONPointer, MovePatch, PatchConflictError, PatchTestFailed, RemovePatch, ReplacePatch, TestPatch, _isEqual, accessorMatch, apply, compile, escapedSlash, escapedTilde, hasOwnProperty, isArray, isEqual, isObject, isString, operationMap, toString; toString = Object.prototype.toString; hasOwnProperty = Object.prototype.hasOwnProperty; isArray = function(obj) { return toString.call(obj) === '[object Array]'; }; isObject = function(obj) { return toString.call(obj) === '[object Object]'; }; isString = function(obj) { return toString.call(obj) === '[object String]'; }; _isEqual = function(a, b, stack) { var className, key, length, result, size; if (a === b) { return a !== 0 || 1 / a === 1 / b; } if (a === null || b === null) { return a === b; } className = toString.call(a); if (className !== toString.call(b)) { return false; } switch (className) { case '[object String]': String(a) === String(b); break; case '[object Number]': a = +a; b = +b; if (a !== a) { b !== b; } else { if (a === 0) { 1 / a === 1 / b; } else { a === b; } } break; case '[object Boolean]': +a === +b; } if (typeof a !== 'object' || typeof b !== 'object') { return false; } length = stack.length; while (length--) { if (stack[length] === a) { return true; } } stack.push(a); size = 0; result = true; if (className === '[object Array]') { size = a.length; result = size === b.length; if (result) { while (size--) { if (!(result = indexOf.call(a, size) >= 0 === indexOf.call(b, size) >= 0 && _isEqual(a[size], b[size], stack))) { break; } } } } else { if (indexOf.call(a, "constructor") >= 0 !== indexOf.call(b, "constructor") >= 0 || a.constructor !== b.constructor) { return false; } for (key in a) { if (hasOwnProperty.call(a, key)) { size++; if (!(result = hasOwnProperty.call(b, key) && _isEqual(a[key], b[key], stack))) { break; } } } if (result) { for (key in b) { if (hasOwnProperty.call(b, key) && !size--) { break; } } result = !size; } } stack.pop(); return result; }; isEqual = function(a, b) { return _isEqual(a, b, []); }; JSONPatchError = (function(superClass) { extend(JSONPatchError, superClass); function JSONPatchError(message) { this.message = message != null ? message : 'JSON patch error'; this.name = 'JSONPatchError'; } return JSONPatchError; })(Error); InvalidPointerError = (function(superClass) { extend(InvalidPointerError, superClass); function InvalidPointerError(message) { this.message = message != null ? message : 'Invalid pointer'; this.name = 'InvalidPointer'; } return InvalidPointerError; })(Error); InvalidPatchError = (function(superClass) { extend(InvalidPatchError, superClass); function InvalidPatchError(message) { this.message = message != null ? message : 'Invalid patch'; this.name = 'InvalidPatch'; } return InvalidPatchError; })(JSONPatchError); PatchConflictError = (function(superClass) { extend(PatchConflictError, superClass); function PatchConflictError(message) { this.message = message != null ? message : 'Patch conflict'; this.name = 'PatchConflictError'; } return PatchConflictError; })(JSONPatchError); PatchTestFailed = (function(superClass) { extend(PatchTestFailed, superClass); function PatchTestFailed(message) { this.message = message != null ? message : 'Patch test failed'; this.name = 'PatchTestFailed'; } return PatchTestFailed; })(Error); escapedSlash = /~1/g; escapedTilde = /~0/g; accessorMatch = /^[-+]?\d+$/; JSONPointer = (function() { function JSONPointer(path) { var i, j, len1, step, steps; steps = []; if (path && (steps = path.split('/')).shift() !== '') { throw new InvalidPointerError(); } for (i = j = 0, len1 = steps.length; j < len1; i = ++j) { step = steps[i]; steps[i] = step.replace(escapedSlash, '/').replace(escapedTilde, '~'); } this.accessor = steps.pop(); this.steps = steps; this.path = path; } JSONPointer.prototype.getReference = function(parent) { var j, len1, ref, step; ref = this.steps; for (j = 0, len1 = ref.length; j < len1; j++) { step = ref[j]; if (isArray(parent)) { step = parseInt(step, 10); } if (!(step in parent)) { throw new PatchConflictError('Array location out of bounds or not an instance property'); } parent = parent[step]; } return parent; }; JSONPointer.prototype.coerce = function(reference, accessor) { if (isArray(reference)) { if (isString(accessor)) { if (accessor === '-') { accessor = reference.length; } else if (accessorMatch.test(accessor)) { accessor = parseInt(accessor, 10); } else { throw new InvalidPointerError('Invalid array index number'); } } } return accessor; }; return JSONPointer; })(); JSONPatch = (function() { function JSONPatch(patch) { if (!('path' in patch)) { throw new InvalidPatchError(); } this.validate(patch); this.patch = patch; this.path = new JSONPointer(patch.path); this.initialize(patch); } JSONPatch.prototype.initialize = function() {}; JSONPatch.prototype.validate = function(patch) {}; JSONPatch.prototype.apply = function(document) { throw new Error('Method not implemented'); }; return JSONPatch; })(); AddPatch = (function(superClass) { extend(AddPatch, superClass); function AddPatch() { return AddPatch.__super__.constructor.apply(this, arguments); } AddPatch.prototype.validate = function(patch) { if (!('value' in patch)) { throw new InvalidPatchError(); } }; AddPatch.prototype.apply = function(document) { var accessor, reference, value; reference = this.path.getReference(document); accessor = this.path.accessor; value = this.patch.value; if (isArray(reference)) { accessor = this.path.coerce(reference, accessor); if (accessor < 0 || accessor > reference.length) { throw new PatchConflictError("Index " + accessor + " out of bounds"); } reference.splice(accessor, 0, value); } else if (accessor == null) { document = value; } else { reference[accessor] = value; } return document; }; return AddPatch; })(JSONPatch); RemovePatch = (function(superClass) { extend(RemovePatch, superClass); function RemovePatch() { return RemovePatch.__super__.constructor.apply(this, arguments); } RemovePatch.prototype.apply = function(document) { var accessor, reference; reference = this.path.getReference(document); accessor = this.path.accessor; if (isArray(reference)) { accessor = this.path.coerce(reference, accessor); if (accessor >= reference.length) { throw new PatchConflictError("Value at " + accessor + " does not exist"); } reference.splice(accessor, 1); } else { if (!(accessor in reference)) { throw new PatchConflictError("Value at " + accessor + " does not exist"); } delete reference[accessor]; } return document; }; return RemovePatch; })(JSONPatch); ReplacePatch = (function(superClass) { extend(ReplacePatch, superClass); function ReplacePatch() { return ReplacePatch.__super__.constructor.apply(this, arguments); } ReplacePatch.prototype.validate = function(patch) { if (!('value' in patch)) { throw new InvalidPatchError(); } }; ReplacePatch.prototype.apply = function(document) { var accessor, reference, value; reference = this.path.getReference(document); accessor = this.path.accessor; value = this.patch.value; if (accessor == null) { return value; } if (isArray(reference)) { accessor = this.path.coerce(reference, accessor); if (accessor >= reference.length) { throw new PatchConflictError("Value at " + accessor + " does not exist"); } reference.splice(accessor, 1, value); } else { if (!(accessor in reference)) { throw new PatchConflictError("Value at " + accessor + " does not exist"); } reference[accessor] = value; } return document; }; return ReplacePatch; })(JSONPatch); TestPatch = (function(superClass) { extend(TestPatch, superClass); function TestPatch() { return TestPatch.__super__.constructor.apply(this, arguments); } TestPatch.prototype.validate = function(patch) { if (!('value' in patch)) { throw new InvalidPatchError("'value' member is required"); } }; TestPatch.prototype.apply = function(document) { var accessor, reference, value; reference = this.path.getReference(document); accessor = this.path.accessor; value = this.patch.value; if (isArray(reference)) { accessor = this.path.coerce(reference, accessor); } if (!isEqual(reference[accessor], value)) { throw new PatchTestFailed(); } return document; }; return TestPatch; })(JSONPatch); MovePatch = (function(superClass) { extend(MovePatch, superClass); function MovePatch() { return MovePatch.__super__.constructor.apply(this, arguments); } MovePatch.prototype.initialize = function(patch) { var i, j, len, ref, within; this.from = new JSONPointer(patch.from); len = this.from.steps.length; within = true; for (i = j = 0, ref = len; 0 <= ref ? j <= ref : j >= ref; i = 0 <= ref ? ++j : --j) { if (this.from.steps[i] !== this.path.steps[i]) { within = false; break; } } if (within) { if (this.path.steps.length !== len) { throw new InvalidPatchError("'to' member cannot be a descendent of 'path'"); } if (this.from.accessor === this.path.accessor) { return this.apply = function(document) { return document; }; } } }; MovePatch.prototype.validate = function(patch) { if (!('from' in patch)) { throw new InvalidPatchError("'from' member is required"); } }; MovePatch.prototype.apply = function(document) { var accessor, reference, value; reference = this.from.getReference(document); accessor = this.from.accessor; if (isArray(reference)) { accessor = this.from.coerce(reference, accessor); if (accessor >= reference.length) { throw new PatchConflictError("Value at " + accessor + " does not exist"); } value = reference.splice(accessor, 1)[0]; } else { if (!(accessor in reference)) { throw new PatchConflictError("Value at " + accessor + " does not exist"); } value = reference[accessor]; delete reference[accessor]; } reference = this.path.getReference(document); accessor = this.path.accessor; if (isArray(reference)) { accessor = this.path.coerce(reference, accessor); if (accessor < 0 || accessor > reference.length) { throw new PatchConflictError("Index " + accessor + " out of bounds"); } reference.splice(accessor, 0, value); } else { if (accessor in reference) { throw new PatchConflictError("Value at " + accessor + " exists"); } reference[accessor] = value; } return document; }; return MovePatch; })(JSONPatch); CopyPatch = (function(superClass) { extend(CopyPatch, superClass); function CopyPatch() { return CopyPatch.__super__.constructor.apply(this, arguments); } CopyPatch.prototype.apply = function(document) { var accessor, reference, value; reference = this.from.getReference(document); accessor = this.from.accessor; if (isArray(reference)) { accessor = this.from.coerce(reference, accessor); if (accessor >= reference.length) { throw new PatchConflictError("Value at " + accessor + " does not exist"); } value = reference.slice(accessor, accessor + 1)[0]; } else { if (!(accessor in reference)) { throw new PatchConflictError("Value at " + accessor + " does not exist"); } value = reference[accessor]; } reference = this.path.getReference(document); accessor = this.path.accessor; if (isArray(reference)) { accessor = this.path.coerce(reference, accessor); if (accessor < 0 || accessor > reference.length) { throw new PatchConflictError("Index " + accessor + " out of bounds"); } reference.splice(accessor, 0, value); } else { if (accessor in reference) { throw new PatchConflictError("Value at " + accessor + " exists"); } reference[accessor] = value; } return document; }; return CopyPatch; })(MovePatch); operationMap = { add: AddPatch, remove: RemovePatch, replace: ReplacePatch, move: MovePatch, copy: CopyPatch, test: TestPatch }; compile = function(patch) { var j, klass, len1, ops, p; if (!isArray(patch)) { if (isObject(patch)) { patch = [patch]; } else { throw new InvalidPatchError('patch must be an object or array'); } } ops = []; for (j = 0, len1 = patch.length; j < len1; j++) { p = patch[j]; if (!(klass = operationMap[p.op])) { throw new InvalidPatchError('invalid operation: ' + p.op); } ops.push(new klass(p)); } return function(document) { var k, len2, op, result; result = document; for (k = 0, len2 = ops.length; k < len2; k++) { op = ops[k]; result = op.apply(result); } return result; }; }; apply = function(document, patch) { return compile(patch)(document); }; exports.version = '0.7.0'; exports.apply = apply; exports.compile = compile; exports.JSONPointer = JSONPointer; exports.JSONPatch = JSONPatch; exports.JSONPatchError = JSONPatchError; exports.InvalidPointerError = InvalidPointerError; exports.InvalidPatchError = InvalidPatchError; exports.PatchConflictError = PatchConflictError; exports.PatchTestFailed = PatchTestFailed; return exports; }); }).call(this);