diff --git a/.gitignore b/.gitignore index 87aa911f..540ff0e6 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ npm-debug.log # Typescript *.d.ts +test/spec/typings/typingsSpec.js # compiled files src/*.js diff --git a/dist/fast-json-patch.js b/dist/fast-json-patch.js index d911a67b..3b98e045 100644 --- a/dist/fast-json-patch.js +++ b/dist/fast-json-patch.js @@ -660,12 +660,36 @@ function validate(sequence, document, externalValidator) { } } exports.validate = validate; +/** + * Default export for backwards compat + */ +exports.default = { + JsonPatchError: exports.JsonPatchError, + deepClone: exports.deepClone, + getValueByPointer: getValueByPointer, + applyOperation: applyOperation, + applyPatch: applyPatch, + applyReducer: applyReducer, + validator: validator, + validate: validate +}; /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; Object.defineProperty(exports, "__esModule", { value: true }); /*! * https://github.com/Starcounter-Jack/JSON-Patch @@ -861,6 +885,21 @@ function compare(tree1, tree2, invertible) { return patches; } exports.compare = compare; +/** + * Default export for backwards compat + */ +// import just to re-export as default +var core = __webpack_require__(1); +var helpers_3 = __webpack_require__(0); +exports.default = __assign({}, core, { + // duplex + unobserve: unobserve, + observe: observe, + generate: generate, + compare: compare, + // helpers + JsonPatchError: helpers_3.PatchError, deepClone: helpers_1._deepClone, escapePathComponent: helpers_1.escapePathComponent, + unescapePathComponent: helpers_3.unescapePathComponent }); /***/ }), diff --git a/dist/fast-json-patch.min.js b/dist/fast-json-patch.min.js index 72b2ccae..2ecb1beb 100644 --- a/dist/fast-json-patch.min.js +++ b/dist/fast-json-patch.min.js @@ -5,10 +5,10 @@ var jsonpatch=function(e){var t={};function r(n){if(t[n])return t[n].exports;var * (c) 2017 Joachim Wester * MIT license */ -var r,n=this&&this.__extends||(r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])})(e,t)},function(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)});Object.defineProperty(t,"__esModule",{value:!0});var o=Object.prototype.hasOwnProperty;function a(e,t){return o.call(e,t)}function i(e){if(Array.isArray(e)){for(var t=new Array(e.length),r=0;r=48&&t<=57))return!1;r++}return!0},t.escapePathComponent=p,t.unescapePathComponent=function(e){return e.replace(/~1/g,"/").replace(/~0/g,"~")},t._getPathRecursive=u,t.getPath=function(e,t){if(e===t)return"/";var r=u(e,t);if(""===r)throw new Error("Object not found in root");return"/"+r},t.hasUndefined=function e(t){if(void 0===t)return!0;if(t)if(Array.isArray(t)){for(var r=0,n=t.length;r=w){if(u&&"add"===r.op&&O>v.length)throw new t.JsonPatchError("The specified index MUST NOT be greater than the number of elements in the array","OPERATION_VALUE_OUT_OF_BOUNDS",l,r,e);if(!1===(h=i[r.op].call(r,v,O,e)).test)throw new t.JsonPatchError("Test operation failed","TEST_OPERATION_FAILED",l,r,e);return h}}else if(O&&-1!=O.indexOf("~")&&(O=o.unescapePathComponent(O)),y>=w){if(!1===(h=a[r.op].call(r,v,O,e)).test)throw new t.JsonPatchError("Test operation failed","TEST_OPERATION_FAILED",l,r,e);return h}v=v[O]}}function s(e,r,n,a,i){if(void 0===a&&(a=!0),void 0===i&&(i=!0),n&&!Array.isArray(r))throw new t.JsonPatchError("Patch sequence must be an array","SEQUENCE_NOT_AN_ARRAY");a||(e=o._deepClone(e));for(var p=new Array(r.length),s=0,c=r.length;s0)throw new t.JsonPatchError('Operation `path` property must start with "/"',"OPERATION_PATH_INVALID",r,e,n);if(("move"===e.op||"copy"===e.op)&&"string"!=typeof e.from)throw new t.JsonPatchError("Operation `from` property is not present (applicable in `move` and `copy` operations)","OPERATION_FROM_REQUIRED",r,e,n);if(("add"===e.op||"replace"===e.op||"test"===e.op)&&void 0===e.value)throw new t.JsonPatchError("Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)","OPERATION_VALUE_REQUIRED",r,e,n);if(("add"===e.op||"replace"===e.op||"test"===e.op)&&o.hasUndefined(e.value))throw new t.JsonPatchError("Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)","OPERATION_VALUE_CANNOT_CONTAIN_UNDEFINED",r,e,n);if(n)if("add"==e.op){var p=e.path.split("/").length,u=i.split("/").length;if(p!==u+1&&p!==u)throw new t.JsonPatchError("Cannot perform an `add` operation at the desired path","OPERATION_PATH_CANNOT_ADD",r,e,n)}else if("replace"===e.op||"remove"===e.op||"_get"===e.op){if(e.path!==i)throw new t.JsonPatchError("Cannot perform the operation at a path that does not exist","OPERATION_PATH_UNRESOLVABLE",r,e,n)}else if("move"===e.op||"copy"===e.op){var s=f([{op:"_get",path:e.from,value:void 0}],n);if(s&&"OPERATION_PATH_UNRESOLVABLE"===s.name)throw new t.JsonPatchError("Cannot perform the operation from a path that does not exist","OPERATION_FROM_UNRESOLVABLE",r,e,n)}}function f(e,r,n){try{if(!Array.isArray(e))throw new t.JsonPatchError("Patch sequence must be an array","SEQUENCE_NOT_AN_ARRAY");if(r)s(o._deepClone(r),o._deepClone(e),n||!0);else{n=n||c;for(var a=0;a=48&&t<=57))return!1;r++}return!0},t.escapePathComponent=p,t.unescapePathComponent=function(e){return e.replace(/~1/g,"/").replace(/~0/g,"~")},t._getPathRecursive=u,t.getPath=function(e,t){if(e===t)return"/";var r=u(e,t);if(""===r)throw new Error("Object not found in root");return"/"+r},t.hasUndefined=function e(t){if(void 0===t)return!0;if(t)if(Array.isArray(t)){for(var r=0,n=t.length;r=w){if(u&&"add"===r.op&&O>v.length)throw new t.JsonPatchError("The specified index MUST NOT be greater than the number of elements in the array","OPERATION_VALUE_OUT_OF_BOUNDS",l,r,e);if(!1===(h=i[r.op].call(r,v,O,e)).test)throw new t.JsonPatchError("Test operation failed","TEST_OPERATION_FAILED",l,r,e);return h}}else if(O&&-1!=O.indexOf("~")&&(O=o.unescapePathComponent(O)),y>=w){if(!1===(h=a[r.op].call(r,v,O,e)).test)throw new t.JsonPatchError("Test operation failed","TEST_OPERATION_FAILED",l,r,e);return h}v=v[O]}}function s(e,r,n,a,i){if(void 0===a&&(a=!0),void 0===i&&(i=!0),n&&!Array.isArray(r))throw new t.JsonPatchError("Patch sequence must be an array","SEQUENCE_NOT_AN_ARRAY");a||(e=o._deepClone(e));for(var p=new Array(r.length),s=0,c=r.length;s0)throw new t.JsonPatchError('Operation `path` property must start with "/"',"OPERATION_PATH_INVALID",r,e,n);if(("move"===e.op||"copy"===e.op)&&"string"!=typeof e.from)throw new t.JsonPatchError("Operation `from` property is not present (applicable in `move` and `copy` operations)","OPERATION_FROM_REQUIRED",r,e,n);if(("add"===e.op||"replace"===e.op||"test"===e.op)&&void 0===e.value)throw new t.JsonPatchError("Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)","OPERATION_VALUE_REQUIRED",r,e,n);if(("add"===e.op||"replace"===e.op||"test"===e.op)&&o.hasUndefined(e.value))throw new t.JsonPatchError("Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)","OPERATION_VALUE_CANNOT_CONTAIN_UNDEFINED",r,e,n);if(n)if("add"==e.op){var p=e.path.split("/").length,u=i.split("/").length;if(p!==u+1&&p!==u)throw new t.JsonPatchError("Cannot perform an `add` operation at the desired path","OPERATION_PATH_CANNOT_ADD",r,e,n)}else if("replace"===e.op||"remove"===e.op||"_get"===e.op){if(e.path!==i)throw new t.JsonPatchError("Cannot perform the operation at a path that does not exist","OPERATION_PATH_UNRESOLVABLE",r,e,n)}else if("move"===e.op||"copy"===e.op){var s=l([{op:"_get",path:e.from,value:void 0}],n);if(s&&"OPERATION_PATH_UNRESOLVABLE"===s.name)throw new t.JsonPatchError("Cannot perform the operation from a path that does not exist","OPERATION_FROM_UNRESOLVABLE",r,e,n)}}function l(e,r,n){try{if(!Array.isArray(e))throw new t.JsonPatchError("Patch sequence must be an array","SEQUENCE_NOT_AN_ARRAY");if(r)s(o._deepClone(r),o._deepClone(e),n||!0);else{n=n||f;for(var a=0;a0&&(e.patches=[],e.callback&&e.callback(n)),n}function f(e,t,r,o,a){if(t!==e){"function"==typeof t.toJSON&&(t=t.toJSON());for(var i=n._objectKeys(t),p=n._objectKeys(e),u=!1,s=p.length-1;s>=0;s--){var c=e[h=p[s]];if(!n.hasOwnProperty(t,h)||void 0===t[h]&&void 0!==c&&!1===Array.isArray(t))Array.isArray(e)===Array.isArray(t)?(a&&r.push({op:"test",path:o+"/"+n.escapePathComponent(h),value:n._deepClone(c)}),r.push({op:"remove",path:o+"/"+n.escapePathComponent(h)}),u=!0):(a&&r.push({op:"test",path:o,value:e}),r.push({op:"replace",path:o,value:t}),!0);else{var l=t[h];"object"==typeof c&&null!=c&&"object"==typeof l&&null!=l?f(c,l,r,o+"/"+n.escapePathComponent(h),a):c!==l&&(!0,a&&r.push({op:"test",path:o+"/"+n.escapePathComponent(h),value:n._deepClone(c)}),r.push({op:"replace",path:o+"/"+n.escapePathComponent(h),value:n._deepClone(l)}))}}if(u||i.length!=p.length)for(s=0;s0&&(e.patches=[],e.callback&&e.callback(n)),n}function d(e,t,r,n,a){if(t!==e){"function"==typeof t.toJSON&&(t=t.toJSON());for(var i=o._objectKeys(t),p=o._objectKeys(e),u=!1,s=p.length-1;s>=0;s--){var c=e[l=p[s]];if(!o.hasOwnProperty(t,l)||void 0===t[l]&&void 0!==c&&!1===Array.isArray(t))Array.isArray(e)===Array.isArray(t)?(a&&r.push({op:"test",path:n+"/"+o.escapePathComponent(l),value:o._deepClone(c)}),r.push({op:"remove",path:n+"/"+o.escapePathComponent(l)}),u=!0):(a&&r.push({op:"test",path:n,value:e}),r.push({op:"replace",path:n,value:t}),!0);else{var f=t[l];"object"==typeof c&&null!=c&&"object"==typeof f&&null!=f?d(c,f,r,n+"/"+o.escapePathComponent(l),a):c!==f&&(!0,a&&r.push({op:"test",path:n+"/"+o.escapePathComponent(l),value:o._deepClone(c)}),r.push({op:"replace",path:n+"/"+o.escapePathComponent(l),value:o._deepClone(f)}))}}if(u||i.length!=p.length)for(s=0;s(sequence: Operation[], document?: T, externalValidat } } } + +/** + * Default export for backwards compat + */ + +export default { + JsonPatchError, + deepClone, + getValueByPointer, + applyOperation, + applyPatch, + applyReducer, + validator, + validate +} \ No newline at end of file diff --git a/src/duplex.ts b/src/duplex.ts index d151ba0a..4501efef 100644 --- a/src/duplex.ts +++ b/src/duplex.ts @@ -216,3 +216,24 @@ export function compare(tree1: Object | Array, tree2: Object | Array, _generate(tree1, tree2, patches, '', invertible); return patches; } + +/** + * Default export for backwards compat + */ +// import just to re-export as default +import * as core from './core'; +import { PatchError as JsonPatchError, unescapePathComponent } from './helpers'; + +export default { + ...core, + // duplex + unobserve, + observe, + generate, + compare, + // helpers + JsonPatchError, + deepClone:_deepClone, + escapePathComponent, + unescapePathComponent +} \ No newline at end of file diff --git a/test/jasmine.json b/test/jasmine.json index 89452f12..45270cd2 100644 --- a/test/jasmine.json +++ b/test/jasmine.json @@ -1,7 +1,7 @@ { "spec_dir": "test", "spec_files": [ - "**/*[sS]pec.js" + "spec/*[sS]pec.js" ], "helpers": [ "helpers/**/*.js" diff --git a/test/spec/commonjs/requireSpec.js b/test/spec/commonjs/requireSpec.js new file mode 100644 index 00000000..a9e8fbd1 --- /dev/null +++ b/test/spec/commonjs/requireSpec.js @@ -0,0 +1,24 @@ +const jsonpatch = require('../../..'); + +describe('CommonJS', function () { + describe('require', function () { + it('should have the expected structure', function () { + expect(typeof jsonpatch).withContext("result from require() should be an object").toEqual("object"); + expect(typeof jsonpatch).withContext("result from require() should not be a function").not.toEqual("function"); + expect(jsonpatch.applyOperation).withContext("applyOperation should be a method within the object").toBeDefined(); + expect(jsonpatch.applyPatch).withContext("applyPatch should be a method within the object").toBeDefined(); + expect(jsonpatch.applyReducer).withContext("applyReducer should be a method within the object").toBeDefined(); + expect(jsonpatch.getValueByPointer).withContext("getValueByPointer should be a method within the object").toBeDefined(); + expect(jsonpatch.validate).withContext("validate should be a method within the object").toBeDefined(); + expect(jsonpatch.validator).withContext("validator should be a method within the object").toBeDefined(); + expect(jsonpatch.JsonPatchError).withContext("JsonPatchError should be a method within the object").toBeDefined(); + expect(jsonpatch.deepClone).withContext("deepClone should be a method within the object").toBeDefined(); + expect(jsonpatch.escapePathComponent).withContext("escapePathComponent should be a method within the object").toBeDefined(); + expect(jsonpatch.unescapePathComponent).withContext("unescapePathComponent should be a method within the object").toBeDefined(); + expect(jsonpatch.unobserve).withContext("unobserve should be a method within the object").toBeDefined(); + expect(jsonpatch.observe).withContext("observe should be a method within the object").toBeDefined(); + expect(jsonpatch.generate).withContext("generate should be a method within the object").toBeDefined(); + expect(jsonpatch.compare).withContext("compare should be a method within the object").toBeDefined(); + }); + }); +}); \ No newline at end of file diff --git a/test/spec/typings/typingsSpec.ts b/test/spec/typings/typingsSpec.ts new file mode 100644 index 00000000..ae7f4d8b --- /dev/null +++ b/test/spec/typings/typingsSpec.ts @@ -0,0 +1,22 @@ +/** + * Run using `npm run test-typings` + * The sole fact that this file compiles means that typings work + * This follows how DefinitelyTyped tests work + * @see https://stackoverflow.com/questions/49296151/how-to-write-tests-for-typescript-typing-definition + */ + +import jsonpatch from '../../..'; +import * as jsonpatchStar from '../../..'; +import { applyPatch, Operation } from '../../..'; + +const document = { firstName: "Albert", contactDetails: { phoneNumbers: [] } }; + +const typedPatch = new Array({ op: "replace", path: "/firstName", value: "Joachim" }); +const untypedPatch = [{ op: "replace", path: "/firstName", value: "Joachim" }]; + +const test_jsonpatch = jsonpatch.applyPatch(document, typedPatch).newDocument; +const test_jsonpatchStar = jsonpatchStar.applyPatch(document, typedPatch).newDocument; +const test_applyPatch = applyPatch(document, typedPatch).newDocument; + +// the below line would NOT compile with TSC +// const test_applyPatch = applyPatch(document, untypedPatch).newDocument; \ No newline at end of file diff --git a/test/spec/webpack/importSpec.build.js b/test/spec/webpack/importSpec.build.js new file mode 100644 index 00000000..46430b25 --- /dev/null +++ b/test/spec/webpack/importSpec.build.js @@ -0,0 +1,13 @@ +!function(e){var t={};function o(n){if(t[n])return t[n].exports;var r=t[n]={i:n,l:!1,exports:{}};return e[n].call(r.exports,r,r.exports,o),r.l=!0,r.exports}o.m=e,o.c=t,o.d=function(e,t,n){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},o.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.t=function(e,t){if(1&t&&(e=o(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(o.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)o.d(n,r,function(t){return e[t]}.bind(null,r));return n},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,"a",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p="",o(o.s=3)}([function(e,t,o){var n=this&&this.__assign||function(){return(n=Object.assign||function(e){for(var t,o=1,n=arguments.length;o0&&(e.patches=[],e.callback&&e.callback(n)),n}function d(e,t,o,n,a){if(t!==e){"function"==typeof t.toJSON&&(t=t.toJSON());for(var i=r._objectKeys(t),p=r._objectKeys(e),c=!1,u=p.length-1;u>=0;u--){var s=e[f=p[u]];if(!r.hasOwnProperty(t,f)||void 0===t[f]&&void 0!==s&&!1===Array.isArray(t))Array.isArray(e)===Array.isArray(t)?(a&&o.push({op:"test",path:n+"/"+r.escapePathComponent(f),value:r._deepClone(s)}),o.push({op:"remove",path:n+"/"+r.escapePathComponent(f)}),c=!0):(a&&o.push({op:"test",path:n,value:e}),o.push({op:"replace",path:n,value:t}),!0);else{var h=t[f];"object"==typeof s&&null!=s&&"object"==typeof h&&null!=h?d(s,h,o,n+"/"+r.escapePathComponent(f),a):s!==h&&(!0,a&&o.push({op:"test",path:n+"/"+r.escapePathComponent(f),value:r._deepClone(s)}),o.push({op:"replace",path:n+"/"+r.escapePathComponent(f),value:r._deepClone(h)}))}}if(c||i.length!=p.length)for(u=0;u=48&&t<=57))return!1;o++}return!0},t.escapePathComponent=p,t.unescapePathComponent=function(e){return e.replace(/~1/g,"/").replace(/~0/g,"~")},t._getPathRecursive=c,t.getPath=function(e,t){if(e===t)return"/";var o=c(e,t);if(""===o)throw new Error("Object not found in root");return"/"+o},t.hasUndefined=function e(t){if(void 0===t)return!0;if(t)if(Array.isArray(t)){for(var o=0,n=t.length;o=y){if(c&&"add"===o.op&&b>v.length)throw new t.JsonPatchError("The specified index MUST NOT be greater than the number of elements in the array","OPERATION_VALUE_OUT_OF_BOUNDS",f,o,e);if(!1===(l=i[o.op].call(o,v,b,e)).test)throw new t.JsonPatchError("Test operation failed","TEST_OPERATION_FAILED",f,o,e);return l}}else if(b&&-1!=b.indexOf("~")&&(b=r.unescapePathComponent(b)),w>=y){if(!1===(l=a[o.op].call(o,v,b,e)).test)throw new t.JsonPatchError("Test operation failed","TEST_OPERATION_FAILED",f,o,e);return l}v=v[b]}}function u(e,o,n,a,i){if(void 0===a&&(a=!0),void 0===i&&(i=!0),n&&!Array.isArray(o))throw new t.JsonPatchError("Patch sequence must be an array","SEQUENCE_NOT_AN_ARRAY");a||(e=r._deepClone(e));for(var p=new Array(o.length),u=0,s=o.length;u0)throw new t.JsonPatchError('Operation `path` property must start with "/"',"OPERATION_PATH_INVALID",o,e,n);if(("move"===e.op||"copy"===e.op)&&"string"!=typeof e.from)throw new t.JsonPatchError("Operation `from` property is not present (applicable in `move` and `copy` operations)","OPERATION_FROM_REQUIRED",o,e,n);if(("add"===e.op||"replace"===e.op||"test"===e.op)&&void 0===e.value)throw new t.JsonPatchError("Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)","OPERATION_VALUE_REQUIRED",o,e,n);if(("add"===e.op||"replace"===e.op||"test"===e.op)&&r.hasUndefined(e.value))throw new t.JsonPatchError("Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)","OPERATION_VALUE_CANNOT_CONTAIN_UNDEFINED",o,e,n);if(n)if("add"==e.op){var p=e.path.split("/").length,c=i.split("/").length;if(p!==c+1&&p!==c)throw new t.JsonPatchError("Cannot perform an `add` operation at the desired path","OPERATION_PATH_CANNOT_ADD",o,e,n)}else if("replace"===e.op||"remove"===e.op||"_get"===e.op){if(e.path!==i)throw new t.JsonPatchError("Cannot perform the operation at a path that does not exist","OPERATION_PATH_UNRESOLVABLE",o,e,n)}else if("move"===e.op||"copy"===e.op){var u=f([{op:"_get",path:e.from,value:void 0}],n);if(u&&"OPERATION_PATH_UNRESOLVABLE"===u.name)throw new t.JsonPatchError("Cannot perform the operation from a path that does not exist","OPERATION_FROM_UNRESOLVABLE",o,e,n)}}function f(e,o,n){try{if(!Array.isArray(e))throw new t.JsonPatchError("Patch sequence must be an array","SEQUENCE_NOT_AN_ARRAY");if(o)u(r._deepClone(o),r._deepClone(e),n||!0);else{n=n||h;for(var a=0;a { + if(env && env.NODE_ENV === "test") { + return [ + { + entry: './test/spec/webpack/importSpec.src.js', + mode: 'production', + output: { + path: path.resolve(__dirname, 'test/spec/webpack'), + filename: 'importSpec.build.js' + }, + target: 'node', + resolve: { + extensions: ['.js'] + } + } + ]; } -]; + else { + return [ + { + entry: './lib/duplex.js', + mode: 'production', + optimization: { + minimize: false + }, + output: { + filename: 'fast-json-patch.js', + library: 'jsonpatch', + libraryTarget: 'var' + }, + resolve: { + extensions: ['.js'] + }, + plugins: [ + new webpack.BannerPlugin('fast-json-patch, version: ' + package['version']) + ] + }, + { + entry: './lib/duplex.js', + mode: 'production', + output: { + filename: 'fast-json-patch.min.js', + library: 'jsonpatch', + libraryTarget: 'var' + }, + resolve: { + extensions: ['.js'] + }, + plugins: [ + new webpack.BannerPlugin('fast-json-patch, version: ' + package['version']) + ] + } + ]; + } +}; + + + + +